reze-engine 0.1.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/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Reze Engine
2
+
3
+ A lightweight engine built with WebGPU and TypeScript for real-time 3D anime character rendering, physics simulation, and semantic pose control.
@@ -0,0 +1,4 @@
1
+ import type { AmmoInstance } from "@fred3d/ammo";
2
+ export declare function loadAmmo(): Promise<AmmoInstance>;
3
+ export declare function getAmmoInstance(): AmmoInstance | null;
4
+ //# sourceMappingURL=ammo-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ammo-loader.d.ts","sourceRoot":"","sources":["../src/ammo-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAKhD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,CAyBtD;AAED,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD"}
@@ -0,0 +1,29 @@
1
+ let ammoInstance = null;
2
+ let ammoPromise = null;
3
+ export async function loadAmmo() {
4
+ // Return cached instance if available
5
+ if (ammoInstance) {
6
+ return ammoInstance;
7
+ }
8
+ // Return existing promise if already loading
9
+ if (ammoPromise) {
10
+ return ammoPromise;
11
+ }
12
+ // Start loading Ammo
13
+ ammoPromise = (async () => {
14
+ try {
15
+ const { Ammo } = await import("@fred3d/ammo");
16
+ ammoInstance = await Ammo();
17
+ return ammoInstance;
18
+ }
19
+ catch (error) {
20
+ console.error("[Ammo] Failed to load:", error);
21
+ ammoPromise = null; // Reset promise so it can be retried
22
+ throw error;
23
+ }
24
+ })();
25
+ return ammoPromise;
26
+ }
27
+ export function getAmmoInstance() {
28
+ return ammoInstance;
29
+ }
@@ -0,0 +1,46 @@
1
+ import { Mat4, Vec3 } from "./math";
2
+ export declare class Camera {
3
+ alpha: number;
4
+ beta: number;
5
+ radius: number;
6
+ target: Vec3;
7
+ fov: number;
8
+ aspect: number;
9
+ near: number;
10
+ far: number;
11
+ private canvas;
12
+ private isDragging;
13
+ private mouseButton;
14
+ private lastMousePos;
15
+ private lastTouchPos;
16
+ private touchIdentifier;
17
+ private isPinching;
18
+ private lastPinchDistance;
19
+ private lastPinchMidpoint;
20
+ private initialPinchDistance;
21
+ angularSensitivity: number;
22
+ panSensitivity: number;
23
+ wheelPrecision: number;
24
+ pinchPrecision: number;
25
+ minZ: number;
26
+ maxZ: number;
27
+ lowerBetaLimit: number;
28
+ upperBetaLimit: number;
29
+ constructor(alpha: number, beta: number, radius: number, target: Vec3, fov?: number);
30
+ getPosition(): Vec3;
31
+ getViewMatrix(): Mat4;
32
+ private getCameraVectors;
33
+ private panCamera;
34
+ getProjectionMatrix(): Mat4;
35
+ attachControl(canvas: HTMLCanvasElement): void;
36
+ detachControl(): void;
37
+ private onMouseDown;
38
+ private onMouseMove;
39
+ private onMouseUp;
40
+ private onWheel;
41
+ private onContextMenu;
42
+ private onTouchStart;
43
+ private onTouchMove;
44
+ private onTouchEnd;
45
+ }
46
+ //# sourceMappingURL=camera.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAInC,qBAAa,MAAM;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAI;IAClB,IAAI,EAAE,MAAM,CAAO;IACnB,GAAG,EAAE,MAAM,CAAM;IAGjB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAY;IAGxC,kBAAkB,EAAE,MAAM,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAS;IAC/B,cAAc,EAAE,MAAM,CAAO;IAC7B,cAAc,EAAE,MAAM,CAAO;IAC7B,IAAI,EAAE,MAAM,CAAM;IAClB,IAAI,EAAE,MAAM,CAAM;IAClB,cAAc,EAAE,MAAM,CAAQ;IAC9B,cAAc,EAAE,MAAM,CAAkB;gBAE5B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAE,MAAoB;IAkBhG,WAAW,IAAI,IAAI;IAQnB,aAAa,IAAI,IAAI;IAQrB,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,SAAS;IAiBjB,mBAAmB,IAAI,IAAI;IAI3B,aAAa,CAAC,MAAM,EAAE,iBAAiB;IAiBvC,aAAa;IAkBb,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IA6BpB,OAAO,CAAC,WAAW;IAiFnB,OAAO,CAAC,UAAU;CA+BnB"}
package/dist/camera.js ADDED
@@ -0,0 +1,303 @@
1
+ import { Mat4, Vec3 } from "./math";
2
+ const FAR = 1000;
3
+ export class Camera {
4
+ constructor(alpha, beta, radius, target, fov = Math.PI / 4) {
5
+ this.aspect = 1;
6
+ this.near = 0.05;
7
+ this.far = FAR;
8
+ // Input state
9
+ this.canvas = null;
10
+ this.isDragging = false;
11
+ this.mouseButton = null; // Track which mouse button is pressed (0 = left, 2 = right)
12
+ this.lastMousePos = { x: 0, y: 0 };
13
+ this.lastTouchPos = { x: 0, y: 0 };
14
+ this.touchIdentifier = null;
15
+ this.isPinching = false;
16
+ this.lastPinchDistance = 0;
17
+ this.lastPinchMidpoint = { x: 0, y: 0 }; // Midpoint of two fingers for panning
18
+ this.initialPinchDistance = 0; // Initial distance when pinch started
19
+ // Camera settings
20
+ this.angularSensitivity = 0.005;
21
+ this.panSensitivity = 0.0002; // Sensitivity for right-click panning
22
+ this.wheelPrecision = 0.01;
23
+ this.pinchPrecision = 0.05;
24
+ this.minZ = 0.1;
25
+ this.maxZ = FAR;
26
+ this.lowerBetaLimit = 0.001;
27
+ this.upperBetaLimit = Math.PI - 0.001;
28
+ this.alpha = alpha;
29
+ this.beta = beta;
30
+ this.radius = radius;
31
+ this.target = target;
32
+ this.fov = fov;
33
+ // Bind event handlers
34
+ this.onMouseDown = this.onMouseDown.bind(this);
35
+ this.onMouseMove = this.onMouseMove.bind(this);
36
+ this.onMouseUp = this.onMouseUp.bind(this);
37
+ this.onWheel = this.onWheel.bind(this);
38
+ this.onContextMenu = this.onContextMenu.bind(this);
39
+ this.onTouchStart = this.onTouchStart.bind(this);
40
+ this.onTouchMove = this.onTouchMove.bind(this);
41
+ this.onTouchEnd = this.onTouchEnd.bind(this);
42
+ }
43
+ getPosition() {
44
+ // Convert spherical coordinates to Cartesian position
45
+ const x = this.target.x + this.radius * Math.sin(this.beta) * Math.sin(this.alpha);
46
+ const y = this.target.y + this.radius * Math.cos(this.beta);
47
+ const z = this.target.z + this.radius * Math.sin(this.beta) * Math.cos(this.alpha);
48
+ return new Vec3(x, y, z);
49
+ }
50
+ getViewMatrix() {
51
+ const eye = this.getPosition();
52
+ const up = new Vec3(0, 1, 0);
53
+ return Mat4.lookAt(eye, this.target, up);
54
+ }
55
+ // Get camera's right and up vectors for panning
56
+ // Uses a more robust calculation similar to BabylonJS
57
+ getCameraVectors() {
58
+ const eye = this.getPosition();
59
+ const forward = this.target.subtract(eye);
60
+ const forwardLen = forward.length();
61
+ // Handle edge case where camera is at target
62
+ if (forwardLen < 0.0001) {
63
+ return { right: new Vec3(1, 0, 0), up: new Vec3(0, 1, 0) };
64
+ }
65
+ const forwardNorm = forward.scale(1 / forwardLen);
66
+ const worldUp = new Vec3(0, 1, 0);
67
+ // Calculate right vector: right = worldUp × forward
68
+ // Use a more stable calculation that handles parallel vectors
69
+ let right = worldUp.cross(forwardNorm);
70
+ const rightLen = right.length();
71
+ // If forward is parallel to worldUp, use a fallback
72
+ if (rightLen < 0.0001) {
73
+ // Camera is looking straight up or down, use X-axis as right
74
+ right = new Vec3(1, 0, 0);
75
+ }
76
+ else {
77
+ right = right.scale(1 / rightLen);
78
+ }
79
+ // Calculate camera up vector: up = forward × right (ensures orthogonality)
80
+ let up = forwardNorm.cross(right);
81
+ const upLen = up.length();
82
+ if (upLen < 0.0001) {
83
+ // Fallback to world up
84
+ up = new Vec3(0, 1, 0);
85
+ }
86
+ else {
87
+ up = up.scale(1 / upLen);
88
+ }
89
+ return { right, up };
90
+ }
91
+ // Pan the camera target based on mouse movement
92
+ // Uses screen-space to world-space translation similar to BabylonJS
93
+ panCamera(deltaX, deltaY) {
94
+ const { right, up } = this.getCameraVectors();
95
+ // Calculate pan distance based on camera distance
96
+ // The pan amount is proportional to the camera distance (radius) for consistent feel
97
+ // This makes panning feel natural at all zoom levels
98
+ const panDistance = this.radius * this.panSensitivity;
99
+ // Horizontal movement: drag right pans left (opposite direction)
100
+ // Vertical movement: drag up pans up (positive up vector)
101
+ const panRight = right.scale(-deltaX * panDistance);
102
+ const panUp = up.scale(deltaY * panDistance);
103
+ // Update target position smoothly
104
+ this.target = this.target.add(panRight).add(panUp);
105
+ }
106
+ getProjectionMatrix() {
107
+ return Mat4.perspective(this.fov, this.aspect, this.near, this.far);
108
+ }
109
+ attachControl(canvas) {
110
+ this.canvas = canvas;
111
+ // Attach mouse event listeners
112
+ // mousedown on canvas, but move/up on window so dragging works everywhere
113
+ this.canvas.addEventListener("mousedown", this.onMouseDown);
114
+ window.addEventListener("mousemove", this.onMouseMove);
115
+ window.addEventListener("mouseup", this.onMouseUp);
116
+ this.canvas.addEventListener("wheel", this.onWheel, { passive: false });
117
+ this.canvas.addEventListener("contextmenu", this.onContextMenu);
118
+ // Attach touch event listeners for mobile
119
+ this.canvas.addEventListener("touchstart", this.onTouchStart, { passive: false });
120
+ window.addEventListener("touchmove", this.onTouchMove, { passive: false });
121
+ window.addEventListener("touchend", this.onTouchEnd);
122
+ }
123
+ detachControl() {
124
+ if (!this.canvas)
125
+ return;
126
+ // Remove mouse event listeners
127
+ this.canvas.removeEventListener("mousedown", this.onMouseDown);
128
+ window.removeEventListener("mousemove", this.onMouseMove);
129
+ window.removeEventListener("mouseup", this.onMouseUp);
130
+ this.canvas.removeEventListener("wheel", this.onWheel);
131
+ this.canvas.removeEventListener("contextmenu", this.onContextMenu);
132
+ // Remove touch event listeners
133
+ this.canvas.removeEventListener("touchstart", this.onTouchStart);
134
+ window.removeEventListener("touchmove", this.onTouchMove);
135
+ window.removeEventListener("touchend", this.onTouchEnd);
136
+ this.canvas = null;
137
+ }
138
+ onMouseDown(e) {
139
+ this.isDragging = true;
140
+ this.mouseButton = e.button;
141
+ this.lastMousePos = { x: e.clientX, y: e.clientY };
142
+ }
143
+ onMouseMove(e) {
144
+ if (!this.isDragging)
145
+ return;
146
+ const deltaX = e.clientX - this.lastMousePos.x;
147
+ const deltaY = e.clientY - this.lastMousePos.y;
148
+ if (this.mouseButton === 2) {
149
+ // Right-click: pan the camera target
150
+ this.panCamera(deltaX, deltaY);
151
+ }
152
+ else {
153
+ // Left-click (or default): rotate the camera
154
+ this.alpha += deltaX * this.angularSensitivity;
155
+ this.beta -= deltaY * this.angularSensitivity;
156
+ // Clamp beta to prevent flipping
157
+ this.beta = Math.max(this.lowerBetaLimit, Math.min(this.upperBetaLimit, this.beta));
158
+ }
159
+ this.lastMousePos = { x: e.clientX, y: e.clientY };
160
+ }
161
+ onMouseUp() {
162
+ this.isDragging = false;
163
+ this.mouseButton = null;
164
+ }
165
+ onWheel(e) {
166
+ e.preventDefault();
167
+ // Update camera radius (zoom)
168
+ this.radius += e.deltaY * this.wheelPrecision;
169
+ // Clamp radius to reasonable bounds
170
+ this.radius = Math.max(this.minZ, Math.min(this.maxZ, this.radius));
171
+ // Expand far plane to keep scene visible when zooming out
172
+ this.far = Math.max(FAR, this.radius * 4);
173
+ }
174
+ onContextMenu(e) {
175
+ e.preventDefault();
176
+ }
177
+ onTouchStart(e) {
178
+ e.preventDefault();
179
+ if (e.touches.length === 1) {
180
+ // Single touch - rotation
181
+ const touch = e.touches[0];
182
+ this.isDragging = true;
183
+ this.isPinching = false;
184
+ this.touchIdentifier = touch.identifier;
185
+ this.lastTouchPos = { x: touch.clientX, y: touch.clientY };
186
+ }
187
+ else if (e.touches.length === 2) {
188
+ // Two touches - can be pinch zoom or pan
189
+ this.isDragging = false;
190
+ this.isPinching = true;
191
+ const touch1 = e.touches[0];
192
+ const touch2 = e.touches[1];
193
+ const dx = touch2.clientX - touch1.clientX;
194
+ const dy = touch2.clientY - touch1.clientY;
195
+ this.lastPinchDistance = Math.sqrt(dx * dx + dy * dy);
196
+ this.initialPinchDistance = this.lastPinchDistance;
197
+ // Calculate initial midpoint for panning
198
+ this.lastPinchMidpoint = {
199
+ x: (touch1.clientX + touch2.clientX) / 2,
200
+ y: (touch1.clientY + touch2.clientY) / 2,
201
+ };
202
+ }
203
+ }
204
+ onTouchMove(e) {
205
+ e.preventDefault();
206
+ if (this.isPinching && e.touches.length === 2) {
207
+ // Two-finger gesture: can be pinch zoom or pan
208
+ const touch1 = e.touches[0];
209
+ const touch2 = e.touches[1];
210
+ const dx = touch2.clientX - touch1.clientX;
211
+ const dy = touch2.clientY - touch1.clientY;
212
+ const distance = Math.sqrt(dx * dx + dy * dy);
213
+ // Calculate current midpoint
214
+ const currentMidpoint = {
215
+ x: (touch1.clientX + touch2.clientX) / 2,
216
+ y: (touch1.clientY + touch2.clientY) / 2,
217
+ };
218
+ // Calculate distance change and midpoint movement
219
+ const distanceDelta = Math.abs(distance - this.lastPinchDistance);
220
+ const midpointDeltaX = currentMidpoint.x - this.lastPinchMidpoint.x;
221
+ const midpointDeltaY = currentMidpoint.y - this.lastPinchMidpoint.y;
222
+ const midpointDelta = Math.sqrt(midpointDeltaX * midpointDeltaX + midpointDeltaY * midpointDeltaY);
223
+ // Determine gesture type based on relative changes
224
+ // Calculate relative change in distance (as percentage of initial distance)
225
+ const distanceChangeRatio = distanceDelta / Math.max(this.initialPinchDistance, 10.0);
226
+ // Threshold: if distance changes more than 3% of initial, it's primarily a zoom gesture
227
+ // Otherwise, if midpoint moves significantly, it's a pan gesture
228
+ const ZOOM_THRESHOLD = 0.03;
229
+ const PAN_THRESHOLD = 2.0; // Minimum pixels of midpoint movement for pan
230
+ const isZoomGesture = distanceChangeRatio > ZOOM_THRESHOLD;
231
+ const isPanGesture = midpointDelta > PAN_THRESHOLD && distanceChangeRatio < ZOOM_THRESHOLD * 2;
232
+ if (isZoomGesture) {
233
+ // Primary gesture is zoom (pinch)
234
+ const delta = this.lastPinchDistance - distance;
235
+ this.radius += delta * this.pinchPrecision;
236
+ // Clamp radius to reasonable bounds
237
+ this.radius = Math.max(this.minZ, Math.min(this.maxZ, this.radius));
238
+ // Expand far plane for pinch zoom as well
239
+ this.far = Math.max(FAR, this.radius * 4);
240
+ }
241
+ if (isPanGesture) {
242
+ // Primary gesture is pan (two-finger drag)
243
+ // Use panning similar to right-click pan
244
+ this.panCamera(midpointDeltaX, midpointDeltaY);
245
+ }
246
+ // Update tracking values
247
+ this.lastPinchDistance = distance;
248
+ this.lastPinchMidpoint = currentMidpoint;
249
+ }
250
+ else if (this.isDragging && this.touchIdentifier !== null) {
251
+ // Single-finger rotation
252
+ // Find the touch we're tracking
253
+ let touch = null;
254
+ for (let i = 0; i < e.touches.length; i++) {
255
+ if (e.touches[i].identifier === this.touchIdentifier) {
256
+ touch = e.touches[i];
257
+ break;
258
+ }
259
+ }
260
+ if (!touch)
261
+ return;
262
+ const deltaX = touch.clientX - this.lastTouchPos.x;
263
+ const deltaY = touch.clientY - this.lastTouchPos.y;
264
+ this.alpha += deltaX * this.angularSensitivity;
265
+ this.beta -= deltaY * this.angularSensitivity;
266
+ // Clamp beta to prevent flipping
267
+ this.beta = Math.max(this.lowerBetaLimit, Math.min(this.upperBetaLimit, this.beta));
268
+ this.lastTouchPos = { x: touch.clientX, y: touch.clientY };
269
+ }
270
+ }
271
+ onTouchEnd(e) {
272
+ if (e.touches.length === 0) {
273
+ // All touches ended
274
+ this.isDragging = false;
275
+ this.isPinching = false;
276
+ this.touchIdentifier = null;
277
+ this.initialPinchDistance = 0;
278
+ }
279
+ else if (e.touches.length === 1 && this.isPinching) {
280
+ // Went from 2 fingers to 1 - switch to rotation
281
+ const touch = e.touches[0];
282
+ this.isPinching = false;
283
+ this.isDragging = true;
284
+ this.touchIdentifier = touch.identifier;
285
+ this.lastTouchPos = { x: touch.clientX, y: touch.clientY };
286
+ this.initialPinchDistance = 0;
287
+ }
288
+ else if (this.touchIdentifier !== null) {
289
+ // Check if our tracked touch ended
290
+ let touchStillActive = false;
291
+ for (let i = 0; i < e.touches.length; i++) {
292
+ if (e.touches[i].identifier === this.touchIdentifier) {
293
+ touchStillActive = true;
294
+ break;
295
+ }
296
+ }
297
+ if (!touchStillActive) {
298
+ this.isDragging = false;
299
+ this.touchIdentifier = null;
300
+ }
301
+ }
302
+ }
303
+ }
@@ -0,0 +1,88 @@
1
+ import { Camera } from "./camera";
2
+ import { Vec3 } from "./math";
3
+ export interface EngineStats {
4
+ fps: number;
5
+ frameTime: number;
6
+ memoryUsed: number;
7
+ vertices: number;
8
+ drawCalls: number;
9
+ triangles: number;
10
+ materials: number;
11
+ textures: number;
12
+ textureMemory: number;
13
+ bufferMemory: number;
14
+ gpuMemory: number;
15
+ }
16
+ export declare class Engine {
17
+ private canvas;
18
+ private device;
19
+ private context;
20
+ private presentationFormat;
21
+ camera: Camera;
22
+ private cameraUniformBuffer;
23
+ private cameraMatrixData;
24
+ private lightUniformBuffer;
25
+ private lightData;
26
+ private lightCount;
27
+ private vertexBuffer;
28
+ private vertexCount;
29
+ private indexBuffer?;
30
+ private resizeObserver;
31
+ private depthTexture;
32
+ private pipeline;
33
+ private outlinePipeline;
34
+ private jointsBuffer;
35
+ private weightsBuffer;
36
+ private skinMatrixBuffer?;
37
+ private worldMatrixBuffer?;
38
+ private inverseBindMatrixBuffer?;
39
+ private skinMatrixComputePipeline?;
40
+ private boneCountBuffer?;
41
+ private multisampleTexture;
42
+ private readonly sampleCount;
43
+ private renderPassDescriptor;
44
+ private currentModel;
45
+ private modelDir;
46
+ private physics;
47
+ private textureSampler;
48
+ private textureCache;
49
+ private textureSizes;
50
+ private lastFpsUpdate;
51
+ private framesSinceLastUpdate;
52
+ private frameTimeSamples;
53
+ private frameTimeSum;
54
+ private drawCallCount;
55
+ private lastFrameTime;
56
+ private stats;
57
+ private animationFrameId;
58
+ private renderLoopCallback;
59
+ constructor(canvas: HTMLCanvasElement);
60
+ init(): Promise<void>;
61
+ private createPipelines;
62
+ private createSkinMatrixComputePipeline;
63
+ private setupResize;
64
+ private handleResize;
65
+ private setupCamera;
66
+ private setupLighting;
67
+ addLight(direction: Vec3, color: Vec3, intensity?: number): boolean;
68
+ setAmbient(intensity: number): void;
69
+ getStats(): EngineStats;
70
+ runRenderLoop(callback?: () => void): void;
71
+ stopRenderLoop(): void;
72
+ dispose(): void;
73
+ loadModel(path: string): Promise<void>;
74
+ private setupModelBuffers;
75
+ private materialDraws;
76
+ private outlineDraws;
77
+ private setupMaterials;
78
+ private createTextureFromPath;
79
+ render(): void;
80
+ private updateCameraUniforms;
81
+ private updateRenderTarget;
82
+ private updateModelPose;
83
+ private computeSkinMatrices;
84
+ private drawOutlines;
85
+ private drawModel;
86
+ private updateStats;
87
+ }
88
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}