nexus-2d 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +3 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types/engine/core.d.ts +131 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var t=require("url"),i=require("path");require("module");var r="undefined"!=typeof document?document.currentScript:null;function e(t=0,i=0){return{x:t,y:i}}i.dirname(t.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:r&&"SCRIPT"===r.tagName.toUpperCase()&&r.src||new URL("index.cjs",document.baseURI).href));class s{constructor(t="node"){this.name=t,this.parent=null,this.children=[],this.position=e(),this.rotation=0,this.scale=e(1,1),this.worldPosition=e(),this.worldRotation=0,this.worldScale=e(1,1),this.transformDirty=!0,this.visible=!0,this.active=!0,this.ready=!1}addChild(t){return t.parent&&t.parent.removeChild(t),t.parent=this,t.transformDirty=!0,this.children.push(t),t}removeChild(t){const i=this.children.indexOf(t);-1!==i&&(this.children.splice(i,1),t.parent=null)}markDirty(){this.transformDirty=!0;for(let t=0;t<this.children.length;t++)this.children[t].markDirty()}updateWorldTransform(){if(this.transformDirty)if(this.parent){this.parent.updateWorldTransform();const t=Math.cos(this.parent.worldRotation),i=Math.sin(this.parent.worldRotation),r=this.position.x*this.parent.worldScale.x,e=this.position.y*this.parent.worldScale.y,s=r*t-e*i,o=r*i+e*t;this.worldPosition.x=this.parent.worldPosition.x+s,this.worldPosition.y=this.parent.worldPosition.y+o,this.worldRotation=this.parent.worldRotation+this.rotation,this.worldScale.x=this.parent.worldScale.x*this.scale.x,this.worldScale.y=this.parent.worldScale.y*this.scale.y}else this.worldPosition.x=this.position.x,this.worldPosition.y=this.position.y,this.worldRotation=this.rotation,this.worldScale.x=this.scale.x,this.worldScale.y=this.scale.y}_ready(){}_process(t){}_draw(t,i){}propagateReady(){this.ready||(this._ready(),this.ready=!0);for(let t=0;t<this.children.length;t++)this.children[t].propagateReady()}propagateProcess(t){this.active&&this._process(t);for(let i=0;i<this.children.length;i++)this.children[i].propagateProcess(t)}propagateDraw(t,i){if(this.visible){this.updateWorldTransform(),this._draw(t,i);for(let r=0;r<this.children.length;r++)this.children[r].propagateDraw(t,i)}}findChild(t,i=!0){for(let r=0;r<this.children.length;r++){if(this.children[r].name===t)return this.children[r];if(i){const i=this.children[r].findChild(t,!0);if(i)return i}}return null}getPath(){return this.parent?this.parent.getPath()+"/"+this.name:this.name}}exports.Node=s,exports.Scene=class{constructor(t){this.canvas=t,this.root=new s("Root"),this.paused=!1,this.timeScale=1,this.camera=null,this.root.propagateReady()}addChild(t){return this.root.addChild(t)}process(t){if(this.paused)return;const i=t*this.timeScale;this.root.propagateProcess(i)}draw(){this.root.propagateDraw(this.canvas,this.camera)}getNode(t){const i=t.split("/");let r=this.root;for(let t=0;t<i.length;t++)if("Root"!==i[t]&&""!==i[t]&&(r=r.findChild(i[t],!1),!r))return null;return r}printTree(t=this.root,i=0){const r=" ".repeat(i),e=`(${t.worldPosition.x.toFixed(1)}, ${t.worldPosition.y.toFixed(1)})`;console.log(`${r}${t.name} ${e}`);for(let r=0;r<t.children.length;r++)this.printTree(t.children[r],i+1)}},exports.Transform2D=class{constructor(){this.position=e(),this.rotation=0,this.scale=e(1,1)}copy(t){this.position.x=t.position.x,this.position.y=t.position.y,this.rotation=t.rotation,this.scale.x=t.scale.x,this.scale.y=t.scale.y}},exports.vec2=e;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/engine/core.js","../../node_modules/tessera.js/dist/esm/index.js"],"sourcesContent":["import { PixelBuffer } from \"tessera.js\";\r\n\r\n\r\nexport function vec2(x = 0, y = 0) {\r\n return { x, y };\r\n}\r\n\r\n/**\r\n * local transforms are relative to an object's parent or its own origin (like moving along its own \"front\"), while global transforms are relative to the fixed world origin (0,0,0)\r\n */\r\nexport class Transform2D {\r\n constructor() {\r\n this.position = vec2();\r\n this.rotation = 0; // radians\r\n this.scale = vec2(1, 1);\r\n }\r\n\r\n copy(other) {\r\n this.position.x = other.position.x;\r\n this.position.y = other.position.y;\r\n this.rotation = other.rotation;\r\n this.scale.x = other.scale.x;\r\n this.scale.y = other.scale.y;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * \r\n * Node - base class for all scene objects\r\n * \r\n * Why this design:\r\n * - Children array for hierarchy\r\n * - Dirty flags prevent redundant transform calculations\r\n * - Lifecycle hooks (_ready, _process, _draw) give clear entry points\r\n * - World transform cached for performance\r\n */\r\n\r\nexport class Node {\r\n constructor(name = \"node\") {\r\n this.name = name;\r\n this.parent = null;\r\n this.children = [];\r\n\r\n // relative to parent\r\n this.position = vec2();\r\n this.rotation = 0;\r\n this.scale = vec2(1, 1);\r\n\r\n // world transform absolute, cached\r\n this.worldPosition = vec2();\r\n this.worldRotation = 0;\r\n this.worldScale = vec2(1, 1);\r\n\r\n\r\n this.transformDirty = true; // needs recalculation?\r\n this.visible = true;\r\n this.active = true; // if false, skip _process\r\n\r\n // lifecycle state\r\n this.ready = false;\r\n\r\n }\r\n /**\r\n * \r\n * @param {Node} node \r\n * @returns \r\n */\r\n addChild(node) {\r\n if (node.parent) {\r\n node.parent.removeChild(node);\r\n }\r\n node.parent = this;\r\n node.transformDirty = true;\r\n this.children.push(node);\r\n return node;\r\n }\r\n /**\r\n * \r\n * @param {Node} node \r\n * @returns \r\n */\r\n removeChild(node) {\r\n\r\n const idx = this.children.indexOf(node);\r\n if (idx !== -1) {\r\n this.children.splice(idx, 1);\r\n node.parent = null;\r\n }\r\n }\r\n\r\n\r\n markDirty() {\r\n this.transformDirty = true;\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].markDirty();\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Calculate world transform from local + parent\r\n * \r\n * Why this order:\r\n * 1. Scale the local position\r\n * 2. Rotate it\r\n * 3. Add parent's world position\r\n * \r\n * This gives proper transform inheritance (child orbits parent)\r\n */\r\n updateWorldTransform() {\r\n\r\n if (!this.transformDirty) return;\r\n\r\n if (this.parent) {\r\n // transform relative to parent \r\n // ensure parent is up to date\r\n this.parent.updateWorldTransform();\r\n\r\n // apply parent's transform to our local transform\r\n const cos = Math.cos(this.parent.worldRotation);\r\n const sin = Math.sin(this.parent.worldRotation);\r\n\r\n // scale local position by parent scale\r\n const scaledX = this.position.x * this.parent.worldScale.x;\r\n const scaledY = this.position.y * this.parent.worldScale.y;\r\n\r\n // rotate scaled position\r\n const rotatedX = scaledX * cos - scaledY * sin;\r\n const rotatedY = scaledX * sin + scaledY * cos;\r\n\r\n // translate by parent world position\r\n this.worldPosition.x = this.parent.worldPosition.x + rotatedX;\r\n this.worldPosition.y = this.parent.worldPosition.y + rotatedY;\r\n\r\n // inherit rotation and scale\r\n this.worldRotation = this.parent.worldRotation + this.rotation;\r\n this.worldScale.x = this.parent.worldScale.x * this.scale.x;\r\n this.worldScale.y = this.parent.worldScale.y * this.scale.y;\r\n } else {\r\n // root node - world = local\r\n this.worldPosition.x = this.position.x;\r\n this.worldPosition.y = this.position.y;\r\n this.worldRotation = this.rotation;\r\n this.worldScale.x = this.scale.x;\r\n this.worldScale.y = this.scale.y;\r\n }\r\n\r\n }\r\n\r\n\r\n _ready() {\r\n // Called once when node enters scene tree\r\n }\r\n\r\n _process(delta) {\r\n // Called every frame with time delta\r\n }\r\n\r\n _draw(canvas, camera) {\r\n // Called every frame for rendering\r\n }\r\n\r\n\r\n /**\r\n * internal tree traversal - don't override these\r\n */\r\n propagateReady() {\r\n if (!this.ready) {\r\n this._ready();\r\n this.ready = true;\r\n }\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateReady();\r\n }\r\n }\r\n\r\n propagateProcess(delta) {\r\n if (this.active) {\r\n this._process(delta);\r\n }\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateProcess(delta);\r\n }\r\n }\r\n\r\n propagateDraw(canvas, camera) {\r\n if (!this.visible) return;\r\n\r\n this.updateWorldTransform();\r\n this._draw(canvas, camera);\r\n\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateDraw(canvas, camera);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * utility: find child by name (recursive)\r\n */\r\n findChild(name, recursive = true) {\r\n for (let i = 0; i < this.children.length; i++) {\r\n if (this.children[i].name === name) {\r\n return this.children[i];\r\n }\r\n if (recursive) {\r\n const found = this.children[i].findChild(name, true);\r\n if (found) return found;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * utility: get full path (e.g., \"Root/Player/Sprite\")\r\n */\r\n getPath() {\r\n if (!this.parent) return this.name;\r\n return this.parent.getPath() + \"/\" + this.name;\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Scene - root container + game loop coordinator\r\n * \r\n * why Scene:\r\n * - single entry point for update/draw\r\n * - manages lifecycle (ready propagation)\r\n * - can pause/unpause entire tree\r\n * - scene loading/unloading\r\n */\r\n\r\nexport class Scene {\r\n /**\r\n * \r\n * @param {PixelBuffer} canvas \r\n */\r\n constructor(canvas) {\r\n this.canvas = canvas;\r\n this.root = new Node(\"Root\");\r\n this.paused = false;\r\n this.timeScale = 1.0; // slow-mo or fast-forward\r\n this.camera = null; \r\n\r\n // trigger _ready on root\r\n this.root.propagateReady();\r\n }\r\n\r\n addChild(node) {\r\n return this.root.addChild(node);\r\n }\r\n\r\n process(delta) {\r\n if (this.paused) return;\r\n const scaledDelta = delta * this.timeScale;\r\n this.root.propagateProcess(scaledDelta);\r\n }\r\n\r\n draw() {\r\n this.root.propagateDraw(this.canvas, this.camera);\r\n }\r\n\r\n /**\r\n * find node by path (e.g., \"Player/Weapon\")\r\n */\r\n getNode(path) {\r\n const parts = path.split('/');\r\n let current = this.root;\r\n\r\n for (let i = 0; i < parts.length; i++) {\r\n if (parts[i] === 'Root' || parts[i] === '') continue;\r\n current = current.findChild(parts[i], false);\r\n if (!current) return null;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n /**\r\n * debug: print tree structure\r\n */\r\n printTree(node = this.root, indent = 0) {\r\n const prefix = ' '.repeat(indent);\r\n const pos = `(${node.worldPosition.x.toFixed(1)}, ${node.worldPosition.y.toFixed(1)})`;\r\n console.log(`${prefix}${node.name} ${pos}`);\r\n for (let i = 0; i < node.children.length; i++) {\r\n this.printTree(node.children[i], indent + 1);\r\n }\r\n }\r\n}","import{fileURLToPath as t}from\"url\";import{dirname as e,join as i}from\"path\";import{createRequire as s}from\"module\";const r=e(t(import.meta.url));class h{constructor(){}isKeyDown(t){}isKeyReleased(t){}onKeyDown(t,e){}onKeyUp(t,e){}onMouseDown(t,e){}onMouseUp(t,e){}onMouseMove(t){}onMouseWheel(t){}}class a{constructor(){this.input=new h,this.targetFPS=60}initialize(t,e,i){}shutdown(){}beginFrame(){}endFrame(){}clear(t){}drawRectangle(t,e,i){}drawCircle(t,e,i){}drawLine(t,e,i,s){}drawText(t,e,i,s){}loadTexture(t){return 0}unloadTexture(t){}drawTexture(t,e,i,s){}createRenderTexture(t,e){return 0}destroyRenderTexture(t){}setRenderTarget(t){}createSharedBuffer(t,e,i){return 0}markBufferDirty(t){}markBufferRegionDirty(t,e,i,s,r){}isBufferDirty(t){return!1}getBufferData(t){return new Uint8Array(0)}updateBufferData(t,e,i=0,s=0,r=0,h=0){}updateTextureFromBuffer(t,e){}loadTextureFromBuffer(t,e,i){return 0}drawTextureSized(t,e,i,s,r,h){}drawTexturePro(t,e,i,s,r){}get width(){return 0}get height(){return 0}get WindowShouldClose(){return!1}onRender(t){}step(){return!1}get input(){return new h}get FPS(){return 0}set onResize(t){}set targetFPS(t){}setWindowState(t){}loadImage(t){}GetInput(){}}function o(){const t=s(import.meta.url);try{return t(\"node-gyp-build\")(i(r,\"..\"))}catch(e){console.log(\"method 1 failed:\",e.message);try{return t(i(r,\"..\",\"prebuilds\",process.platform+\"-\"+process.arch,\"renderer.node\"))}catch(e){console.log(\"method 2 failed:\",e.message);try{return t(i(r,\"..\",\"prebuilds\",process.platform+\"-\"+process.arch,\"renderer.node\"))}catch(t){throw console.log(\"method 3 failed:\",t.message),new Error(\"all methods to load the native module failed: please open an issue\")}}}}class n{constructor(t){this.canvas=t,this.width=t.width,this.height=t.height,this.reset()}reset(){this.minX=this.width,this.minY=this.height,this.maxX=-1,this.maxY=-1,this.modified=!1}markRect(t,e,i,s){const r=0|t,h=0|e,a=t+i-1|0,o=e+s-1|0;r<this.minX&&(this.minX=r),h<this.minY&&(this.minY=h),a>this.maxX&&(this.maxX=a),o>this.maxY&&(this.maxY=o),this.modified=!0}mark(t,e){this.markRect(t,e,1,1)}flush(){if(!this.modified)return null;const t=Math.max(0,this.minX),e=Math.max(0,this.minY),i=Math.min(this.width-1,this.maxX),s=Math.min(this.height-1,this.maxY);if(t>i||e>s)return this.reset(),null;const r=i-t+1,h=s-e+1,a=this._extractRegion(t,e,r,h);this.canvas.renderer.updateBufferData(this.canvas.bufferId,a,t,e,r,h),this.canvas.needsUpload=!0;const o={minX:t,minY:e,regionWidth:r,regionHeight:h};return this.reset(),o}_extractRegion(t,e,i,s){const r=this.canvas.data,h=this.width,a=new Uint8Array(i*s*4);for(let o=0;o<s;o++){const s=4*((e+o)*h+t),n=o*i*4;a.set(r.subarray(s,s+4*i),n)}return a}}class l{constructor(t,e,i){this.renderer=t,this.size=e*i*4,this.bufferId=t.createSharedBuffer(this.size,e,i),this.dirty=!1}markDirty(){this.renderer.markBufferDirty(this.bufferId),this.dirty=!0}isDirty(){return this.renderer.isBufferDirty(this.bufferId)}getData(){return this.dirty=!1,this.renderer.getBufferData(this.bufferId)}updateData(t){if(!(t instanceof Uint8Array))throw new Error(\"Data must be Uint8Array\");if(t.length!==this.size)throw new Error(`Data size mismatch: expected ${this.size}, got ${t.length}`);this.renderer.updateBufferData(this.bufferId,t),this.dirty=!0}}class c{constructor(t,e,i,s){this.renderer=t,this.textureId=t.loadTextureFromBuffer(e,i,s),this.width=i,this.height=s,this.bufferId=e}draw(t,e){this.renderer.drawTexture(this.textureId,t,e)}drawTexturePro(t,e,i,s){this.renderer.drawTextureSized(this.textureId,t,e,i,s)}drawTexturePro(t,e,i,s,r){this.renderer.drawTextureSized(this.textureId,t,e,i,s,r)}unload(){this.renderer.unloadTexture(this.textureId)}update(){this.renderer.isBufferDirty(this.bufferId)&&this.renderer.updateTextureFromBuffer(this.textureId,this.bufferId)}}class d{constructor(t,e,i,s){this.canvasX=t,this.canvasY=e,this.canvasWidth=i,this.canvasHeight=s,this.scale=1}screenToCanvas(t,e){return{x:Math.floor((t-this.canvasX)/this.scale),y:Math.floor((e-this.canvasY)/this.scale)}}canvasToScreen(t,e){return{x:Math.floor(t*this.scale+this.canvasX),y:Math.floor(e*this.scale+this.canvasY)}}isPointInCanvas(t,e){const i=this.screenToCanvas(t,e);return i.x>=0&&i.x<this.canvasWidth&&i.y>=0&&i.y<this.canvasHeight}setScale(t){this.scale=Math.max(.1,Math.min(5,t))}}class u{constructor(t){this.canvas=t}drawLine(t,e,i,s,r){const h=Math.abs(i-t),a=-Math.abs(s-e),o=t<i?1:-1,n=e<s?1:-1;let l=h+a;for(;this.canvas.setPixelColor(t,e,r),t!==i||e!==s;){const i=2*l;i>=a&&(l+=a,t+=o),i<=h&&(l+=h,e+=n)}this.canvas.sharedBuffer.markDirty()}drawRectangle(t,e,i,s,r,h=!0){if(h)for(let h=e;h<e+s;h++)for(let e=t;e<t+i;e++)this.canvas.setPixelColor(e,h,r);else this.drawLine(t,e,t+i,e,r),this.drawLine(t+i,e,t+i,e+s,r),this.drawLine(t+i,e+s,t,e+s,r),this.drawLine(t,e+s,t,e,r);this.canvas.sharedBuffer.markDirty()}drawCircle(t,e,i,s,r=!0){let h=i,a=0,o=0;for(;h>=a;)r?(this.drawLine(t-h,e+a,t+h,e+a,s),this.drawLine(t-h,e-a,t+h,e-a,s),this.drawLine(t-a,e+h,t+a,e+h,s),this.drawLine(t-a,e-h,t+a,e-h,s)):(this.canvas.setPixelColor(t+h,e+a,s),this.canvas.setPixelColor(t+a,e+h,s),this.canvas.setPixelColor(t-a,e+h,s),this.canvas.setPixelColor(t-h,e+a,s),this.canvas.setPixelColor(t-h,e-a,s),this.canvas.setPixelColor(t-a,e-h,s),this.canvas.setPixelColor(t+a,e-h,s),this.canvas.setPixelColor(t+h,e-a,s)),a+=1,o+=1+2*a,2*(o-h)+1>0&&(h-=1,o+=1-2*h);this.canvas.sharedBuffer.markDirty()}}class f{static RGBtoHSV(t,e,i){t/=255,e/=255,i/=255;const s=Math.max(t,e,i),r=s-Math.min(t,e,i);let h=0,a=0;return 0!==r&&(a=r/s,h=t===s?(e-i)/r:e===s?2+(i-t)/r:4+(t-e)/r,h*=60,h<0&&(h+=360)),{h:h,s:100*a,v:100*s}}static HSVtoRGB(t,e,i){const s=(i/=100)*(e/=100),r=s*(1-Math.abs(t/60%2-1)),h=i-s;let a,o,n;return[a,o,n]=t>=0&&t<60?[s,r,0]:t<120?[r,s,0]:t<180?[0,s,r]:t<240?[0,r,s]:t<300?[r,0,s]:[s,0,r],{r:Math.floor(255*(a+h)),g:Math.floor(255*(o+h)),b:Math.floor(255*(n+h))}}static complementary(t){const e=this.RGBtoHSV(t.r,t.g,t.b);return e.h=(e.h+180)%360,this.HSVtoRGB(e.h,e.s,e.v)}static analogous(t,e=30){const i=this.RGBtoHSV(t.r,t.g,t.b);return[this.HSVtoRGB((i.h-e+360)%360,i.s,i.v),t,this.HSVtoRGB((i.h+e)%360,i.s,i.v)]}}class m{constructor(){this.metrics=new Map,this.frameTimes=[],this.samples=60}start(t){this.metrics.set(t,{start:performance.now(),calls:(this.metrics.get(t)?.calls||0)+1})}end(t){const e=this.metrics.get(t);if(e){const t=performance.now()-e.start;e.total=(e.total||0)+t,e.max=Math.max(e.max||0,t),e.min=Math.min(e.min||1/0,t)}}recordFrameTime(t){const e=performance.now()-t;this.frameTimes.push(e),this.frameTimes.length>this.samples&&this.frameTimes.shift()}logMetrics(){console.log(\"Performance Report:\");for(const[t,e]of this.metrics){const i=e.total/e.calls;console.log(` ${t}: ${i.toFixed(2)}ms avg (${e.min.toFixed(2)}-${e.max.toFixed(2)}ms)`)}const t=this.frameTimes.reduce((t,e)=>t+e)/this.frameTimes.length;console.log(` Frame Time: ${t.toFixed(2)}ms (${(1e3/t).toFixed(1)} FPS)`)}}function x(t,e,i,s){const r={r:t/255,g:e/255,b:i/255};return null!=s&&(r.a=s/255),r}function p(t,e,i=\"bilinear\",s=e.width,r=e.height){const h=new n(e),a=e.data,o=t.data,l=t.width,c=t.height,d=l/s,u=c/r;for(let t=0;t<r;t++)for(let e=0;e<s;e++){const r=4*(t*s+e);if(\"nn\"===i){const i=Math.floor((e+.5)*d),s=Math.floor((t+.5)*u),h=Math.max(0,Math.min(i,l-1)),n=Math.max(0,Math.min(s,c-1));for(let t=0;t<4;t++)a[r+t]=o[4*(n*l+h)+t]}else{const i=(e+.5)*d-.5,s=(t+.5)*u-.5,h=Math.floor(i),n=Math.floor(s),f=Math.min(h+1,l-1),m=Math.min(n+1,c-1),x=i-h,p=s-n;for(let t=0;t<4;t++){const e=(o[4*(n*l+h)+t]*(1-x)+o[4*(n*l+f)+t]*x)*(1-p)+(o[4*(m*l+h)+t]*(1-x)+o[4*(m*l+f)+t]*x)*p;a[r+t]=Math.round(e)}}}h.markRect(0,0,s,r),h.flush()}function M(t,e,i,s,r=\"bilinear\"){const h=new n(i),a=i.data,o=t.data,l=t.width,c=e.width,d=e.height,u=s.width,f=s.height,m=c/u,x=d/f;for(let h=0;h<f;h++)for(let n=0;n<u;n++){const u=4*((h+s.y)*i.width+(n+s.x));if(\"nn\"===r){const t=e.x+Math.floor((n+.5)*m),i=e.y+Math.floor((h+.5)*x),s=Math.max(e.x,Math.min(t,e.x+c-1)),r=Math.max(e.y,Math.min(i,e.y+d-1));for(let t=0;t<4;t++)a[u+t]=o[4*(r*l+s)+t]}else{const i=e.x+(n+.5)*m-.5,s=e.y+(h+.5)*x-.5,r=Math.floor(i),c=Math.floor(s),d=Math.min(r+1,l-1),f=Math.min(c+1,t.height-1),p=i-r,M=s-c;for(let t=0;t<4;t++){const e=(o[4*(c*l+r)+t]*(1-p)+o[4*(c*l+d)+t]*p)*(1-M)+(o[4*(f*l+r)+t]*(1-p)+o[4*(f*l+d)+t]*p)*M;a[u+t]=Math.round(e)}}}h.markRect(s.x,s.y,s.width,s.height),h.flush()}function g(t,e,i,s,r){const h=[];for(let a=0;a<t;a++)for(let t=0;t<e;t++)h.push({offset:{x:i+t*r,y:s+a*r}});return h}class y{constructor(t){this.input=t,this.actions=new Map,this.mouseActions=new Map,this.callbackIds=[]}mapAction(t,e){\"string\"==typeof e&&(e=[e]),this.actions.set(t,e)}MapMouseAction(t,e){\"string\"==typeof e&&(e=[e]),this.mouseActions.set(t,e)}isMouseActionActive(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonDown(t))}isMousePressed(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonPressed(t))}IsMouseActionReleased(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonReleased(t))}get mousePosition(){return this.input.getMousePosition()}get mouseDelta(){return this.input.getMouseDelta()}get mouseWheelDelta(){return this.input.getMouseWheelDelta()}isActionActive(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyDown(t))}wasActionTriggered(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyPressed(t))}isActionReleased(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyReleased(t))}onActionDown(t,e){const i=this.actions.get(t);i?i.forEach(i=>{const s=this.input.onKeyDown(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onActionUp(t,e){const i=this.actions.get(t);i?i.forEach(i=>{const s=this.input.onKeyUp(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseDown(t,e){const i=this.mouseActions.get(t);i?i.forEach(i=>{const s=this.input.onMouseDown(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseUp(t,e){const i=this.mouseActions.get(t);i?i.forEach(i=>{const s=this.input.onMouseUp(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseMove(t){const e=this.input.onMouseMove(e=>{t(e)});this.callbackIds.push(e)}onMouseWheel(t,e){const i=this.input.onMouseWheel(t=>{e(t)});this.callbackIds.push(i)}cleanup(){this.callbackIds.forEach(t=>{this.input.removeCallback(t)}),this.callbackIds=[]}}class w{constructor(t=60){this.maxSize=t,this.buffer=[]}recordInput(t,e){this.buffer.push({input:t,timestamp:e}),this.buffer.length>this.maxSize&&this.buffer.shift()}checkSequence(t,e=1e3){if(0===t.length||this.buffer.length<t.length)return!1;const i=performance.now();let s=0;for(let r=this.buffer.length-1;r>=0&&s<t.length;r--){const h=this.buffer[r];if(i-h.timestamp>e)break;h.input===t[t.length-1-s]&&s++}return s===t.length}}class b{constructor(t,e,i,s=!1){this.renderer=t,this.width=e,this.height=i,this.DEBUG=s;const r=e*i*4;this.bufferId=t.createSharedBuffer(r,e,i);{let e=t.getBufferData(this.bufferId);this.data=new Uint8Array(new SharedArrayBuffer(r)),this.data.set(new Uint8Array(e)),e=null}this.textureId=t.loadTextureFromBuffer(this.bufferId,e,i),this.needsUpload=!1,this.DEBUG&&console.log(`Created ${e}x${i} buffer (${r} bytes)`)}coordToIndex(t,e){return t<0||t>=this.width||e<0||e>=this.height?-1:4*(e*this.width+t)}setPixel(t,e,i,s,r,h=255){const a=this.coordToIndex(t,e);-1!==a&&(this.data[a+0]=i,this.data[a+1]=s,this.data[a+2]=r,this.data[a+3]=h,this.renderer.updateBufferData(this.bufferId,this.data.subarray(a,a+4),t,e,1,1),this.needsUpload=!0)}getPixel(t,e){const i=this.coordToIndex(t,e);return-1===i?null:{r:this.data[i+0],g:this.data[i+1],b:this.data[i+2],a:this.data[i+3]}}clear(t,e,i,s=255){const r=performance.now(),h=(255&s)<<24|(255&i)<<16|(255&e)<<8|255&t;new Uint32Array(this.data.buffer).fill(h),this.renderer.updateBufferData(this.bufferId,this.data),this.needsUpload=!0;const a=performance.now()-r;this.DEBUG&&console.log(`Clear (${this.width}x${this.height}): ${a.toFixed(2)}ms`)}upload(){this.needsUpload&&(this.renderer.updateTextureFromBuffer(this.textureId,this.bufferId),this.needsUpload=!1)}draw(t,e){this.renderer.drawTexture(this.textureId,{x:t,y:e})}grow(t,e){if(t<=this.width&&e<=this.height)return;const i=t*e*4,s=this.renderer.createSharedBuffer(i,t,e),r=this.renderer.getBufferData(s),h=new Uint8Array(new SharedArrayBuffer(i));h.set(new Uint8Array(r));const a=this.renderer.loadTextureFromBuffer(s,t,e),o=Math.min(this.width,t),n=Math.min(this.height,e);for(let e=0;e<n;e++){const i=e*this.width*4,s=i+4*o,r=e*t*4;h.set(this.data.subarray(i,s),r)}this.renderer.updateBufferData(s,h);try{this.renderer.unloadTexture(this.textureId)}catch(t){this.DEBUG&&console.warn(\"unloadTexture failed while growing buffer:\",t.message||t)}this.bufferId=s,this.data=h,this.textureId=a,this.width=t,this.height=e,this.needsUpload=!0,this.DEBUG&&console.log(`Grew buffer to ${t}x${e} (${i} bytes)`)}destroy(){this.renderer.unloadTexture(this.textureId)}}function v(t,e,i,s){return!(t<0||t>=i.width||e<0||e>=i.height)&&!(s&&s.viewport&&s.viewport.shouldClip(t,e))}class T{constructor(t=0,e=0,i=800,s=600){this.x=t,this.y=e,this.width=i,this.height=s,this.viewport=null}worldToScreen(t,e){const i=t-this.x,s=e-this.y,r=i+this.width/2,h=s+this.height/2;if(this.viewport){const t=this.viewport.width/this.width,e=this.viewport.height/this.height;return{x:r*t+this.viewport.x,y:h*e+this.viewport.y}}return{x:r,y:h}}setViewport(t){this.viewport=t}screenToWorld(t,e){let i,s;if(this.viewport){const r=this.width/this.viewport.width,h=this.height/this.viewport.height;i=(t-this.viewport.x)*r,s=(e-this.viewport.y)*h}else i=t,s=e;return{x:i-this.width/2+this.x,y:s-this.height/2+this.y}}isVisible(t,e){const i=this.worldToScreen(t,e);return this.viewport?this.viewport.contains(i.x,i.y):i.x>=0&&i.x<this.width&&i.y>=0&&i.y<this.height}getVisibleBounds(){const t=this.width/2,e=this.height/2;return{left:this.x-t,right:this.x+t,top:this.y-e,bottom:this.y+e}}move(t,e){this.x+=t,this.y+=e}setPosition(t,e){this.x=t,this.y=e}}class C{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s,this.scissorEnabled=!0}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}toCanvas(t,e){return{x:t+this.x,y:e+this.y}}toLocal(t,e){return{x:t-this.x,y:e-this.y}}getAspectRatio(){return this.width/this.height}setScissor(t){this.scissorEnabled=t}shouldClip(t,e){return!!this.scissorEnabled&&(t<this.x||t>=this.x+this.width||e<this.y||e>=this.y+this.height)}}function A(t,e,i){let s,r,h,a;return t/e>i?(a=e,h=e*i,s=(t-h)/2,r=0):(h=t,a=t/i,s=0,r=(e-a)/2),new C(s,r,h,a)}function P(t,e){if(e.y>0)for(let i=0;i<e.y;i++)for(let e=0;e<t.width;e++)t.setPixel(e,i,0,0,0,255);const i=e.y+e.height;if(i<t.height)for(let e=i;e<t.height;e++)for(let i=0;i<t.width;i++)t.setPixel(i,e,0,0,0,255);if(e.x>0)for(let i=0;i<t.height;i++)for(let s=0;s<e.x;s++)t.setPixel(s,i,0,0,0,255);const s=e.x+e.width;if(s<t.width)for(let e=0;e<t.height;e++)for(let i=s;i<t.width;i++)t.setPixel(i,e,0,0,0,255)}class k{static drawLine(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=performance.now();e=Math.floor(e),i=Math.floor(i),s=Math.floor(s),r=Math.floor(r);const d=Math.abs(s-e),u=Math.abs(r-i),f=e<s?1:-1,m=i<r?1:-1;let x=d-u,p=e,M=i,g=1/0,y=1/0,w=-1/0,b=-1/0;const T=t.data,C=t.width;t.height;let A=0;for(;;){if(v(p,M,t,l)){const t=4*(M*C+p);T[t+0]=h,T[t+1]=a,T[t+2]=o,T[t+3]=n,A++,g=Math.min(g,p),y=Math.min(y,M),w=Math.max(w,p),b=Math.max(b,M)}if(p===s&&M===r)break;const e=2*x;e>-u&&(x-=u,p+=f),e<d&&(x+=d,M+=m)}if(0===A)return{pixels:0,time:0,regionSize:0};const P=w-g+1,B=b-y+1,R=k._extractRegion(T,C,g,y,P,B);t.renderer.updateBufferData(t.bufferId,R,g,y,P,B),t.needsUpload=!0;return{pixels:A,time:performance.now()-c,regionSize:P*B}}static drawThickLine(t,e,i,s,r,h,a,o,n,l=255,c=void 0){e=Math.floor(e),i=Math.floor(i),s=Math.floor(s),r=Math.floor(r),h=Math.max(1,Math.floor(h));const d=performance.now(),u=Math.ceil(h/2),f=k._createBrushStamp(u,a,o,n,l),m=k._bresenhamPoints(e,i,s,r);let x=1/0,p=1/0,M=-1/0,g=-1/0;const y=t.data,w=t.width,b=t.height;let v=0;for(const{x:t,y:e}of m){const i=k._stampBrush(y,w,b,t,e,u,f,c);v+=i.pixels,i.pixels>0&&(x=Math.min(x,i.minX),p=Math.min(p,i.minY),M=Math.max(M,i.maxX),g=Math.max(g,i.maxY))}if(0===v)return{pixels:0,linePoints:m.length,regionSize:0};const T=M-x+1,C=g-p+1,A=k._extractRegion(y,w,x,p,T,C);t.renderer.updateBufferData(t.bufferId,A,x,p,T,C),t.needsUpload=!0;const P=performance.now()-d;return{pixels:v,linePoints:m.length,time:P,regionSize:T*C}}static _bresenhamPoints(t,e,i,s){const r=[],h=Math.abs(i-t),a=Math.abs(s-e),o=t<i?1:-1,n=e<s?1:-1;let l=h-a,c=t,d=e;for(;r.push({x:c,y:d}),c!==i||d!==s;){const t=2*l;t>-a&&(l-=a,c+=o),t<h&&(l+=h,d+=n)}return r}static _createBrushStamp(t,e,i,s,r){const h=[];for(let a=-t;a<=t;a++)for(let o=-t;o<=t;o++){const n=Math.sqrt(o*o+a*a);if(n<=t){const l=Math.max(0,1-n/t),c=Math.floor(r*l);h.push({dx:o,dy:a,r:e,g:i,b:s,a:c})}}return h}static _stampBrush(t,e,i,s,r,h,a,o){let n=0,l=1/0,c=1/0,d=-1/0,u=-1/0;for(const{dx:h,dy:f,r:m,g:x,b:p,a:M}of a){const a=s+h,g=r+f;if(!v(a,g,{width:e,height:i,data:t},o))continue;const y=4*(g*e+a),w=M/255,b=1-w;t[y+0]=Math.floor(m*w+t[y+0]*b),t[y+1]=Math.floor(x*w+t[y+1]*b),t[y+2]=Math.floor(p*w+t[y+2]*b),t[y+3]=255,n++,l=Math.min(l,a),c=Math.min(c,g),d=Math.max(d,a),u=Math.max(u,g)}return{pixels:n,minX:l,minY:c,maxX:d,maxY:u}}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class B{static fillRect(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=function(t,e,i,s,r,h){const a=Math.max(0,Math.floor(t)),o=Math.max(0,Math.floor(e)),n=Math.min(r,Math.ceil(t+i))-a,l=Math.min(h,Math.ceil(e+s))-o;return n<=0||l<=0?null:{x:a,y:o,width:n,height:l}}(e,i,s,r,t.width,t.height);if(!c)return{pixels:0};let{x:d,y:u,width:f,height:m}=c;const x=t.data,p=t.width;let M=1/0,g=1/0,y=-1/0,w=-1/0,b=0;for(let e=u;e<u+m;e++)for(let i=d;i<d+f;i++){if(!v(i,e,t,l))continue;const s=4*(e*p+i);x[s+0]=h,x[s+1]=a,x[s+2]=o,x[s+3]=n,b++,M=Math.min(M,i),g=Math.min(g,e),y=Math.max(y,i),w=Math.max(w,e)}if(0===b)return{pixels:0};const T=y-M+1,C=w-g+1,A=B._extractRegion(x,p,M,g,T,C);return t.renderer.updateBufferData(t.bufferId,A,M,g,T,C),t.needsUpload=!0,{pixels:b}}static strokeRect(t,e,i,s,r,h,a,o,n,l=255,c=void 0){e=Math.floor(e),i=Math.floor(i),s=Math.ceil(s),r=Math.ceil(r),h=Math.max(1,Math.floor(h)),k.drawThickLine(t,e,i,e+s,i,h,a,o,n,l,c),k.drawThickLine(t,e+s,i,e+s,i+r,h,a,o,n,l,c),k.drawThickLine(t,e+s,i+r,e,i+r,h,a,o,n,l,c),k.drawThickLine(t,e,i+r,e,i,h,a,o,n,l,c)}static fillCircle(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=Math.floor(s);if(d<=0)return{pixels:0,time:0};let u=1/0,f=1/0,m=-1/0,x=-1/0;const p=t.data,M=t.width;t.height;let g=d,y=0,w=1-d,b=0;const T=(e,i,s)=>{for(let l=i;l<=s;l++){if(!v(l,e,t,n))continue;const i=4*(e*M+l);p[i+0]=r,p[i+1]=h,p[i+2]=a,p[i+3]=o,b++,u=Math.min(u,l),f=Math.min(f,e),m=Math.max(m,l),x=Math.max(x,e)}};for(T(c,l-g,l+g);g>y;)y++,w<0?w+=2*y+1:(g--,w+=2*(y-g)+1),T(c+y,l-g,l+g),T(c+g,l-y,l+y),T(c-y,l-g,l+g),T(c-g,l-y,l+y);if(0===b)return{pixels:0};const C=m-u+1,A=x-f+1,P=B._extractRegion(p,M,u,f,C,A);t.renderer.updateBufferData(t.bufferId,P,u,f,C,A),t.needsUpload=!0}static strokeCircle(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=Math.floor(e),d=Math.floor(i),u=Math.floor(s);if(u<=0)return{pixels:0,time:0};if(r>1)return B._strokeCircleThick(t,c,d,u,r,h,a,o,n);const f=t.data,m=t.width;t.height;let x=1/0,p=1/0,M=-1/0,g=-1/0,y=u,w=0,b=1-u,T=0;const C=(e,i)=>{if(!v(e,i,t,l))return;const s=4*(i*m+e);f[s+0]=h,f[s+1]=a,f[s+2]=o,f[s+3]=n,T++,x=Math.min(x,e),p=Math.min(p,i),M=Math.max(M,e),g=Math.max(g,i)};for(;y>=w;)C(c+y,d+w),C(c+w,d+y),C(c-y,d+w),C(c-w,d+y),C(c-y,d-w),C(c-w,d-y),C(c+y,d-w),C(c+w,d-y),w++,b<0?b+=2*w+1:(y--,b+=2*(w-y)+1);if(0===T)return{pixels:0};const A=M-x+1,P=g-p+1,k=B._extractRegion(f,m,x,p,A,P);t.renderer.updateBufferData(t.bufferId,k,x,p,A,P),t.needsUpload=!0}static _strokeCircleThick(t,e,i,s,r,h,a,o,n,l){const c=s,d=Math.max(0,s-r),u=t.data,f=t.width,m=t.height;let x=1/0,p=1/0,M=-1/0,g=-1/0,y=0;const w=c*c,b=d*d,T=Math.max(0,e-c),C=Math.max(0,i-c),A=Math.min(f-1,e+c),P=Math.min(m-1,i+c);for(let s=C;s<=P;s++)for(let r=T;r<=A;r++){const c=r-e,d=s-i,m=c*c+d*d;if(m<=w&&m>=b){if(!v(r,s,t,l))continue;const e=4*(s*f+r);u[e+0]=h,u[e+1]=a,u[e+2]=o,u[e+3]=n,y++,x=Math.min(x,r),p=Math.min(p,s),M=Math.max(M,r),g=Math.max(g,s)}}if(0===y)return{pixels:0};const k=M-x+1,R=g-p+1,S=B._extractRegion(u,f,x,p,k,R);t.renderer.updateBufferData(t.bufferId,S,x,p,k,R),t.needsUpload=!0}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class R{static fillPolygon(t,e,i,s,r,h=255,a=void 0){if(e.length<3)return{pixels:0};const o=R._buildEdgeTable(e);if(0===o.length)return{pixels:0};let n=1/0,l=-1/0;for(const t of o)n=Math.min(n,t.yMin),l=Math.max(l,t.yMax);n=Math.max(0,Math.floor(n)),l=Math.min(t.height-1,Math.ceil(l));const c=t.data,d=t.width;t.height;let u=1/0,f=1/0,m=-1/0,x=-1/0,p=0;for(let e=n;e<=l;e++){const n=[];for(const t of o)if(e>=t.yMin&&e<t.yMax){const i=t.x+(e-t.yMin)*t.dx;n.push(i)}n.sort((t,e)=>t-e);for(let o=0;o<n.length-1;o+=2){const l=Math.floor(n[o]),M=Math.ceil(n[o+1]);for(let o=l;o<=M;o++){if(!v(o,e,t,a))continue;const n=4*(e*d+o);c[n+0]=i,c[n+1]=s,c[n+2]=r,c[n+3]=h,p++,u=Math.min(u,o),f=Math.min(f,e),m=Math.max(m,o),x=Math.max(x,e)}}}if(0===p)return{pixels:0};const M=m-u+1,g=x-f+1,y=R._extractRegion(c,d,u,f,M,g);return t.renderer.updateBufferData(t.bufferId,y,u,f,M,g),t.needsUpload=!0,{pixels:p,vertices:e.length,scanlines:x-f+1}}static _buildEdgeTable(t){const e=[],i=t.length;for(let s=0;s<i;s++){const r=t[s],h=t[(s+1)%i];if(Math.abs(r.y-h.y)<.001)continue;let a=r.x,o=r.y,n=h.x,l=h.y;o>l&&([a,n]=[n,a],[o,l]=[l,o]);const c=(n-a)/(l-o);e.push({yMin:o,yMax:l,x:a,dx:c})}return e}static strokePolygon(t,e,i,s,r,h,a=255,o=void 0){if(!(e.length<2))for(let n=0;n<e.length;n++){const l=e[n],c=e[(n+1)%e.length];k.drawThickLine(t,l.x,l.y,c.x,c.y,i,s,r,h,a,o)}}static createRegularPolygon(t,e,i,s){const r=[],h=2*Math.PI/s;for(let a=0;a<s;a++){const s=a*h-Math.PI/2;r.push({x:t+Math.cos(s)*i,y:e+Math.sin(s)*i})}return r}static createStar(t,e,i,s,r){const h=[],a=2*Math.PI/(2*r);for(let o=0;o<2*r;o++){const r=o*a-Math.PI/2,n=o%2==0?i:s;h.push({x:t+Math.cos(r)*n,y:e+Math.sin(r)*n})}return h}static createRoundedRect(t,e,i,s,r){const h=[],a=(t,e,i,s,r)=>{for(let a=0;a<=8;a++){const o=s+(r-s)*(a/8);h.push({x:t+Math.cos(o)*i,y:e+Math.sin(o)*i})}},o=Math.min(r,i/2,s/2);return a(t+i-o,e+o,o,-Math.PI/2,0),a(t+i-o,e+s-o,o,0,Math.PI/2),a(t+o,e+s-o,o,Math.PI/2,Math.PI),a(t+o,e+o,o,Math.PI,1.5*Math.PI),h}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class S{static drawLineAA(t,e,i,s,r,h,a,o,n=255,l=void 0){let c=1/0,d=1/0,u=-1/0,f=-1/0,m=0;const x=t.data,p=t.width;if(t.height,e===s&&i===r){if(S._setPixelAA(t,e,i,h,a,o,n,l)){const t=Math.floor(e),s=Math.floor(i);m=1,c=Math.min(c,t),d=Math.min(d,s),u=Math.max(u,t),f=Math.max(f,s)}}else{const x=Math.abs(r-i)>Math.abs(s-e);x&&([e,i]=[i,e],[s,r]=[r,s]),e>s&&([e,s]=[s,e],[i,r]=[r,i]);const p=s-e,M=0===p?1:(r-i)/p;let g=Math.round(e),y=i+M*(g-e),w=1-(e+.5-Math.floor(e+.5)),b=g,v=Math.floor(y),T=!1;x?(T=S._setPixelAA(t,v,b,h,a,o,n*(1-(y-v))*w,l),T&&(m++,c=Math.min(c,v),d=Math.min(d,b),u=Math.max(u,v),f=Math.max(f,b)),T=S._setPixelAA(t,v+1,b,h,a,o,n*(y-v)*w,l),T&&(m++,c=Math.min(c,v+1),d=Math.min(d,b),u=Math.max(u,v+1),f=Math.max(f,b))):(T=S._setPixelAA(t,b,v,h,a,o,n*(1-(y-v))*w,l),T&&(m++,c=Math.min(c,b),d=Math.min(d,v),u=Math.max(u,b),f=Math.max(f,v)),T=S._setPixelAA(t,b,v+1,h,a,o,n*(y-v)*w,l),T&&(m++,c=Math.min(c,b),d=Math.min(d,v+1),u=Math.max(u,b),f=Math.max(f,v+1)));let C=y+M;g=Math.round(s),y=r+M*(g-s),w=s+.5-Math.floor(s+.5);let A=g,P=Math.floor(y);if(x?(T=S._setPixelAA(t,P,A,h,a,o,n*(1-(y-P))*w,l),T&&(m++,c=Math.min(c,P),d=Math.min(d,A),u=Math.max(u,P),f=Math.max(f,A)),T=S._setPixelAA(t,P+1,A,h,a,o,n*(y-P)*w,l),T&&(m++,c=Math.min(c,P+1),d=Math.min(d,A),u=Math.max(u,P+1),f=Math.max(f,A))):(T=S._setPixelAA(t,A,P,h,a,o,n*(1-(y-P))*w,l),T&&(m++,c=Math.min(c,A),d=Math.min(d,P),u=Math.max(u,A),f=Math.max(f,P)),T=S._setPixelAA(t,A,P+1,h,a,o,n*(y-P)*w,l),T&&(m++,c=Math.min(c,A),d=Math.min(d,P+1),u=Math.max(u,A),f=Math.max(f,P+1))),x)for(let e=b+1;e<A;e++){const i=Math.floor(C),s=C-i;T=S._setPixelAA(t,i,e,h,a,o,n*(1-s),l),T&&(m++,c=Math.min(c,i),d=Math.min(d,e),u=Math.max(u,i),f=Math.max(f,e)),T=S._setPixelAA(t,i+1,e,h,a,o,n*s,l),T&&(m++,c=Math.min(c,i+1),d=Math.min(d,e),u=Math.max(u,i+1),f=Math.max(f,e)),C+=M}else for(let e=b+1;e<A;e++){const i=Math.floor(C),s=C-i;T=S._setPixelAA(t,e,i,h,a,o,n*(1-s),l),T&&(m++,c=Math.min(c,e),d=Math.min(d,i),u=Math.max(u,e),f=Math.max(f,i)),T=S._setPixelAA(t,e,i+1,h,a,o,n*s,l),T&&(m++,c=Math.min(c,e),d=Math.min(d,i+1),u=Math.max(u,e),f=Math.max(f,i+1)),C+=M}}if(0===m)return;const M=u-c+1,g=f-d+1,y=S._extractRegion(x,p,c,d,M,g);t.renderer.updateBufferData(t.bufferId,y,c,d,M,g),t.needsUpload=!0}static _setPixelAA(t,e,i,s,r,h,a,o){if(!v(e=Math.floor(e),i=Math.floor(i),t,o))return!1;const n=Math.max(0,Math.min(1,a/255));if(n<=0)return!1;const l=4*(i*t.width+e),c=t.data,d=1-n;return c[l+0]=Math.floor(s*n+c[l+0]*d),c[l+1]=Math.floor(r*n+c[l+1]*d),c[l+2]=Math.floor(h*n+c[l+2]*d),c[l+3]=255,!0}static drawCircleAA(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=s;if(d<=0)return;const u=(d-.5)*(d-.5),f=(d+.5)*(d+.5),m=Math.max(0,l-Math.ceil(d)-1),x=Math.max(0,c-Math.ceil(d)-1),p=Math.min(t.width-1,l+Math.ceil(d)+1),M=Math.min(t.height-1,c+Math.ceil(d)+1);let g=1/0,y=1/0,w=-1/0,b=-1/0,v=0;for(let s=x;s<=M;s++){const l=s-i;for(let i=m;i<=p;i++){const c=i-e,m=c*c+l*l;if(m<u||m>f)continue;const x=Math.sqrt(m),p=1-Math.abs(x-d)/.5;S._setPixelAA(t,i,s,r,h,a,o*p,n)&&(v++,g=Math.min(g,i),y=Math.min(y,s),w=Math.max(w,i),b=Math.max(b,s))}}if(0===v)return;const T=w-g+1,C=b-y+1,A=S._extractRegion(t.data,t.width,g,y,T,C);t.renderer.updateBufferData(t.bufferId,A,g,y,T,C),t.needsUpload=!0}static fillCircleAA(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=s;if(d<=0)return{pixels:0,time:0};const u=Math.max(0,l-Math.ceil(d)-1),f=Math.max(0,c-Math.ceil(d)-1),m=Math.min(t.width-1,l+Math.ceil(d)+1),x=Math.min(t.height-1,c+Math.ceil(d)+1);let p=1/0,M=1/0,g=-1/0,y=-1/0,w=0;for(let s=f;s<=x;s++)for(let l=u;l<=m;l++){const c=l-e,u=s-i,f=Math.sqrt(c*c+u*u);if(f>d+.5)continue;const m=f<=d-.5?1:d+.5-f;S._setPixelAA(t,l,s,r,h,a,o*m,n)&&(w++,p=Math.min(p,l),M=Math.min(M,s),g=Math.max(g,l),y=Math.max(y,s))}if(0===w)return;const b=g-p+1,v=y-M+1,T=S._extractRegion(t.data,t.width,p,M,b,v);t.renderer.updateBufferData(t.bufferId,T,p,M,b,v),t.needsUpload=!0}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}const D={NORMAL:0,MULTIPLY:1,SCREEN:2,OVERLAY:3,ADD:4,SUBTRACT:5,DARKEN:6,LIGHTEN:7,DIFFERENCE:8,COLOR_DODGE:9,COLOR_BURN:10};class I{static tempCanvas=void 0;static drawWithBlend(t,e,i=D.NORMAL){const s=t.width,r=t.height,h=t.data;this.tempCanvas||(this.tempCanvas=new b(t.renderer,s,r)),this.tempCanvas.clear(0,0,0,0),e(this.tempCanvas);const a=this.tempCanvas.data,o=h.length,n=this._getBlendFunction(i);for(let t=0;t<o;t+=16)0!==a[t+3]&&n(a[t],a[t+1],a[t+2],a[t+3],h[t],h[t+1],h[t+2],h[t+3],h,t),0!==a[t+7]&&n(a[t+4],a[t+5],a[t+6],a[t+7],h[t+4],h[t+5],h[t+6],h[t+7],h,t+4),0!==a[t+11]&&n(a[t+8],a[t+9],a[t+10],a[t+11],h[t+8],h[t+9],h[t+10],h[t+11],h,t+8),0!==a[t+15]&&n(a[t+12],a[t+13],a[t+14],a[t+15],h[t+12],h[t+13],h[t+14],h[t+15],h,t+12);t.renderer.updateBufferData(t.bufferId,h),t.needsUpload=!0}static _getBlendFunction(t){switch(t){case D.MULTIPLY:return this._blendMultiply;case D.SCREEN:return this._blendScreen;case D.OVERLAY:return this._blendOverlay;case D.ADD:return this._blendAdd;case D.SUBTRACT:return this._blendSubtract;case D.DARKEN:return this._blendDarken;case D.LIGHTEN:return this._blendLighten;case D.DIFFERENCE:return this._blendDifference;case D.COLOR_DODGE:return this._blendColorDodge;case D.COLOR_BURN:return this._blendColorBurn;default:return this._blendNormal}}static _blendNormal(t,e,i,s,r,h,a,o,n,l){if(255===s)return n[l]=t,n[l+1]=e,n[l+2]=i,void(n[l+3]=255);if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;n[l]=(t*c+r*d*(1-c))*f,n[l+1]=(e*c+h*d*(1-c))*f,n[l+2]=(i*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendMultiply(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t*r*.00392156862745098,x=e*h*.00392156862745098,p=i*a*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendScreen(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=255-(255-t)*(255-r)*.00392156862745098,x=255-(255-e)*(255-h)*.00392156862745098,p=255-(255-i)*(255-a)*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendOverlay(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=r<128?2*t*r*.00392156862745098:255-2*(255-t)*(255-r)*.00392156862745098,x=h<128?2*e*h*.00392156862745098:255-2*(255-e)*(255-h)*.00392156862745098,p=a<128?2*i*a*.00392156862745098:255-2*(255-i)*(255-a)*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendAdd(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;let m=t+r;m>255&&(m=255);let x=e+h;x>255&&(x=255);let p=i+a;p>255&&(p=255),n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendSubtract(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;let m=r-t;m<0&&(m=0);let x=h-e;x<0&&(x=0);let p=a-i;p<0&&(p=0),n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendDarken(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t<r?t:r,x=e<h?e:h,p=i<a?i:a;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendLighten(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t>r?t:r,x=e>h?e:h,p=i>a?i:a;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendDifference(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=Math.abs(t-r),x=Math.abs(e-h),p=Math.abs(i-a);n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendColorDodge(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=255===t?255:Math.min(255,255*r/(255-t)),x=255===e?255:Math.min(255,255*h/(255-e)),p=255===i?255:Math.min(255,255*a/(255-i));n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendColorBurn(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=0===t?0:Math.max(0,255-255*(255-r)/t),x=0===e?0:Math.max(0,255-255*(255-h)/e),p=0===i?0:Math.max(0,255-255*(255-a)/i);n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static setPixelBlended(t,e,i,s,r,h,a,o=D.NORMAL){if(e<0||e>=t.width||i<0||i>=t.height||0===a)return;const n=4*(i*t.width+e),l=t.data,c=l[n],d=l[n+1],u=l[n+2],f=l[n+3];if(o===D.NORMAL){if(255===a)return l[n]=s,l[n+1]=r,l[n+2]=h,void(l[n+3]=255);const t=.00392156862745098*a,e=.00392156862745098*f,i=t+e*(1-t);if(i<.001)return l[n]=0,l[n+1]=0,l[n+2]=0,void(l[n+3]=0);const o=1/i;return l[n]=(s*t+c*e*(1-t))*o,l[n+1]=(r*t+d*e*(1-t))*o,l[n+2]=(h*t+u*e*(1-t))*o,void(l[n+3]=255*i)}this._getBlendFunction(o)(s,r,h,a,c,d,u,f,l,n)}static createTestGradient(t){const e=t.width,i=t.height,s=t.data;for(let t=0;t<i;t++){const r=t/i*255;for(let i=0;i<e;i++){const h=4*(t*e+i);s[h]=i/e*255,s[h+1]=r,s[h+2]=128,s[h+3]=255}}t.upload()}}class _{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s}intersects(t,e,i,s){return!(t+i<this.x||t>this.x+this.width||e+s<this.y||e>this.y+this.height)}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}intersect(t){const e=Math.max(this.x,t.x),i=Math.max(this.y,t.y),s=Math.min(this.x+this.width,t.x+t.width),r=Math.min(this.y+this.height,t.y+t.height);return s<=e||r<=i?null:new _(e,i,s-e,r-i)}computeOutcode(t,e){let i=0;return t<this.x&&(i|=1),t>=this.x+this.width&&(i|=2),e<this.y&&(i|=4),e>=this.y+this.height&&(i|=8),i}}class L{constructor(t=0,e=0,i=1,s=1,r=0){this.translateX=t,this.translateY=e,this.scaleX=i,this.scaleY=s,this.rotation=r}apply(t,e){if(0!==this.rotation){const i=Math.cos(this.rotation),s=Math.sin(this.rotation),r=t*s+e*i;t=t*i-e*s,e=r}return{x:t*this.scaleX+this.translateX,y:e*this.scaleY+this.translateY}}applyRect(t,e,i,s){const r=[this.apply(t,e),this.apply(t+i,e),this.apply(t,e+s),this.apply(t+i,e+s)];let h=1/0,a=1/0,o=-1/0,n=-1/0;for(const t of r)h=Math.min(h,t.x),a=Math.min(a,t.y),o=Math.max(o,t.x),n=Math.max(n,t.y);return{x:h,y:a,width:o-h,height:n-a}}compose(t){return new L(this.translateX+t.translateX*this.scaleX,this.translateY+t.translateY*this.scaleY,this.scaleX*t.scaleX,this.scaleY*t.scaleY,this.rotation+t.rotation)}static identity(){return new L(0,0,1,1,0)}}class U{constructor(){this.clipStack=[],this.transformStack=[L.identity()],this.globalAlpha=1,this.fillStyle={r:0,g:0,b:0,a:255},this.strokeStyle={r:0,g:0,b:0,a:255},this.lineWidth=1}get currentClip(){return this.clipStack.length>0?this.clipStack[this.clipStack.length-1]:null}get currentTransform(){return this.transformStack[this.transformStack.length-1]}pushClip(t){this.clipStack.push(t)}popClip(){return this.clipStack.pop()}pushTransform(t){const e=this.currentTransform;this.transformStack.push(e.compose(t))}popTransform(){return this.transformStack.length>1?this.transformStack.pop():this.currentTransform}save(){return{clipStack:[...this.clipStack],transformStack:[...this.transformStack],globalAlpha:this.globalAlpha,fillStyle:{...this.fillStyle},strokeStyle:{...this.strokeStyle},lineWidth:this.lineWidth}}restore(t){this.clipStack=t.clipStack,this.transformStack=t.transformStack,this.globalAlpha=t.globalAlpha,this.fillStyle=t.fillStyle,this.strokeStyle=t.strokeStyle,this.lineWidth=t.lineWidth}}class F{constructor(t){this.canvas=t,this.state=new U,this.state.pushClip(new _(0,0,t.width,t.height))}save(){return this.state.save()}restore(t){this.state.restore(t)}pushClipRect(t,e,i,s){const r=this.state.currentTransform.applyRect(t,e,i,s),h=new _(r.x,r.y,r.width,r.height),a=this.state.currentClip;if(a){const t=a.intersect(h);t?this.state.pushClip(t):this.state.pushClip(new _(0,0,0,0))}else this.state.pushClip(h)}popClipRect(){this.state.popClip()}pushTransform(t=0,e=0,i=1,s=1,r=0){const h=new L(t,e,i,s,r);this.state.pushTransform(h)}popTransform(){this.state.popTransform()}isRectVisible(t,e,i,s){const r=this.state.currentTransform.applyRect(t,e,i,s),h=this.state.currentClip;return!h||h.intersects(r.x,r.y,r.width,r.height)}transformPoint(t,e){return this.state.currentTransform.apply(t,e)}clipLine(t,e,i,s){const r=this.state.currentClip;if(!r)return{x1:t,y1:e,x2:i,y2:s};const h=this.state.currentTransform;let a=h.apply(t,e),o=h.apply(i,s),n=r.computeOutcode(a.x,a.y),l=r.computeOutcode(o.x,o.y),c=!1;for(;;){if(0===(n|l)){c=!0;break}if(0!==(n&l))break;{let t,e;const i=0!==n?n:l;8&i?(t=a.x+(o.x-a.x)*(r.y+r.height-a.y)/(o.y-a.y),e=r.y+r.height):4&i?(t=a.x+(o.x-a.x)*(r.y-a.y)/(o.y-a.y),e=r.y):2&i?(e=a.y+(o.y-a.y)*(r.x+r.width-a.x)/(o.x-a.x),t=r.x+r.width):1&i&&(e=a.y+(o.y-a.y)*(r.x-a.x)/(o.x-a.x),t=r.x),i===n?(a.x=t,a.y=e,n=r.computeOutcode(a.x,a.y)):(o.x=t,o.y=e,l=r.computeOutcode(o.x,o.y))}}return c?{x1:a.x,y1:a.y,x2:o.x,y2:o.y}:null}fillRect(t,e,i,s,r,h,a,o=255){if(!this.isRectVisible(t,e,i,s))return;const n=this.state.currentTransform.applyRect(t,e,i,s),l=this.state.currentClip,c=Math.max(l.x,n.x),d=Math.max(l.y,n.y),u=Math.min(l.x+l.width,n.x+n.width),f=Math.min(l.y+l.height,n.y+n.height);if(u>c&&f>d){const t=o*this.state.globalAlpha;B.fillRect(this.canvas,c,d,u-c,f-d,r,h,a,t)}}strokeRect(t,e,i,s,r,h,a,o,n=255){if(!this.isRectVisible(t,e,i,s))return;const l=n*this.state.globalAlpha,c=this.state.currentTransform,d=c.apply(t,e),u=c.apply(t+i,e),f=c.apply(t+i,e+s),m=c.apply(t,e+s);this._drawClippedLine(d.x,d.y,u.x,u.y,r,h,a,o,l),this._drawClippedLine(u.x,u.y,f.x,f.y,r,h,a,o,l),this._drawClippedLine(f.x,f.y,m.x,m.y,r,h,a,o,l),this._drawClippedLine(m.x,m.y,d.x,d.y,r,h,a,o,l)}drawLine(t,e,i,s,r,h,a,o,n=255){const l=this.clipLine(t,e,i,s);if(!l)return;const c=n*this.state.globalAlpha;1===r?LineDrawer.drawLine(this.canvas,l.x1,l.y1,l.x2,l.y2,h,a,o,c):LineDrawer.drawThickLine(this.canvas,l.x1,l.y1,l.x2,l.y2,r,h,a,o,c)}fillCircle(t,e,i,s,r,h,a=255){if(!this.isRectVisible(t-i,e-i,2*i,2*i))return;const o=this.state.currentTransform,n=o.apply(t,e),l=i*(Math.abs(o.scaleX)+Math.abs(o.scaleY))/2,c=a*this.state.globalAlpha;this._fillCircleClipped(n.x,n.y,l,s,r,h,c)}_drawClippedLine(t,e,i,s,r,h,a,o,n){const l=this.clipLine(t,e,i,s);l&&(1===r?LineDrawer.drawLine(this.canvas,l.x1,l.y1,l.x2,l.y2,h,a,o,n):LineDrawer.drawThickLine(this.canvas,l.x1,l.y1,l.x2,l.y2,r,h,a,o,n))}_fillCircleClipped(t,e,i,s,r,h,a){const o=this.state.currentClip,n=this.canvas.data,l=this.canvas.width,c=this.canvas.height,d=Math.max(0,Math.floor(t-i)),u=Math.min(l-1,Math.ceil(t+i)),f=Math.max(0,Math.floor(e-i)),m=Math.min(c-1,Math.ceil(e+i));for(let c=f;c<=m;c++)for(let f=d;f<=u;f++){if(o&&!o.contains(f,c))continue;const d=f-t,u=c-e;if(Math.sqrt(d*d+u*u)<=i){const t=4*(c*l+f);n[t+0]=s,n[t+1]=r,n[t+2]=h,n[t+3]=a}}this.canvas.renderer.updateBufferData(this.canvas.bufferId,this.canvas.data.subarray(0,l*c*4),d,f,u-d+1,m-f+1),this.canvas.needsUpload=!0}setFillStyle(t,e,i,s=255){this.state.fillStyle={r:t,g:e,b:i,a:s}}setStrokeStyle(t,e,i,s=255){this.state.strokeStyle={r:t,g:e,b:i,a:s}}setLineWidth(t){this.state.lineWidth=t}setGlobalAlpha(t){this.state.globalAlpha=Math.max(0,Math.min(1,t))}}class E{constructor(t,e,i,s,r,h,a,o){this.char=t,this.x=e,this.y=i,this.width=s,this.height=r,this.xOffset=h,this.yOffset=a,this.xAdvance=o}}class H{constructor(t,e,i={}){this.renderer=t,this.atlasImage=t.loadImage(e),this.atlasImage.data||console.warn(\"image data empty\"),this.config={bitmapWidth:i.bitmapWidth||this.atlasImage.width,bitmapHeight:i.bitmapHeight||this.atlasImage.height,cellsPerRow:i.cellsPerRow||16,cellsPerColumn:i.cellsPerColumn||16,cellWidth:i.cellWidth||32,cellHeight:i.cellHeight||32,fontSize:i.fontSize||16,offsetX:i.offsetX||0,offsetY:i.offsetY||0,charOrder:i.charOrder||this.getDefaultCharOrder()},this.glyphs=new Map,this.buildGlyphMap(),this.lineHeight=this.config.cellHeight,this.baseline=Math.floor(.8*this.lineHeight)}getDefaultCharOrder(){return\" ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{¦}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■□\"}buildGlyphMap(){const{cellsPerRow:t,cellsPerColumn:e,cellWidth:i,cellHeight:s,offsetX:r,offsetY:h,charOrder:a}=this.config;let o=0;for(let n=0;n<e;n++)for(let e=0;e<t&&!(o>=a.length);e++){const t=a[o],l=new E(t,e*i+r,n*s+h,i,s,0,0,i);this.glyphs.set(t,l),o++}console.log(`Built ${this.glyphs.size} glyphs from atlas`)}getGlyph(t){let e=this.glyphs.get(t);if(!e){if(\"\\n\"==e)return this.glyphs.get(\" \");e=this.glyphs.get(\"?\")||this.glyphs.get(\" \")||this.glyphs.values().next().value}return e}measureText(t){let e=0;for(let i=0;i<t.length;i++){e+=this.getGlyph(t[i]).xAdvance}return{width:e,height:this.lineHeight}}drawText(t,e,i,s,r={r:255,g:255,b:255,a:255},h=void 0){let a=i;const o=s,n=this.atlasImage.data,l=this.atlasImage.width,c=t.data,d=t.width,u=t.height;let f=1/0,m=1/0,x=-1/0,p=-1/0;for(let i=0;i<e.length;i++){const s=e[i];if(\" \"===s){a+=this.getGlyph(s).xAdvance;continue}const M=this.getGlyph(s),g=Math.floor(a+M.xOffset),y=Math.floor(o+M.yOffset);for(let e=0;e<M.height;e++)for(let i=0;i<M.width;i++){const s=g+i,a=y+e;if(s<0||s>=d||a<0||a>=u)continue;if(!v(s,a,t,h))continue;const o=M.x+i,w=4*((M.y+e)*l+o),b=n[w+0],T=n[w+1],C=n[w+2],A=n[w+3];if(0===A)continue;const P=(b+T+C)/3/255*(A/255)*(r.a/255);if(P<.01)continue;const k=4*(a*d+s),B=1-P;c[k+0]=Math.floor(r.r*P+c[k+0]*B),c[k+1]=Math.floor(r.g*P+c[k+1]*B),c[k+2]=Math.floor(r.b*P+c[k+2]*B),c[k+3]=255,f=Math.min(f,s),m=Math.min(m,a),x=Math.max(x,s),p=Math.max(p,a)}a+=M.xAdvance}if(f!==1/0){const e=x-f,i=p-m,s=new Uint8Array(e*i*4);for(let t=0;t<i;t++){const i=4*((m+t)*d+f),r=t*e*4,h=4*e;s.set(c.subarray(i,i+h),r)}t.renderer.updateBufferData(t.bufferId,s,f,m,e,i),t.needsUpload=!0,t.upload()}}drawTextWithTint(t,e,i,s,r,h,a,o=255,n=void 0){return this.drawText(t,e,i,s,{r:r,g:h,b:a,a:o},n)}wrapText(t,e){const i=t.split(\" \"),s=[];let r=\"\";return i.forEach(t=>{const i=r+(r?\" \":\"\")+t;this.measureText(i).width>e&&r?(s.push(r),r=t):r=i}),r&&s.push(r),s}drawMultilineText(t,e,i,s,r,h=\"left\",a={r:255,g:255,b:255,a:255},o=void 0){const n=this.wrapText(e,r);let l=s;return n.forEach(e=>{const s=this.measureText(e);let n=i;\"center\"===h?n=i+(r-s.width)/2:\"right\"===h&&(n=i+r-s.width),this.drawText(t,e,n,l,a,o),l+=this.lineHeight}),{width:r,height:n.length*this.lineHeight}}}class O{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s,this.visible=!0,this.enabled=!0}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}update(t){}draw(t,e){}}class Y extends O{constructor(t,e,i,s,r,h){super(t,e,i,s),this.text=r,this.onClick=h,this.isHovered=!1,this.isPressed=!1,this.normalColor={r:70,g:80,b:100},this.hoverColor={r:90,g:100,b:120},this.pressedColor={r:50,g:60,b:80},this.textColor={r:255,g:255,b:255,a:255},this.borderRadius=8}update(t){if(!this.enabled)return;const e=t.mousePosition;this.isHovered,this.isHovered=this.contains(e.x,e.y),this.isHovered&&t.isMousePressed(\"click\")&&(this.isPressed=!0),this.isPressed&&t.IsMouseActionReleased(\"click\")&&(this.isHovered&&this.onClick&&this.onClick(),this.isPressed=!1)}draw(t,e){if(!this.visible)return;let i=this.normalColor;this.enabled?this.isPressed?i=this.pressedColor:this.isHovered&&(i=this.hoverColor):i={r:40,g:45,b:50};const s=R.createRoundedRect(this.x,this.y,this.width,this.height,this.borderRadius);if(R.fillPolygon(t,s,i.r,i.g,i.b,255),R.strokePolygon(t,s,2,this.isHovered?120:80,this.isHovered?140:100,this.isHovered?160:120,255),e&&this.text){const i=e.measureText(this.text),s=this.x+(this.width-i.width)/2,r=this.y+(this.height-i.height)/2;e.drawText(t,this.text,s,r,this.textColor)}}}class V extends O{constructor(t,e,i,s,r=\"\"){super(t,e,i,s),this.text=\"\",this.placeholder=r,this.isFocused=!1,this.cursorPosition=0,this.cursorBlinkTime=0,this.cursorVisible=!0,this.backgroundColor={r:40,g:45,b:55},this.focusedBackgroundColor={r:50,g:55,b:65},this.borderColor={r:80,g:90,b:110},this.focusedBorderColor={r:100,g:150,b:200},this.textColor={r:255,g:255,b:255,a:255},this.placeholderColor={r:120,g:130,b:140,a:255},this.cursorColor={r:255,g:255,b:255,a:255},this.padding=8,this.borderRadius=6,this.onTextChange=null,this.onSubmit=null}update(t,e=16){if(!this.enabled)return;const i=t.mousePosition;if(t.isMousePressed(\"click\")){const t=this.contains(i.x,i.y);t&&!this.isFocused?this.focus():!t&&this.isFocused&&this.blur()}this.isFocused&&(this.cursorBlinkTime+=e,this.cursorBlinkTime>=530&&(this.cursorVisible=!this.cursorVisible,this.cursorBlinkTime=0))}focus(){this.isFocused=!0,this.cursorPosition=this.text.length,this.cursorVisible=!0,this.cursorBlinkTime=0}blur(){this.isFocused=!1,this.cursorVisible=!1}handleChar(t){this.isFocused&&(this.text=this.text.slice(0,this.cursorPosition)+t+this.text.slice(this.cursorPosition),this.cursorPosition++,this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleBackspace(){this.isFocused&&0!==this.cursorPosition&&(this.text=this.text.slice(0,this.cursorPosition-1)+this.text.slice(this.cursorPosition),this.cursorPosition--,this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleDelete(){!this.isFocused||this.cursorPosition>=this.text.length||(this.text=this.text.slice(0,this.cursorPosition)+this.text.slice(this.cursorPosition+1),this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleSubmit(){this.isFocused&&this.onSubmit&&this.onSubmit(this.text)}moveCursorLeft(){this.isFocused&&0!==this.cursorPosition&&(this.cursorPosition--,this.cursorVisible=!0,this.cursorBlinkTime=0)}moveCursorRight(){!this.isFocused||this.cursorPosition>=this.text.length||(this.cursorPosition++,this.cursorVisible=!0,this.cursorBlinkTime=0)}setText(t){this.text=t,this.cursorPosition=t.length,this.cursorVisible=!0,this.cursorBlinkTime=0}getText(){return this.text}clear(){this.text=\"\",this.cursorPosition=0,this.cursorVisible=!0,this.cursorBlinkTime=0}draw(t,e){if(!this.visible)return;const i=this.isFocused?this.focusedBackgroundColor:this.backgroundColor,s=R.createRoundedRect(this.x,this.y,this.width,this.height,this.borderRadius);R.fillPolygon(t,s,i.r,i.g,i.b,255);const r=this.isFocused?this.focusedBorderColor:this.borderColor;if(R.strokePolygon(t,s,this.isFocused?2:1,r.r,r.g,r.b,255),!e)return;const h=this.text||this.placeholder,a=this.text?this.textColor:this.placeholderColor;if(h){const i=this.x+this.padding,s=this.y+(this.height-e.lineHeight)/2;e.drawText(t,h,i,s,a)}if(this.isFocused&&this.cursorVisible){const i=this.text.slice(0,this.cursorPosition),s=e.measureText(i).width,r=this.x+this.padding+s,h=this.y+this.padding,a=this.y+this.height-this.padding;B.fillRect(t,r,h,2,a-h,this.cursorColor.r,this.cursorColor.g,this.cursorColor.b,this.cursorColor.a)}}}class X extends O{constructor(t,e,i,s={r:255,g:255,b:255,a:255}){super(t,e,0,0),this.text=i,this.color=s}draw(t,e){this.visible&&e&&e.drawText(t,this.text,this.x,this.y,this.color)}}class G{constructor(t,e,i){this.canvas=t,this.font=e,this.inputMap=i,this.elements=[],this.focusedElement=null,this.lastFrameTime=performance.now()}add(t){return this.elements.push(t),t}remove(t){const e=this.elements.indexOf(t);e>-1&&this.elements.splice(e,1)}clear(){this.elements=[],this.focusedElement=null}update(){const t=performance.now(),e=t-this.lastFrameTime;this.lastFrameTime=t,this.elements.forEach(t=>{t.enabled&&t.update(this.inputMap,e)})}draw(){this.elements.forEach(t=>{t.visible&&t.draw(this.canvas,this.font)})}}export{S as AADrawer,H as BitmapFont,D as BlendMode,Y as Button,T as Camera,_ as ClipRect,F as ClippingContext,f as ColorTheory,I as Compositor,d as CoordinateSystem,n as DirtyRegionTracker,u as DrawingTools,U as GraphicsState,w as InputBuffer,y as InputMap,X as Label,k as LineDrawer,m as PerformanceMonitor,b as PixelBuffer,R as PolygonDrawer,a as Renderer,B as ShapeDrawer,l as SharedBuffer,V as TextInput,c as Texture,L as Transform,O as UIElement,G as UIManager,C as Viewport,A as createLetterboxedViewport,M as drawAtlasRegionToCanvas,P as drawLetterboxBars,g as genFrames,p as imageToCanvas,o as loadRenderer,x as normalizeRGBA};\n//# sourceMappingURL=index.js.map\n"],"names":["vec2","x","y","e","t","document","require","pathToFileURL","__filename","href","_documentCurrentScript","tagName","toUpperCase","src","URL","baseURI","Node","constructor","name","this","parent","children","position","rotation","scale","worldPosition","worldRotation","worldScale","transformDirty","visible","active","ready","addChild","node","removeChild","push","idx","indexOf","splice","markDirty","i","length","updateWorldTransform","cos","Math","sin","scaledX","scaledY","rotatedX","rotatedY","_ready","_process","delta","_draw","canvas","camera","propagateReady","propagateProcess","propagateDraw","findChild","recursive","found","getPath","root","paused","timeScale","process","scaledDelta","draw","getNode","path","parts","split","current","printTree","indent","prefix","repeat","pos","toFixed","console","log","copy","other"],"mappings":"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","x_google_ignoreList":[1]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{fileURLToPath as t}from"url";import{dirname as i}from"path";import"module";function r(t=0,i=0){return{x:t,y:i}}i(t(import.meta.url));class s{constructor(){this.position=r(),this.rotation=0,this.scale=r(1,1)}copy(t){this.position.x=t.position.x,this.position.y=t.position.y,this.rotation=t.rotation,this.scale.x=t.scale.x,this.scale.y=t.scale.y}}class o{constructor(t="node"){this.name=t,this.parent=null,this.children=[],this.position=r(),this.rotation=0,this.scale=r(1,1),this.worldPosition=r(),this.worldRotation=0,this.worldScale=r(1,1),this.transformDirty=!0,this.visible=!0,this.active=!0,this.ready=!1}addChild(t){return t.parent&&t.parent.removeChild(t),t.parent=this,t.transformDirty=!0,this.children.push(t),t}removeChild(t){const i=this.children.indexOf(t);-1!==i&&(this.children.splice(i,1),t.parent=null)}markDirty(){this.transformDirty=!0;for(let t=0;t<this.children.length;t++)this.children[t].markDirty()}updateWorldTransform(){if(this.transformDirty)if(this.parent){this.parent.updateWorldTransform();const t=Math.cos(this.parent.worldRotation),i=Math.sin(this.parent.worldRotation),r=this.position.x*this.parent.worldScale.x,s=this.position.y*this.parent.worldScale.y,o=r*t-s*i,e=r*i+s*t;this.worldPosition.x=this.parent.worldPosition.x+o,this.worldPosition.y=this.parent.worldPosition.y+e,this.worldRotation=this.parent.worldRotation+this.rotation,this.worldScale.x=this.parent.worldScale.x*this.scale.x,this.worldScale.y=this.parent.worldScale.y*this.scale.y}else this.worldPosition.x=this.position.x,this.worldPosition.y=this.position.y,this.worldRotation=this.rotation,this.worldScale.x=this.scale.x,this.worldScale.y=this.scale.y}_ready(){}_process(t){}_draw(t,i){}propagateReady(){this.ready||(this._ready(),this.ready=!0);for(let t=0;t<this.children.length;t++)this.children[t].propagateReady()}propagateProcess(t){this.active&&this._process(t);for(let i=0;i<this.children.length;i++)this.children[i].propagateProcess(t)}propagateDraw(t,i){if(this.visible){this.updateWorldTransform(),this._draw(t,i);for(let r=0;r<this.children.length;r++)this.children[r].propagateDraw(t,i)}}findChild(t,i=!0){for(let r=0;r<this.children.length;r++){if(this.children[r].name===t)return this.children[r];if(i){const i=this.children[r].findChild(t,!0);if(i)return i}}return null}getPath(){return this.parent?this.parent.getPath()+"/"+this.name:this.name}}class e{constructor(t){this.canvas=t,this.root=new o("Root"),this.paused=!1,this.timeScale=1,this.camera=null,this.root.propagateReady()}addChild(t){return this.root.addChild(t)}process(t){if(this.paused)return;const i=t*this.timeScale;this.root.propagateProcess(i)}draw(){this.root.propagateDraw(this.canvas,this.camera)}getNode(t){const i=t.split("/");let r=this.root;for(let t=0;t<i.length;t++)if("Root"!==i[t]&&""!==i[t]&&(r=r.findChild(i[t],!1),!r))return null;return r}printTree(t=this.root,i=0){const r=" ".repeat(i),s=`(${t.worldPosition.x.toFixed(1)}, ${t.worldPosition.y.toFixed(1)})`;console.log(`${r}${t.name} ${s}`);for(let r=0;r<t.children.length;r++)this.printTree(t.children[r],i+1)}}export{o as Node,e as Scene,s as Transform2D,r as vec2};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/engine/core.js","../../node_modules/tessera.js/dist/esm/index.js"],"sourcesContent":["import { PixelBuffer } from \"tessera.js\";\r\n\r\n\r\nexport function vec2(x = 0, y = 0) {\r\n return { x, y };\r\n}\r\n\r\n/**\r\n * local transforms are relative to an object's parent or its own origin (like moving along its own \"front\"), while global transforms are relative to the fixed world origin (0,0,0)\r\n */\r\nexport class Transform2D {\r\n constructor() {\r\n this.position = vec2();\r\n this.rotation = 0; // radians\r\n this.scale = vec2(1, 1);\r\n }\r\n\r\n copy(other) {\r\n this.position.x = other.position.x;\r\n this.position.y = other.position.y;\r\n this.rotation = other.rotation;\r\n this.scale.x = other.scale.x;\r\n this.scale.y = other.scale.y;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * \r\n * Node - base class for all scene objects\r\n * \r\n * Why this design:\r\n * - Children array for hierarchy\r\n * - Dirty flags prevent redundant transform calculations\r\n * - Lifecycle hooks (_ready, _process, _draw) give clear entry points\r\n * - World transform cached for performance\r\n */\r\n\r\nexport class Node {\r\n constructor(name = \"node\") {\r\n this.name = name;\r\n this.parent = null;\r\n this.children = [];\r\n\r\n // relative to parent\r\n this.position = vec2();\r\n this.rotation = 0;\r\n this.scale = vec2(1, 1);\r\n\r\n // world transform absolute, cached\r\n this.worldPosition = vec2();\r\n this.worldRotation = 0;\r\n this.worldScale = vec2(1, 1);\r\n\r\n\r\n this.transformDirty = true; // needs recalculation?\r\n this.visible = true;\r\n this.active = true; // if false, skip _process\r\n\r\n // lifecycle state\r\n this.ready = false;\r\n\r\n }\r\n /**\r\n * \r\n * @param {Node} node \r\n * @returns \r\n */\r\n addChild(node) {\r\n if (node.parent) {\r\n node.parent.removeChild(node);\r\n }\r\n node.parent = this;\r\n node.transformDirty = true;\r\n this.children.push(node);\r\n return node;\r\n }\r\n /**\r\n * \r\n * @param {Node} node \r\n * @returns \r\n */\r\n removeChild(node) {\r\n\r\n const idx = this.children.indexOf(node);\r\n if (idx !== -1) {\r\n this.children.splice(idx, 1);\r\n node.parent = null;\r\n }\r\n }\r\n\r\n\r\n markDirty() {\r\n this.transformDirty = true;\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].markDirty();\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Calculate world transform from local + parent\r\n * \r\n * Why this order:\r\n * 1. Scale the local position\r\n * 2. Rotate it\r\n * 3. Add parent's world position\r\n * \r\n * This gives proper transform inheritance (child orbits parent)\r\n */\r\n updateWorldTransform() {\r\n\r\n if (!this.transformDirty) return;\r\n\r\n if (this.parent) {\r\n // transform relative to parent \r\n // ensure parent is up to date\r\n this.parent.updateWorldTransform();\r\n\r\n // apply parent's transform to our local transform\r\n const cos = Math.cos(this.parent.worldRotation);\r\n const sin = Math.sin(this.parent.worldRotation);\r\n\r\n // scale local position by parent scale\r\n const scaledX = this.position.x * this.parent.worldScale.x;\r\n const scaledY = this.position.y * this.parent.worldScale.y;\r\n\r\n // rotate scaled position\r\n const rotatedX = scaledX * cos - scaledY * sin;\r\n const rotatedY = scaledX * sin + scaledY * cos;\r\n\r\n // translate by parent world position\r\n this.worldPosition.x = this.parent.worldPosition.x + rotatedX;\r\n this.worldPosition.y = this.parent.worldPosition.y + rotatedY;\r\n\r\n // inherit rotation and scale\r\n this.worldRotation = this.parent.worldRotation + this.rotation;\r\n this.worldScale.x = this.parent.worldScale.x * this.scale.x;\r\n this.worldScale.y = this.parent.worldScale.y * this.scale.y;\r\n } else {\r\n // root node - world = local\r\n this.worldPosition.x = this.position.x;\r\n this.worldPosition.y = this.position.y;\r\n this.worldRotation = this.rotation;\r\n this.worldScale.x = this.scale.x;\r\n this.worldScale.y = this.scale.y;\r\n }\r\n\r\n }\r\n\r\n\r\n _ready() {\r\n // Called once when node enters scene tree\r\n }\r\n\r\n _process(delta) {\r\n // Called every frame with time delta\r\n }\r\n\r\n _draw(canvas, camera) {\r\n // Called every frame for rendering\r\n }\r\n\r\n\r\n /**\r\n * internal tree traversal - don't override these\r\n */\r\n propagateReady() {\r\n if (!this.ready) {\r\n this._ready();\r\n this.ready = true;\r\n }\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateReady();\r\n }\r\n }\r\n\r\n propagateProcess(delta) {\r\n if (this.active) {\r\n this._process(delta);\r\n }\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateProcess(delta);\r\n }\r\n }\r\n\r\n propagateDraw(canvas, camera) {\r\n if (!this.visible) return;\r\n\r\n this.updateWorldTransform();\r\n this._draw(canvas, camera);\r\n\r\n for (let i = 0; i < this.children.length; i++) {\r\n this.children[i].propagateDraw(canvas, camera);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * utility: find child by name (recursive)\r\n */\r\n findChild(name, recursive = true) {\r\n for (let i = 0; i < this.children.length; i++) {\r\n if (this.children[i].name === name) {\r\n return this.children[i];\r\n }\r\n if (recursive) {\r\n const found = this.children[i].findChild(name, true);\r\n if (found) return found;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * utility: get full path (e.g., \"Root/Player/Sprite\")\r\n */\r\n getPath() {\r\n if (!this.parent) return this.name;\r\n return this.parent.getPath() + \"/\" + this.name;\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Scene - root container + game loop coordinator\r\n * \r\n * why Scene:\r\n * - single entry point for update/draw\r\n * - manages lifecycle (ready propagation)\r\n * - can pause/unpause entire tree\r\n * - scene loading/unloading\r\n */\r\n\r\nexport class Scene {\r\n /**\r\n * \r\n * @param {PixelBuffer} canvas \r\n */\r\n constructor(canvas) {\r\n this.canvas = canvas;\r\n this.root = new Node(\"Root\");\r\n this.paused = false;\r\n this.timeScale = 1.0; // slow-mo or fast-forward\r\n this.camera = null; \r\n\r\n // trigger _ready on root\r\n this.root.propagateReady();\r\n }\r\n\r\n addChild(node) {\r\n return this.root.addChild(node);\r\n }\r\n\r\n process(delta) {\r\n if (this.paused) return;\r\n const scaledDelta = delta * this.timeScale;\r\n this.root.propagateProcess(scaledDelta);\r\n }\r\n\r\n draw() {\r\n this.root.propagateDraw(this.canvas, this.camera);\r\n }\r\n\r\n /**\r\n * find node by path (e.g., \"Player/Weapon\")\r\n */\r\n getNode(path) {\r\n const parts = path.split('/');\r\n let current = this.root;\r\n\r\n for (let i = 0; i < parts.length; i++) {\r\n if (parts[i] === 'Root' || parts[i] === '') continue;\r\n current = current.findChild(parts[i], false);\r\n if (!current) return null;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n /**\r\n * debug: print tree structure\r\n */\r\n printTree(node = this.root, indent = 0) {\r\n const prefix = ' '.repeat(indent);\r\n const pos = `(${node.worldPosition.x.toFixed(1)}, ${node.worldPosition.y.toFixed(1)})`;\r\n console.log(`${prefix}${node.name} ${pos}`);\r\n for (let i = 0; i < node.children.length; i++) {\r\n this.printTree(node.children[i], indent + 1);\r\n }\r\n }\r\n}","import{fileURLToPath as t}from\"url\";import{dirname as e,join as i}from\"path\";import{createRequire as s}from\"module\";const r=e(t(import.meta.url));class h{constructor(){}isKeyDown(t){}isKeyReleased(t){}onKeyDown(t,e){}onKeyUp(t,e){}onMouseDown(t,e){}onMouseUp(t,e){}onMouseMove(t){}onMouseWheel(t){}}class a{constructor(){this.input=new h,this.targetFPS=60}initialize(t,e,i){}shutdown(){}beginFrame(){}endFrame(){}clear(t){}drawRectangle(t,e,i){}drawCircle(t,e,i){}drawLine(t,e,i,s){}drawText(t,e,i,s){}loadTexture(t){return 0}unloadTexture(t){}drawTexture(t,e,i,s){}createRenderTexture(t,e){return 0}destroyRenderTexture(t){}setRenderTarget(t){}createSharedBuffer(t,e,i){return 0}markBufferDirty(t){}markBufferRegionDirty(t,e,i,s,r){}isBufferDirty(t){return!1}getBufferData(t){return new Uint8Array(0)}updateBufferData(t,e,i=0,s=0,r=0,h=0){}updateTextureFromBuffer(t,e){}loadTextureFromBuffer(t,e,i){return 0}drawTextureSized(t,e,i,s,r,h){}drawTexturePro(t,e,i,s,r){}get width(){return 0}get height(){return 0}get WindowShouldClose(){return!1}onRender(t){}step(){return!1}get input(){return new h}get FPS(){return 0}set onResize(t){}set targetFPS(t){}setWindowState(t){}loadImage(t){}GetInput(){}}function o(){const t=s(import.meta.url);try{return t(\"node-gyp-build\")(i(r,\"..\"))}catch(e){console.log(\"method 1 failed:\",e.message);try{return t(i(r,\"..\",\"prebuilds\",process.platform+\"-\"+process.arch,\"renderer.node\"))}catch(e){console.log(\"method 2 failed:\",e.message);try{return t(i(r,\"..\",\"prebuilds\",process.platform+\"-\"+process.arch,\"renderer.node\"))}catch(t){throw console.log(\"method 3 failed:\",t.message),new Error(\"all methods to load the native module failed: please open an issue\")}}}}class n{constructor(t){this.canvas=t,this.width=t.width,this.height=t.height,this.reset()}reset(){this.minX=this.width,this.minY=this.height,this.maxX=-1,this.maxY=-1,this.modified=!1}markRect(t,e,i,s){const r=0|t,h=0|e,a=t+i-1|0,o=e+s-1|0;r<this.minX&&(this.minX=r),h<this.minY&&(this.minY=h),a>this.maxX&&(this.maxX=a),o>this.maxY&&(this.maxY=o),this.modified=!0}mark(t,e){this.markRect(t,e,1,1)}flush(){if(!this.modified)return null;const t=Math.max(0,this.minX),e=Math.max(0,this.minY),i=Math.min(this.width-1,this.maxX),s=Math.min(this.height-1,this.maxY);if(t>i||e>s)return this.reset(),null;const r=i-t+1,h=s-e+1,a=this._extractRegion(t,e,r,h);this.canvas.renderer.updateBufferData(this.canvas.bufferId,a,t,e,r,h),this.canvas.needsUpload=!0;const o={minX:t,minY:e,regionWidth:r,regionHeight:h};return this.reset(),o}_extractRegion(t,e,i,s){const r=this.canvas.data,h=this.width,a=new Uint8Array(i*s*4);for(let o=0;o<s;o++){const s=4*((e+o)*h+t),n=o*i*4;a.set(r.subarray(s,s+4*i),n)}return a}}class l{constructor(t,e,i){this.renderer=t,this.size=e*i*4,this.bufferId=t.createSharedBuffer(this.size,e,i),this.dirty=!1}markDirty(){this.renderer.markBufferDirty(this.bufferId),this.dirty=!0}isDirty(){return this.renderer.isBufferDirty(this.bufferId)}getData(){return this.dirty=!1,this.renderer.getBufferData(this.bufferId)}updateData(t){if(!(t instanceof Uint8Array))throw new Error(\"Data must be Uint8Array\");if(t.length!==this.size)throw new Error(`Data size mismatch: expected ${this.size}, got ${t.length}`);this.renderer.updateBufferData(this.bufferId,t),this.dirty=!0}}class c{constructor(t,e,i,s){this.renderer=t,this.textureId=t.loadTextureFromBuffer(e,i,s),this.width=i,this.height=s,this.bufferId=e}draw(t,e){this.renderer.drawTexture(this.textureId,t,e)}drawTexturePro(t,e,i,s){this.renderer.drawTextureSized(this.textureId,t,e,i,s)}drawTexturePro(t,e,i,s,r){this.renderer.drawTextureSized(this.textureId,t,e,i,s,r)}unload(){this.renderer.unloadTexture(this.textureId)}update(){this.renderer.isBufferDirty(this.bufferId)&&this.renderer.updateTextureFromBuffer(this.textureId,this.bufferId)}}class d{constructor(t,e,i,s){this.canvasX=t,this.canvasY=e,this.canvasWidth=i,this.canvasHeight=s,this.scale=1}screenToCanvas(t,e){return{x:Math.floor((t-this.canvasX)/this.scale),y:Math.floor((e-this.canvasY)/this.scale)}}canvasToScreen(t,e){return{x:Math.floor(t*this.scale+this.canvasX),y:Math.floor(e*this.scale+this.canvasY)}}isPointInCanvas(t,e){const i=this.screenToCanvas(t,e);return i.x>=0&&i.x<this.canvasWidth&&i.y>=0&&i.y<this.canvasHeight}setScale(t){this.scale=Math.max(.1,Math.min(5,t))}}class u{constructor(t){this.canvas=t}drawLine(t,e,i,s,r){const h=Math.abs(i-t),a=-Math.abs(s-e),o=t<i?1:-1,n=e<s?1:-1;let l=h+a;for(;this.canvas.setPixelColor(t,e,r),t!==i||e!==s;){const i=2*l;i>=a&&(l+=a,t+=o),i<=h&&(l+=h,e+=n)}this.canvas.sharedBuffer.markDirty()}drawRectangle(t,e,i,s,r,h=!0){if(h)for(let h=e;h<e+s;h++)for(let e=t;e<t+i;e++)this.canvas.setPixelColor(e,h,r);else this.drawLine(t,e,t+i,e,r),this.drawLine(t+i,e,t+i,e+s,r),this.drawLine(t+i,e+s,t,e+s,r),this.drawLine(t,e+s,t,e,r);this.canvas.sharedBuffer.markDirty()}drawCircle(t,e,i,s,r=!0){let h=i,a=0,o=0;for(;h>=a;)r?(this.drawLine(t-h,e+a,t+h,e+a,s),this.drawLine(t-h,e-a,t+h,e-a,s),this.drawLine(t-a,e+h,t+a,e+h,s),this.drawLine(t-a,e-h,t+a,e-h,s)):(this.canvas.setPixelColor(t+h,e+a,s),this.canvas.setPixelColor(t+a,e+h,s),this.canvas.setPixelColor(t-a,e+h,s),this.canvas.setPixelColor(t-h,e+a,s),this.canvas.setPixelColor(t-h,e-a,s),this.canvas.setPixelColor(t-a,e-h,s),this.canvas.setPixelColor(t+a,e-h,s),this.canvas.setPixelColor(t+h,e-a,s)),a+=1,o+=1+2*a,2*(o-h)+1>0&&(h-=1,o+=1-2*h);this.canvas.sharedBuffer.markDirty()}}class f{static RGBtoHSV(t,e,i){t/=255,e/=255,i/=255;const s=Math.max(t,e,i),r=s-Math.min(t,e,i);let h=0,a=0;return 0!==r&&(a=r/s,h=t===s?(e-i)/r:e===s?2+(i-t)/r:4+(t-e)/r,h*=60,h<0&&(h+=360)),{h:h,s:100*a,v:100*s}}static HSVtoRGB(t,e,i){const s=(i/=100)*(e/=100),r=s*(1-Math.abs(t/60%2-1)),h=i-s;let a,o,n;return[a,o,n]=t>=0&&t<60?[s,r,0]:t<120?[r,s,0]:t<180?[0,s,r]:t<240?[0,r,s]:t<300?[r,0,s]:[s,0,r],{r:Math.floor(255*(a+h)),g:Math.floor(255*(o+h)),b:Math.floor(255*(n+h))}}static complementary(t){const e=this.RGBtoHSV(t.r,t.g,t.b);return e.h=(e.h+180)%360,this.HSVtoRGB(e.h,e.s,e.v)}static analogous(t,e=30){const i=this.RGBtoHSV(t.r,t.g,t.b);return[this.HSVtoRGB((i.h-e+360)%360,i.s,i.v),t,this.HSVtoRGB((i.h+e)%360,i.s,i.v)]}}class m{constructor(){this.metrics=new Map,this.frameTimes=[],this.samples=60}start(t){this.metrics.set(t,{start:performance.now(),calls:(this.metrics.get(t)?.calls||0)+1})}end(t){const e=this.metrics.get(t);if(e){const t=performance.now()-e.start;e.total=(e.total||0)+t,e.max=Math.max(e.max||0,t),e.min=Math.min(e.min||1/0,t)}}recordFrameTime(t){const e=performance.now()-t;this.frameTimes.push(e),this.frameTimes.length>this.samples&&this.frameTimes.shift()}logMetrics(){console.log(\"Performance Report:\");for(const[t,e]of this.metrics){const i=e.total/e.calls;console.log(` ${t}: ${i.toFixed(2)}ms avg (${e.min.toFixed(2)}-${e.max.toFixed(2)}ms)`)}const t=this.frameTimes.reduce((t,e)=>t+e)/this.frameTimes.length;console.log(` Frame Time: ${t.toFixed(2)}ms (${(1e3/t).toFixed(1)} FPS)`)}}function x(t,e,i,s){const r={r:t/255,g:e/255,b:i/255};return null!=s&&(r.a=s/255),r}function p(t,e,i=\"bilinear\",s=e.width,r=e.height){const h=new n(e),a=e.data,o=t.data,l=t.width,c=t.height,d=l/s,u=c/r;for(let t=0;t<r;t++)for(let e=0;e<s;e++){const r=4*(t*s+e);if(\"nn\"===i){const i=Math.floor((e+.5)*d),s=Math.floor((t+.5)*u),h=Math.max(0,Math.min(i,l-1)),n=Math.max(0,Math.min(s,c-1));for(let t=0;t<4;t++)a[r+t]=o[4*(n*l+h)+t]}else{const i=(e+.5)*d-.5,s=(t+.5)*u-.5,h=Math.floor(i),n=Math.floor(s),f=Math.min(h+1,l-1),m=Math.min(n+1,c-1),x=i-h,p=s-n;for(let t=0;t<4;t++){const e=(o[4*(n*l+h)+t]*(1-x)+o[4*(n*l+f)+t]*x)*(1-p)+(o[4*(m*l+h)+t]*(1-x)+o[4*(m*l+f)+t]*x)*p;a[r+t]=Math.round(e)}}}h.markRect(0,0,s,r),h.flush()}function M(t,e,i,s,r=\"bilinear\"){const h=new n(i),a=i.data,o=t.data,l=t.width,c=e.width,d=e.height,u=s.width,f=s.height,m=c/u,x=d/f;for(let h=0;h<f;h++)for(let n=0;n<u;n++){const u=4*((h+s.y)*i.width+(n+s.x));if(\"nn\"===r){const t=e.x+Math.floor((n+.5)*m),i=e.y+Math.floor((h+.5)*x),s=Math.max(e.x,Math.min(t,e.x+c-1)),r=Math.max(e.y,Math.min(i,e.y+d-1));for(let t=0;t<4;t++)a[u+t]=o[4*(r*l+s)+t]}else{const i=e.x+(n+.5)*m-.5,s=e.y+(h+.5)*x-.5,r=Math.floor(i),c=Math.floor(s),d=Math.min(r+1,l-1),f=Math.min(c+1,t.height-1),p=i-r,M=s-c;for(let t=0;t<4;t++){const e=(o[4*(c*l+r)+t]*(1-p)+o[4*(c*l+d)+t]*p)*(1-M)+(o[4*(f*l+r)+t]*(1-p)+o[4*(f*l+d)+t]*p)*M;a[u+t]=Math.round(e)}}}h.markRect(s.x,s.y,s.width,s.height),h.flush()}function g(t,e,i,s,r){const h=[];for(let a=0;a<t;a++)for(let t=0;t<e;t++)h.push({offset:{x:i+t*r,y:s+a*r}});return h}class y{constructor(t){this.input=t,this.actions=new Map,this.mouseActions=new Map,this.callbackIds=[]}mapAction(t,e){\"string\"==typeof e&&(e=[e]),this.actions.set(t,e)}MapMouseAction(t,e){\"string\"==typeof e&&(e=[e]),this.mouseActions.set(t,e)}isMouseActionActive(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonDown(t))}isMousePressed(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonPressed(t))}IsMouseActionReleased(t){const e=this.mouseActions.get(t);return!!e&&e.some(t=>this.input.isMouseButtonReleased(t))}get mousePosition(){return this.input.getMousePosition()}get mouseDelta(){return this.input.getMouseDelta()}get mouseWheelDelta(){return this.input.getMouseWheelDelta()}isActionActive(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyDown(t))}wasActionTriggered(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyPressed(t))}isActionReleased(t){const e=this.actions.get(t);return!!e&&e.some(t=>this.input.isKeyReleased(t))}onActionDown(t,e){const i=this.actions.get(t);i?i.forEach(i=>{const s=this.input.onKeyDown(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onActionUp(t,e){const i=this.actions.get(t);i?i.forEach(i=>{const s=this.input.onKeyUp(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseDown(t,e){const i=this.mouseActions.get(t);i?i.forEach(i=>{const s=this.input.onMouseDown(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseUp(t,e){const i=this.mouseActions.get(t);i?i.forEach(i=>{const s=this.input.onMouseUp(i,i=>{e(t,i)});this.callbackIds.push(s)}):console.warn(`Action '${t}' not mapped`)}onMouseMove(t){const e=this.input.onMouseMove(e=>{t(e)});this.callbackIds.push(e)}onMouseWheel(t,e){const i=this.input.onMouseWheel(t=>{e(t)});this.callbackIds.push(i)}cleanup(){this.callbackIds.forEach(t=>{this.input.removeCallback(t)}),this.callbackIds=[]}}class w{constructor(t=60){this.maxSize=t,this.buffer=[]}recordInput(t,e){this.buffer.push({input:t,timestamp:e}),this.buffer.length>this.maxSize&&this.buffer.shift()}checkSequence(t,e=1e3){if(0===t.length||this.buffer.length<t.length)return!1;const i=performance.now();let s=0;for(let r=this.buffer.length-1;r>=0&&s<t.length;r--){const h=this.buffer[r];if(i-h.timestamp>e)break;h.input===t[t.length-1-s]&&s++}return s===t.length}}class b{constructor(t,e,i,s=!1){this.renderer=t,this.width=e,this.height=i,this.DEBUG=s;const r=e*i*4;this.bufferId=t.createSharedBuffer(r,e,i);{let e=t.getBufferData(this.bufferId);this.data=new Uint8Array(new SharedArrayBuffer(r)),this.data.set(new Uint8Array(e)),e=null}this.textureId=t.loadTextureFromBuffer(this.bufferId,e,i),this.needsUpload=!1,this.DEBUG&&console.log(`Created ${e}x${i} buffer (${r} bytes)`)}coordToIndex(t,e){return t<0||t>=this.width||e<0||e>=this.height?-1:4*(e*this.width+t)}setPixel(t,e,i,s,r,h=255){const a=this.coordToIndex(t,e);-1!==a&&(this.data[a+0]=i,this.data[a+1]=s,this.data[a+2]=r,this.data[a+3]=h,this.renderer.updateBufferData(this.bufferId,this.data.subarray(a,a+4),t,e,1,1),this.needsUpload=!0)}getPixel(t,e){const i=this.coordToIndex(t,e);return-1===i?null:{r:this.data[i+0],g:this.data[i+1],b:this.data[i+2],a:this.data[i+3]}}clear(t,e,i,s=255){const r=performance.now(),h=(255&s)<<24|(255&i)<<16|(255&e)<<8|255&t;new Uint32Array(this.data.buffer).fill(h),this.renderer.updateBufferData(this.bufferId,this.data),this.needsUpload=!0;const a=performance.now()-r;this.DEBUG&&console.log(`Clear (${this.width}x${this.height}): ${a.toFixed(2)}ms`)}upload(){this.needsUpload&&(this.renderer.updateTextureFromBuffer(this.textureId,this.bufferId),this.needsUpload=!1)}draw(t,e){this.renderer.drawTexture(this.textureId,{x:t,y:e})}grow(t,e){if(t<=this.width&&e<=this.height)return;const i=t*e*4,s=this.renderer.createSharedBuffer(i,t,e),r=this.renderer.getBufferData(s),h=new Uint8Array(new SharedArrayBuffer(i));h.set(new Uint8Array(r));const a=this.renderer.loadTextureFromBuffer(s,t,e),o=Math.min(this.width,t),n=Math.min(this.height,e);for(let e=0;e<n;e++){const i=e*this.width*4,s=i+4*o,r=e*t*4;h.set(this.data.subarray(i,s),r)}this.renderer.updateBufferData(s,h);try{this.renderer.unloadTexture(this.textureId)}catch(t){this.DEBUG&&console.warn(\"unloadTexture failed while growing buffer:\",t.message||t)}this.bufferId=s,this.data=h,this.textureId=a,this.width=t,this.height=e,this.needsUpload=!0,this.DEBUG&&console.log(`Grew buffer to ${t}x${e} (${i} bytes)`)}destroy(){this.renderer.unloadTexture(this.textureId)}}function v(t,e,i,s){return!(t<0||t>=i.width||e<0||e>=i.height)&&!(s&&s.viewport&&s.viewport.shouldClip(t,e))}class T{constructor(t=0,e=0,i=800,s=600){this.x=t,this.y=e,this.width=i,this.height=s,this.viewport=null}worldToScreen(t,e){const i=t-this.x,s=e-this.y,r=i+this.width/2,h=s+this.height/2;if(this.viewport){const t=this.viewport.width/this.width,e=this.viewport.height/this.height;return{x:r*t+this.viewport.x,y:h*e+this.viewport.y}}return{x:r,y:h}}setViewport(t){this.viewport=t}screenToWorld(t,e){let i,s;if(this.viewport){const r=this.width/this.viewport.width,h=this.height/this.viewport.height;i=(t-this.viewport.x)*r,s=(e-this.viewport.y)*h}else i=t,s=e;return{x:i-this.width/2+this.x,y:s-this.height/2+this.y}}isVisible(t,e){const i=this.worldToScreen(t,e);return this.viewport?this.viewport.contains(i.x,i.y):i.x>=0&&i.x<this.width&&i.y>=0&&i.y<this.height}getVisibleBounds(){const t=this.width/2,e=this.height/2;return{left:this.x-t,right:this.x+t,top:this.y-e,bottom:this.y+e}}move(t,e){this.x+=t,this.y+=e}setPosition(t,e){this.x=t,this.y=e}}class C{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s,this.scissorEnabled=!0}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}toCanvas(t,e){return{x:t+this.x,y:e+this.y}}toLocal(t,e){return{x:t-this.x,y:e-this.y}}getAspectRatio(){return this.width/this.height}setScissor(t){this.scissorEnabled=t}shouldClip(t,e){return!!this.scissorEnabled&&(t<this.x||t>=this.x+this.width||e<this.y||e>=this.y+this.height)}}function A(t,e,i){let s,r,h,a;return t/e>i?(a=e,h=e*i,s=(t-h)/2,r=0):(h=t,a=t/i,s=0,r=(e-a)/2),new C(s,r,h,a)}function P(t,e){if(e.y>0)for(let i=0;i<e.y;i++)for(let e=0;e<t.width;e++)t.setPixel(e,i,0,0,0,255);const i=e.y+e.height;if(i<t.height)for(let e=i;e<t.height;e++)for(let i=0;i<t.width;i++)t.setPixel(i,e,0,0,0,255);if(e.x>0)for(let i=0;i<t.height;i++)for(let s=0;s<e.x;s++)t.setPixel(s,i,0,0,0,255);const s=e.x+e.width;if(s<t.width)for(let e=0;e<t.height;e++)for(let i=s;i<t.width;i++)t.setPixel(i,e,0,0,0,255)}class k{static drawLine(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=performance.now();e=Math.floor(e),i=Math.floor(i),s=Math.floor(s),r=Math.floor(r);const d=Math.abs(s-e),u=Math.abs(r-i),f=e<s?1:-1,m=i<r?1:-1;let x=d-u,p=e,M=i,g=1/0,y=1/0,w=-1/0,b=-1/0;const T=t.data,C=t.width;t.height;let A=0;for(;;){if(v(p,M,t,l)){const t=4*(M*C+p);T[t+0]=h,T[t+1]=a,T[t+2]=o,T[t+3]=n,A++,g=Math.min(g,p),y=Math.min(y,M),w=Math.max(w,p),b=Math.max(b,M)}if(p===s&&M===r)break;const e=2*x;e>-u&&(x-=u,p+=f),e<d&&(x+=d,M+=m)}if(0===A)return{pixels:0,time:0,regionSize:0};const P=w-g+1,B=b-y+1,R=k._extractRegion(T,C,g,y,P,B);t.renderer.updateBufferData(t.bufferId,R,g,y,P,B),t.needsUpload=!0;return{pixels:A,time:performance.now()-c,regionSize:P*B}}static drawThickLine(t,e,i,s,r,h,a,o,n,l=255,c=void 0){e=Math.floor(e),i=Math.floor(i),s=Math.floor(s),r=Math.floor(r),h=Math.max(1,Math.floor(h));const d=performance.now(),u=Math.ceil(h/2),f=k._createBrushStamp(u,a,o,n,l),m=k._bresenhamPoints(e,i,s,r);let x=1/0,p=1/0,M=-1/0,g=-1/0;const y=t.data,w=t.width,b=t.height;let v=0;for(const{x:t,y:e}of m){const i=k._stampBrush(y,w,b,t,e,u,f,c);v+=i.pixels,i.pixels>0&&(x=Math.min(x,i.minX),p=Math.min(p,i.minY),M=Math.max(M,i.maxX),g=Math.max(g,i.maxY))}if(0===v)return{pixels:0,linePoints:m.length,regionSize:0};const T=M-x+1,C=g-p+1,A=k._extractRegion(y,w,x,p,T,C);t.renderer.updateBufferData(t.bufferId,A,x,p,T,C),t.needsUpload=!0;const P=performance.now()-d;return{pixels:v,linePoints:m.length,time:P,regionSize:T*C}}static _bresenhamPoints(t,e,i,s){const r=[],h=Math.abs(i-t),a=Math.abs(s-e),o=t<i?1:-1,n=e<s?1:-1;let l=h-a,c=t,d=e;for(;r.push({x:c,y:d}),c!==i||d!==s;){const t=2*l;t>-a&&(l-=a,c+=o),t<h&&(l+=h,d+=n)}return r}static _createBrushStamp(t,e,i,s,r){const h=[];for(let a=-t;a<=t;a++)for(let o=-t;o<=t;o++){const n=Math.sqrt(o*o+a*a);if(n<=t){const l=Math.max(0,1-n/t),c=Math.floor(r*l);h.push({dx:o,dy:a,r:e,g:i,b:s,a:c})}}return h}static _stampBrush(t,e,i,s,r,h,a,o){let n=0,l=1/0,c=1/0,d=-1/0,u=-1/0;for(const{dx:h,dy:f,r:m,g:x,b:p,a:M}of a){const a=s+h,g=r+f;if(!v(a,g,{width:e,height:i,data:t},o))continue;const y=4*(g*e+a),w=M/255,b=1-w;t[y+0]=Math.floor(m*w+t[y+0]*b),t[y+1]=Math.floor(x*w+t[y+1]*b),t[y+2]=Math.floor(p*w+t[y+2]*b),t[y+3]=255,n++,l=Math.min(l,a),c=Math.min(c,g),d=Math.max(d,a),u=Math.max(u,g)}return{pixels:n,minX:l,minY:c,maxX:d,maxY:u}}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class B{static fillRect(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=function(t,e,i,s,r,h){const a=Math.max(0,Math.floor(t)),o=Math.max(0,Math.floor(e)),n=Math.min(r,Math.ceil(t+i))-a,l=Math.min(h,Math.ceil(e+s))-o;return n<=0||l<=0?null:{x:a,y:o,width:n,height:l}}(e,i,s,r,t.width,t.height);if(!c)return{pixels:0};let{x:d,y:u,width:f,height:m}=c;const x=t.data,p=t.width;let M=1/0,g=1/0,y=-1/0,w=-1/0,b=0;for(let e=u;e<u+m;e++)for(let i=d;i<d+f;i++){if(!v(i,e,t,l))continue;const s=4*(e*p+i);x[s+0]=h,x[s+1]=a,x[s+2]=o,x[s+3]=n,b++,M=Math.min(M,i),g=Math.min(g,e),y=Math.max(y,i),w=Math.max(w,e)}if(0===b)return{pixels:0};const T=y-M+1,C=w-g+1,A=B._extractRegion(x,p,M,g,T,C);return t.renderer.updateBufferData(t.bufferId,A,M,g,T,C),t.needsUpload=!0,{pixels:b}}static strokeRect(t,e,i,s,r,h,a,o,n,l=255,c=void 0){e=Math.floor(e),i=Math.floor(i),s=Math.ceil(s),r=Math.ceil(r),h=Math.max(1,Math.floor(h)),k.drawThickLine(t,e,i,e+s,i,h,a,o,n,l,c),k.drawThickLine(t,e+s,i,e+s,i+r,h,a,o,n,l,c),k.drawThickLine(t,e+s,i+r,e,i+r,h,a,o,n,l,c),k.drawThickLine(t,e,i+r,e,i,h,a,o,n,l,c)}static fillCircle(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=Math.floor(s);if(d<=0)return{pixels:0,time:0};let u=1/0,f=1/0,m=-1/0,x=-1/0;const p=t.data,M=t.width;t.height;let g=d,y=0,w=1-d,b=0;const T=(e,i,s)=>{for(let l=i;l<=s;l++){if(!v(l,e,t,n))continue;const i=4*(e*M+l);p[i+0]=r,p[i+1]=h,p[i+2]=a,p[i+3]=o,b++,u=Math.min(u,l),f=Math.min(f,e),m=Math.max(m,l),x=Math.max(x,e)}};for(T(c,l-g,l+g);g>y;)y++,w<0?w+=2*y+1:(g--,w+=2*(y-g)+1),T(c+y,l-g,l+g),T(c+g,l-y,l+y),T(c-y,l-g,l+g),T(c-g,l-y,l+y);if(0===b)return{pixels:0};const C=m-u+1,A=x-f+1,P=B._extractRegion(p,M,u,f,C,A);t.renderer.updateBufferData(t.bufferId,P,u,f,C,A),t.needsUpload=!0}static strokeCircle(t,e,i,s,r,h,a,o,n=255,l=void 0){const c=Math.floor(e),d=Math.floor(i),u=Math.floor(s);if(u<=0)return{pixels:0,time:0};if(r>1)return B._strokeCircleThick(t,c,d,u,r,h,a,o,n);const f=t.data,m=t.width;t.height;let x=1/0,p=1/0,M=-1/0,g=-1/0,y=u,w=0,b=1-u,T=0;const C=(e,i)=>{if(!v(e,i,t,l))return;const s=4*(i*m+e);f[s+0]=h,f[s+1]=a,f[s+2]=o,f[s+3]=n,T++,x=Math.min(x,e),p=Math.min(p,i),M=Math.max(M,e),g=Math.max(g,i)};for(;y>=w;)C(c+y,d+w),C(c+w,d+y),C(c-y,d+w),C(c-w,d+y),C(c-y,d-w),C(c-w,d-y),C(c+y,d-w),C(c+w,d-y),w++,b<0?b+=2*w+1:(y--,b+=2*(w-y)+1);if(0===T)return{pixels:0};const A=M-x+1,P=g-p+1,k=B._extractRegion(f,m,x,p,A,P);t.renderer.updateBufferData(t.bufferId,k,x,p,A,P),t.needsUpload=!0}static _strokeCircleThick(t,e,i,s,r,h,a,o,n,l){const c=s,d=Math.max(0,s-r),u=t.data,f=t.width,m=t.height;let x=1/0,p=1/0,M=-1/0,g=-1/0,y=0;const w=c*c,b=d*d,T=Math.max(0,e-c),C=Math.max(0,i-c),A=Math.min(f-1,e+c),P=Math.min(m-1,i+c);for(let s=C;s<=P;s++)for(let r=T;r<=A;r++){const c=r-e,d=s-i,m=c*c+d*d;if(m<=w&&m>=b){if(!v(r,s,t,l))continue;const e=4*(s*f+r);u[e+0]=h,u[e+1]=a,u[e+2]=o,u[e+3]=n,y++,x=Math.min(x,r),p=Math.min(p,s),M=Math.max(M,r),g=Math.max(g,s)}}if(0===y)return{pixels:0};const k=M-x+1,R=g-p+1,S=B._extractRegion(u,f,x,p,k,R);t.renderer.updateBufferData(t.bufferId,S,x,p,k,R),t.needsUpload=!0}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class R{static fillPolygon(t,e,i,s,r,h=255,a=void 0){if(e.length<3)return{pixels:0};const o=R._buildEdgeTable(e);if(0===o.length)return{pixels:0};let n=1/0,l=-1/0;for(const t of o)n=Math.min(n,t.yMin),l=Math.max(l,t.yMax);n=Math.max(0,Math.floor(n)),l=Math.min(t.height-1,Math.ceil(l));const c=t.data,d=t.width;t.height;let u=1/0,f=1/0,m=-1/0,x=-1/0,p=0;for(let e=n;e<=l;e++){const n=[];for(const t of o)if(e>=t.yMin&&e<t.yMax){const i=t.x+(e-t.yMin)*t.dx;n.push(i)}n.sort((t,e)=>t-e);for(let o=0;o<n.length-1;o+=2){const l=Math.floor(n[o]),M=Math.ceil(n[o+1]);for(let o=l;o<=M;o++){if(!v(o,e,t,a))continue;const n=4*(e*d+o);c[n+0]=i,c[n+1]=s,c[n+2]=r,c[n+3]=h,p++,u=Math.min(u,o),f=Math.min(f,e),m=Math.max(m,o),x=Math.max(x,e)}}}if(0===p)return{pixels:0};const M=m-u+1,g=x-f+1,y=R._extractRegion(c,d,u,f,M,g);return t.renderer.updateBufferData(t.bufferId,y,u,f,M,g),t.needsUpload=!0,{pixels:p,vertices:e.length,scanlines:x-f+1}}static _buildEdgeTable(t){const e=[],i=t.length;for(let s=0;s<i;s++){const r=t[s],h=t[(s+1)%i];if(Math.abs(r.y-h.y)<.001)continue;let a=r.x,o=r.y,n=h.x,l=h.y;o>l&&([a,n]=[n,a],[o,l]=[l,o]);const c=(n-a)/(l-o);e.push({yMin:o,yMax:l,x:a,dx:c})}return e}static strokePolygon(t,e,i,s,r,h,a=255,o=void 0){if(!(e.length<2))for(let n=0;n<e.length;n++){const l=e[n],c=e[(n+1)%e.length];k.drawThickLine(t,l.x,l.y,c.x,c.y,i,s,r,h,a,o)}}static createRegularPolygon(t,e,i,s){const r=[],h=2*Math.PI/s;for(let a=0;a<s;a++){const s=a*h-Math.PI/2;r.push({x:t+Math.cos(s)*i,y:e+Math.sin(s)*i})}return r}static createStar(t,e,i,s,r){const h=[],a=2*Math.PI/(2*r);for(let o=0;o<2*r;o++){const r=o*a-Math.PI/2,n=o%2==0?i:s;h.push({x:t+Math.cos(r)*n,y:e+Math.sin(r)*n})}return h}static createRoundedRect(t,e,i,s,r){const h=[],a=(t,e,i,s,r)=>{for(let a=0;a<=8;a++){const o=s+(r-s)*(a/8);h.push({x:t+Math.cos(o)*i,y:e+Math.sin(o)*i})}},o=Math.min(r,i/2,s/2);return a(t+i-o,e+o,o,-Math.PI/2,0),a(t+i-o,e+s-o,o,0,Math.PI/2),a(t+o,e+s-o,o,Math.PI/2,Math.PI),a(t+o,e+o,o,Math.PI,1.5*Math.PI),h}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}class S{static drawLineAA(t,e,i,s,r,h,a,o,n=255,l=void 0){let c=1/0,d=1/0,u=-1/0,f=-1/0,m=0;const x=t.data,p=t.width;if(t.height,e===s&&i===r){if(S._setPixelAA(t,e,i,h,a,o,n,l)){const t=Math.floor(e),s=Math.floor(i);m=1,c=Math.min(c,t),d=Math.min(d,s),u=Math.max(u,t),f=Math.max(f,s)}}else{const x=Math.abs(r-i)>Math.abs(s-e);x&&([e,i]=[i,e],[s,r]=[r,s]),e>s&&([e,s]=[s,e],[i,r]=[r,i]);const p=s-e,M=0===p?1:(r-i)/p;let g=Math.round(e),y=i+M*(g-e),w=1-(e+.5-Math.floor(e+.5)),b=g,v=Math.floor(y),T=!1;x?(T=S._setPixelAA(t,v,b,h,a,o,n*(1-(y-v))*w,l),T&&(m++,c=Math.min(c,v),d=Math.min(d,b),u=Math.max(u,v),f=Math.max(f,b)),T=S._setPixelAA(t,v+1,b,h,a,o,n*(y-v)*w,l),T&&(m++,c=Math.min(c,v+1),d=Math.min(d,b),u=Math.max(u,v+1),f=Math.max(f,b))):(T=S._setPixelAA(t,b,v,h,a,o,n*(1-(y-v))*w,l),T&&(m++,c=Math.min(c,b),d=Math.min(d,v),u=Math.max(u,b),f=Math.max(f,v)),T=S._setPixelAA(t,b,v+1,h,a,o,n*(y-v)*w,l),T&&(m++,c=Math.min(c,b),d=Math.min(d,v+1),u=Math.max(u,b),f=Math.max(f,v+1)));let C=y+M;g=Math.round(s),y=r+M*(g-s),w=s+.5-Math.floor(s+.5);let A=g,P=Math.floor(y);if(x?(T=S._setPixelAA(t,P,A,h,a,o,n*(1-(y-P))*w,l),T&&(m++,c=Math.min(c,P),d=Math.min(d,A),u=Math.max(u,P),f=Math.max(f,A)),T=S._setPixelAA(t,P+1,A,h,a,o,n*(y-P)*w,l),T&&(m++,c=Math.min(c,P+1),d=Math.min(d,A),u=Math.max(u,P+1),f=Math.max(f,A))):(T=S._setPixelAA(t,A,P,h,a,o,n*(1-(y-P))*w,l),T&&(m++,c=Math.min(c,A),d=Math.min(d,P),u=Math.max(u,A),f=Math.max(f,P)),T=S._setPixelAA(t,A,P+1,h,a,o,n*(y-P)*w,l),T&&(m++,c=Math.min(c,A),d=Math.min(d,P+1),u=Math.max(u,A),f=Math.max(f,P+1))),x)for(let e=b+1;e<A;e++){const i=Math.floor(C),s=C-i;T=S._setPixelAA(t,i,e,h,a,o,n*(1-s),l),T&&(m++,c=Math.min(c,i),d=Math.min(d,e),u=Math.max(u,i),f=Math.max(f,e)),T=S._setPixelAA(t,i+1,e,h,a,o,n*s,l),T&&(m++,c=Math.min(c,i+1),d=Math.min(d,e),u=Math.max(u,i+1),f=Math.max(f,e)),C+=M}else for(let e=b+1;e<A;e++){const i=Math.floor(C),s=C-i;T=S._setPixelAA(t,e,i,h,a,o,n*(1-s),l),T&&(m++,c=Math.min(c,e),d=Math.min(d,i),u=Math.max(u,e),f=Math.max(f,i)),T=S._setPixelAA(t,e,i+1,h,a,o,n*s,l),T&&(m++,c=Math.min(c,e),d=Math.min(d,i+1),u=Math.max(u,e),f=Math.max(f,i+1)),C+=M}}if(0===m)return;const M=u-c+1,g=f-d+1,y=S._extractRegion(x,p,c,d,M,g);t.renderer.updateBufferData(t.bufferId,y,c,d,M,g),t.needsUpload=!0}static _setPixelAA(t,e,i,s,r,h,a,o){if(!v(e=Math.floor(e),i=Math.floor(i),t,o))return!1;const n=Math.max(0,Math.min(1,a/255));if(n<=0)return!1;const l=4*(i*t.width+e),c=t.data,d=1-n;return c[l+0]=Math.floor(s*n+c[l+0]*d),c[l+1]=Math.floor(r*n+c[l+1]*d),c[l+2]=Math.floor(h*n+c[l+2]*d),c[l+3]=255,!0}static drawCircleAA(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=s;if(d<=0)return;const u=(d-.5)*(d-.5),f=(d+.5)*(d+.5),m=Math.max(0,l-Math.ceil(d)-1),x=Math.max(0,c-Math.ceil(d)-1),p=Math.min(t.width-1,l+Math.ceil(d)+1),M=Math.min(t.height-1,c+Math.ceil(d)+1);let g=1/0,y=1/0,w=-1/0,b=-1/0,v=0;for(let s=x;s<=M;s++){const l=s-i;for(let i=m;i<=p;i++){const c=i-e,m=c*c+l*l;if(m<u||m>f)continue;const x=Math.sqrt(m),p=1-Math.abs(x-d)/.5;S._setPixelAA(t,i,s,r,h,a,o*p,n)&&(v++,g=Math.min(g,i),y=Math.min(y,s),w=Math.max(w,i),b=Math.max(b,s))}}if(0===v)return;const T=w-g+1,C=b-y+1,A=S._extractRegion(t.data,t.width,g,y,T,C);t.renderer.updateBufferData(t.bufferId,A,g,y,T,C),t.needsUpload=!0}static fillCircleAA(t,e,i,s,r,h,a,o=255,n=void 0){const l=Math.floor(e),c=Math.floor(i),d=s;if(d<=0)return{pixels:0,time:0};const u=Math.max(0,l-Math.ceil(d)-1),f=Math.max(0,c-Math.ceil(d)-1),m=Math.min(t.width-1,l+Math.ceil(d)+1),x=Math.min(t.height-1,c+Math.ceil(d)+1);let p=1/0,M=1/0,g=-1/0,y=-1/0,w=0;for(let s=f;s<=x;s++)for(let l=u;l<=m;l++){const c=l-e,u=s-i,f=Math.sqrt(c*c+u*u);if(f>d+.5)continue;const m=f<=d-.5?1:d+.5-f;S._setPixelAA(t,l,s,r,h,a,o*m,n)&&(w++,p=Math.min(p,l),M=Math.min(M,s),g=Math.max(g,l),y=Math.max(y,s))}if(0===w)return;const b=g-p+1,v=y-M+1,T=S._extractRegion(t.data,t.width,p,M,b,v);t.renderer.updateBufferData(t.bufferId,T,p,M,b,v),t.needsUpload=!0}static _extractRegion(t,e,i,s,r,h){const a=new Uint8Array(r*h*4);for(let o=0;o<h;o++){const h=4*((s+o)*e+i),n=o*r*4,l=4*r;a.set(t.subarray(h,h+l),n)}return a}}const D={NORMAL:0,MULTIPLY:1,SCREEN:2,OVERLAY:3,ADD:4,SUBTRACT:5,DARKEN:6,LIGHTEN:7,DIFFERENCE:8,COLOR_DODGE:9,COLOR_BURN:10};class I{static tempCanvas=void 0;static drawWithBlend(t,e,i=D.NORMAL){const s=t.width,r=t.height,h=t.data;this.tempCanvas||(this.tempCanvas=new b(t.renderer,s,r)),this.tempCanvas.clear(0,0,0,0),e(this.tempCanvas);const a=this.tempCanvas.data,o=h.length,n=this._getBlendFunction(i);for(let t=0;t<o;t+=16)0!==a[t+3]&&n(a[t],a[t+1],a[t+2],a[t+3],h[t],h[t+1],h[t+2],h[t+3],h,t),0!==a[t+7]&&n(a[t+4],a[t+5],a[t+6],a[t+7],h[t+4],h[t+5],h[t+6],h[t+7],h,t+4),0!==a[t+11]&&n(a[t+8],a[t+9],a[t+10],a[t+11],h[t+8],h[t+9],h[t+10],h[t+11],h,t+8),0!==a[t+15]&&n(a[t+12],a[t+13],a[t+14],a[t+15],h[t+12],h[t+13],h[t+14],h[t+15],h,t+12);t.renderer.updateBufferData(t.bufferId,h),t.needsUpload=!0}static _getBlendFunction(t){switch(t){case D.MULTIPLY:return this._blendMultiply;case D.SCREEN:return this._blendScreen;case D.OVERLAY:return this._blendOverlay;case D.ADD:return this._blendAdd;case D.SUBTRACT:return this._blendSubtract;case D.DARKEN:return this._blendDarken;case D.LIGHTEN:return this._blendLighten;case D.DIFFERENCE:return this._blendDifference;case D.COLOR_DODGE:return this._blendColorDodge;case D.COLOR_BURN:return this._blendColorBurn;default:return this._blendNormal}}static _blendNormal(t,e,i,s,r,h,a,o,n,l){if(255===s)return n[l]=t,n[l+1]=e,n[l+2]=i,void(n[l+3]=255);if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;n[l]=(t*c+r*d*(1-c))*f,n[l+1]=(e*c+h*d*(1-c))*f,n[l+2]=(i*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendMultiply(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t*r*.00392156862745098,x=e*h*.00392156862745098,p=i*a*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendScreen(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=255-(255-t)*(255-r)*.00392156862745098,x=255-(255-e)*(255-h)*.00392156862745098,p=255-(255-i)*(255-a)*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendOverlay(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=r<128?2*t*r*.00392156862745098:255-2*(255-t)*(255-r)*.00392156862745098,x=h<128?2*e*h*.00392156862745098:255-2*(255-e)*(255-h)*.00392156862745098,p=a<128?2*i*a*.00392156862745098:255-2*(255-i)*(255-a)*.00392156862745098;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendAdd(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;let m=t+r;m>255&&(m=255);let x=e+h;x>255&&(x=255);let p=i+a;p>255&&(p=255),n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendSubtract(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u;let m=r-t;m<0&&(m=0);let x=h-e;x<0&&(x=0);let p=a-i;p<0&&(p=0),n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendDarken(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t<r?t:r,x=e<h?e:h,p=i<a?i:a;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendLighten(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=t>r?t:r,x=e>h?e:h,p=i>a?i:a;n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendDifference(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=Math.abs(t-r),x=Math.abs(e-h),p=Math.abs(i-a);n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendColorDodge(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=255===t?255:Math.min(255,255*r/(255-t)),x=255===e?255:Math.min(255,255*h/(255-e)),p=255===i?255:Math.min(255,255*a/(255-i));n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static _blendColorBurn(t,e,i,s,r,h,a,o,n,l){if(0===s)return;const c=.00392156862745098*s,d=.00392156862745098*o,u=c+d*(1-c);if(u<.001)return n[l]=0,n[l+1]=0,n[l+2]=0,void(n[l+3]=0);const f=1/u,m=0===t?0:Math.max(0,255-255*(255-r)/t),x=0===e?0:Math.max(0,255-255*(255-h)/e),p=0===i?0:Math.max(0,255-255*(255-a)/i);n[l]=(m*c+r*d*(1-c))*f,n[l+1]=(x*c+h*d*(1-c))*f,n[l+2]=(p*c+a*d*(1-c))*f,n[l+3]=255*u}static setPixelBlended(t,e,i,s,r,h,a,o=D.NORMAL){if(e<0||e>=t.width||i<0||i>=t.height||0===a)return;const n=4*(i*t.width+e),l=t.data,c=l[n],d=l[n+1],u=l[n+2],f=l[n+3];if(o===D.NORMAL){if(255===a)return l[n]=s,l[n+1]=r,l[n+2]=h,void(l[n+3]=255);const t=.00392156862745098*a,e=.00392156862745098*f,i=t+e*(1-t);if(i<.001)return l[n]=0,l[n+1]=0,l[n+2]=0,void(l[n+3]=0);const o=1/i;return l[n]=(s*t+c*e*(1-t))*o,l[n+1]=(r*t+d*e*(1-t))*o,l[n+2]=(h*t+u*e*(1-t))*o,void(l[n+3]=255*i)}this._getBlendFunction(o)(s,r,h,a,c,d,u,f,l,n)}static createTestGradient(t){const e=t.width,i=t.height,s=t.data;for(let t=0;t<i;t++){const r=t/i*255;for(let i=0;i<e;i++){const h=4*(t*e+i);s[h]=i/e*255,s[h+1]=r,s[h+2]=128,s[h+3]=255}}t.upload()}}class _{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s}intersects(t,e,i,s){return!(t+i<this.x||t>this.x+this.width||e+s<this.y||e>this.y+this.height)}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}intersect(t){const e=Math.max(this.x,t.x),i=Math.max(this.y,t.y),s=Math.min(this.x+this.width,t.x+t.width),r=Math.min(this.y+this.height,t.y+t.height);return s<=e||r<=i?null:new _(e,i,s-e,r-i)}computeOutcode(t,e){let i=0;return t<this.x&&(i|=1),t>=this.x+this.width&&(i|=2),e<this.y&&(i|=4),e>=this.y+this.height&&(i|=8),i}}class L{constructor(t=0,e=0,i=1,s=1,r=0){this.translateX=t,this.translateY=e,this.scaleX=i,this.scaleY=s,this.rotation=r}apply(t,e){if(0!==this.rotation){const i=Math.cos(this.rotation),s=Math.sin(this.rotation),r=t*s+e*i;t=t*i-e*s,e=r}return{x:t*this.scaleX+this.translateX,y:e*this.scaleY+this.translateY}}applyRect(t,e,i,s){const r=[this.apply(t,e),this.apply(t+i,e),this.apply(t,e+s),this.apply(t+i,e+s)];let h=1/0,a=1/0,o=-1/0,n=-1/0;for(const t of r)h=Math.min(h,t.x),a=Math.min(a,t.y),o=Math.max(o,t.x),n=Math.max(n,t.y);return{x:h,y:a,width:o-h,height:n-a}}compose(t){return new L(this.translateX+t.translateX*this.scaleX,this.translateY+t.translateY*this.scaleY,this.scaleX*t.scaleX,this.scaleY*t.scaleY,this.rotation+t.rotation)}static identity(){return new L(0,0,1,1,0)}}class U{constructor(){this.clipStack=[],this.transformStack=[L.identity()],this.globalAlpha=1,this.fillStyle={r:0,g:0,b:0,a:255},this.strokeStyle={r:0,g:0,b:0,a:255},this.lineWidth=1}get currentClip(){return this.clipStack.length>0?this.clipStack[this.clipStack.length-1]:null}get currentTransform(){return this.transformStack[this.transformStack.length-1]}pushClip(t){this.clipStack.push(t)}popClip(){return this.clipStack.pop()}pushTransform(t){const e=this.currentTransform;this.transformStack.push(e.compose(t))}popTransform(){return this.transformStack.length>1?this.transformStack.pop():this.currentTransform}save(){return{clipStack:[...this.clipStack],transformStack:[...this.transformStack],globalAlpha:this.globalAlpha,fillStyle:{...this.fillStyle},strokeStyle:{...this.strokeStyle},lineWidth:this.lineWidth}}restore(t){this.clipStack=t.clipStack,this.transformStack=t.transformStack,this.globalAlpha=t.globalAlpha,this.fillStyle=t.fillStyle,this.strokeStyle=t.strokeStyle,this.lineWidth=t.lineWidth}}class F{constructor(t){this.canvas=t,this.state=new U,this.state.pushClip(new _(0,0,t.width,t.height))}save(){return this.state.save()}restore(t){this.state.restore(t)}pushClipRect(t,e,i,s){const r=this.state.currentTransform.applyRect(t,e,i,s),h=new _(r.x,r.y,r.width,r.height),a=this.state.currentClip;if(a){const t=a.intersect(h);t?this.state.pushClip(t):this.state.pushClip(new _(0,0,0,0))}else this.state.pushClip(h)}popClipRect(){this.state.popClip()}pushTransform(t=0,e=0,i=1,s=1,r=0){const h=new L(t,e,i,s,r);this.state.pushTransform(h)}popTransform(){this.state.popTransform()}isRectVisible(t,e,i,s){const r=this.state.currentTransform.applyRect(t,e,i,s),h=this.state.currentClip;return!h||h.intersects(r.x,r.y,r.width,r.height)}transformPoint(t,e){return this.state.currentTransform.apply(t,e)}clipLine(t,e,i,s){const r=this.state.currentClip;if(!r)return{x1:t,y1:e,x2:i,y2:s};const h=this.state.currentTransform;let a=h.apply(t,e),o=h.apply(i,s),n=r.computeOutcode(a.x,a.y),l=r.computeOutcode(o.x,o.y),c=!1;for(;;){if(0===(n|l)){c=!0;break}if(0!==(n&l))break;{let t,e;const i=0!==n?n:l;8&i?(t=a.x+(o.x-a.x)*(r.y+r.height-a.y)/(o.y-a.y),e=r.y+r.height):4&i?(t=a.x+(o.x-a.x)*(r.y-a.y)/(o.y-a.y),e=r.y):2&i?(e=a.y+(o.y-a.y)*(r.x+r.width-a.x)/(o.x-a.x),t=r.x+r.width):1&i&&(e=a.y+(o.y-a.y)*(r.x-a.x)/(o.x-a.x),t=r.x),i===n?(a.x=t,a.y=e,n=r.computeOutcode(a.x,a.y)):(o.x=t,o.y=e,l=r.computeOutcode(o.x,o.y))}}return c?{x1:a.x,y1:a.y,x2:o.x,y2:o.y}:null}fillRect(t,e,i,s,r,h,a,o=255){if(!this.isRectVisible(t,e,i,s))return;const n=this.state.currentTransform.applyRect(t,e,i,s),l=this.state.currentClip,c=Math.max(l.x,n.x),d=Math.max(l.y,n.y),u=Math.min(l.x+l.width,n.x+n.width),f=Math.min(l.y+l.height,n.y+n.height);if(u>c&&f>d){const t=o*this.state.globalAlpha;B.fillRect(this.canvas,c,d,u-c,f-d,r,h,a,t)}}strokeRect(t,e,i,s,r,h,a,o,n=255){if(!this.isRectVisible(t,e,i,s))return;const l=n*this.state.globalAlpha,c=this.state.currentTransform,d=c.apply(t,e),u=c.apply(t+i,e),f=c.apply(t+i,e+s),m=c.apply(t,e+s);this._drawClippedLine(d.x,d.y,u.x,u.y,r,h,a,o,l),this._drawClippedLine(u.x,u.y,f.x,f.y,r,h,a,o,l),this._drawClippedLine(f.x,f.y,m.x,m.y,r,h,a,o,l),this._drawClippedLine(m.x,m.y,d.x,d.y,r,h,a,o,l)}drawLine(t,e,i,s,r,h,a,o,n=255){const l=this.clipLine(t,e,i,s);if(!l)return;const c=n*this.state.globalAlpha;1===r?LineDrawer.drawLine(this.canvas,l.x1,l.y1,l.x2,l.y2,h,a,o,c):LineDrawer.drawThickLine(this.canvas,l.x1,l.y1,l.x2,l.y2,r,h,a,o,c)}fillCircle(t,e,i,s,r,h,a=255){if(!this.isRectVisible(t-i,e-i,2*i,2*i))return;const o=this.state.currentTransform,n=o.apply(t,e),l=i*(Math.abs(o.scaleX)+Math.abs(o.scaleY))/2,c=a*this.state.globalAlpha;this._fillCircleClipped(n.x,n.y,l,s,r,h,c)}_drawClippedLine(t,e,i,s,r,h,a,o,n){const l=this.clipLine(t,e,i,s);l&&(1===r?LineDrawer.drawLine(this.canvas,l.x1,l.y1,l.x2,l.y2,h,a,o,n):LineDrawer.drawThickLine(this.canvas,l.x1,l.y1,l.x2,l.y2,r,h,a,o,n))}_fillCircleClipped(t,e,i,s,r,h,a){const o=this.state.currentClip,n=this.canvas.data,l=this.canvas.width,c=this.canvas.height,d=Math.max(0,Math.floor(t-i)),u=Math.min(l-1,Math.ceil(t+i)),f=Math.max(0,Math.floor(e-i)),m=Math.min(c-1,Math.ceil(e+i));for(let c=f;c<=m;c++)for(let f=d;f<=u;f++){if(o&&!o.contains(f,c))continue;const d=f-t,u=c-e;if(Math.sqrt(d*d+u*u)<=i){const t=4*(c*l+f);n[t+0]=s,n[t+1]=r,n[t+2]=h,n[t+3]=a}}this.canvas.renderer.updateBufferData(this.canvas.bufferId,this.canvas.data.subarray(0,l*c*4),d,f,u-d+1,m-f+1),this.canvas.needsUpload=!0}setFillStyle(t,e,i,s=255){this.state.fillStyle={r:t,g:e,b:i,a:s}}setStrokeStyle(t,e,i,s=255){this.state.strokeStyle={r:t,g:e,b:i,a:s}}setLineWidth(t){this.state.lineWidth=t}setGlobalAlpha(t){this.state.globalAlpha=Math.max(0,Math.min(1,t))}}class E{constructor(t,e,i,s,r,h,a,o){this.char=t,this.x=e,this.y=i,this.width=s,this.height=r,this.xOffset=h,this.yOffset=a,this.xAdvance=o}}class H{constructor(t,e,i={}){this.renderer=t,this.atlasImage=t.loadImage(e),this.atlasImage.data||console.warn(\"image data empty\"),this.config={bitmapWidth:i.bitmapWidth||this.atlasImage.width,bitmapHeight:i.bitmapHeight||this.atlasImage.height,cellsPerRow:i.cellsPerRow||16,cellsPerColumn:i.cellsPerColumn||16,cellWidth:i.cellWidth||32,cellHeight:i.cellHeight||32,fontSize:i.fontSize||16,offsetX:i.offsetX||0,offsetY:i.offsetY||0,charOrder:i.charOrder||this.getDefaultCharOrder()},this.glyphs=new Map,this.buildGlyphMap(),this.lineHeight=this.config.cellHeight,this.baseline=Math.floor(.8*this.lineHeight)}getDefaultCharOrder(){return\" ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{¦}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■□\"}buildGlyphMap(){const{cellsPerRow:t,cellsPerColumn:e,cellWidth:i,cellHeight:s,offsetX:r,offsetY:h,charOrder:a}=this.config;let o=0;for(let n=0;n<e;n++)for(let e=0;e<t&&!(o>=a.length);e++){const t=a[o],l=new E(t,e*i+r,n*s+h,i,s,0,0,i);this.glyphs.set(t,l),o++}console.log(`Built ${this.glyphs.size} glyphs from atlas`)}getGlyph(t){let e=this.glyphs.get(t);if(!e){if(\"\\n\"==e)return this.glyphs.get(\" \");e=this.glyphs.get(\"?\")||this.glyphs.get(\" \")||this.glyphs.values().next().value}return e}measureText(t){let e=0;for(let i=0;i<t.length;i++){e+=this.getGlyph(t[i]).xAdvance}return{width:e,height:this.lineHeight}}drawText(t,e,i,s,r={r:255,g:255,b:255,a:255},h=void 0){let a=i;const o=s,n=this.atlasImage.data,l=this.atlasImage.width,c=t.data,d=t.width,u=t.height;let f=1/0,m=1/0,x=-1/0,p=-1/0;for(let i=0;i<e.length;i++){const s=e[i];if(\" \"===s){a+=this.getGlyph(s).xAdvance;continue}const M=this.getGlyph(s),g=Math.floor(a+M.xOffset),y=Math.floor(o+M.yOffset);for(let e=0;e<M.height;e++)for(let i=0;i<M.width;i++){const s=g+i,a=y+e;if(s<0||s>=d||a<0||a>=u)continue;if(!v(s,a,t,h))continue;const o=M.x+i,w=4*((M.y+e)*l+o),b=n[w+0],T=n[w+1],C=n[w+2],A=n[w+3];if(0===A)continue;const P=(b+T+C)/3/255*(A/255)*(r.a/255);if(P<.01)continue;const k=4*(a*d+s),B=1-P;c[k+0]=Math.floor(r.r*P+c[k+0]*B),c[k+1]=Math.floor(r.g*P+c[k+1]*B),c[k+2]=Math.floor(r.b*P+c[k+2]*B),c[k+3]=255,f=Math.min(f,s),m=Math.min(m,a),x=Math.max(x,s),p=Math.max(p,a)}a+=M.xAdvance}if(f!==1/0){const e=x-f,i=p-m,s=new Uint8Array(e*i*4);for(let t=0;t<i;t++){const i=4*((m+t)*d+f),r=t*e*4,h=4*e;s.set(c.subarray(i,i+h),r)}t.renderer.updateBufferData(t.bufferId,s,f,m,e,i),t.needsUpload=!0,t.upload()}}drawTextWithTint(t,e,i,s,r,h,a,o=255,n=void 0){return this.drawText(t,e,i,s,{r:r,g:h,b:a,a:o},n)}wrapText(t,e){const i=t.split(\" \"),s=[];let r=\"\";return i.forEach(t=>{const i=r+(r?\" \":\"\")+t;this.measureText(i).width>e&&r?(s.push(r),r=t):r=i}),r&&s.push(r),s}drawMultilineText(t,e,i,s,r,h=\"left\",a={r:255,g:255,b:255,a:255},o=void 0){const n=this.wrapText(e,r);let l=s;return n.forEach(e=>{const s=this.measureText(e);let n=i;\"center\"===h?n=i+(r-s.width)/2:\"right\"===h&&(n=i+r-s.width),this.drawText(t,e,n,l,a,o),l+=this.lineHeight}),{width:r,height:n.length*this.lineHeight}}}class O{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s,this.visible=!0,this.enabled=!0}contains(t,e){return t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height}update(t){}draw(t,e){}}class Y extends O{constructor(t,e,i,s,r,h){super(t,e,i,s),this.text=r,this.onClick=h,this.isHovered=!1,this.isPressed=!1,this.normalColor={r:70,g:80,b:100},this.hoverColor={r:90,g:100,b:120},this.pressedColor={r:50,g:60,b:80},this.textColor={r:255,g:255,b:255,a:255},this.borderRadius=8}update(t){if(!this.enabled)return;const e=t.mousePosition;this.isHovered,this.isHovered=this.contains(e.x,e.y),this.isHovered&&t.isMousePressed(\"click\")&&(this.isPressed=!0),this.isPressed&&t.IsMouseActionReleased(\"click\")&&(this.isHovered&&this.onClick&&this.onClick(),this.isPressed=!1)}draw(t,e){if(!this.visible)return;let i=this.normalColor;this.enabled?this.isPressed?i=this.pressedColor:this.isHovered&&(i=this.hoverColor):i={r:40,g:45,b:50};const s=R.createRoundedRect(this.x,this.y,this.width,this.height,this.borderRadius);if(R.fillPolygon(t,s,i.r,i.g,i.b,255),R.strokePolygon(t,s,2,this.isHovered?120:80,this.isHovered?140:100,this.isHovered?160:120,255),e&&this.text){const i=e.measureText(this.text),s=this.x+(this.width-i.width)/2,r=this.y+(this.height-i.height)/2;e.drawText(t,this.text,s,r,this.textColor)}}}class V extends O{constructor(t,e,i,s,r=\"\"){super(t,e,i,s),this.text=\"\",this.placeholder=r,this.isFocused=!1,this.cursorPosition=0,this.cursorBlinkTime=0,this.cursorVisible=!0,this.backgroundColor={r:40,g:45,b:55},this.focusedBackgroundColor={r:50,g:55,b:65},this.borderColor={r:80,g:90,b:110},this.focusedBorderColor={r:100,g:150,b:200},this.textColor={r:255,g:255,b:255,a:255},this.placeholderColor={r:120,g:130,b:140,a:255},this.cursorColor={r:255,g:255,b:255,a:255},this.padding=8,this.borderRadius=6,this.onTextChange=null,this.onSubmit=null}update(t,e=16){if(!this.enabled)return;const i=t.mousePosition;if(t.isMousePressed(\"click\")){const t=this.contains(i.x,i.y);t&&!this.isFocused?this.focus():!t&&this.isFocused&&this.blur()}this.isFocused&&(this.cursorBlinkTime+=e,this.cursorBlinkTime>=530&&(this.cursorVisible=!this.cursorVisible,this.cursorBlinkTime=0))}focus(){this.isFocused=!0,this.cursorPosition=this.text.length,this.cursorVisible=!0,this.cursorBlinkTime=0}blur(){this.isFocused=!1,this.cursorVisible=!1}handleChar(t){this.isFocused&&(this.text=this.text.slice(0,this.cursorPosition)+t+this.text.slice(this.cursorPosition),this.cursorPosition++,this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleBackspace(){this.isFocused&&0!==this.cursorPosition&&(this.text=this.text.slice(0,this.cursorPosition-1)+this.text.slice(this.cursorPosition),this.cursorPosition--,this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleDelete(){!this.isFocused||this.cursorPosition>=this.text.length||(this.text=this.text.slice(0,this.cursorPosition)+this.text.slice(this.cursorPosition+1),this.cursorVisible=!0,this.cursorBlinkTime=0,this.onTextChange&&this.onTextChange(this.text))}handleSubmit(){this.isFocused&&this.onSubmit&&this.onSubmit(this.text)}moveCursorLeft(){this.isFocused&&0!==this.cursorPosition&&(this.cursorPosition--,this.cursorVisible=!0,this.cursorBlinkTime=0)}moveCursorRight(){!this.isFocused||this.cursorPosition>=this.text.length||(this.cursorPosition++,this.cursorVisible=!0,this.cursorBlinkTime=0)}setText(t){this.text=t,this.cursorPosition=t.length,this.cursorVisible=!0,this.cursorBlinkTime=0}getText(){return this.text}clear(){this.text=\"\",this.cursorPosition=0,this.cursorVisible=!0,this.cursorBlinkTime=0}draw(t,e){if(!this.visible)return;const i=this.isFocused?this.focusedBackgroundColor:this.backgroundColor,s=R.createRoundedRect(this.x,this.y,this.width,this.height,this.borderRadius);R.fillPolygon(t,s,i.r,i.g,i.b,255);const r=this.isFocused?this.focusedBorderColor:this.borderColor;if(R.strokePolygon(t,s,this.isFocused?2:1,r.r,r.g,r.b,255),!e)return;const h=this.text||this.placeholder,a=this.text?this.textColor:this.placeholderColor;if(h){const i=this.x+this.padding,s=this.y+(this.height-e.lineHeight)/2;e.drawText(t,h,i,s,a)}if(this.isFocused&&this.cursorVisible){const i=this.text.slice(0,this.cursorPosition),s=e.measureText(i).width,r=this.x+this.padding+s,h=this.y+this.padding,a=this.y+this.height-this.padding;B.fillRect(t,r,h,2,a-h,this.cursorColor.r,this.cursorColor.g,this.cursorColor.b,this.cursorColor.a)}}}class X extends O{constructor(t,e,i,s={r:255,g:255,b:255,a:255}){super(t,e,0,0),this.text=i,this.color=s}draw(t,e){this.visible&&e&&e.drawText(t,this.text,this.x,this.y,this.color)}}class G{constructor(t,e,i){this.canvas=t,this.font=e,this.inputMap=i,this.elements=[],this.focusedElement=null,this.lastFrameTime=performance.now()}add(t){return this.elements.push(t),t}remove(t){const e=this.elements.indexOf(t);e>-1&&this.elements.splice(e,1)}clear(){this.elements=[],this.focusedElement=null}update(){const t=performance.now(),e=t-this.lastFrameTime;this.lastFrameTime=t,this.elements.forEach(t=>{t.enabled&&t.update(this.inputMap,e)})}draw(){this.elements.forEach(t=>{t.visible&&t.draw(this.canvas,this.font)})}}export{S as AADrawer,H as BitmapFont,D as BlendMode,Y as Button,T as Camera,_ as ClipRect,F as ClippingContext,f as ColorTheory,I as Compositor,d as CoordinateSystem,n as DirtyRegionTracker,u as DrawingTools,U as GraphicsState,w as InputBuffer,y as InputMap,X as Label,k as LineDrawer,m as PerformanceMonitor,b as PixelBuffer,R as PolygonDrawer,a as Renderer,B as ShapeDrawer,l as SharedBuffer,V as TextInput,c as Texture,L as Transform,O as UIElement,G as UIManager,C as Viewport,A as createLetterboxedViewport,M as drawAtlasRegionToCanvas,P as drawLetterboxBars,g as genFrames,p as imageToCanvas,o as loadRenderer,x as normalizeRGBA};\n//# sourceMappingURL=index.js.map\n"],"names":["vec2","x","y","e","t","url","Transform2D","constructor","this","position","rotation","scale","copy","other","Node","name","parent","children","worldPosition","worldRotation","worldScale","transformDirty","visible","active","ready","addChild","node","removeChild","push","idx","indexOf","splice","markDirty","i","length","updateWorldTransform","cos","Math","sin","scaledX","scaledY","rotatedX","rotatedY","_ready","_process","delta","_draw","canvas","camera","propagateReady","propagateProcess","propagateDraw","findChild","recursive","found","getPath","Scene","root","paused","timeScale","process","scaledDelta","draw","getNode","path","parts","split","current","printTree","indent","prefix","repeat","pos","toFixed","console","log"],"mappings":"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","x_google_ignoreList":[1]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export function vec2(x?: number, y?: number): {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* local transforms are relative to an object's parent or its own origin (like moving along its own "front"), while global transforms are relative to the fixed world origin (0,0,0)
|
|
7
|
+
*/
|
|
8
|
+
export class Transform2D {
|
|
9
|
+
position: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
rotation: number;
|
|
14
|
+
scale: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
copy(other: any): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* Node - base class for all scene objects
|
|
23
|
+
*
|
|
24
|
+
* Why this design:
|
|
25
|
+
* - Children array for hierarchy
|
|
26
|
+
* - Dirty flags prevent redundant transform calculations
|
|
27
|
+
* - Lifecycle hooks (_ready, _process, _draw) give clear entry points
|
|
28
|
+
* - World transform cached for performance
|
|
29
|
+
*/
|
|
30
|
+
export class Node {
|
|
31
|
+
constructor(name?: string);
|
|
32
|
+
name: string;
|
|
33
|
+
parent: any;
|
|
34
|
+
children: any[];
|
|
35
|
+
position: {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
};
|
|
39
|
+
rotation: number;
|
|
40
|
+
scale: {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
};
|
|
44
|
+
worldPosition: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
worldRotation: number;
|
|
49
|
+
worldScale: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
};
|
|
53
|
+
transformDirty: boolean;
|
|
54
|
+
visible: boolean;
|
|
55
|
+
active: boolean;
|
|
56
|
+
ready: boolean;
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @param {Node} node
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
addChild(node: Node): Node;
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @param {Node} node
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
removeChild(node: Node): void;
|
|
69
|
+
markDirty(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Calculate world transform from local + parent
|
|
72
|
+
*
|
|
73
|
+
* Why this order:
|
|
74
|
+
* 1. Scale the local position
|
|
75
|
+
* 2. Rotate it
|
|
76
|
+
* 3. Add parent's world position
|
|
77
|
+
*
|
|
78
|
+
* This gives proper transform inheritance (child orbits parent)
|
|
79
|
+
*/
|
|
80
|
+
updateWorldTransform(): void;
|
|
81
|
+
_ready(): void;
|
|
82
|
+
_process(delta: any): void;
|
|
83
|
+
_draw(canvas: any, camera: any): void;
|
|
84
|
+
/**
|
|
85
|
+
* internal tree traversal - don't override these
|
|
86
|
+
*/
|
|
87
|
+
propagateReady(): void;
|
|
88
|
+
propagateProcess(delta: any): void;
|
|
89
|
+
propagateDraw(canvas: any, camera: any): void;
|
|
90
|
+
/**
|
|
91
|
+
* utility: find child by name (recursive)
|
|
92
|
+
*/
|
|
93
|
+
findChild(name: any, recursive?: boolean): any;
|
|
94
|
+
/**
|
|
95
|
+
* utility: get full path (e.g., "Root/Player/Sprite")
|
|
96
|
+
*/
|
|
97
|
+
getPath(): string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Scene - root container + game loop coordinator
|
|
101
|
+
*
|
|
102
|
+
* why Scene:
|
|
103
|
+
* - single entry point for update/draw
|
|
104
|
+
* - manages lifecycle (ready propagation)
|
|
105
|
+
* - can pause/unpause entire tree
|
|
106
|
+
* - scene loading/unloading
|
|
107
|
+
*/
|
|
108
|
+
export class Scene {
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
* @param {PixelBuffer} canvas
|
|
112
|
+
*/
|
|
113
|
+
constructor(canvas: PixelBuffer);
|
|
114
|
+
canvas: PixelBuffer;
|
|
115
|
+
root: Node;
|
|
116
|
+
paused: boolean;
|
|
117
|
+
timeScale: number;
|
|
118
|
+
camera: any;
|
|
119
|
+
addChild(node: any): Node;
|
|
120
|
+
process(delta: any): void;
|
|
121
|
+
draw(): void;
|
|
122
|
+
/**
|
|
123
|
+
* find node by path (e.g., "Player/Weapon")
|
|
124
|
+
*/
|
|
125
|
+
getNode(path: any): Node;
|
|
126
|
+
/**
|
|
127
|
+
* debug: print tree structure
|
|
128
|
+
*/
|
|
129
|
+
printTree(node?: Node, indent?: number): void;
|
|
130
|
+
}
|
|
131
|
+
import { PixelBuffer } from "tessera.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./engine/core.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nexus-2d",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"author": "sk",
|
|
6
|
+
"license": "GPL-3.0-or-later",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tessera.js": "^0.2.5"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"module": "dist/esm/index.js",
|
|
15
|
+
"types": "dist/types/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/esm/index.js",
|
|
22
|
+
"require": "./dist/cjs/index.cjs",
|
|
23
|
+
"types": "./dist/types/index.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build:js": "rollup -c",
|
|
28
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
29
|
+
"build": "npm run build:js && npm run build:types",
|
|
30
|
+
"prepublishOnly": "npm run build"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
34
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
35
|
+
"@types/node": "^25.0.3",
|
|
36
|
+
"rollup": "^4.54.0",
|
|
37
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
38
|
+
"typescript": "^5.9.3"
|
|
39
|
+
}
|
|
40
|
+
}
|