create-photon-engine 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19,6 +19,9 @@ const pkgJson = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));
19
19
  pkgJson.name = projectName;
20
20
  delete pkgJson.private;
21
21
  writeFileSync(join(cwd, "package.json"), JSON.stringify(pkgJson, null, 2));
22
+ const htmlPath = join(cwd, "index.html");
23
+ const html = readFileSync(htmlPath, "utf-8");
24
+ writeFileSync(htmlPath, html.replace(/<title>.*?<\/title>/, `<title>${projectName}</title>`));
22
25
  console.log(" Installing dependencies...\n");
23
26
  execSync(`npm install`, { cwd, stdio: "inherit" });
24
27
  console.log(`\n Done! Run:\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-photon-engine",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Scaffold a new Photon Engine project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,8 +1,8 @@
1
1
  {
2
- "hash": "a0a13569",
3
- "configHash": "c9c6091a",
4
- "lockfileHash": "3b55699f",
5
- "browserHash": "dabf2bc9",
2
+ "hash": "54634c5a",
3
+ "configHash": "cfe65a55",
4
+ "lockfileHash": "2ed15c2a",
5
+ "browserHash": "a160a6f3",
6
6
  "optimized": {},
7
7
  "chunks": {}
8
8
  }
@@ -0,0 +1,58 @@
1
+ // Photon Engine — HUD demo
2
+ panel "hud" {
3
+ x: 20; y: 20;
4
+ width: 300; height: 210;
5
+ color: [0.08, 0.08, 0.1, 0.85];
6
+ borderRadius: 8;
7
+
8
+ text "title" {
9
+ x: 0; y: 12;
10
+ width: 300; height: 28;
11
+ text: "Photon Engine UI Demo";
12
+ fontSize: 18;
13
+ color: [0.5, 0.7, 1, 1];
14
+ align: center;
15
+ bold: true;
16
+ zIndex: 1;
17
+ }
18
+
19
+ text "score" {
20
+ x: 10; y: 52;
21
+ width: 280; height: 24;
22
+ text: "Clicks: 0";
23
+ fontSize: 15;
24
+ color: [1, 1, 1, 1];
25
+ fontFamily: monospace;
26
+ zIndex: 1;
27
+ }
28
+
29
+ button "clickBtn" {
30
+ x: 70; y: 88;
31
+ width: 160; height: 38;
32
+ label: "Click Me!";
33
+ color: [0.16, 0.5, 1, 1];
34
+ hoverColor: [0.29, 0.62, 1, 1];
35
+ pressedColor: [0.1, 0.37, 0.8, 1];
36
+ borderRadius: 8;
37
+ fontSize: 15;
38
+ zIndex: 1;
39
+ }
40
+
41
+ text "nameLabel" {
42
+ x: 10; y: 146;
43
+ width: 60; height: 22;
44
+ text: "Name:";
45
+ fontSize: 13;
46
+ color: [0.7, 0.7, 0.7, 1];
47
+ zIndex: 1;
48
+ }
49
+
50
+ textInput "nameInput" {
51
+ x: 70; y: 143;
52
+ width: 220; height: 28;
53
+ placeholder: "Type here...";
54
+ maxLength: 64;
55
+ fontSize: 13;
56
+ zIndex: 1;
57
+ }
58
+ }
@@ -1,5 +1,8 @@
1
+ import puiSource from "./hud.pui?raw";
1
2
  import {
2
3
  Engine, Scene, Transform2D, Camera2D, Sprite, Component,
4
+ UIText, UIRenderSystem,
5
+ parsePui, loadPui,
3
6
  } from "photon-engine";
4
7
 
5
8
  class OrbitalSpeed extends Component {
@@ -12,15 +15,19 @@ class OrbitalSpeed extends Component {
12
15
  ) { super(); }
13
16
  }
14
17
 
15
- class AtomScene extends Scene {
16
- readonly name = "atom";
18
+ class DemoScene extends Scene {
19
+ readonly name = "demo";
20
+ private uiSystem = new UIRenderSystem();
21
+ private clickCount = 0;
22
+ private scoreId = 0;
23
+ private btnId = 0;
17
24
 
18
25
  onEnter(): void {
26
+ this.world.registerSystem(this.uiSystem);
27
+
19
28
  const cam = this.world.createEntity();
20
29
  this.world.addComponent(cam.id, new Transform2D());
21
- const camComp = new Camera2D();
22
- camComp.zoom = 1;
23
- this.world.addComponent(cam.id, camComp);
30
+ this.world.addComponent(cam.id, new Camera2D());
24
31
 
25
32
  const nucleus = this.world.createEntity().tag("nucleus");
26
33
  const nPos = new Transform2D();
@@ -35,9 +42,9 @@ class AtomScene extends Scene {
35
42
  this.world.addComponent(glow.id, new Sprite(0.9, 0.5, 0.1, 0.15, 60, 60));
36
43
 
37
44
  const orbits = [
38
- { radius: 80, speed: 2.0, tilt: 0, color: [0.3, 0.7, 1.0], size: 8, offset: 0 },
39
- { radius: 130, speed: 1.3, tilt: Math.PI / 3, color: [0.4, 1.0, 0.6], size: 7, offset: Math.PI * 0.66 },
40
- { radius: 180, speed: 0.8, tilt: -Math.PI / 4, color: [1.0, 0.4, 0.8], size: 6, offset: Math.PI * 1.33 },
45
+ { radius: 80, speed: 2.0, tilt: 0, color: [0.3, 0.7, 1.0], size: 8, offset: 0 },
46
+ { radius: 130, speed: 1.3, tilt: Math.PI / 3, color: [0.4, 1.0, 0.6], size: 7, offset: Math.PI * 0.66 },
47
+ { radius: 180, speed: 0.8, tilt: -Math.PI / 4, color: [1.0, 0.4, 0.8], size: 6, offset: Math.PI * 1.33 },
41
48
  ];
42
49
 
43
50
  for (const orbit of orbits) {
@@ -48,10 +55,10 @@ class AtomScene extends Scene {
48
55
  dPos.zIndex = 1;
49
56
  this.world.addComponent(dot.id, dPos);
50
57
  this.world.addComponent(dot.id, new OrbitalSpeed(
51
- orbit.radius, 0, (i / ringCount) * Math.PI * 2, orbit.tilt
58
+ orbit.radius, 0, (i / ringCount) * Math.PI * 2, orbit.tilt,
52
59
  ));
53
60
  this.world.addComponent(dot.id, new Sprite(
54
- orbit.color[0] * 0.3, orbit.color[1] * 0.3, orbit.color[2] * 0.3, 0.25, 2, 2
61
+ orbit.color[0] * 0.3, orbit.color[1] * 0.3, orbit.color[2] * 0.3, 0.25, 2, 2,
55
62
  ));
56
63
  }
57
64
 
@@ -60,37 +67,39 @@ class AtomScene extends Scene {
60
67
  ePos.zIndex = 5;
61
68
  this.world.addComponent(electron.id, ePos);
62
69
  this.world.addComponent(electron.id, new OrbitalSpeed(
63
- orbit.radius, orbit.speed, orbit.offset, orbit.tilt
70
+ orbit.radius, orbit.speed, orbit.offset, orbit.tilt,
64
71
  ));
65
72
  this.world.addComponent(electron.id, new Sprite(
66
- orbit.color[0], orbit.color[1], orbit.color[2], 1, orbit.size, orbit.size
67
- ));
68
-
69
- const eGlow = this.world.createEntity().tag("electron-glow");
70
- const egPos = new Transform2D();
71
- egPos.zIndex = 4;
72
- this.world.addComponent(eGlow.id, egPos);
73
- this.world.addComponent(eGlow.id, new OrbitalSpeed(
74
- orbit.radius, orbit.speed, orbit.offset, orbit.tilt
75
- ));
76
- this.world.addComponent(eGlow.id, new Sprite(
77
- orbit.color[0], orbit.color[1], orbit.color[2], 0.2, orbit.size * 4, orbit.size * 4
73
+ orbit.color[0], orbit.color[1], orbit.color[2], 1, orbit.size, orbit.size,
78
74
  ));
79
75
  }
76
+
77
+ // Load UI from hud.pui
78
+ const ui = loadPui(this.world, parsePui(puiSource));
79
+ this.scoreId = ui.entities.get("score")!;
80
+ this.btnId = ui.entities.get("clickBtn")!;
81
+
82
+ this.world.eventBus.on<number>("ui:click", (entityId) => {
83
+ if (entityId === this.btnId) {
84
+ this.clickCount++;
85
+ const arch = this.world.getArchetype(this.scoreId);
86
+ if (arch) {
87
+ arch.get<UIText>("uiText")!.text = `Clicks: ${this.clickCount}`;
88
+ }
89
+ }
90
+ });
80
91
  }
81
92
 
82
93
  onUpdate(): void {
83
94
  const time = performance.now() * 0.001;
84
- const entities = this.world.query("transform2d", "orbitalSpeed");
85
95
 
86
- for (const arch of entities) {
96
+ for (const arch of this.world.query("transform2d", "orbitalSpeed")) {
87
97
  const t = arch.get<Transform2D>("transform2d")!;
88
98
  const o = arch.get<OrbitalSpeed>("orbitalSpeed")!;
89
99
 
90
100
  const angle = o.angleOffset + time * o.speed;
91
101
  const x = Math.cos(angle) * o.radius;
92
102
  const y = Math.sin(angle) * o.radius * 0.4;
93
-
94
103
  const cosT = Math.cos(o.orbitTilt);
95
104
  const sinT = Math.sin(o.orbitTilt);
96
105
  t.x = x * cosT - y * sinT;
@@ -99,19 +108,19 @@ class AtomScene extends Scene {
99
108
 
100
109
  const nucleusArch = this.world.queryByTag("nucleus")[0];
101
110
  if (nucleusArch) {
102
- const nSprite = nucleusArch.get<Sprite>("sprite")!;
111
+ const s = nucleusArch.get<Sprite>("sprite")!;
103
112
  const pulse = 28 + Math.sin(time * 3) * 4;
104
- nSprite.width = pulse;
105
- nSprite.height = pulse;
113
+ s.width = pulse;
114
+ s.height = pulse;
106
115
  }
107
116
 
108
117
  const glowArch = this.world.queryByTag("glow")[0];
109
118
  if (glowArch) {
110
- const gSprite = glowArch.get<Sprite>("sprite")!;
119
+ const s = glowArch.get<Sprite>("sprite")!;
111
120
  const pulse = 60 + Math.sin(time * 2) * 10;
112
- gSprite.width = pulse;
113
- gSprite.height = pulse;
114
- gSprite.colorA = 0.12 + Math.sin(time * 3) * 0.05;
121
+ s.width = pulse;
122
+ s.height = pulse;
123
+ s.colorA = 0.12 + Math.sin(time * 3) * 0.05;
115
124
  }
116
125
  }
117
126
 
@@ -119,6 +128,6 @@ class AtomScene extends Scene {
119
128
  }
120
129
 
121
130
  const engine = new Engine({ canvasId: "game-canvas" });
122
- engine.sceneManager.register(new AtomScene());
123
- engine.sceneManager.switchTo("atom");
124
- engine.start();
131
+ engine.sceneManager.register(new DemoScene());
132
+ engine.sceneManager.switchTo("demo");
133
+ engine.start();
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1 @@
1
+ const e={},t=Object.freeze(Object.defineProperty({__proto__:null,default:e},Symbol.toStringTag,{value:"Module"}));export{t as _};
@@ -0,0 +1 @@
1
+ import{_ as u}from"./__vite-browser-external-D7Ct-6yo.js";function l(t,n){for(var r=0;r<n.length;r++){const e=n[r];if(typeof e!="string"&&!Array.isArray(e)){for(const o in e)if(o!=="default"&&!(o in t)){const i=Object.getOwnPropertyDescriptor(e,o);i&&Object.defineProperty(t,o,i.get?i:{enumerable:!0,get:()=>e[o]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}function f(t){if(Object.prototype.hasOwnProperty.call(t,"__esModule"))return t;var n=t.default;if(typeof n=="function"){var r=function e(){return this instanceof e?Reflect.construct(n,arguments,this.constructor):n.apply(this,arguments)};r.prototype=n.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(t).forEach(function(e){var o=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(r,e,o.get?o:{enumerable:!0,get:function(){return t[e]}})}),r}const a=f(u);var c,s;function p(){if(s)return c;s=1;var t={};const n=a,r=a,e=r.join(__dirname,"path.txt");function o(){let i;if(n.existsSync(e)&&(i=n.readFileSync(e,"utf-8")),t.ELECTRON_OVERRIDE_DIST_PATH)return r.join(t.ELECTRON_OVERRIDE_DIST_PATH,i||"electron");if(i)return r.join(__dirname,"dist",i);throw new Error("Electron failed to install correctly, please delete node_modules/electron and try installing again")}return c=o(),c}var _=p();const y=l({__proto__:null},[_]);export{y as i};
@@ -0,0 +1,92 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-Cxo-KaTG.js","./__vite-browser-external-D7Ct-6yo.js"])))=>i.map(i=>d[i]);
2
+ var N=Object.defineProperty;var V=(d,e,t)=>e in d?N(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var r=(d,e,t)=>V(d,typeof e!="symbol"?e+"":e,t);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))i(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function t(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(s){if(s.ep)return;s.ep=!0;const n=t(s);fetch(s.href,n)}})();const X=`// Photon Engine — HUD demo
3
+ panel "hud" {
4
+ x: 20; y: 20;
5
+ width: 300; height: 210;
6
+ color: [0.08, 0.08, 0.1, 0.85];
7
+ borderRadius: 8;
8
+
9
+ text "title" {
10
+ x: 0; y: 12;
11
+ width: 300; height: 28;
12
+ text: "Photon Engine — Electron";
13
+ fontSize: 18;
14
+ color: [0.5, 0.7, 1, 1];
15
+ align: center;
16
+ bold: true;
17
+ zIndex: 1;
18
+ }
19
+
20
+ text "score" {
21
+ x: 10; y: 52;
22
+ width: 280; height: 24;
23
+ text: "Clicks: 0";
24
+ fontSize: 15;
25
+ color: [1, 1, 1, 1];
26
+ fontFamily: monospace;
27
+ zIndex: 1;
28
+ }
29
+
30
+ button "clickBtn" {
31
+ x: 70; y: 88;
32
+ width: 160; height: 38;
33
+ label: "Click Me!";
34
+ color: [0.16, 0.5, 1, 1];
35
+ hoverColor: [0.29, 0.62, 1, 1];
36
+ pressedColor: [0.1, 0.37, 0.8, 1];
37
+ borderRadius: 8;
38
+ fontSize: 15;
39
+ zIndex: 1;
40
+ }
41
+
42
+ text "nameLabel" {
43
+ x: 10; y: 146;
44
+ width: 60; height: 22;
45
+ text: "Name:";
46
+ fontSize: 13;
47
+ color: [0.7, 0.7, 0.7, 1];
48
+ zIndex: 1;
49
+ }
50
+
51
+ textInput "nameInput" {
52
+ x: 70; y: 143;
53
+ width: 220; height: 28;
54
+ placeholder: "Type here...";
55
+ maxLength: 64;
56
+ fontSize: 13;
57
+ zIndex: 1;
58
+ }
59
+ }
60
+ `;class W{constructor(){r(this,"listeners",new Map)}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}once(e,t){const i=s=>{this.off(e,i),t(s)};return this.on(e,i)}off(e,t){var i;(i=this.listeners.get(e))==null||i.delete(t)}emit(e,t){const i=this.listeners.get(e);if(i)for(const s of i)try{s(t)}catch(n){console.error(`[EventBus] Error in "${e}":`,n)}}clear(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var t;return((t=this.listeners.get(e))==null?void 0:t.size)??0}}class j{constructor(e,t){r(this,"scenes",new Map);r(this,"current",null);r(this,"bus");r(this,"engine");this.bus=e??new W,this.engine=t}register(e){e.engine=this.engine,this.scenes.set(e.name,e)}unregister(e){var t;((t=this.current)==null?void 0:t.name)===e&&(this.current.onExit(),this.current=null),this.scenes.delete(e)}switchTo(e){const t=this.scenes.get(e);return t?(this.current&&this.current.onExit(),this.current=t,this.current.engine=this.engine,this.current.onEnter(),this.bus.emit("scene:switched",e),!0):!1}get currentScene(){return this.current}get sceneNames(){return[...this.scenes.keys()]}get eventBus(){return this.bus}getScene(e){return this.scenes.get(e)}}class K{constructor(e,t,i){r(this,"gl");r(this,"program");this.gl=e;const s=this.compile(e.VERTEX_SHADER,t),n=this.compile(e.FRAGMENT_SHADER,i);if(this.program=e.createProgram(),e.attachShader(this.program,s),e.attachShader(this.program,n),e.linkProgram(this.program),!e.getProgramParameter(this.program,e.LINK_STATUS)){const o=e.getProgramInfoLog(this.program);throw e.deleteProgram(this.program),new Error(`Shader link error: ${o}`)}e.deleteShader(s),e.deleteShader(n)}compile(e,t){const i=this.gl.createShader(e);if(this.gl.shaderSource(i,t),this.gl.compileShader(i),!this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS)){const s=this.gl.getShaderInfoLog(i);throw this.gl.deleteShader(i),new Error(`Shader compile error: ${s}`)}return i}use(){this.gl.useProgram(this.program)}getAttribLocation(e){return this.gl.getAttribLocation(this.program,e)}getUniformLocation(e){return this.gl.getUniformLocation(this.program,e)}setUniformMat3(e,t){const i=this.getUniformLocation(e);i&&this.gl.uniformMatrix3fv(i,!1,t)}setUniformVec4(e,t,i,s,n){const o=this.getUniformLocation(e);o&&this.gl.uniform4f(o,t,i,s,n)}setUniformVec2(e,t,i){const s=this.getUniformLocation(e);s&&this.gl.uniform2f(s,t,i)}setUniformFloat(e,t){const i=this.getUniformLocation(e);i&&this.gl.uniform1f(i,t)}setUniformInt(e,t){const i=this.getUniformLocation(e);i&&this.gl.uniform1i(i,t)}destroy(){this.gl.deleteProgram(this.program)}}const Z=`#version 300 es
61
+ layout(location = 0) in vec2 aPosition;
62
+ layout(location = 1) in vec2 aTexCoord;
63
+ layout(location = 2) in vec4 aColor;
64
+
65
+ uniform mat3 uViewProj;
66
+
67
+ out vec2 vTexCoord;
68
+ out vec4 vColor;
69
+
70
+ void main() {
71
+ vec3 pos = uViewProj * vec3(aPosition, 1.0);
72
+ gl_Position = vec4(pos.xy, 0.0, 1.0);
73
+ vTexCoord = aTexCoord;
74
+ vColor = aColor;
75
+ }
76
+ `,J=`#version 300 es
77
+ precision mediump float;
78
+
79
+ in vec2 vTexCoord;
80
+ in vec4 vColor;
81
+
82
+ uniform sampler2D uTexture;
83
+ uniform float uUseTexture;
84
+
85
+ out vec4 fragColor;
86
+
87
+ void main() {
88
+ vec4 texColor = mix(vec4(1.0), texture(uTexture, vTexCoord), uUseTexture);
89
+ fragColor = vColor * texColor;
90
+ }
91
+ `,M=8,O=1e4;class Q{constructor(e){r(this,"gl");r(this,"shader");r(this,"vao");r(this,"vbo");r(this,"vertices");r(this,"vertexCount",0);r(this,"currentTexture",null);const t=e.getContext("webgl2",{alpha:!1,antialias:!1,premultipliedAlpha:!1});if(!t)throw new Error("WebGL2 not supported");this.gl=t,this.shader=new K(t,Z,J),this.vertices=new Float32Array(O*6*M),this.vao=t.createVertexArray(),this.vbo=t.createBuffer(),t.bindVertexArray(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.vbo),t.bufferData(t.ARRAY_BUFFER,this.vertices.byteLength,t.DYNAMIC_DRAW);const i=M*4;t.enableVertexAttribArray(0),t.vertexAttribPointer(0,2,t.FLOAT,!1,i,0),t.enableVertexAttribArray(1),t.vertexAttribPointer(1,2,t.FLOAT,!1,i,8),t.enableVertexAttribArray(2),t.vertexAttribPointer(2,4,t.FLOAT,!1,i,16),t.bindVertexArray(null),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}clear(e=0,t=0,i=0,s=1){this.gl.clearColor(e,t,i,s),this.gl.clear(this.gl.COLOR_BUFFER_BIT)}begin(e){this.shader.use(),this.shader.setUniformMat3("uViewProj",e.data),this.gl.bindVertexArray(this.vao)}drawSprite(e,t){const i=t.texture??null;(i!==this.currentTexture||this.vertexCount+6>O*6)&&(this.flush(),this.currentTexture=i),i?(this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,i),this.shader.setUniformInt("uTexture",0),this.shader.setUniformFloat("uUseTexture",1)):this.shader.setUniformFloat("uUseTexture",0);const s=t.width*.5,n=t.height*.5,o=e.getLocalMatrix(),c=[{x:-s,y:-n,u:t.texCoordU,v:t.texCoordV},{x:s,y:-n,u:t.texCoordU+t.texCoordW,v:t.texCoordV},{x:s,y:n,u:t.texCoordU+t.texCoordW,v:t.texCoordV+t.texCoordH},{x:-s,y:n,u:t.texCoordU,v:t.texCoordV+t.texCoordH}].map(f=>{const g=o.transformPoint({x:f.x,y:f.y});return{x:g.x,y:g.y,u:f.u,v:f.v}}),h=this.vertices;let l=this.vertexCount*M;const u=f=>{const g=c[f];h[l++]=g.x,h[l++]=g.y,h[l++]=g.u,h[l++]=g.v,h[l++]=t.colorR,h[l++]=t.colorG,h[l++]=t.colorB,h[l++]=t.colorA};u(0),u(1),u(2),u(0),u(2),u(3),this.vertexCount+=6}flush(){this.vertexCount!==0&&(this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertices,0,this.vertexCount*M),this.gl.drawArrays(this.gl.TRIANGLES,0,this.vertexCount),this.vertexCount=0)}end(){this.flush(),this.gl.bindVertexArray(null),this.currentTexture=null}resize(e,t){this.gl.viewport(0,0,e,t)}get context(){return this.gl}destroy(){this.shader.destroy(),this.gl.deleteBuffer(this.vbo),this.gl.deleteVertexArray(this.vao)}}const p=class p{constructor(e=0,t=0){r(this,"x");r(this,"y");this.x=e,this.y=t}clone(){return new p(this.x,this.y)}set(e,t){return this.x=e,this.y=t,this}add(e){return new p(this.x+e.x,this.y+e.y)}sub(e){return new p(this.x-e.x,this.y-e.y)}mul(e){return new p(this.x*e,this.y*e)}div(e){return new p(this.x/e,this.y/e)}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}lengthSq(){return this.x*this.x+this.y*this.y}normalize(){const e=this.length();return e>0?this.div(e):p.ZERO.clone()}distance(e){return this.sub(e).length()}distanceSq(e){return this.sub(e).lengthSq()}angle(){return Math.atan2(this.y,this.x)}rotate(e){const t=Math.cos(e),i=Math.sin(e);return new p(this.x*t-this.y*i,this.x*i+this.y*t)}lerp(e,t){return new p(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)}equals(e,t=1e-6){return Math.abs(this.x-e.x)<t&&Math.abs(this.y-e.y)<t}static fromAngle(e,t=1){return new p(Math.cos(e)*t,Math.sin(e)*t)}static lerp(e,t,i){return e.lerp(t,i)}};r(p,"ZERO",new p(0,0)),r(p,"ONE",new p(1,1)),r(p,"UP",new p(0,-1)),r(p,"DOWN",new p(0,1)),r(p,"LEFT",new p(-1,0)),r(p,"RIGHT",new p(1,0));let T=p;var z;(function(d){d[d.Game=0]="Game",d[d.UI=100]="UI",d[d.Console=200]="Console",d[d.Modal=300]="Modal"})(z||(z={}));class tt{constructor(){r(this,"stack",[]);r(this,"counter",0)}request(e,t){const i=this.stack.findIndex(n=>n.holderId===e);i!==-1&&this.stack.splice(i,1);const s={holderId:e,priority:t,timestamp:this.counter++};return this.stack.push(s),this.stack.sort((n,o)=>n.priority!==o.priority?o.priority-n.priority:o.timestamp-n.timestamp),this.stack[0].holderId===e}release(e){const t=this.stack.findIndex(i=>i.holderId===e);t!==-1&&this.stack.splice(t,1)}isCaptured(){return this.stack.length>0}getCurrentHolder(){return this.stack.length>0?this.stack[0].holderId:null}hasOwnership(e){return this.stack.length>0&&this.stack[0].holderId===e}getStack(){return this.stack}clear(){this.stack=[],this.counter=0}}class et{constructor(e){r(this,"canvas");r(this,"keysDown",new Set);r(this,"keysPressed",new Set);r(this,"keysReleased",new Set);r(this,"mouseButtonsDown",new Set);r(this,"mouseButtonsPressed",new Set);r(this,"mouseButtonsReleased",new Set);r(this,"mousePos",new T);r(this,"mouseDelta",new T);r(this,"scrollDelta",0);r(this,"bound",!1);r(this,"captureStack",new tt);r(this,"keyDownHandler");r(this,"keyUpHandler");r(this,"mouseMoveHandler");r(this,"mouseDownHandler");r(this,"mouseUpHandler");r(this,"wheelHandler");this.canvas=e,this.keyDownHandler=t=>{this.captureStack.isCaptured()||(this.keysDown.has(t.code)||this.keysPressed.add(t.code),this.keysDown.add(t.code),t.preventDefault())},this.keyUpHandler=t=>{this.captureStack.isCaptured()||(this.keysDown.delete(t.code),this.keysReleased.add(t.code))},this.mouseMoveHandler=t=>{const i=this.canvas.getBoundingClientRect(),s=t.clientX-i.left,n=t.clientY-i.top;this.mouseDelta=new T(s-this.mousePos.x,n-this.mousePos.y),this.mousePos=new T(s,n)},this.mouseDownHandler=t=>{this.captureStack.isCaptured()||(this.mouseButtonsDown.has(t.button)||this.mouseButtonsPressed.add(t.button),this.mouseButtonsDown.add(t.button))},this.mouseUpHandler=t=>{this.captureStack.isCaptured()||(this.mouseButtonsDown.delete(t.button),this.mouseButtonsReleased.add(t.button))},this.wheelHandler=t=>{this.captureStack.isCaptured()||(this.scrollDelta=t.deltaY)}}capture(e,t=z.UI){return this.captureStack.request(e,t)}release(e){this.captureStack.release(e)}hasOwnership(e){return this.captureStack.hasOwnership(e)}isCaptured(){return this.captureStack.isCaptured()}getCurrentHolder(){return this.captureStack.getCurrentHolder()}init(){this.bound||(this.bound=!0,window.addEventListener("keydown",this.keyDownHandler),window.addEventListener("keyup",this.keyUpHandler),this.canvas.addEventListener("mousemove",this.mouseMoveHandler),this.canvas.addEventListener("mousedown",this.mouseDownHandler),this.canvas.addEventListener("mouseup",this.mouseUpHandler),this.canvas.addEventListener("wheel",this.wheelHandler))}destroy(){this.bound&&(this.bound=!1,window.removeEventListener("keydown",this.keyDownHandler),window.removeEventListener("keyup",this.keyUpHandler),this.canvas.removeEventListener("mousemove",this.mouseMoveHandler),this.canvas.removeEventListener("mousedown",this.mouseDownHandler),this.canvas.removeEventListener("mouseup",this.mouseUpHandler),this.canvas.removeEventListener("wheel",this.wheelHandler),this.captureStack.clear())}endFrame(){this.keysPressed.clear(),this.keysReleased.clear(),this.mouseButtonsPressed.clear(),this.mouseButtonsReleased.clear(),this.mouseDelta=T.ZERO.clone(),this.scrollDelta=0}isKeyDown(e){return this.captureStack.isCaptured()?!1:this.keysDown.has(e)}isKeyPressed(e){return this.captureStack.isCaptured()?!1:this.keysPressed.has(e)}isKeyReleased(e){return this.captureStack.isCaptured()?!1:this.keysReleased.has(e)}isMouseButtonDown(e=0){return this.captureStack.isCaptured()?!1:this.mouseButtonsDown.has(e)}isMouseButtonPressed(e=0){return this.captureStack.isCaptured()?!1:this.mouseButtonsPressed.has(e)}isMouseButtonReleased(e=0){return this.captureStack.isCaptured()?!1:this.mouseButtonsReleased.has(e)}get mousePosition(){return this.mousePos.clone()}get mouseDeltaPosition(){return this.mouseDelta.clone()}get scrollY(){return this.captureStack.isCaptured()?0:this.scrollDelta}}class st{async collideAABB(e,t,i,s,n,o,a,c){return e<n+a&&e+i>n&&t<o+c&&t+s>o}async batchTransform(e,t){return e}async noise2D(e,t,i){const s=Math.sin(e*127.1+t*311.7)*43758.5453123;return s-Math.floor(s)}async pathfind(){return console.warn("[Photon] pathfind: no compute backend, returning null"),null}}class it{constructor(e){r(this,"fs");this.fs=e}async invoke(e,t){throw new Error(`[Photon] Native invoke "${e}" not available in browser mode`)}}class rt{constructor(){r(this,"storage",new Map)}async readText(e){const t=this.storage.get(e);if(!t)throw new Error(`File not found: ${e}`);return new TextDecoder().decode(t)}async writeText(e,t){this.storage.set(e,new TextEncoder().encode(t)),this.persistToLocalStorage()}async readBinary(e){const t=this.storage.get(e);if(!t)throw new Error(`File not found: ${e}`);return t}async writeBinary(e,t){this.storage.set(e,t),this.persistToLocalStorage()}async exists(e){return this.storage.has(e)}async mkdir(e){}async remove(e){this.storage.delete(e),this.persistToLocalStorage()}async listDir(e){const t=e.endsWith("/")?e:e+"/",i=new Set;for(const s of this.storage.keys())if(s.startsWith(t)){const o=s.slice(t.length).split("/")[0];i.add(o)}return[...i]}async isFile(e){return this.storage.has(e)}async isDir(e){const t=e.endsWith("/")?e:e+"/";for(const i of this.storage.keys())if(i.startsWith(t))return!0;return!1}persistToLocalStorage(){try{const e={};for(const[t,i]of this.storage)e[t]=[...i];localStorage.setItem("photon:fs",JSON.stringify(e))}catch{}}loadFromLocalStorage(){try{const e=localStorage.getItem("photon:fs");if(!e)return;const t=JSON.parse(e);for(const[i,s]of Object.entries(t))this.storage.set(i,new Uint8Array(s))}catch{}}}class nt{constructor(e={}){r(this,"sceneManager");r(this,"renderer");r(this,"input");r(this,"eventBus");r(this,"fs");r(this,"bridge");r(this,"compute");r(this,"running",!1);r(this,"lastTime",0);r(this,"rafId",0);r(this,"fixedAccumulator",0);r(this,"fixedStep",1e3/60);r(this,"canvas");r(this,"dpr",1);r(this,"loop",e=>{if(!this.running)return;this.rafId=requestAnimationFrame(this.loop);const t=e-this.lastTime;this.lastTime=e;const i=Math.min(t,250);for(this.fixedAccumulator+=i;this.fixedAccumulator>=this.fixedStep;)this.fixedUpdate(this.fixedStep/1e3),this.fixedAccumulator-=this.fixedStep;this.update(i/1e3),this.render(),this.input.endFrame()});const t=e.canvasId??"photon-canvas",i=document.getElementById(t);if(!i)throw new Error(`Canvas "#${t}" not found`);this.dpr=window.devicePixelRatio||1;const s=e.width??window.innerWidth,n=e.height??window.innerHeight;if(i.style.width=s+"px",i.style.height=n+"px",i.width=Math.round(s*this.dpr),i.height=Math.round(n*this.dpr),this.canvas=i,this.eventBus=new W,this.renderer=new Q(i),this.input=new et(i),this.sceneManager=new j(this.eventBus,this),e.fs)this.fs=e.fs;else{const o=new rt;o.loadFromLocalStorage(),this.fs=o}this.bridge=e.nativeBridge??new it(this.fs),this.compute=new st,window.addEventListener("resize",()=>this.handleResize())}handleResize(){this.dpr=window.devicePixelRatio||1;const e=window.innerWidth,t=window.innerHeight;this.canvas.style.width=e+"px",this.canvas.style.height=t+"px",this.canvas.width=Math.round(e*this.dpr),this.canvas.height=Math.round(t*this.dpr),this.renderer.resize(this.canvas.width,this.canvas.height),this.eventBus.emit("engine:resize",{width:this.canvas.width,height:this.canvas.height})}get pixelRatio(){return this.dpr}get cssWidth(){return this.canvas.getBoundingClientRect().width}get cssHeight(){return this.canvas.getBoundingClientRect().height}start(){this.running||(this.running=!0,this.input.init(),this.lastTime=performance.now(),this.loop(this.lastTime),this.eventBus.emit("engine:start",null))}stop(){this.running=!1,this.input.destroy(),cancelAnimationFrame(this.rafId),this.eventBus.emit("engine:stop",null)}fixedUpdate(e){const t=this.sceneManager.currentScene;t&&(t.world.update(e),t.onUpdate(e))}update(e){}render(){const e=this.sceneManager.currentScene;if(!e){this.renderer.clear(.1,.1,.1);return}const t=e.world.query("camera2d","transform2d");if(t.length===0){this.renderer.clear(.1,.1,.1);return}const i=t[0],s=i.get("camera2d"),n=i.get("transform2d");s.x=n.x,s.y=n.y,s.rotation=n.rotation,s.viewportWidth=this.canvas.width,s.viewportHeight=this.canvas.height;const o=s.getViewProjectionMatrix();this.renderer.clear(.1,.1,.12),this.renderer.begin(o);const a=e.world.query("transform2d","sprite");a.sort((c,h)=>{const l=c.get("transform2d").zIndex,u=h.get("transform2d").zIndex;return l-u});for(const c of a){const h=c.get("transform2d"),l=c.get("sprite");this.renderer.drawSprite(h,l)}this.renderer.end()}resizeUIOverlay(){const e=document.getElementById("photon-ui-overlay");e&&(e.width=this.canvas.width,e.height=this.canvas.height)}destroy(){var e;this.stop(),this.renderer.destroy(),(e=this.sceneManager.currentScene)==null||e.world.clear(),this.eventBus.clear()}}class E{}let ot=1;class at{constructor(e){r(this,"id");r(this,"tags",new Set);r(this,"active",!0);this.id=e??ot++}tag(...e){for(const t of e)this.tags.add(t);return this}untag(...e){for(const t of e)this.tags.delete(t);return this}hasTag(e){return this.tags.has(e)}equals(e){return this.id===e.id}}class ht{constructor(e){r(this,"entity");r(this,"components",new Map);this.entity=e}add(e){return this.components.set(e.type,e),this}remove(e){const t=this.components.get(e);return this.components.delete(e),t}get(e){return this.components.get(e)}has(e){return this.components.has(e)}hasAll(e){for(const t of e)if(!this.components.has(t))return!1;return!0}getAll(){return new Map(this.components)}}class ct{constructor(){r(this,"priority",0);r(this,"active",!0)}}class dt{constructor(){r(this,"archetypes",new Map);r(this,"systems",[]);r(this,"entityRecycleBin",[]);r(this,"bus",new W);r(this,"scene")}createEntity(){const e=this.entityRecycleBin.length>0?this.entityRecycleBin.pop():void 0,t=new at(e),i=new ht(t);return this.archetypes.set(t.id,i),this.bus.emit("entity:created",t),t}destroyEntity(e){const t=this.archetypes.get(e);t&&(this.bus.emit("entity:destroyed",t.entity),this.archetypes.delete(e),this.entityRecycleBin.push(e))}getArchetype(e){return this.archetypes.get(e)}addComponent(e,t){const i=this.archetypes.get(e);i&&(i.add(t),this.bus.emit("component:added",{entityId:e,type:t.type}))}removeComponent(e,t){const i=this.archetypes.get(e);i&&(i.remove(t),this.bus.emit("component:removed",{entityId:e,type:t}))}getComponent(e,t){var i;return(i=this.archetypes.get(e))==null?void 0:i.get(t)}getEntity(e){var t;return(t=this.archetypes.get(e))==null?void 0:t.entity}hasEntity(e){return this.archetypes.has(e)}getAllEntities(){const e=[];for(const[,t]of this.archetypes)e.push(t.entity);return e}registerSystem(e){this.systems.push(e),this.systems.sort((t,i)=>t.priority-i.priority),e.onInit(this)}unregisterSystem(e){const t=this.systems.indexOf(e);t!==-1&&(e.onDestroy(this),this.systems.splice(t,1))}query(...e){const t=[];for(const[,i]of this.archetypes)i.entity.active&&i.hasAll(e)&&t.push(i);return t}queryByTag(e){const t=[];for(const[,i]of this.archetypes)i.entity.active&&i.entity.hasTag(e)&&t.push(i);return t}update(e){for(const t of this.systems){if(!t.active)continue;const i=this.query(...t.requiredComponents);t.onUpdate(this,i,e)}}get entityCount(){return this.archetypes.size}get eventBus(){return this.bus}clear(){for(const e of this.systems)e.onDestroy(this);this.systems=[],this.archetypes.clear(),this.entityRecycleBin=[],this.bus.clear()}}class lt{constructor(){r(this,"world");r(this,"engine");this.world=new dt,this.world.scene=this}moveEntityTo(e,t){const i=this.world.getArchetype(e);if(!i)return!1;const s=i.getAll(),n=i.entity;this.world.destroyEntity(e);const o=t.world.createEntity();o.tags=new Set(n.tags),o.active=n.active;const a=t.world.getArchetype(o.id);for(const[,c]of s)a.add(c);return!0}copyEntityTo(e,t){const i=this.world.getArchetype(e);if(!i)return null;const s=t.world.createEntity();s.tags=new Set(i.entity.tags);const n=t.world.getArchetype(s.id);for(const[,o]of i.getAll())n.add(o);return s}}class v{constructor(e=v.identity().data){r(this,"data");this.data=e}static identity(){return new v(new Float32Array([1,0,0,0,1,0,0,0,1]))}static translation(e,t){const i=v.identity();return i.data[6]=e,i.data[7]=t,i}static rotation(e){const t=Math.cos(e),i=Math.sin(e),s=v.identity();return s.data[0]=t,s.data[1]=i,s.data[3]=-i,s.data[4]=t,s}static scale(e,t){const i=v.identity();return i.data[0]=e,i.data[4]=t,i}static orthographic(e,t,i,s){const n=v.identity();return n.data[0]=2/(t-e),n.data[4]=2/(s-i),n.data[6]=-(t+e)/(t-e),n.data[7]=-(s+i)/(s-i),n}multiply(e){const t=this.data,i=e.data,s=new Float32Array(9);for(let n=0;n<3;n++)for(let o=0;o<3;o++)s[o*3+n]=t[n]*i[o*3]+t[3+n]*i[o*3+1]+t[6+n]*i[o*3+2];return new v(s)}transformPoint(e){const t=this.data;return new T(t[0]*e.x+t[3]*e.y+t[6],t[1]*e.x+t[4]*e.y+t[7])}clone(){return new v(new Float32Array(this.data))}invert(){const e=this.data,t=e[0]*(e[4]*e[8]-e[5]*e[7])-e[1]*(e[3]*e[8]-e[5]*e[6])+e[2]*(e[3]*e[7]-e[4]*e[6]);if(Math.abs(t)<1e-10)return v.identity();const i=1/t,s=new Float32Array(9);return s[0]=(e[4]*e[8]-e[5]*e[7])*i,s[1]=(e[2]*e[7]-e[1]*e[8])*i,s[2]=(e[1]*e[5]-e[2]*e[4])*i,s[3]=(e[5]*e[6]-e[3]*e[8])*i,s[4]=(e[0]*e[8]-e[2]*e[6])*i,s[5]=(e[2]*e[3]-e[0]*e[5])*i,s[6]=(e[3]*e[7]-e[4]*e[6])*i,s[7]=(e[1]*e[6]-e[0]*e[7])*i,s[8]=(e[0]*e[4]-e[1]*e[3])*i,new v(s)}}class D{constructor(e=0,t=0,i=0,s=0){r(this,"x");r(this,"y");r(this,"width");r(this,"height");this.x=e,this.y=t,this.width=i,this.height=s}get left(){return this.x}get right(){return this.x+this.width}get top(){return this.y}get bottom(){return this.y+this.height}get centerX(){return this.x+this.width*.5}get centerY(){return this.y+this.height*.5}contains(e){return e.x>=this.left&&e.x<=this.right&&e.y>=this.top&&e.y<=this.bottom}intersects(e){return this.left<e.right&&this.right>e.left&&this.top<e.bottom&&this.bottom>e.top}clone(){return new D(this.x,this.y,this.width,this.height)}static fromPoints(e,t){const i=Math.min(e.x,t.x),s=Math.min(e.y,t.y);return new D(i,s,Math.max(e.x,t.x)-i,Math.max(e.y,t.y)-s)}}class I extends E{constructor(){super(...arguments);r(this,"type","transform2d");r(this,"x",0);r(this,"y",0);r(this,"rotation",0);r(this,"scaleX",1);r(this,"scaleY",1);r(this,"zIndex",0)}get position(){return new T(this.x,this.y)}set position(t){this.x=t.x,this.y=t.y}getLocalMatrix(){return v.translation(this.x,this.y).multiply(v.rotation(this.rotation)).multiply(v.scale(this.scaleX,this.scaleY))}}class ut extends E{constructor(){super(...arguments);r(this,"type","camera2d");r(this,"x",0);r(this,"y",0);r(this,"zoom",1);r(this,"rotation",0);r(this,"viewportWidth",1280);r(this,"viewportHeight",720)}get position(){return new T(this.x,this.y)}set position(t){this.x=t.x,this.y=t.y}getViewProjectionMatrix(){const t=this.viewportWidth*.5/this.zoom,i=this.viewportHeight*.5/this.zoom;return v.translation(-this.x,-this.y).multiply(v.rotation(-this.rotation)).multiply(v.orthographic(-t,t,-i,i))}screenToWorld(t,i){const s=t/this.viewportWidth*2-1,n=1-i/this.viewportHeight*2,o=this.viewportWidth*.5/this.zoom,a=this.viewportHeight*.5/this.zoom;return this.getViewProjectionMatrix().invert().transformPoint(new T(s*o,n*a))}getVisibleBounds(){const t=this.viewportWidth*.5/this.zoom,i=this.viewportHeight*.5/this.zoom;return new D(this.x-t,this.y-i,t*2,i*2)}}class L extends E{constructor(t=1,i=1,s=1,n=1,o=32,a=32,c,h=0,l=0,u=1,f=1){super();r(this,"colorR");r(this,"colorG");r(this,"colorB");r(this,"colorA");r(this,"width");r(this,"height");r(this,"texture");r(this,"texCoordU");r(this,"texCoordV");r(this,"texCoordW");r(this,"texCoordH");r(this,"type","sprite");this.colorR=t,this.colorG=i,this.colorB=s,this.colorA=n,this.width=o,this.height=a,this.texture=c,this.texCoordU=h,this.texCoordV=l,this.texCoordW=u,this.texCoordH=f}}class ft extends E{constructor(t=0,i=0,s=100,n=100,o=0,a=0){super();r(this,"x");r(this,"y");r(this,"width");r(this,"height");r(this,"originX");r(this,"originY");r(this,"type","uiTransform");r(this,"zIndex",0);this.x=t,this.y=i,this.width=s,this.height=n,this.originX=o,this.originY=a}get drawX(){return this.x-this.width*this.originX}get drawY(){return this.y-this.height*this.originY}containsPoint(t,i){const s=this.drawX,n=this.drawY;return t>=s&&t<=s+this.width&&i>=n&&i<=n+this.height}}var B;(function(d){d.Left="left",d.Center="center",d.Right="right"})(B||(B={}));class $ extends E{constructor(t="",i="sans-serif",s=16,n=1,o=1,a=1,c=1,h=B.Left,l=!1,u=0,f=0,g=0,m=0,y=0,b=4){super();r(this,"text");r(this,"fontFamily");r(this,"fontSize");r(this,"colorR");r(this,"colorG");r(this,"colorB");r(this,"colorA");r(this,"align");r(this,"bold");r(this,"strokeR");r(this,"strokeG");r(this,"strokeB");r(this,"strokeA");r(this,"strokeWidth");r(this,"padding");r(this,"type","uiText");this.text=t,this.fontFamily=i,this.fontSize=s,this.colorR=n,this.colorG=o,this.colorB=a,this.colorA=c,this.align=h,this.bold=l,this.strokeR=u,this.strokeG=f,this.strokeB=g,this.strokeA=m,this.strokeWidth=y,this.padding=b}get fontString(){const t=[];return this.bold&&t.push("bold"),t.push(`${this.fontSize}px`),t.push(this.fontFamily),t.join(" ")}rgba(t,i,s,n){return`rgba(${t*255|0},${i*255|0},${s*255|0},${n})`}}class gt extends E{constructor(t=100,i=40,s="Button",n=.2,o=.5,a=1,c=1,h=.3,l=.6,u=1,f=1,g=.1,m=.4,y=.8,b=1,C=4,A=16,k=!0){super();r(this,"width");r(this,"height");r(this,"label");r(this,"r");r(this,"g");r(this,"b");r(this,"a");r(this,"hoverR");r(this,"hoverG");r(this,"hoverB");r(this,"hoverA");r(this,"pressedR");r(this,"pressedG");r(this,"pressedB");r(this,"pressedA");r(this,"borderRadius");r(this,"fontSize");r(this,"interactive");r(this,"type","uiButton");r(this,"hovered",!1);r(this,"pressed",!1);r(this,"focused",!1);this.width=t,this.height=i,this.label=s,this.r=n,this.g=o,this.b=a,this.a=c,this.hoverR=h,this.hoverG=l,this.hoverB=u,this.hoverA=f,this.pressedR=g,this.pressedG=m,this.pressedB=y,this.pressedA=b,this.borderRadius=C,this.fontSize=A,this.interactive=k}}class pt extends E{constructor(t=200,i=32,s="",n=256,o=.15,a=.15,c=.15,h=1,l=.4,u=.4,f=.4,g=1,m=.3,y=.6,b=1,C=1,A=14,k=3,P=!0){super();r(this,"width");r(this,"height");r(this,"placeholder");r(this,"maxLength");r(this,"bgColorR");r(this,"bgColorG");r(this,"bgColorB");r(this,"bgColorA");r(this,"borderColorR");r(this,"borderColorG");r(this,"borderColorB");r(this,"borderColorA");r(this,"focusBorderR");r(this,"focusBorderG");r(this,"focusBorderB");r(this,"focusBorderA");r(this,"fontSize");r(this,"borderRadius");r(this,"interactive");r(this,"type","uiTextInput");r(this,"focused",!1);r(this,"hovered",!1);r(this,"cursorBlink",0);r(this,"cursorVisible",!0);this.width=t,this.height=i,this.placeholder=s,this.maxLength=n,this.bgColorR=o,this.bgColorG=a,this.bgColorB=c,this.bgColorA=h,this.borderColorR=l,this.borderColorG=u,this.borderColorB=f,this.borderColorA=g,this.focusBorderR=m,this.focusBorderG=y,this.focusBorderB=b,this.focusBorderA=C,this.fontSize=A,this.borderRadius=k,this.interactive=P}}class mt extends E{constructor(t=200,i=200,s=.1,n=.1,o=.12,a=.9,c=6,h=.3,l=.3,u=.3,f=.5,g=1){super();r(this,"width");r(this,"height");r(this,"r");r(this,"g");r(this,"b");r(this,"a");r(this,"borderRadius");r(this,"borderR");r(this,"borderG");r(this,"borderB");r(this,"borderA");r(this,"borderWidth");r(this,"type","uiPanel");this.width=t,this.height=i,this.r=s,this.g=n,this.b=o,this.a=a,this.borderRadius=c,this.borderR=h,this.borderG=l,this.borderB=u,this.borderA=f,this.borderWidth=g}}function x(d,e,t,i){return`rgba(${d*255|0},${e*255|0},${t*255|0},${i})`}class yt extends ct{constructor(){super();r(this,"requiredComponents",["uiTransform"]);r(this,"overlay");r(this,"ctx");r(this,"engine");r(this,"bus");r(this,"focusedId",null);r(this,"hoveredId",null);r(this,"hiddenTextarea");r(this,"textareaEntityId",null);r(this,"_onMouseMove");r(this,"_onMouseDown");r(this,"_onMouseUp");r(this,"_onKeyDown");r(this,"_onResize");r(this,"_onInput");r(this,"_onBlur");r(this,"_onCompositionStart");r(this,"_onCompositionEnd");r(this,"logicalW",0);r(this,"logicalH",0);r(this,"isComposing",!1);r(this,"holderId");this.holderId=`ui-${Date.now()}-${Math.random().toString(36).slice(2)}`}onInit(t){var i;if(!((i=t.scene)!=null&&i.engine))throw new Error("UIRenderSystem requires scene registered via engine.sceneManager.register()");this.engine=t.scene.engine,this.bus=t.eventBus,this.setupOverlay(),this.setupHiddenTextarea(),this._onMouseMove=s=>{const n=this.engine.canvas.getBoundingClientRect();this.handleMouseMove(s.clientX-n.left,s.clientY-n.top)},this._onMouseDown=s=>{const n=this.engine.canvas.getBoundingClientRect();this.handleMouseDown(s.clientX-n.left,s.clientY-n.top,s.button),s.preventDefault()},this._onMouseUp=s=>{const n=this.engine.canvas.getBoundingClientRect();this.handleMouseUp(s.clientX-n.left,s.clientY-n.top,s.button)},this._onResize=()=>this.syncSize(),this._onKeyDown=s=>this.handleKeyDown(s),this.engine.canvas.addEventListener("mousemove",this._onMouseMove),this.engine.canvas.addEventListener("mousedown",this._onMouseDown),this.engine.canvas.addEventListener("mouseup",this._onMouseUp),window.addEventListener("resize",this._onResize),window.addEventListener("keydown",this._onKeyDown)}setupOverlay(){this.overlay=document.createElement("canvas"),this.overlay.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:10;",this.engine.canvas.style.position="relative";const t=this.engine.canvas.parentElement;t&&(t.style.position="relative"),t==null||t.appendChild(this.overlay),this.ctx=this.overlay.getContext("2d"),this.syncSize()}syncSize(){const t=this.engine.pixelRatio,i=this.engine.canvas.getBoundingClientRect();this.logicalW=i.width,this.logicalH=i.height,this.overlay.width=Math.round(this.logicalW*t),this.overlay.height=Math.round(this.logicalH*t),this.overlay.style.width=this.logicalW+"px",this.overlay.style.height=this.logicalH+"px",this.ctx.setTransform(t,0,0,t,0,0)}setupHiddenTextarea(){this.hiddenTextarea=document.createElement("textarea"),this.hiddenTextarea.style.cssText="position:fixed;left:0;top:0;width:1px;height:1px;opacity:0.01;border:none;outline:none;padding:0;margin:0;",this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("tabindex","-1"),document.body.appendChild(this.hiddenTextarea),this._onInput=()=>this.handleTextareaInput(),this._onBlur=()=>this.blurFocusedInput(),this._onCompositionStart=()=>{this.isComposing=!0},this._onCompositionEnd=t=>this.handleCompositionEnd(t),this.hiddenTextarea.addEventListener("input",this._onInput),this.hiddenTextarea.addEventListener("blur",this._onBlur),this.hiddenTextarea.addEventListener("compositionstart",this._onCompositionStart),this.hiddenTextarea.addEventListener("compositionend",this._onCompositionEnd)}focusInput(t){this.focusedId=t,this.textareaEntityId=t,this.isComposing=!1;const i=this.engine.sceneManager.currentScene;if(i){const s=i.world.getArchetype(t),n=s==null?void 0:s.get("uiText");this.hiddenTextarea.value=(n==null?void 0:n.text)??""}else this.hiddenTextarea.value="";this.engine.input.capture(this.holderId,z.UI),this.hiddenTextarea.focus(),this.bus.emit("ui:focus",t)}blurFocusedInput(){if(this.textareaEntityId!==null){const t=this.engine.sceneManager.currentScene;if(t){const i=t.world.getArchetype(this.textareaEntityId),s=i==null?void 0:i.get("uiTextInput");s&&(s.focused=!1)}this.bus.emit("ui:blur",this.textareaEntityId)}this.engine.input.release(this.holderId),this.textareaEntityId=null,this.focusedId=null,this.isComposing=!1,this.hiddenTextarea.blur()}handleTextareaInput(){if(this.textareaEntityId===null)return;const t=this.engine.sceneManager.currentScene;if(!t)return;const i=t.world.getArchetype(this.textareaEntityId);if(!i)return;const s=i.get("uiTextInput"),n=i.get("uiText");if(!s||!n)return;const o=n.text;n.text=this.hiddenTextarea.value.slice(0,s.maxLength),n.text!==o&&this.bus.emit("ui:change",{entityId:this.textareaEntityId,value:n.text})}handleCompositionEnd(t){this.isComposing=!1,this.handleTextareaInput()}handleMouseMove(t,i){const s=this.engine.sceneManager.currentScene;if(!s)return;let n=null;const o=s.world.query("uiTransform");for(let a=o.length-1;a>=0;a--){const c=o[a],h=c.get("uiTransform"),l=c.get("uiButton"),u=c.get("uiTextInput");if((((l==null?void 0:l.interactive)??!1)||((u==null?void 0:u.interactive)??!1))&&h!=null&&h.containsPoint(t,i)){n=c.entity.id;break}}if(this.hoveredId!==null&&this.hoveredId!==n){const a=s.world.getArchetype(this.hoveredId);if(a){const c=a.get("uiButton"),h=a.get("uiTextInput");c&&(c.hovered=!1),h&&(h.hovered=!1)}}if(n!==null){const a=s.world.getArchetype(n);if(a){const c=a.get("uiButton"),h=a.get("uiTextInput");c&&(c.hovered=!0),h&&(h.hovered=!0)}this.engine.canvas.style.cursor="pointer"}else this.engine.canvas.style.cursor="default";this.hoveredId=n}handleMouseDown(t,i,s){if(s!==0)return;const n=this.engine.sceneManager.currentScene;if(!n)return;const o=n.world.query("uiTransform");let a=!1;for(let c=o.length-1;c>=0;c--){const h=o[c],l=h.get("uiTransform");if(!(l!=null&&l.containsPoint(t,i)))continue;a=!0;const u=h.get("uiButton"),f=h.get("uiTextInput");u!=null&&u.interactive&&(u.pressed=!0,u.focused=!0),f!=null&&f.interactive?(this.focusInput(h.entity.id),f.focused=!0):this.textareaEntityId!==null&&this.blurFocusedInput(),this.focusedId=h.entity.id;break}!a&&this.textareaEntityId!==null&&this.blurFocusedInput()}handleMouseUp(t,i,s){if(s!==0)return;const n=this.engine.sceneManager.currentScene;if(!n)return;const o=n.world.query("uiTransform");for(const a of o){const c=a.get("uiButton"),h=a.get("uiTransform");!c||!h||(c.pressed&&h.containsPoint(t,i)&&this.bus.emit("ui:click",a.entity.id),c.pressed=!1)}}handleKeyDown(t){this.textareaEntityId!==null&&t.code==="Escape"&&(this.blurFocusedInput(),t.preventDefault())}onUpdate(t,i,s){const n=this.ctx;n.clearRect(0,0,this.logicalW,this.logicalH),i.sort((o,a)=>{var l,u;const c=((l=o.get("uiTransform"))==null?void 0:l.zIndex)??0,h=((u=a.get("uiTransform"))==null?void 0:u.zIndex)??0;return c-h});for(const o of i){const a=o.get("uiTransform");if(!a)continue;const c=o.get("uiPanel"),h=o.get("uiButton"),l=o.get("uiTextInput"),u=o.get("uiText");c&&this.drawPanel(n,a,c),h&&this.drawButton(n,a,h),l&&this.drawTextInput(n,a,l,u,s),u&&!h&&!l&&this.drawText(n,a,u,0,0,a.width,a.height)}}drawPanel(t,i,s){const n=i.drawX,o=i.drawY,a=s.width,c=s.height;t.fillStyle=x(s.r,s.g,s.b,s.a),t.beginPath(),this.roundRect(t,n,o,a,c,s.borderRadius),t.fill(),s.borderWidth>0&&(t.strokeStyle=x(s.borderR,s.borderG,s.borderB,s.borderA),t.lineWidth=s.borderWidth,t.stroke())}drawButton(t,i,s){const n=i.drawX,o=i.drawY;let a=s.r,c=s.g,h=s.b,l=s.a;s.pressed?(a=s.pressedR,c=s.pressedG,h=s.pressedB,l=s.pressedA):s.hovered&&(a=s.hoverR,c=s.hoverG,h=s.hoverB,l=s.hoverA),t.fillStyle=x(a,c,h,l),t.beginPath(),this.roundRect(t,n,o,s.width,s.height,s.borderRadius),t.fill(),t.save(),t.beginPath(),t.rect(n,o,s.width,s.height),t.clip(),t.font=`${s.fontSize}px sans-serif`,t.textAlign="center",t.textBaseline="middle",t.fillStyle=x(1,1,1,1),t.fillText(s.label,n+s.width/2,o+s.height/2),t.restore(),s.focused&&(t.strokeStyle=x(1,1,1,.6),t.lineWidth=2,t.beginPath(),this.roundRect(t,n,o,s.width,s.height,s.borderRadius),t.stroke())}drawTextInput(t,i,s,n,o){const a=i.drawX,c=i.drawY;t.fillStyle=x(s.bgColorR,s.bgColorG,s.bgColorB,s.bgColorA),t.beginPath(),this.roundRect(t,a,c,s.width,s.height,s.borderRadius),t.fill(),s.focused?t.strokeStyle=x(s.focusBorderR,s.focusBorderG,s.focusBorderB,s.focusBorderA):s.hovered?t.strokeStyle=x(.6,.6,.6,1):t.strokeStyle=x(s.borderColorR,s.borderColorG,s.borderColorB,s.borderColorA),t.lineWidth=1,t.stroke();const h=(n==null?void 0:n.text)??"",l=6;if(t.save(),t.beginPath(),t.rect(a,c,s.width,s.height),t.clip(),t.font=`${s.fontSize}px sans-serif`,t.textAlign="left",t.textBaseline="middle",h.length>0?(t.fillStyle=n?x(n.colorR,n.colorG,n.colorB,n.colorA):x(1,1,1,1),t.fillText(h,a+l,c+s.height/2)):s.placeholder.length>0&&(t.fillStyle=x(.5,.5,.5,1),t.fillText(s.placeholder,a+l,c+s.height/2)),s.focused&&(s.cursorBlink+=o,s.cursorBlink>1&&(s.cursorBlink-=1),s.cursorVisible=s.cursorBlink<.5,s.cursorVisible)){const u=t.measureText(h).width,f=a+l+u+1;t.fillStyle=x(1,1,1,1),t.fillRect(f,c+6,1,s.height-12)}t.restore()}drawText(t,i,s,n,o,a,c){t.save(),t.beginPath(),t.rect(i.drawX+n,i.drawY+o,a,c),t.clip(),t.font=s.fontString;let h="left",l=i.drawX+n+s.padding;s.align===B.Center?(h="center",l=i.drawX+n+a/2):s.align===B.Right&&(h="right",l=i.drawX+n+a-s.padding),t.textAlign=h,t.textBaseline="top";const u=i.drawY+o+s.padding;s.strokeWidth>0&&(t.strokeStyle=x(s.strokeR,s.strokeG,s.strokeB,s.strokeA),t.lineWidth=s.strokeWidth,t.strokeText(s.text,l,u)),t.fillStyle=x(s.colorR,s.colorG,s.colorB,s.colorA),t.fillText(s.text,l,u),t.restore()}roundRect(t,i,s,n,o,a){t.moveTo(i+a,s),t.lineTo(i+n-a,s),t.quadraticCurveTo(i+n,s,i+n,s+a),t.lineTo(i+n,s+o-a),t.quadraticCurveTo(i+n,s+o,i+n-a,s+o),t.lineTo(i+a,s+o),t.quadraticCurveTo(i,s+o,i,s+o-a),t.lineTo(i,s+a),t.quadraticCurveTo(i,s,i+a,s),t.closePath()}onDestroy(t){this.blurFocusedInput(),this.engine.input.release(this.holderId),this.engine.canvas.removeEventListener("mousemove",this._onMouseMove),this.engine.canvas.removeEventListener("mousedown",this._onMouseDown),this.engine.canvas.removeEventListener("mouseup",this._onMouseUp),window.removeEventListener("resize",this._onResize),this.hiddenTextarea.removeEventListener("input",this._onInput),this.hiddenTextarea.removeEventListener("blur",this._onBlur),this.hiddenTextarea.removeEventListener("compositionstart",this._onCompositionStart),this.hiddenTextarea.removeEventListener("compositionend",this._onCompositionEnd),window.removeEventListener("keydown",this._onKeyDown),this.hiddenTextarea.remove(),this.overlay.remove()}}const wt=new Set(["width","height","fontSize","borderRadius","padding","maxWidth","maxLength","strokeWidth","borderWidth","zIndex"]),vt=new Set(["x","y","originX","originY"]);function xt(d){return d.includes(":")&&!d.endsWith(":")}function bt(d){const e=d.match(/^(\s*)/);return e?e[1].length:0}function Ct(d){const e=d.split(`
92
+ `).map(n=>n.replace(/\s+$/,"")).filter(n=>n.length>0&&!n.startsWith("//"));let t=0;function i(n){const a=e[t].trim(),c=a.match(/^(\w+)\s+"([^"]*)"\s*\{$/)||a.match(/^(\w+)\s+'([^']*)'\s*\{$/)||a.match(/^(\w+)\s+(\S+)\s*\{$/)||a.match(/^(\w+)\s*\{$/);if(!c)throw new F(t+1,`Expected node declaration, got: ${a}`);const h=c[1],l=c[2]??"";t++;const u={},f=[];for(;t<e.length;){const g=e[t],m=bt(g),y=g.trim();if(m<n)break;if(y==="}"){t++;break}if(xt(y)){const b=y.split(";").map(C=>C.trim()).filter(C=>C.includes(":"));for(const C of b){const A=C.indexOf(":"),k=C.slice(0,A).trim(),P=C.slice(A+1).trim();k&&P&&(u[k]=St(k,P,t+1))}t++}else f.push(i(m))}return{type:h,name:l,props:u,children:f}}return{root:i(0)}}function St(d,e,t){if(e==="true")return!0;if(e==="false")return!1;if(e.startsWith("[")&&e.endsWith("]")){const i=e.slice(1,-1).split(",").map(s=>s.trim());if(i.length===4&&i.every(s=>!isNaN(Number(s))))return i.map(Number);throw new F(t,`Invalid color array for "${d}": ${e}`)}if(wt.has(d)||vt.has(d)){const i=Number(e);if(isNaN(i))throw new F(t,`Expected number for "${d}", got: ${e}`);return i}return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}class F extends Error{constructor(t,i){super(`.pui syntax error (line ${t}): ${i}`);r(this,"line");this.line=t,this.name="PuiSyntaxError"}}function Tt(d,e){const t=new Map;return Y(d,e.root,t,0,0),{entities:t}}function w(d,e){return typeof d=="number"?d:e}function S(d,e,t,i,s){return Array.isArray(d)&&d.length===4?d:[e,t,i,s]}function R(d,e){return typeof d=="string"?d:e}function U(d,e){return typeof d=="boolean"?d:e}function Et(d){const e=R(d,"left");return e==="center"?B.Center:e==="right"?B.Right:B.Left}function Y(d,e,t,i,s){const n=d.createEntity();e.name&&t.set(e.name,n.id);const o=e.props,a=new ft(i+w(o.x,0),s+w(o.y,0),w(o.width,100),w(o.height,100),w(o.originX,0),w(o.originY,0));switch(a.zIndex=w(o.zIndex,0),d.addComponent(n.id,a),e.type){case"panel":{const c=S(o.color,.1,.1,.12,.9),h=S(o.borderColor,.3,.3,.3,.5);d.addComponent(n.id,new mt(a.width,a.height,c[0],c[1],c[2],c[3],w(o.borderRadius,6),h[0],h[1],h[2],h[3],w(o.borderWidth,1)));break}case"text":{const c=S(o.color,1,1,1,1),h=S(o.strokeColor,0,0,0,0);d.addComponent(n.id,new $(R(o.text,""),R(o.fontFamily,"sans-serif"),w(o.fontSize,16),c[0],c[1],c[2],c[3],Et(o.align),U(o.bold,!1),h[0],h[1],h[2],h[3],w(o.strokeWidth,0),w(o.padding,4)));break}case"button":{const c=S(o.color,.2,.5,1,1),h=S(o.hoverColor,.3,.6,1,1),l=S(o.pressedColor,.1,.4,.8,1);d.addComponent(n.id,new gt(a.width,a.height,R(o.label,"Button"),c[0],c[1],c[2],c[3],h[0],h[1],h[2],h[3],l[0],l[1],l[2],l[3],w(o.borderRadius,4),w(o.fontSize,16),U(o.interactive,!0)));break}case"textInput":{const c=S(o.bgColor,.15,.15,.15,1),h=S(o.borderColor,.4,.4,.4,1),l=S(o.focusBorderColor,.3,.6,1,1);d.addComponent(n.id,new pt(a.width,a.height,R(o.placeholder,""),w(o.maxLength,256),c[0],c[1],c[2],c[3],h[0],h[1],h[2],h[3],l[0],l[1],l[2],l[3],w(o.fontSize,14),w(o.borderRadius,3),U(o.interactive,!0)));const u=S(o.color,1,1,1,1);d.addComponent(n.id,new $(R(o.text,""),R(o.fontFamily,"sans-serif"),w(o.fontSize,14),u[0],u[1],u[2],u[3]));break}}for(const c of e.children)Y(d,c,t,a.drawX,a.drawY)}const Bt="modulepreload",kt=function(d,e){return new URL(d,e).href},G={},H=function(e,t,i){let s=Promise.resolve();if(t&&t.length>0){let o=function(l){return Promise.all(l.map(u=>Promise.resolve(u).then(f=>({status:"fulfilled",value:f}),f=>({status:"rejected",reason:f}))))};const a=document.getElementsByTagName("link"),c=document.querySelector("meta[property=csp-nonce]"),h=(c==null?void 0:c.nonce)||(c==null?void 0:c.getAttribute("nonce"));s=o(t.map(l=>{if(l=kt(l,i),l in G)return;G[l]=!0;const u=l.endsWith(".css"),f=u?'[rel="stylesheet"]':"";if(!!i)for(let y=a.length-1;y>=0;y--){const b=a[y];if(b.href===l&&(!u||b.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${l}"]${f}`))return;const m=document.createElement("link");if(m.rel=u?"stylesheet":Bt,u||(m.as="script"),m.crossOrigin="",m.href=l,h&&m.setAttribute("nonce",h),document.head.appendChild(m),u)return new Promise((y,b)=>{m.addEventListener("load",y),m.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${l}`)))})}))}function n(o){const a=new Event("vite:preloadError",{cancelable:!0});if(a.payload=o,window.dispatchEvent(a),!a.defaultPrevented)throw o}return s.then(o=>{for(const a of o||[])a.status==="rejected"&&n(a.reason);return e().catch(n)})};class Rt{constructor(){r(this,"nodeFs",null);r(this,"nodePath",null)}async getFs(){return this.nodeFs&&this.nodePath?{fs:this.nodeFs,path:this.nodePath}:(this.nodeFs=await H(()=>import("./__vite-browser-external-D7Ct-6yo.js").then(e=>e._),[],import.meta.url),this.nodePath=await H(()=>import("./__vite-browser-external-D7Ct-6yo.js").then(e=>e._),[],import.meta.url),{fs:this.nodeFs,path:this.nodePath})}async readText(e){const{fs:t}=await this.getFs();return t.promises.readFile(e,"utf-8")}async writeText(e,t){const{fs:i}=await this.getFs();await i.promises.writeFile(e,t,"utf-8")}async readBinary(e){const{fs:t}=await this.getFs(),i=await t.promises.readFile(e);return new Uint8Array(i.buffer,i.byteOffset,i.byteLength)}async writeBinary(e,t){const{fs:i}=await this.getFs();await i.promises.writeFile(e,t)}async exists(e){const{fs:t}=await this.getFs();try{return await t.promises.access(e),!0}catch{return!1}}async mkdir(e){const{fs:t}=await this.getFs();await t.promises.mkdir(e,{recursive:!0})}async remove(e){const{fs:t}=await this.getFs();await t.promises.rm(e,{recursive:!0,force:!0})}async listDir(e){const{fs:t}=await this.getFs();return(await t.promises.readdir(e,{withFileTypes:!0})).map(s=>s.name)}async isFile(e){const{fs:t}=await this.getFs();return(await t.promises.stat(e)).isFile()}async isDir(e){const{fs:t}=await this.getFs();return(await t.promises.stat(e)).isDirectory()}}class At{constructor(){r(this,"fs");this.fs=new Rt}async invoke(e,t){const{ipcRenderer:i}=await H(async()=>{const{ipcRenderer:s}=await import("./index-Cxo-KaTG.js").then(n=>n.i);return{ipcRenderer:s}},__vite__mapDeps([0,1]),import.meta.url);return i.invoke(e,t)}}class q extends E{constructor(t=100,i=1,s=0,n=0){super();r(this,"type","orbitalSpeed");this.radius=t,this.speed=i,this.angleOffset=s,this.orbitTilt=n}}class It extends lt{constructor(){super(...arguments);r(this,"name","demo");r(this,"uiSystem",new yt);r(this,"clickCount",0);r(this,"scoreId",0);r(this,"btnId",0)}onEnter(){this.world.registerSystem(this.uiSystem);const t=this.world.createEntity();this.world.addComponent(t.id,new I),this.world.addComponent(t.id,new ut);const i=this.world.createEntity().tag("nucleus"),s=new I;s.zIndex=10,this.world.addComponent(i.id,s),this.world.addComponent(i.id,new L(.9,.6,.1,1,28,28));const n=this.world.createEntity().tag("glow"),o=new I;o.zIndex=9,this.world.addComponent(n.id,o),this.world.addComponent(n.id,new L(.9,.5,.1,.15,60,60));const a=[{radius:80,speed:2,tilt:0,color:[.3,.7,1],size:8,offset:0},{radius:130,speed:1.3,tilt:Math.PI/3,color:[.4,1,.6],size:7,offset:Math.PI*.66},{radius:180,speed:.8,tilt:-Math.PI/4,color:[1,.4,.8],size:6,offset:Math.PI*1.33}];for(const h of a){for(let g=0;g<60;g++){const m=this.world.createEntity().tag("ring"),y=new I;y.zIndex=1,this.world.addComponent(m.id,y),this.world.addComponent(m.id,new q(h.radius,0,g/60*Math.PI*2,h.tilt)),this.world.addComponent(m.id,new L(h.color[0]*.3,h.color[1]*.3,h.color[2]*.3,.25,2,2))}const u=this.world.createEntity().tag("electron"),f=new I;f.zIndex=5,this.world.addComponent(u.id,f),this.world.addComponent(u.id,new q(h.radius,h.speed,h.offset,h.tilt)),this.world.addComponent(u.id,new L(h.color[0],h.color[1],h.color[2],1,h.size,h.size))}const c=Tt(this.world,Ct(X));this.scoreId=c.entities.get("score"),this.btnId=c.entities.get("clickBtn"),this.world.eventBus.on("ui:click",h=>{if(h===this.btnId){this.clickCount++;const l=this.world.getArchetype(this.scoreId);l&&(l.get("uiText").text=`Clicks: ${this.clickCount}`)}})}onUpdate(){const t=performance.now()*.001;for(const n of this.world.query("transform2d","orbitalSpeed")){const o=n.get("transform2d"),a=n.get("orbitalSpeed"),c=a.angleOffset+t*a.speed,h=Math.cos(c)*a.radius,l=Math.sin(c)*a.radius*.4,u=Math.cos(a.orbitTilt),f=Math.sin(a.orbitTilt);o.x=h*u-l*f,o.y=h*f+l*u}const i=this.world.queryByTag("nucleus")[0];if(i){const n=i.get("sprite"),o=28+Math.sin(t*3)*4;n.width=o,n.height=o}const s=this.world.queryByTag("glow")[0];if(s){const n=s.get("sprite"),o=60+Math.sin(t*2)*10;n.width=o,n.height=o,n.colorA=.12+Math.sin(t*3)*.05}}onExit(){this.world.clear()}}const _=new nt({canvasId:"game-canvas",nativeBridge:new At});_.sceneManager.register(new It);_.sceneManager.switchTo("demo");_.start();
@@ -2,13 +2,13 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <title>My Ion Game</title>
5
+ <title>Photon</title>
6
6
  <style>
7
7
  * { margin: 0; padding: 0; }
8
8
  html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
9
9
  canvas { display: block; width: 100%; height: 100%; }
10
10
  </style>
11
- <script type="module" crossorigin src="./assets/index-Dmalnvpw.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-XXTau1xu.js"></script>
12
12
  </head>
13
13
  <body>
14
14
  <canvas id="game-canvas"></canvas>
@@ -0,0 +1,58 @@
1
+ // Photon Engine — HUD demo
2
+ panel "hud" {
3
+ x: 20; y: 20;
4
+ width: 300; height: 210;
5
+ color: [0.08, 0.08, 0.1, 0.85];
6
+ borderRadius: 8;
7
+
8
+ text "title" {
9
+ x: 0; y: 12;
10
+ width: 300; height: 28;
11
+ text: "Photon Engine — Electron";
12
+ fontSize: 18;
13
+ color: [0.5, 0.7, 1, 1];
14
+ align: center;
15
+ bold: true;
16
+ zIndex: 1;
17
+ }
18
+
19
+ text "score" {
20
+ x: 10; y: 52;
21
+ width: 280; height: 24;
22
+ text: "Clicks: 0";
23
+ fontSize: 15;
24
+ color: [1, 1, 1, 1];
25
+ fontFamily: monospace;
26
+ zIndex: 1;
27
+ }
28
+
29
+ button "clickBtn" {
30
+ x: 70; y: 88;
31
+ width: 160; height: 38;
32
+ label: "Click Me!";
33
+ color: [0.16, 0.5, 1, 1];
34
+ hoverColor: [0.29, 0.62, 1, 1];
35
+ pressedColor: [0.1, 0.37, 0.8, 1];
36
+ borderRadius: 8;
37
+ fontSize: 15;
38
+ zIndex: 1;
39
+ }
40
+
41
+ text "nameLabel" {
42
+ x: 10; y: 146;
43
+ width: 60; height: 22;
44
+ text: "Name:";
45
+ fontSize: 13;
46
+ color: [0.7, 0.7, 0.7, 1];
47
+ zIndex: 1;
48
+ }
49
+
50
+ textInput "nameInput" {
51
+ x: 70; y: 143;
52
+ width: 220; height: 28;
53
+ placeholder: "Type here...";
54
+ maxLength: 64;
55
+ fontSize: 13;
56
+ zIndex: 1;
57
+ }
58
+ }
@@ -1,6 +1,10 @@
1
+ import puiSource from "./hud.pui?raw";
1
2
  import {
2
3
  Engine, Scene, Transform2D, Camera2D, Sprite, Component,
4
+ UIText, UIRenderSystem,
5
+ parsePui, loadPui,
3
6
  } from "photon-engine";
7
+ import { ElectronNativeBridge } from "photon-engine-electron";
4
8
 
5
9
  class OrbitalSpeed extends Component {
6
10
  readonly type = "orbitalSpeed";
@@ -12,15 +16,19 @@ class OrbitalSpeed extends Component {
12
16
  ) { super(); }
13
17
  }
14
18
 
15
- class AtomScene extends Scene {
16
- readonly name = "atom";
19
+ class DemoScene extends Scene {
20
+ readonly name = "demo";
21
+ private uiSystem = new UIRenderSystem();
22
+ private clickCount = 0;
23
+ private scoreId = 0;
24
+ private btnId = 0;
17
25
 
18
26
  onEnter(): void {
27
+ this.world.registerSystem(this.uiSystem);
28
+
19
29
  const cam = this.world.createEntity();
20
30
  this.world.addComponent(cam.id, new Transform2D());
21
- const camComp = new Camera2D();
22
- camComp.zoom = 1;
23
- this.world.addComponent(cam.id, camComp);
31
+ this.world.addComponent(cam.id, new Camera2D());
24
32
 
25
33
  const nucleus = this.world.createEntity().tag("nucleus");
26
34
  const nPos = new Transform2D();
@@ -35,9 +43,9 @@ class AtomScene extends Scene {
35
43
  this.world.addComponent(glow.id, new Sprite(0.9, 0.5, 0.1, 0.15, 60, 60));
36
44
 
37
45
  const orbits = [
38
- { radius: 80, speed: 2.0, tilt: 0, color: [0.3, 0.7, 1.0], size: 8, offset: 0 },
39
- { radius: 130, speed: 1.3, tilt: Math.PI / 3, color: [0.4, 1.0, 0.6], size: 7, offset: Math.PI * 0.66 },
40
- { radius: 180, speed: 0.8, tilt: -Math.PI / 4, color: [1.0, 0.4, 0.8], size: 6, offset: Math.PI * 1.33 },
46
+ { radius: 80, speed: 2.0, tilt: 0, color: [0.3, 0.7, 1.0], size: 8, offset: 0 },
47
+ { radius: 130, speed: 1.3, tilt: Math.PI / 3, color: [0.4, 1.0, 0.6], size: 7, offset: Math.PI * 0.66 },
48
+ { radius: 180, speed: 0.8, tilt: -Math.PI / 4, color: [1.0, 0.4, 0.8], size: 6, offset: Math.PI * 1.33 },
41
49
  ];
42
50
 
43
51
  for (const orbit of orbits) {
@@ -48,10 +56,10 @@ class AtomScene extends Scene {
48
56
  dPos.zIndex = 1;
49
57
  this.world.addComponent(dot.id, dPos);
50
58
  this.world.addComponent(dot.id, new OrbitalSpeed(
51
- orbit.radius, 0, (i / ringCount) * Math.PI * 2, orbit.tilt
59
+ orbit.radius, 0, (i / ringCount) * Math.PI * 2, orbit.tilt,
52
60
  ));
53
61
  this.world.addComponent(dot.id, new Sprite(
54
- orbit.color[0] * 0.3, orbit.color[1] * 0.3, orbit.color[2] * 0.3, 0.25, 2, 2
62
+ orbit.color[0] * 0.3, orbit.color[1] * 0.3, orbit.color[2] * 0.3, 0.25, 2, 2,
55
63
  ));
56
64
  }
57
65
 
@@ -60,37 +68,39 @@ class AtomScene extends Scene {
60
68
  ePos.zIndex = 5;
61
69
  this.world.addComponent(electron.id, ePos);
62
70
  this.world.addComponent(electron.id, new OrbitalSpeed(
63
- orbit.radius, orbit.speed, orbit.offset, orbit.tilt
71
+ orbit.radius, orbit.speed, orbit.offset, orbit.tilt,
64
72
  ));
65
73
  this.world.addComponent(electron.id, new Sprite(
66
- orbit.color[0], orbit.color[1], orbit.color[2], 1, orbit.size, orbit.size
67
- ));
68
-
69
- const eGlow = this.world.createEntity().tag("electron-glow");
70
- const egPos = new Transform2D();
71
- egPos.zIndex = 4;
72
- this.world.addComponent(eGlow.id, egPos);
73
- this.world.addComponent(eGlow.id, new OrbitalSpeed(
74
- orbit.radius, orbit.speed, orbit.offset, orbit.tilt
75
- ));
76
- this.world.addComponent(eGlow.id, new Sprite(
77
- orbit.color[0], orbit.color[1], orbit.color[2], 0.2, orbit.size * 4, orbit.size * 4
74
+ orbit.color[0], orbit.color[1], orbit.color[2], 1, orbit.size, orbit.size,
78
75
  ));
79
76
  }
77
+
78
+ // Load UI from hud.pui
79
+ const ui = loadPui(this.world, parsePui(puiSource));
80
+ this.scoreId = ui.entities.get("score")!;
81
+ this.btnId = ui.entities.get("clickBtn")!;
82
+
83
+ this.world.eventBus.on<number>("ui:click", (entityId) => {
84
+ if (entityId === this.btnId) {
85
+ this.clickCount++;
86
+ const arch = this.world.getArchetype(this.scoreId);
87
+ if (arch) {
88
+ arch.get<UIText>("uiText")!.text = `Clicks: ${this.clickCount}`;
89
+ }
90
+ }
91
+ });
80
92
  }
81
93
 
82
94
  onUpdate(): void {
83
95
  const time = performance.now() * 0.001;
84
- const entities = this.world.query("transform2d", "orbitalSpeed");
85
96
 
86
- for (const arch of entities) {
97
+ for (const arch of this.world.query("transform2d", "orbitalSpeed")) {
87
98
  const t = arch.get<Transform2D>("transform2d")!;
88
99
  const o = arch.get<OrbitalSpeed>("orbitalSpeed")!;
89
100
 
90
101
  const angle = o.angleOffset + time * o.speed;
91
102
  const x = Math.cos(angle) * o.radius;
92
103
  const y = Math.sin(angle) * o.radius * 0.4;
93
-
94
104
  const cosT = Math.cos(o.orbitTilt);
95
105
  const sinT = Math.sin(o.orbitTilt);
96
106
  t.x = x * cosT - y * sinT;
@@ -99,26 +109,29 @@ class AtomScene extends Scene {
99
109
 
100
110
  const nucleusArch = this.world.queryByTag("nucleus")[0];
101
111
  if (nucleusArch) {
102
- const nSprite = nucleusArch.get<Sprite>("sprite")!;
112
+ const s = nucleusArch.get<Sprite>("sprite")!;
103
113
  const pulse = 28 + Math.sin(time * 3) * 4;
104
- nSprite.width = pulse;
105
- nSprite.height = pulse;
114
+ s.width = pulse;
115
+ s.height = pulse;
106
116
  }
107
117
 
108
118
  const glowArch = this.world.queryByTag("glow")[0];
109
119
  if (glowArch) {
110
- const gSprite = glowArch.get<Sprite>("sprite")!;
120
+ const s = glowArch.get<Sprite>("sprite")!;
111
121
  const pulse = 60 + Math.sin(time * 2) * 10;
112
- gSprite.width = pulse;
113
- gSprite.height = pulse;
114
- gSprite.colorA = 0.12 + Math.sin(time * 3) * 0.05;
122
+ s.width = pulse;
123
+ s.height = pulse;
124
+ s.colorA = 0.12 + Math.sin(time * 3) * 0.05;
115
125
  }
116
126
  }
117
127
 
118
128
  onExit(): void { this.world.clear(); }
119
129
  }
120
130
 
121
- const engine = new Engine({ canvasId: "game-canvas" });
122
- engine.sceneManager.register(new AtomScene());
123
- engine.sceneManager.switchTo("atom");
124
- engine.start();
131
+ const engine = new Engine({
132
+ canvasId: "game-canvas",
133
+ nativeBridge: new ElectronNativeBridge(),
134
+ });
135
+ engine.sceneManager.register(new DemoScene());
136
+ engine.sceneManager.switchTo("demo");
137
+ engine.start();
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -1,32 +0,0 @@
1
- var L=Object.defineProperty;var D=(h,t,e)=>t in h?L(h,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):h[t]=e;var n=(h,t,e)=>D(h,typeof t!="symbol"?t+"":t,e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function e(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=e(r);fetch(r.href,o)}})();class T{constructor(){n(this,"listeners",new Map)}on(t,e){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e),()=>this.off(t,e)}once(t,e){const s=r=>{this.off(t,s),e(r)};return this.on(t,s)}off(t,e){var s;(s=this.listeners.get(t))==null||s.delete(e)}emit(t,e){const s=this.listeners.get(t);if(s)for(const r of s)try{r(e)}catch(o){console.error(`[EventBus] Error in "${t}":`,o)}}clear(t){t?this.listeners.delete(t):this.listeners.clear()}listenerCount(t){var e;return((e=this.listeners.get(t))==null?void 0:e.size)??0}}class U{constructor(t){n(this,"scenes",new Map);n(this,"current",null);n(this,"bus");this.bus=t??new T}register(t){this.scenes.set(t.name,t)}unregister(t){var e;((e=this.current)==null?void 0:e.name)===t&&(this.current.onExit(),this.current=null),this.scenes.delete(t)}switchTo(t){const e=this.scenes.get(t);return e?(this.current&&this.current.onExit(),this.current=e,this.current.onEnter(),this.bus.emit("scene:switched",t),!0):!1}get currentScene(){return this.current}get sceneNames(){return[...this.scenes.keys()]}get eventBus(){return this.bus}getScene(t){return this.scenes.get(t)}}class H{constructor(t,e,s){n(this,"gl");n(this,"program");this.gl=t;const r=this.compile(t.VERTEX_SHADER,e),o=this.compile(t.FRAGMENT_SHADER,s);if(this.program=t.createProgram(),t.attachShader(this.program,r),t.attachShader(this.program,o),t.linkProgram(this.program),!t.getProgramParameter(this.program,t.LINK_STATUS)){const i=t.getProgramInfoLog(this.program);throw t.deleteProgram(this.program),new Error(`Shader link error: ${i}`)}t.deleteShader(r),t.deleteShader(o)}compile(t,e){const s=this.gl.createShader(t);if(this.gl.shaderSource(s,e),this.gl.compileShader(s),!this.gl.getShaderParameter(s,this.gl.COMPILE_STATUS)){const r=this.gl.getShaderInfoLog(s);throw this.gl.deleteShader(s),new Error(`Shader compile error: ${r}`)}return s}use(){this.gl.useProgram(this.program)}getAttribLocation(t){return this.gl.getAttribLocation(this.program,t)}getUniformLocation(t){return this.gl.getUniformLocation(this.program,t)}setUniformMat3(t,e){const s=this.getUniformLocation(t);s&&this.gl.uniformMatrix3fv(s,!1,e)}setUniformVec4(t,e,s,r,o){const i=this.getUniformLocation(t);i&&this.gl.uniform4f(i,e,s,r,o)}setUniformVec2(t,e,s){const r=this.getUniformLocation(t);r&&this.gl.uniform2f(r,e,s)}setUniformFloat(t,e){const s=this.getUniformLocation(t);s&&this.gl.uniform1f(s,e)}setUniformInt(t,e){const s=this.getUniformLocation(t);s&&this.gl.uniform1i(s,e)}destroy(){this.gl.deleteProgram(this.program)}}const F=`#version 300 es
2
- layout(location = 0) in vec2 aPosition;
3
- layout(location = 1) in vec2 aTexCoord;
4
- layout(location = 2) in vec4 aColor;
5
-
6
- uniform mat3 uViewProj;
7
-
8
- out vec2 vTexCoord;
9
- out vec4 vColor;
10
-
11
- void main() {
12
- vec3 pos = uViewProj * vec3(aPosition, 1.0);
13
- gl_Position = vec4(pos.xy, 0.0, 1.0);
14
- vTexCoord = aTexCoord;
15
- vColor = aColor;
16
- }
17
- `,z=`#version 300 es
18
- precision mediump float;
19
-
20
- in vec2 vTexCoord;
21
- in vec4 vColor;
22
-
23
- uniform sampler2D uTexture;
24
- uniform float uUseTexture;
25
-
26
- out vec4 fragColor;
27
-
28
- void main() {
29
- vec4 texColor = mix(vec4(1.0), texture(uTexture, vTexCoord), uUseTexture);
30
- fragColor = vColor * texColor;
31
- }
32
- `,v=8,R=1e4;class I{constructor(t){n(this,"gl");n(this,"shader");n(this,"vao");n(this,"vbo");n(this,"vertices");n(this,"vertexCount",0);n(this,"currentTexture",null);const e=t.getContext("webgl2",{alpha:!1,antialias:!1,premultipliedAlpha:!1});if(!e)throw new Error("WebGL2 not supported");this.gl=e,this.shader=new H(e,F,z),this.vertices=new Float32Array(R*6*v),this.vao=e.createVertexArray(),this.vbo=e.createBuffer(),e.bindVertexArray(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.vbo),e.bufferData(e.ARRAY_BUFFER,this.vertices.byteLength,e.DYNAMIC_DRAW);const s=v*4;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,s,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,2,e.FLOAT,!1,s,8),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,4,e.FLOAT,!1,s,16),e.bindVertexArray(null),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA)}clear(t=0,e=0,s=0,r=1){this.gl.clearColor(t,e,s,r),this.gl.clear(this.gl.COLOR_BUFFER_BIT)}begin(t){this.shader.use(),this.shader.setUniformMat3("uViewProj",t.data),this.gl.bindVertexArray(this.vao)}drawSprite(t,e){const s=e.texture??null;(s!==this.currentTexture||this.vertexCount+6>R*6)&&(this.flush(),this.currentTexture=s),s?(this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,s),this.shader.setUniformInt("uTexture",0),this.shader.setUniformFloat("uUseTexture",1)):this.shader.setUniformFloat("uUseTexture",0);const r=e.width*.5,o=e.height*.5,i=t.getLocalMatrix(),l=[{x:-r,y:-o,u:e.texCoordU,v:e.texCoordV},{x:r,y:-o,u:e.texCoordU+e.texCoordW,v:e.texCoordV},{x:r,y:o,u:e.texCoordU+e.texCoordW,v:e.texCoordV+e.texCoordH},{x:-r,y:o,u:e.texCoordU,v:e.texCoordV+e.texCoordH}].map(g=>{const f=i.transformPoint({x:g.x,y:g.y});return{x:f.x,y:f.y,u:g.u,v:g.v}}),a=this.vertices;let u=this.vertexCount*v;const m=g=>{const f=l[g];a[u++]=f.x,a[u++]=f.y,a[u++]=f.u,a[u++]=f.v,a[u++]=e.colorR,a[u++]=e.colorG,a[u++]=e.colorB,a[u++]=e.colorA};m(0),m(1),m(2),m(0),m(2),m(3),this.vertexCount+=6}flush(){this.vertexCount!==0&&(this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertices,0,this.vertexCount*v),this.gl.drawArrays(this.gl.TRIANGLES,0,this.vertexCount),this.vertexCount=0)}end(){this.flush(),this.gl.bindVertexArray(null),this.currentTexture=null}resize(t,e){this.gl.viewport(0,0,t,e)}get context(){return this.gl}destroy(){this.shader.destroy(),this.gl.deleteBuffer(this.vbo),this.gl.deleteVertexArray(this.vao)}}const d=class d{constructor(t=0,e=0){n(this,"x");n(this,"y");this.x=t,this.y=e}clone(){return new d(this.x,this.y)}set(t,e){return this.x=t,this.y=e,this}add(t){return new d(this.x+t.x,this.y+t.y)}sub(t){return new d(this.x-t.x,this.y-t.y)}mul(t){return new d(this.x*t,this.y*t)}div(t){return new d(this.x/t,this.y/t)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}lengthSq(){return this.x*this.x+this.y*this.y}normalize(){const t=this.length();return t>0?this.div(t):d.ZERO.clone()}distance(t){return this.sub(t).length()}distanceSq(t){return this.sub(t).lengthSq()}angle(){return Math.atan2(this.y,this.x)}rotate(t){const e=Math.cos(t),s=Math.sin(t);return new d(this.x*e-this.y*s,this.x*s+this.y*e)}lerp(t,e){return new d(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)}equals(t,e=1e-6){return Math.abs(this.x-t.x)<e&&Math.abs(this.y-t.y)<e}static fromAngle(t,e=1){return new d(Math.cos(t)*e,Math.sin(t)*e)}static lerp(t,e,s){return t.lerp(e,s)}};n(d,"ZERO",new d(0,0)),n(d,"ONE",new d(1,1)),n(d,"UP",new d(0,-1)),n(d,"DOWN",new d(0,1)),n(d,"LEFT",new d(-1,0)),n(d,"RIGHT",new d(1,0));let w=d;class k{constructor(t){n(this,"canvas");n(this,"keysDown",new Set);n(this,"keysPressed",new Set);n(this,"keysReleased",new Set);n(this,"mouseButtonsDown",new Set);n(this,"mouseButtonsPressed",new Set);n(this,"mouseButtonsReleased",new Set);n(this,"mousePos",new w);n(this,"mouseDelta",new w);n(this,"scrollDelta",0);n(this,"bound",!1);n(this,"keyDownHandler");n(this,"keyUpHandler");n(this,"mouseMoveHandler");n(this,"mouseDownHandler");n(this,"mouseUpHandler");n(this,"wheelHandler");this.canvas=t,this.keyDownHandler=e=>{this.keysDown.has(e.code)||this.keysPressed.add(e.code),this.keysDown.add(e.code),e.preventDefault()},this.keyUpHandler=e=>{this.keysDown.delete(e.code),this.keysReleased.add(e.code)},this.mouseMoveHandler=e=>{const s=this.canvas.getBoundingClientRect(),r=e.clientX-s.left,o=e.clientY-s.top;this.mouseDelta=new w(r-this.mousePos.x,o-this.mousePos.y),this.mousePos=new w(r,o)},this.mouseDownHandler=e=>{this.mouseButtonsDown.has(e.button)||this.mouseButtonsPressed.add(e.button),this.mouseButtonsDown.add(e.button)},this.mouseUpHandler=e=>{this.mouseButtonsDown.delete(e.button),this.mouseButtonsReleased.add(e.button)},this.wheelHandler=e=>{this.scrollDelta=e.deltaY}}init(){this.bound||(this.bound=!0,window.addEventListener("keydown",this.keyDownHandler),window.addEventListener("keyup",this.keyUpHandler),this.canvas.addEventListener("mousemove",this.mouseMoveHandler),this.canvas.addEventListener("mousedown",this.mouseDownHandler),this.canvas.addEventListener("mouseup",this.mouseUpHandler),this.canvas.addEventListener("wheel",this.wheelHandler))}destroy(){this.bound&&(this.bound=!1,window.removeEventListener("keydown",this.keyDownHandler),window.removeEventListener("keyup",this.keyUpHandler),this.canvas.removeEventListener("mousemove",this.mouseMoveHandler),this.canvas.removeEventListener("mousedown",this.mouseDownHandler),this.canvas.removeEventListener("mouseup",this.mouseUpHandler),this.canvas.removeEventListener("wheel",this.wheelHandler))}endFrame(){this.keysPressed.clear(),this.keysReleased.clear(),this.mouseButtonsPressed.clear(),this.mouseButtonsReleased.clear(),this.mouseDelta=w.ZERO.clone(),this.scrollDelta=0}isKeyDown(t){return this.keysDown.has(t)}isKeyPressed(t){return this.keysPressed.has(t)}isKeyReleased(t){return this.keysReleased.has(t)}isMouseButtonDown(t=0){return this.mouseButtonsDown.has(t)}isMouseButtonPressed(t=0){return this.mouseButtonsPressed.has(t)}isMouseButtonReleased(t=0){return this.mouseButtonsReleased.has(t)}get mousePosition(){return this.mousePos.clone()}get mouseDeltaPosition(){return this.mouseDelta.clone()}get scrollY(){return this.scrollDelta}}class O{async collideAABB(t,e,s,r,o,i,c,l){return t<o+c&&t+s>o&&e<i+l&&e+r>i}async batchTransform(t,e){return t}async noise2D(t,e,s){const r=Math.sin(t*127.1+e*311.7)*43758.5453123;return r-Math.floor(r)}async pathfind(){return console.warn("[Ion] pathfind: no compute backend, returning null"),null}}class W{constructor(t){n(this,"fs");this.fs=t}async invoke(t,e){throw new Error(`[Ion] Native invoke "${t}" not available in browser mode`)}}class V{constructor(){n(this,"storage",new Map)}async readText(t){const e=this.storage.get(t);if(!e)throw new Error(`File not found: ${t}`);return new TextDecoder().decode(e)}async writeText(t,e){this.storage.set(t,new TextEncoder().encode(e)),this.persistToLocalStorage()}async readBinary(t){const e=this.storage.get(t);if(!e)throw new Error(`File not found: ${t}`);return e}async writeBinary(t,e){this.storage.set(t,e),this.persistToLocalStorage()}async exists(t){return this.storage.has(t)}async mkdir(t){}async remove(t){this.storage.delete(t),this.persistToLocalStorage()}async listDir(t){const e=t.endsWith("/")?t:t+"/",s=new Set;for(const r of this.storage.keys())if(r.startsWith(e)){const i=r.slice(e.length).split("/")[0];s.add(i)}return[...s]}async isFile(t){return this.storage.has(t)}async isDir(t){const e=t.endsWith("/")?t:t+"/";for(const s of this.storage.keys())if(s.startsWith(e))return!0;return!1}persistToLocalStorage(){try{const t={};for(const[e,s]of this.storage)t[e]=[...s];localStorage.setItem("ion:fs",JSON.stringify(t))}catch{}}loadFromLocalStorage(){try{const t=localStorage.getItem("ion:fs");if(!t)return;const e=JSON.parse(t);for(const[s,r]of Object.entries(e))this.storage.set(s,new Uint8Array(r))}catch{}}}class N{constructor(t={}){n(this,"sceneManager");n(this,"renderer");n(this,"input");n(this,"eventBus");n(this,"fs");n(this,"bridge");n(this,"compute");n(this,"running",!1);n(this,"lastTime",0);n(this,"rafId",0);n(this,"fixedAccumulator",0);n(this,"fixedStep",1e3/60);n(this,"canvas");n(this,"loop",t=>{if(!this.running)return;this.rafId=requestAnimationFrame(this.loop);const e=t-this.lastTime;this.lastTime=t;const s=Math.min(e,250);for(this.fixedAccumulator+=s;this.fixedAccumulator>=this.fixedStep;)this.fixedUpdate(this.fixedStep/1e3),this.fixedAccumulator-=this.fixedStep;this.update(s/1e3),this.render(),this.input.endFrame()});const e=t.canvasId??"ion-canvas",s=document.getElementById(e);if(!s)throw new Error(`Canvas "#${e}" not found`);if(s.width=t.width??window.innerWidth,s.height=t.height??window.innerHeight,this.canvas=s,this.eventBus=new T,this.renderer=new I(s),this.input=new k(s),this.sceneManager=new U(this.eventBus),t.fs)this.fs=t.fs;else{const r=new V;r.loadFromLocalStorage(),this.fs=r}this.bridge=t.nativeBridge??new W(this.fs),this.compute=new O,window.addEventListener("resize",()=>this.handleResize())}handleResize(){this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.renderer.resize(this.canvas.width,this.canvas.height),this.eventBus.emit("engine:resize",{width:this.canvas.width,height:this.canvas.height})}start(){this.running||(this.running=!0,this.input.init(),this.lastTime=performance.now(),this.loop(this.lastTime),this.eventBus.emit("engine:start",null))}stop(){this.running=!1,this.input.destroy(),cancelAnimationFrame(this.rafId),this.eventBus.emit("engine:stop",null)}fixedUpdate(t){const e=this.sceneManager.currentScene;e&&(e.world.update(t),e.onUpdate(t))}update(t){}render(){const t=this.sceneManager.currentScene;if(!t){this.renderer.clear(.1,.1,.1);return}const e=t.world.query("camera2d","transform2d");if(e.length===0){this.renderer.clear(.1,.1,.1);return}const s=e[0],r=s.get("camera2d"),o=s.get("transform2d");r.x=o.x,r.y=o.y,r.rotation=o.rotation,r.viewportWidth=this.canvas.width,r.viewportHeight=this.canvas.height;const i=r.getViewProjectionMatrix();this.renderer.clear(.1,.1,.12),this.renderer.begin(i);const c=t.world.query("transform2d","sprite");c.sort((l,a)=>{const u=l.get("transform2d").zIndex,m=a.get("transform2d").zIndex;return u-m});for(const l of c){const a=l.get("transform2d"),u=l.get("sprite");this.renderer.drawSprite(a,u)}this.renderer.end()}destroy(){var t;this.stop(),this.renderer.destroy(),(t=this.sceneManager.currentScene)==null||t.world.clear(),this.eventBus.clear()}}class A{}let q=1;class Y{constructor(t){n(this,"id");n(this,"tags",new Set);n(this,"active",!0);this.id=t??q++}tag(...t){for(const e of t)this.tags.add(e);return this}untag(...t){for(const e of t)this.tags.delete(e);return this}hasTag(t){return this.tags.has(t)}equals(t){return this.id===t.id}}class j{constructor(t){n(this,"entity");n(this,"components",new Map);this.entity=t}add(t){return this.components.set(t.type,t),this}remove(t){const e=this.components.get(t);return this.components.delete(t),e}get(t){return this.components.get(t)}has(t){return this.components.has(t)}hasAll(t){for(const e of t)if(!this.components.has(e))return!1;return!0}getAll(){return new Map(this.components)}}class X{constructor(){n(this,"archetypes",new Map);n(this,"systems",[]);n(this,"entityRecycleBin",[]);n(this,"bus",new T)}createEntity(){const t=this.entityRecycleBin.length>0?this.entityRecycleBin.pop():void 0,e=new Y(t),s=new j(e);return this.archetypes.set(e.id,s),this.bus.emit("entity:created",e),e}destroyEntity(t){const e=this.archetypes.get(t);e&&(this.bus.emit("entity:destroyed",e.entity),this.archetypes.delete(t),this.entityRecycleBin.push(t))}getArchetype(t){return this.archetypes.get(t)}addComponent(t,e){const s=this.archetypes.get(t);s&&(s.add(e),this.bus.emit("component:added",{entityId:t,type:e.type}))}removeComponent(t,e){const s=this.archetypes.get(t);s&&(s.remove(e),this.bus.emit("component:removed",{entityId:t,type:e}))}getComponent(t,e){var s;return(s=this.archetypes.get(t))==null?void 0:s.get(e)}registerSystem(t){this.systems.push(t),this.systems.sort((e,s)=>e.priority-s.priority),t.onInit(this)}unregisterSystem(t){const e=this.systems.indexOf(t);e!==-1&&(t.onDestroy(this),this.systems.splice(e,1))}query(...t){const e=[];for(const[,s]of this.archetypes)s.entity.active&&s.hasAll(t)&&e.push(s);return e}queryByTag(t){const e=[];for(const[,s]of this.archetypes)s.entity.active&&s.entity.hasTag(t)&&e.push(s);return e}update(t){for(const e of this.systems){if(!e.active)continue;const s=this.query(...e.requiredComponents);e.onUpdate(this,s,t)}}get entityCount(){return this.archetypes.size}get eventBus(){return this.bus}clear(){for(const t of this.systems)t.onDestroy(this);this.systems=[],this.archetypes.clear(),this.entityRecycleBin=[],this.bus.clear()}}class G{constructor(){n(this,"world",new X)}moveEntityTo(t,e){const s=this.world.getArchetype(t);if(!s)return!1;const r=s.getAll(),o=s.entity;this.world.destroyEntity(t);const i=e.world.createEntity();i.tags=new Set(o.tags),i.active=o.active;const c=e.world.getArchetype(i.id);for(const[,l]of r)c.add(l);return!0}copyEntityTo(t,e){const s=this.world.getArchetype(t);if(!s)return null;const r=e.world.createEntity();r.tags=new Set(s.entity.tags);const o=e.world.getArchetype(r.id);for(const[,i]of s.getAll())o.add(i);return r}}class y{constructor(t=y.identity().data){n(this,"data");this.data=t}static identity(){return new y(new Float32Array([1,0,0,0,1,0,0,0,1]))}static translation(t,e){const s=y.identity();return s.data[6]=t,s.data[7]=e,s}static rotation(t){const e=Math.cos(t),s=Math.sin(t),r=y.identity();return r.data[0]=e,r.data[1]=s,r.data[3]=-s,r.data[4]=e,r}static scale(t,e){const s=y.identity();return s.data[0]=t,s.data[4]=e,s}static orthographic(t,e,s,r){const o=y.identity();return o.data[0]=2/(e-t),o.data[4]=2/(r-s),o.data[6]=-(e+t)/(e-t),o.data[7]=-(r+s)/(r-s),o}multiply(t){const e=this.data,s=t.data,r=new Float32Array(9);for(let o=0;o<3;o++)for(let i=0;i<3;i++)r[i*3+o]=e[o]*s[i*3]+e[3+o]*s[i*3+1]+e[6+o]*s[i*3+2];return new y(r)}transformPoint(t){const e=this.data;return new w(e[0]*t.x+e[3]*t.y+e[6],e[1]*t.x+e[4]*t.y+e[7])}clone(){return new y(new Float32Array(this.data))}invert(){const t=this.data,e=t[0]*(t[4]*t[8]-t[5]*t[7])-t[1]*(t[3]*t[8]-t[5]*t[6])+t[2]*(t[3]*t[7]-t[4]*t[6]);if(Math.abs(e)<1e-10)return y.identity();const s=1/e,r=new Float32Array(9);return r[0]=(t[4]*t[8]-t[5]*t[7])*s,r[1]=(t[2]*t[7]-t[1]*t[8])*s,r[2]=(t[1]*t[5]-t[2]*t[4])*s,r[3]=(t[5]*t[6]-t[3]*t[8])*s,r[4]=(t[0]*t[8]-t[2]*t[6])*s,r[5]=(t[2]*t[3]-t[0]*t[5])*s,r[6]=(t[3]*t[7]-t[4]*t[6])*s,r[7]=(t[1]*t[6]-t[0]*t[7])*s,r[8]=(t[0]*t[4]-t[1]*t[3])*s,new y(r)}}class C{constructor(t=0,e=0,s=0,r=0){n(this,"x");n(this,"y");n(this,"width");n(this,"height");this.x=t,this.y=e,this.width=s,this.height=r}get left(){return this.x}get right(){return this.x+this.width}get top(){return this.y}get bottom(){return this.y+this.height}get centerX(){return this.x+this.width*.5}get centerY(){return this.y+this.height*.5}contains(t){return t.x>=this.left&&t.x<=this.right&&t.y>=this.top&&t.y<=this.bottom}intersects(t){return this.left<t.right&&this.right>t.left&&this.top<t.bottom&&this.bottom>t.top}clone(){return new C(this.x,this.y,this.width,this.height)}static fromPoints(t,e){const s=Math.min(t.x,e.x),r=Math.min(t.y,e.y);return new C(s,r,Math.max(t.x,e.x)-s,Math.max(t.y,e.y)-r)}}class p extends A{constructor(){super(...arguments);n(this,"type","transform2d");n(this,"x",0);n(this,"y",0);n(this,"rotation",0);n(this,"scaleX",1);n(this,"scaleY",1);n(this,"zIndex",0)}get position(){return new w(this.x,this.y)}set position(e){this.x=e.x,this.y=e.y}getLocalMatrix(){return y.translation(this.x,this.y).multiply(y.rotation(this.rotation)).multiply(y.scale(this.scaleX,this.scaleY))}}class $ extends A{constructor(){super(...arguments);n(this,"type","camera2d");n(this,"x",0);n(this,"y",0);n(this,"zoom",1);n(this,"rotation",0);n(this,"viewportWidth",1280);n(this,"viewportHeight",720)}get position(){return new w(this.x,this.y)}set position(e){this.x=e.x,this.y=e.y}getViewProjectionMatrix(){const e=this.viewportWidth*.5/this.zoom,s=this.viewportHeight*.5/this.zoom;return y.translation(-this.x,-this.y).multiply(y.rotation(-this.rotation)).multiply(y.orthographic(-e,e,-s,s))}screenToWorld(e,s){const r=e/this.viewportWidth*2-1,o=1-s/this.viewportHeight*2,i=this.viewportWidth*.5/this.zoom,c=this.viewportHeight*.5/this.zoom;return this.getViewProjectionMatrix().invert().transformPoint(new w(r*i,o*c))}getVisibleBounds(){const e=this.viewportWidth*.5/this.zoom,s=this.viewportHeight*.5/this.zoom;return new C(this.x-e,this.y-s,e*2,s*2)}}class x extends A{constructor(e=1,s=1,r=1,o=1,i=32,c=32,l,a=0,u=0,m=1,g=1){super();n(this,"colorR");n(this,"colorG");n(this,"colorB");n(this,"colorA");n(this,"width");n(this,"height");n(this,"texture");n(this,"texCoordU");n(this,"texCoordV");n(this,"texCoordW");n(this,"texCoordH");n(this,"type","sprite");this.colorR=e,this.colorG=s,this.colorB=r,this.colorA=o,this.width=i,this.height=c,this.texture=l,this.texCoordU=a,this.texCoordV=u,this.texCoordW=m,this.texCoordH=g}}class E extends A{constructor(e=100,s=1,r=0,o=0){super();n(this,"type","orbitalSpeed");this.radius=e,this.speed=s,this.angleOffset=r,this.orbitTilt=o}}class K extends G{constructor(){super(...arguments);n(this,"name","atom")}onEnter(){const e=this.world.createEntity();this.world.addComponent(e.id,new p);const s=new $;s.zoom=1,this.world.addComponent(e.id,s);const r=this.world.createEntity().tag("nucleus"),o=new p;o.zIndex=10,this.world.addComponent(r.id,o),this.world.addComponent(r.id,new x(.9,.6,.1,1,28,28));const i=this.world.createEntity().tag("glow"),c=new p;c.zIndex=9,this.world.addComponent(i.id,c),this.world.addComponent(i.id,new x(.9,.5,.1,.15,60,60));const l=[{radius:80,speed:2,tilt:0,color:[.3,.7,1],size:8,offset:0},{radius:130,speed:1.3,tilt:Math.PI/3,color:[.4,1,.6],size:7,offset:Math.PI*.66},{radius:180,speed:.8,tilt:-Math.PI/4,color:[1,.4,.8],size:6,offset:Math.PI*1.33}];for(const a of l){for(let b=0;b<60;b++){const S=this.world.createEntity().tag("ring"),M=new p;M.zIndex=1,this.world.addComponent(S.id,M),this.world.addComponent(S.id,new E(a.radius,0,b/60*Math.PI*2,a.tilt)),this.world.addComponent(S.id,new x(a.color[0]*.3,a.color[1]*.3,a.color[2]*.3,.25,2,2))}const m=this.world.createEntity().tag("electron"),g=new p;g.zIndex=5,this.world.addComponent(m.id,g),this.world.addComponent(m.id,new E(a.radius,a.speed,a.offset,a.tilt)),this.world.addComponent(m.id,new x(a.color[0],a.color[1],a.color[2],1,a.size,a.size));const f=this.world.createEntity().tag("electron-glow"),B=new p;B.zIndex=4,this.world.addComponent(f.id,B),this.world.addComponent(f.id,new E(a.radius,a.speed,a.offset,a.tilt)),this.world.addComponent(f.id,new x(a.color[0],a.color[1],a.color[2],.2,a.size*4,a.size*4))}}onUpdate(){const e=performance.now()*.001,s=this.world.query("transform2d","orbitalSpeed");for(const i of s){const c=i.get("transform2d"),l=i.get("orbitalSpeed"),a=l.angleOffset+e*l.speed,u=Math.cos(a)*l.radius,m=Math.sin(a)*l.radius*.4,g=Math.cos(l.orbitTilt),f=Math.sin(l.orbitTilt);c.x=u*g-m*f,c.y=u*f+m*g}const r=this.world.queryByTag("nucleus")[0];if(r){const i=r.get("sprite"),c=28+Math.sin(e*3)*4;i.width=c,i.height=c}const o=this.world.queryByTag("glow")[0];if(o){const i=o.get("sprite"),c=60+Math.sin(e*2)*10;i.width=c,i.height=c,i.colorA=.12+Math.sin(e*3)*.05}}onExit(){this.world.clear()}}const P=new N({canvasId:"game-canvas"});P.sceneManager.register(new K);P.sceneManager.switchTo("atom");P.start();
@@ -1,15 +0,0 @@
1
- {
2
- "hash": "f73e02d2",
3
- "configHash": "b8ee81f7",
4
- "lockfileHash": "3b55699f",
5
- "browserHash": "515ae1dd",
6
- "optimized": {
7
- "electron": {
8
- "src": "../../../../../../../node_modules/electron/index.js",
9
- "file": "electron.js",
10
- "fileHash": "dd513bd8",
11
- "needsInterop": true
12
- }
13
- },
14
- "chunks": {}
15
- }
@@ -1,56 +0,0 @@
1
- var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __commonJS = (cb, mod) => function __require() {
3
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
- };
5
-
6
- // browser-external:fs
7
- var require_fs = __commonJS({
8
- "browser-external:fs"(exports, module) {
9
- module.exports = Object.create(new Proxy({}, {
10
- get(_, key) {
11
- if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
12
- console.warn(`Module "fs" has been externalized for browser compatibility. Cannot access "fs.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
13
- }
14
- }
15
- }));
16
- }
17
- });
18
-
19
- // browser-external:path
20
- var require_path = __commonJS({
21
- "browser-external:path"(exports, module) {
22
- module.exports = Object.create(new Proxy({}, {
23
- get(_, key) {
24
- if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
25
- console.warn(`Module "path" has been externalized for browser compatibility. Cannot access "path.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
26
- }
27
- }
28
- }));
29
- }
30
- });
31
-
32
- // ../../../../node_modules/electron/index.js
33
- var require_electron = __commonJS({
34
- "../../../../node_modules/electron/index.js"(exports, module) {
35
- var fs = require_fs();
36
- var path = require_path();
37
- var pathFile = path.join(__dirname, "path.txt");
38
- function getElectronPath() {
39
- let executablePath;
40
- if (fs.existsSync(pathFile)) {
41
- executablePath = fs.readFileSync(pathFile, "utf-8");
42
- }
43
- if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {
44
- return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath || "electron");
45
- }
46
- if (executablePath) {
47
- return path.join(__dirname, "dist", executablePath);
48
- } else {
49
- throw new Error("Electron failed to install correctly, please delete node_modules/electron and try installing again");
50
- }
51
- }
52
- module.exports = getElectronPath();
53
- }
54
- });
55
- export default require_electron();
56
- //# sourceMappingURL=electron.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["browser-external:fs", "browser-external:path", "../../../../../../../node_modules/electron/index.js"],
4
- "sourcesContent": ["module.exports = Object.create(new Proxy({}, {\n get(_, key) {\n if (\n key !== '__esModule' &&\n key !== '__proto__' &&\n key !== 'constructor' &&\n key !== 'splice'\n ) {\n console.warn(`Module \"fs\" has been externalized for browser compatibility. Cannot access \"fs.${key}\" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`)\n }\n }\n}))", "module.exports = Object.create(new Proxy({}, {\n get(_, key) {\n if (\n key !== '__esModule' &&\n key !== '__proto__' &&\n key !== 'constructor' &&\n key !== 'splice'\n ) {\n console.warn(`Module \"path\" has been externalized for browser compatibility. Cannot access \"path.${key}\" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`)\n }\n }\n}))", "const fs = require('fs');\nconst path = require('path');\n\nconst pathFile = path.join(__dirname, 'path.txt');\n\nfunction getElectronPath () {\n let executablePath;\n if (fs.existsSync(pathFile)) {\n executablePath = fs.readFileSync(pathFile, 'utf-8');\n }\n if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {\n return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath || 'electron');\n }\n if (executablePath) {\n return path.join(__dirname, 'dist', executablePath);\n } else {\n throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again');\n }\n}\n\nmodule.exports = getElectronPath();\n"],
5
- "mappings": ";;;;;;AAAA;AAAA;AAAA,WAAO,UAAU,OAAO,OAAO,IAAI,MAAM,CAAC,GAAG;AAAA,MAC3C,IAAI,GAAG,KAAK;AACV,YACE,QAAQ,gBACR,QAAQ,eACR,QAAQ,iBACR,QAAQ,UACR;AACA,kBAAQ,KAAK,kFAAkF,GAAG,mIAAmI;AAAA,QACvO;AAAA,MACF;AAAA,IACF,CAAC,CAAC;AAAA;AAAA;;;ACXF;AAAA;AAAA,WAAO,UAAU,OAAO,OAAO,IAAI,MAAM,CAAC,GAAG;AAAA,MAC3C,IAAI,GAAG,KAAK;AACV,YACE,QAAQ,gBACR,QAAQ,eACR,QAAQ,iBACR,QAAQ,UACR;AACA,kBAAQ,KAAK,sFAAsF,GAAG,mIAAmI;AAAA,QAC3O;AAAA,MACF;AAAA,IACF,CAAC,CAAC;AAAA;AAAA;;;ACXF;AAAA;AAAA,QAAM,KAAK;AACX,QAAM,OAAO;AAEb,QAAM,WAAW,KAAK,KAAK,WAAW,UAAU;AAEhD,aAAS,kBAAmB;AAC1B,UAAI;AACJ,UAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,yBAAiB,GAAG,aAAa,UAAU,OAAO;AAAA,MACpD;AACA,UAAI,QAAQ,IAAI,6BAA6B;AAC3C,eAAO,KAAK,KAAK,QAAQ,IAAI,6BAA6B,kBAAkB,UAAU;AAAA,MACxF;AACA,UAAI,gBAAgB;AAClB,eAAO,KAAK,KAAK,WAAW,QAAQ,cAAc;AAAA,MACpD,OAAO;AACL,cAAM,IAAI,MAAM,oGAAoG;AAAA,MACtH;AAAA,IACF;AAEA,WAAO,UAAU,gBAAgB;AAAA;AAAA;",
6
- "names": []
7
- }
@@ -1,3 +0,0 @@
1
- {
2
- "type": "module"
3
- }