@almadar/ui 5.142.0 → 5.143.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.
@@ -13214,6 +13214,83 @@ var init_DrawText = __esm({
13214
13214
  };
13215
13215
  }
13216
13216
  });
13217
+ function isAnimatedGroup(node) {
13218
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
13219
+ }
13220
+ function DrawGroup(props) {
13221
+ const register = React94.useContext(DrawableRegistryContext);
13222
+ if (register) register({ ...props, type: "draw-group" });
13223
+ return null;
13224
+ }
13225
+ var init_DrawGroup = __esm({
13226
+ "components/game/atoms/DrawGroup.tsx"() {
13227
+ "use client";
13228
+ init_registry();
13229
+ }
13230
+ });
13231
+ function applyMeshAnimation(node, timeMs) {
13232
+ const anim = node.animation;
13233
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
13234
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
13235
+ const cycle = timeMs / anim.durationMs;
13236
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
13237
+ const trackValue = (key) => {
13238
+ const defined = frames.filter((f3) => f3[key] !== void 0);
13239
+ if (defined.length === 0) return void 0;
13240
+ let prev;
13241
+ let next;
13242
+ for (const f3 of defined) {
13243
+ if (f3.at <= t) prev = f3;
13244
+ else if (!next) next = f3;
13245
+ }
13246
+ if (!prev) return defined[0][key];
13247
+ if (!next) return prev[key];
13248
+ const span = next.at - prev.at;
13249
+ const k = span > 0 ? (t - prev.at) / span : 1;
13250
+ const a = prev[key];
13251
+ const b = next[key];
13252
+ if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
13253
+ return a;
13254
+ };
13255
+ const num = {};
13256
+ for (const key of NUMERIC_TRACKS2) {
13257
+ const v = trackValue(key);
13258
+ if (v !== void 0) num[key] = v;
13259
+ }
13260
+ return {
13261
+ offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
13262
+ rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
13263
+ scale: num.scale ?? 1,
13264
+ opacity: num.opacity,
13265
+ emissiveIntensity: num.emissiveIntensity,
13266
+ color: trackValue("color"),
13267
+ emissive: trackValue("emissive")
13268
+ };
13269
+ }
13270
+ function DrawMesh(props) {
13271
+ const register = React94.useContext(DrawableRegistryContext);
13272
+ if (register) register({ ...props, type: "draw-mesh" });
13273
+ return null;
13274
+ }
13275
+ var lerp2, NUMERIC_TRACKS2;
13276
+ var init_DrawMesh = __esm({
13277
+ "components/game/atoms/DrawMesh.tsx"() {
13278
+ "use client";
13279
+ init_registry();
13280
+ lerp2 = (a, b, k) => a + (b - a) * k;
13281
+ NUMERIC_TRACKS2 = [
13282
+ "offsetX",
13283
+ "offsetY",
13284
+ "offsetZ",
13285
+ "rotateX",
13286
+ "rotateY",
13287
+ "rotateZ",
13288
+ "scale",
13289
+ "opacity",
13290
+ "emissiveIntensity"
13291
+ ];
13292
+ }
13293
+ });
13217
13294
 
13218
13295
  // components/game/molecules/DrawSpriteLayer.tsx
13219
13296
  function DrawSpriteLayer(_props) {
@@ -13280,18 +13357,22 @@ function paintDrawable(painter, node, dctx) {
13280
13357
  if (!isValidScenePos(node.position)) break;
13281
13358
  if (!Array.isArray(node.items)) break;
13282
13359
  const p = dctx.projector.project(node.position);
13360
+ const anim = dctx.time > 0 && isAnimatedGroup(node) ? applyMeshAnimation(node, dctx.time) : null;
13361
+ const tw = dctx.projector.tileWidth;
13283
13362
  painter.save();
13284
- painter.translate(p.x, p.y);
13285
- if (node.scale !== void 0) painter.scale(node.scale, node.scale);
13286
- if (node.rotate !== void 0) painter.rotate(node.rotate);
13287
- if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
13363
+ painter.translate(p.x + (anim ? anim.offset[0] * tw : 0), p.y + (anim ? anim.offset[1] * tw : 0));
13364
+ const scale = (node.scale ?? 1) * (anim?.scale ?? 1);
13365
+ if (scale !== 1) painter.scale(scale, scale);
13366
+ const rotate = (node.rotate ?? 0) + (node.rotation?.[2] ?? 0) + (anim?.rotate[2] ?? 0);
13367
+ if (rotate !== 0) painter.rotate(rotate);
13368
+ const opacity = (node.opacity ?? 1) * (anim?.opacity ?? 1);
13369
+ if (opacity !== 1) painter.setAlpha(opacity);
13288
13370
  if (node.clip) {
13289
- const tw = dctx.projector.tileWidth;
13290
13371
  painter.scale(tw, tw);
13291
13372
  painter.clipPath(node.clip);
13292
13373
  painter.scale(1 / tw, 1 / tw);
13293
13374
  }
13294
- const childCtx = node.scale !== void 0 && node.scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * node.scale } : dctx;
13375
+ const childCtx = scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * scale } : dctx;
13295
13376
  for (const item of node.items) paintDrawable(painter, item, childCtx);
13296
13377
  painter.restore();
13297
13378
  break;
@@ -13317,6 +13398,8 @@ var init_paintDispatch = __esm({
13317
13398
  init_DrawSprite();
13318
13399
  init_DrawShape();
13319
13400
  init_DrawText();
13401
+ init_DrawGroup();
13402
+ init_DrawMesh();
13320
13403
  init_DrawSpriteLayer();
13321
13404
  init_DrawShapeLayer();
13322
13405
  init_DrawTextLayer();
@@ -13563,7 +13646,8 @@ function Canvas2D({
13563
13646
  const miniMapHeight = gridExtent.height || 10;
13564
13647
  const drawableIsAnimated = (node) => {
13565
13648
  if (node.type === "draw-shape") return isAnimatedShape(node);
13566
- if (node.type === "draw-group") return Array.isArray(node.items) && node.items.some(drawableIsAnimated);
13649
+ if (node.type === "draw-group")
13650
+ return isAnimatedGroup(node) || Array.isArray(node.items) && node.items.some(drawableIsAnimated);
13567
13651
  if (node.type === "draw-shape-layer") return Array.isArray(node.items) && node.items.some(isAnimatedShape);
13568
13652
  return false;
13569
13653
  };
@@ -13905,6 +13989,7 @@ var init_Canvas2D = __esm({
13905
13989
  init_projector();
13906
13990
  init_paintDispatch();
13907
13991
  init_DrawShape();
13992
+ init_DrawGroup();
13908
13993
  init_registry();
13909
13994
  init_hitTest();
13910
13995
  init_isometric();
@@ -40924,28 +41009,6 @@ var init_DetailPanel = __esm({
40924
41009
  DetailPanel.displayName = "DetailPanel";
40925
41010
  }
40926
41011
  });
40927
- function DrawGroup(props) {
40928
- const register = React94.useContext(DrawableRegistryContext);
40929
- if (register) register({ ...props, type: "draw-group" });
40930
- return null;
40931
- }
40932
- var init_DrawGroup = __esm({
40933
- "components/game/atoms/DrawGroup.tsx"() {
40934
- "use client";
40935
- init_registry();
40936
- }
40937
- });
40938
- function DrawMesh(props) {
40939
- const register = React94.useContext(DrawableRegistryContext);
40940
- if (register) register({ ...props, type: "draw-mesh" });
40941
- return null;
40942
- }
40943
- var init_DrawMesh = __esm({
40944
- "components/game/atoms/DrawMesh.tsx"() {
40945
- "use client";
40946
- init_registry();
40947
- }
40948
- });
40949
41012
  function extractTitle(children) {
40950
41013
  if (!React94__namespace.default.isValidElement(children)) return void 0;
40951
41014
  const props = children.props;
package/dist/avl/index.js CHANGED
@@ -13138,6 +13138,83 @@ var init_DrawText = __esm({
13138
13138
  };
13139
13139
  }
13140
13140
  });
13141
+ function isAnimatedGroup(node) {
13142
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
13143
+ }
13144
+ function DrawGroup(props) {
13145
+ const register = useContext(DrawableRegistryContext);
13146
+ if (register) register({ ...props, type: "draw-group" });
13147
+ return null;
13148
+ }
13149
+ var init_DrawGroup = __esm({
13150
+ "components/game/atoms/DrawGroup.tsx"() {
13151
+ "use client";
13152
+ init_registry();
13153
+ }
13154
+ });
13155
+ function applyMeshAnimation(node, timeMs) {
13156
+ const anim = node.animation;
13157
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
13158
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
13159
+ const cycle = timeMs / anim.durationMs;
13160
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
13161
+ const trackValue = (key) => {
13162
+ const defined = frames.filter((f3) => f3[key] !== void 0);
13163
+ if (defined.length === 0) return void 0;
13164
+ let prev;
13165
+ let next;
13166
+ for (const f3 of defined) {
13167
+ if (f3.at <= t) prev = f3;
13168
+ else if (!next) next = f3;
13169
+ }
13170
+ if (!prev) return defined[0][key];
13171
+ if (!next) return prev[key];
13172
+ const span = next.at - prev.at;
13173
+ const k = span > 0 ? (t - prev.at) / span : 1;
13174
+ const a = prev[key];
13175
+ const b = next[key];
13176
+ if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
13177
+ return a;
13178
+ };
13179
+ const num = {};
13180
+ for (const key of NUMERIC_TRACKS2) {
13181
+ const v = trackValue(key);
13182
+ if (v !== void 0) num[key] = v;
13183
+ }
13184
+ return {
13185
+ offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
13186
+ rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
13187
+ scale: num.scale ?? 1,
13188
+ opacity: num.opacity,
13189
+ emissiveIntensity: num.emissiveIntensity,
13190
+ color: trackValue("color"),
13191
+ emissive: trackValue("emissive")
13192
+ };
13193
+ }
13194
+ function DrawMesh(props) {
13195
+ const register = useContext(DrawableRegistryContext);
13196
+ if (register) register({ ...props, type: "draw-mesh" });
13197
+ return null;
13198
+ }
13199
+ var lerp2, NUMERIC_TRACKS2;
13200
+ var init_DrawMesh = __esm({
13201
+ "components/game/atoms/DrawMesh.tsx"() {
13202
+ "use client";
13203
+ init_registry();
13204
+ lerp2 = (a, b, k) => a + (b - a) * k;
13205
+ NUMERIC_TRACKS2 = [
13206
+ "offsetX",
13207
+ "offsetY",
13208
+ "offsetZ",
13209
+ "rotateX",
13210
+ "rotateY",
13211
+ "rotateZ",
13212
+ "scale",
13213
+ "opacity",
13214
+ "emissiveIntensity"
13215
+ ];
13216
+ }
13217
+ });
13141
13218
 
13142
13219
  // components/game/molecules/DrawSpriteLayer.tsx
13143
13220
  function DrawSpriteLayer(_props) {
@@ -13204,18 +13281,22 @@ function paintDrawable(painter, node, dctx) {
13204
13281
  if (!isValidScenePos(node.position)) break;
13205
13282
  if (!Array.isArray(node.items)) break;
13206
13283
  const p = dctx.projector.project(node.position);
13284
+ const anim = dctx.time > 0 && isAnimatedGroup(node) ? applyMeshAnimation(node, dctx.time) : null;
13285
+ const tw = dctx.projector.tileWidth;
13207
13286
  painter.save();
13208
- painter.translate(p.x, p.y);
13209
- if (node.scale !== void 0) painter.scale(node.scale, node.scale);
13210
- if (node.rotate !== void 0) painter.rotate(node.rotate);
13211
- if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
13287
+ painter.translate(p.x + (anim ? anim.offset[0] * tw : 0), p.y + (anim ? anim.offset[1] * tw : 0));
13288
+ const scale = (node.scale ?? 1) * (anim?.scale ?? 1);
13289
+ if (scale !== 1) painter.scale(scale, scale);
13290
+ const rotate = (node.rotate ?? 0) + (node.rotation?.[2] ?? 0) + (anim?.rotate[2] ?? 0);
13291
+ if (rotate !== 0) painter.rotate(rotate);
13292
+ const opacity = (node.opacity ?? 1) * (anim?.opacity ?? 1);
13293
+ if (opacity !== 1) painter.setAlpha(opacity);
13212
13294
  if (node.clip) {
13213
- const tw = dctx.projector.tileWidth;
13214
13295
  painter.scale(tw, tw);
13215
13296
  painter.clipPath(node.clip);
13216
13297
  painter.scale(1 / tw, 1 / tw);
13217
13298
  }
13218
- const childCtx = node.scale !== void 0 && node.scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * node.scale } : dctx;
13299
+ const childCtx = scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * scale } : dctx;
13219
13300
  for (const item of node.items) paintDrawable(painter, item, childCtx);
13220
13301
  painter.restore();
13221
13302
  break;
@@ -13241,6 +13322,8 @@ var init_paintDispatch = __esm({
13241
13322
  init_DrawSprite();
13242
13323
  init_DrawShape();
13243
13324
  init_DrawText();
13325
+ init_DrawGroup();
13326
+ init_DrawMesh();
13244
13327
  init_DrawSpriteLayer();
13245
13328
  init_DrawShapeLayer();
13246
13329
  init_DrawTextLayer();
@@ -13487,7 +13570,8 @@ function Canvas2D({
13487
13570
  const miniMapHeight = gridExtent.height || 10;
13488
13571
  const drawableIsAnimated = (node) => {
13489
13572
  if (node.type === "draw-shape") return isAnimatedShape(node);
13490
- if (node.type === "draw-group") return Array.isArray(node.items) && node.items.some(drawableIsAnimated);
13573
+ if (node.type === "draw-group")
13574
+ return isAnimatedGroup(node) || Array.isArray(node.items) && node.items.some(drawableIsAnimated);
13491
13575
  if (node.type === "draw-shape-layer") return Array.isArray(node.items) && node.items.some(isAnimatedShape);
13492
13576
  return false;
13493
13577
  };
@@ -13829,6 +13913,7 @@ var init_Canvas2D = __esm({
13829
13913
  init_projector();
13830
13914
  init_paintDispatch();
13831
13915
  init_DrawShape();
13916
+ init_DrawGroup();
13832
13917
  init_registry();
13833
13918
  init_hitTest();
13834
13919
  init_isometric();
@@ -40848,28 +40933,6 @@ var init_DetailPanel = __esm({
40848
40933
  DetailPanel.displayName = "DetailPanel";
40849
40934
  }
40850
40935
  });
40851
- function DrawGroup(props) {
40852
- const register = useContext(DrawableRegistryContext);
40853
- if (register) register({ ...props, type: "draw-group" });
40854
- return null;
40855
- }
40856
- var init_DrawGroup = __esm({
40857
- "components/game/atoms/DrawGroup.tsx"() {
40858
- "use client";
40859
- init_registry();
40860
- }
40861
- });
40862
- function DrawMesh(props) {
40863
- const register = useContext(DrawableRegistryContext);
40864
- if (register) register({ ...props, type: "draw-mesh" });
40865
- return null;
40866
- }
40867
- var init_DrawMesh = __esm({
40868
- "components/game/atoms/DrawMesh.tsx"() {
40869
- "use client";
40870
- init_registry();
40871
- }
40872
- });
40873
40936
  function extractTitle(children) {
40874
40937
  if (!React94__default.isValidElement(children)) return void 0;
40875
40938
  const props = children.props;
@@ -1,7 +1,7 @@
1
1
  import { AnimationName, Asset, ScenePos, EventEmit, JsonObject, JsonValue } from '@almadar/core';
2
2
  import React__default from 'react';
3
3
  import * as THREE from 'three';
4
- import { D as DrawableNode } from './paintDispatch-BQn5Lyx1.js';
4
+ import { D as DrawableNode } from './paintDispatch-D3-5_cOb.js';
5
5
 
6
6
  /**
7
7
  * Sprite Sheet Animation Types
@@ -310,7 +310,7 @@ interface CameraState {
310
310
  /** Camera mode for 3D view.
311
311
  * - `follow` tracks `followTarget` (the neutral `Camera.target`) from a fixed offset.
312
312
  * - `chase` sits behind + above the target. */
313
- type CameraMode = 'isometric' | 'perspective' | 'top-down' | 'follow' | 'chase';
313
+ type CameraMode = 'isometric' | 'perspective' | 'top-down' | 'front' | 'follow' | 'chase';
314
314
  /** Map orientation */
315
315
  type MapOrientation = 'standard' | 'rotated';
316
316
  /** Overlay control */
@@ -351,6 +351,10 @@ interface CanvasLighting {
351
351
  * RoomEnvironment via PMREMGenerator — no network fetch. Default 'none' (today's
352
352
  * look). */
353
353
  environment?: 'room' | 'none';
354
+ /** Output tone mapping. Default 'aces' (R3F's filmic default — the stylized look
355
+ * every existing scene was authored under); 'none' renders material colors
356
+ * faithfully (raw three default — what GLB viewers show). */
357
+ toneMapping?: 'aces' | 'none';
354
358
  }
355
359
  /** Canvas-level post-processing stack. Every field is optional — an omitted field
356
360
  * means that pass is not mounted. */
@@ -1,7 +1,7 @@
1
1
  import { AnimationName, Asset, ScenePos, EventEmit, JsonObject, JsonValue } from '@almadar/core';
2
2
  import React__default from 'react';
3
3
  import * as THREE from 'three';
4
- import { D as DrawableNode } from './paintDispatch-BQn5Lyx1.cjs';
4
+ import { D as DrawableNode } from './paintDispatch-D3-5_cOb.cjs';
5
5
 
6
6
  /**
7
7
  * Sprite Sheet Animation Types
@@ -310,7 +310,7 @@ interface CameraState {
310
310
  /** Camera mode for 3D view.
311
311
  * - `follow` tracks `followTarget` (the neutral `Camera.target`) from a fixed offset.
312
312
  * - `chase` sits behind + above the target. */
313
- type CameraMode = 'isometric' | 'perspective' | 'top-down' | 'follow' | 'chase';
313
+ type CameraMode = 'isometric' | 'perspective' | 'top-down' | 'front' | 'follow' | 'chase';
314
314
  /** Map orientation */
315
315
  type MapOrientation = 'standard' | 'rotated';
316
316
  /** Overlay control */
@@ -351,6 +351,10 @@ interface CanvasLighting {
351
351
  * RoomEnvironment via PMREMGenerator — no network fetch. Default 'none' (today's
352
352
  * look). */
353
353
  environment?: 'room' | 'none';
354
+ /** Output tone mapping. Default 'aces' (R3F's filmic default — the stylized look
355
+ * every existing scene was authored under); 'none' renders material colors
356
+ * faithfully (raw three default — what GLB viewers show). */
357
+ toneMapping?: 'aces' | 'none';
354
358
  }
355
359
  /** Canvas-level post-processing stack. Every field is optional — an omitted field
356
360
  * means that pass is not mounted. */
@@ -1,5 +1,5 @@
1
1
  import { OrbitalSchema, SExpr, Effect, OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, ServerResponseTrace, CheckStatus, AssetLoadStatus } from '@almadar/core';
2
- import { D as DrawableNode } from './paintDispatch-BQn5Lyx1.cjs';
2
+ import { D as DrawableNode } from './paintDispatch-D3-5_cOb.cjs';
3
3
  import { ClassValue } from 'clsx';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { OrbitalSchema, SExpr, Effect, OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, ServerResponseTrace, CheckStatus, AssetLoadStatus } from '@almadar/core';
2
- import { D as DrawableNode } from './paintDispatch-BQn5Lyx1.js';
2
+ import { D as DrawableNode } from './paintDispatch-D3-5_cOb.js';
3
3
  import { ClassValue } from 'clsx';
4
4
 
5
5
  /**
@@ -16344,6 +16344,83 @@ var init_DrawText = __esm({
16344
16344
  };
16345
16345
  }
16346
16346
  });
16347
+ function isAnimatedGroup(node) {
16348
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
16349
+ }
16350
+ function DrawGroup(props) {
16351
+ const register = React77.useContext(DrawableRegistryContext);
16352
+ if (register) register({ ...props, type: "draw-group" });
16353
+ return null;
16354
+ }
16355
+ var init_DrawGroup = __esm({
16356
+ "components/game/atoms/DrawGroup.tsx"() {
16357
+ "use client";
16358
+ init_registry();
16359
+ }
16360
+ });
16361
+ function applyMeshAnimation(node, timeMs) {
16362
+ const anim = node.animation;
16363
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
16364
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
16365
+ const cycle = timeMs / anim.durationMs;
16366
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
16367
+ const trackValue = (key) => {
16368
+ const defined = frames.filter((f3) => f3[key] !== void 0);
16369
+ if (defined.length === 0) return void 0;
16370
+ let prev;
16371
+ let next;
16372
+ for (const f3 of defined) {
16373
+ if (f3.at <= t) prev = f3;
16374
+ else if (!next) next = f3;
16375
+ }
16376
+ if (!prev) return defined[0][key];
16377
+ if (!next) return prev[key];
16378
+ const span = next.at - prev.at;
16379
+ const k = span > 0 ? (t - prev.at) / span : 1;
16380
+ const a = prev[key];
16381
+ const b = next[key];
16382
+ if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
16383
+ return a;
16384
+ };
16385
+ const num2 = {};
16386
+ for (const key of NUMERIC_TRACKS2) {
16387
+ const v = trackValue(key);
16388
+ if (v !== void 0) num2[key] = v;
16389
+ }
16390
+ return {
16391
+ offset: [num2.offsetX ?? 0, num2.offsetY ?? 0, num2.offsetZ ?? 0],
16392
+ rotate: [num2.rotateX ?? 0, num2.rotateY ?? 0, num2.rotateZ ?? 0],
16393
+ scale: num2.scale ?? 1,
16394
+ opacity: num2.opacity,
16395
+ emissiveIntensity: num2.emissiveIntensity,
16396
+ color: trackValue("color"),
16397
+ emissive: trackValue("emissive")
16398
+ };
16399
+ }
16400
+ function DrawMesh(props) {
16401
+ const register = React77.useContext(DrawableRegistryContext);
16402
+ if (register) register({ ...props, type: "draw-mesh" });
16403
+ return null;
16404
+ }
16405
+ var lerp2, NUMERIC_TRACKS2;
16406
+ var init_DrawMesh = __esm({
16407
+ "components/game/atoms/DrawMesh.tsx"() {
16408
+ "use client";
16409
+ init_registry();
16410
+ lerp2 = (a, b, k) => a + (b - a) * k;
16411
+ NUMERIC_TRACKS2 = [
16412
+ "offsetX",
16413
+ "offsetY",
16414
+ "offsetZ",
16415
+ "rotateX",
16416
+ "rotateY",
16417
+ "rotateZ",
16418
+ "scale",
16419
+ "opacity",
16420
+ "emissiveIntensity"
16421
+ ];
16422
+ }
16423
+ });
16347
16424
 
16348
16425
  // components/game/molecules/DrawSpriteLayer.tsx
16349
16426
  function DrawSpriteLayer(_props) {
@@ -16410,18 +16487,22 @@ function paintDrawable(painter, node, dctx) {
16410
16487
  if (!isValidScenePos(node.position)) break;
16411
16488
  if (!Array.isArray(node.items)) break;
16412
16489
  const p = dctx.projector.project(node.position);
16490
+ const anim = dctx.time > 0 && isAnimatedGroup(node) ? applyMeshAnimation(node, dctx.time) : null;
16491
+ const tw = dctx.projector.tileWidth;
16413
16492
  painter.save();
16414
- painter.translate(p.x, p.y);
16415
- if (node.scale !== void 0) painter.scale(node.scale, node.scale);
16416
- if (node.rotate !== void 0) painter.rotate(node.rotate);
16417
- if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
16493
+ painter.translate(p.x + (anim ? anim.offset[0] * tw : 0), p.y + (anim ? anim.offset[1] * tw : 0));
16494
+ const scale = (node.scale ?? 1) * (anim?.scale ?? 1);
16495
+ if (scale !== 1) painter.scale(scale, scale);
16496
+ const rotate = (node.rotate ?? 0) + (node.rotation?.[2] ?? 0) + (anim?.rotate[2] ?? 0);
16497
+ if (rotate !== 0) painter.rotate(rotate);
16498
+ const opacity = (node.opacity ?? 1) * (anim?.opacity ?? 1);
16499
+ if (opacity !== 1) painter.setAlpha(opacity);
16418
16500
  if (node.clip) {
16419
- const tw = dctx.projector.tileWidth;
16420
16501
  painter.scale(tw, tw);
16421
16502
  painter.clipPath(node.clip);
16422
16503
  painter.scale(1 / tw, 1 / tw);
16423
16504
  }
16424
- const childCtx = node.scale !== void 0 && node.scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * node.scale } : dctx;
16505
+ const childCtx = scale !== 1 ? { ...dctx, groupScale: (dctx.groupScale ?? 1) * scale } : dctx;
16425
16506
  for (const item of node.items) paintDrawable(painter, item, childCtx);
16426
16507
  painter.restore();
16427
16508
  break;
@@ -16447,6 +16528,8 @@ var init_paintDispatch = __esm({
16447
16528
  init_DrawSprite();
16448
16529
  init_DrawShape();
16449
16530
  init_DrawText();
16531
+ init_DrawGroup();
16532
+ init_DrawMesh();
16450
16533
  init_DrawSpriteLayer();
16451
16534
  init_DrawShapeLayer();
16452
16535
  init_DrawTextLayer();
@@ -16693,7 +16776,8 @@ function Canvas2D({
16693
16776
  const miniMapHeight = gridExtent.height || 10;
16694
16777
  const drawableIsAnimated = (node) => {
16695
16778
  if (node.type === "draw-shape") return isAnimatedShape(node);
16696
- if (node.type === "draw-group") return Array.isArray(node.items) && node.items.some(drawableIsAnimated);
16779
+ if (node.type === "draw-group")
16780
+ return isAnimatedGroup(node) || Array.isArray(node.items) && node.items.some(drawableIsAnimated);
16697
16781
  if (node.type === "draw-shape-layer") return Array.isArray(node.items) && node.items.some(isAnimatedShape);
16698
16782
  return false;
16699
16783
  };
@@ -17035,6 +17119,7 @@ var init_Canvas2D = __esm({
17035
17119
  init_projector();
17036
17120
  init_paintDispatch();
17037
17121
  init_DrawShape();
17122
+ init_DrawGroup();
17038
17123
  init_registry();
17039
17124
  init_hitTest();
17040
17125
  init_isometric();
@@ -40349,28 +40434,6 @@ var init_DetailPanel = __esm({
40349
40434
  exports.DetailPanel.displayName = "DetailPanel";
40350
40435
  }
40351
40436
  });
40352
- function DrawGroup(props) {
40353
- const register = React77.useContext(DrawableRegistryContext);
40354
- if (register) register({ ...props, type: "draw-group" });
40355
- return null;
40356
- }
40357
- var init_DrawGroup = __esm({
40358
- "components/game/atoms/DrawGroup.tsx"() {
40359
- "use client";
40360
- init_registry();
40361
- }
40362
- });
40363
- function DrawMesh(props) {
40364
- const register = React77.useContext(DrawableRegistryContext);
40365
- if (register) register({ ...props, type: "draw-mesh" });
40366
- return null;
40367
- }
40368
- var init_DrawMesh = __esm({
40369
- "components/game/atoms/DrawMesh.tsx"() {
40370
- "use client";
40371
- init_registry();
40372
- }
40373
- });
40374
40437
  function extractTitle(children) {
40375
40438
  if (!React77__namespace.default.isValidElement(children)) return void 0;
40376
40439
  const props = children.props;
@@ -6,11 +6,11 @@ import { LucideIcon } from 'lucide-react';
6
6
  import { C as ColorToken, U as UiError, P as Point, L as LinkAction, I as ImageSource } from '../GameAudioProvider-CPGwD49P.cjs';
7
7
  export { A as AudioManifest, G as GameAudioContext, a as GameAudioContextValue, e as GameAudioControls, b as GameAudioProvider, c as GameAudioProviderProps, R as Rect, S as SoundEntry, f as UseGameAudioOptions, g as useGameAudio, u as useGameAudioContext } from '../GameAudioProvider-CPGwD49P.cjs';
8
8
  import { SExpr } from '@almadar/evaluator';
9
- import { U as UnitAnimationState, F as FacingDirection, S as SpriteSheetUrls, g as SpriteFrameDims, R as ResolvedFrame, h as CanvasLighting, i as CanvasPost, a as IsometricUnit, j as CameraState, k as FieldInfo, l as OrbitalTraitInfo, m as OrbitalPageInfo, T as TraitLevelData, E as ExternalLink } from '../avl-schema-parser-wOkfbwAh.cjs';
10
- export { B as BoardTile, G as GameAction, n as GamePhase, o as GameState, p as GameUnit, b as IsometricFeature, I as IsometricTile, P as Position, q as UnitTrait, r as calculateAttackTargets, s as calculateValidMoves, t as createInitialGameState } from '../avl-schema-parser-wOkfbwAh.cjs';
11
- import { D as DrawableNode } from '../paintDispatch-BQn5Lyx1.cjs';
12
- import { C as ContentSegment, b as DomLayoutData, d as DomStateNode, V as VisualizerConfig, e as DomTransitionLabel } from '../cn-rwc3svaX.cjs';
13
- export { n as cn } from '../cn-rwc3svaX.cjs';
9
+ import { U as UnitAnimationState, F as FacingDirection, S as SpriteSheetUrls, g as SpriteFrameDims, R as ResolvedFrame, h as CanvasLighting, i as CanvasPost, a as IsometricUnit, j as CameraState, k as FieldInfo, l as OrbitalTraitInfo, m as OrbitalPageInfo, T as TraitLevelData, E as ExternalLink } from '../avl-schema-parser-BZ8pICOS.cjs';
10
+ export { B as BoardTile, G as GameAction, n as GamePhase, o as GameState, p as GameUnit, b as IsometricFeature, I as IsometricTile, P as Position, q as UnitTrait, r as calculateAttackTargets, s as calculateValidMoves, t as createInitialGameState } from '../avl-schema-parser-BZ8pICOS.cjs';
11
+ import { D as DrawableNode } from '../paintDispatch-D3-5_cOb.cjs';
12
+ import { C as ContentSegment, b as DomLayoutData, d as DomStateNode, V as VisualizerConfig, e as DomTransitionLabel } from '../cn-CvImTgKH.cjs';
13
+ export { n as cn } from '../cn-CvImTgKH.cjs';
14
14
  import { b as SlotContent } from '../useUISlots-BesZYMks.cjs';
15
15
  export { D as DEFAULT_SLOTS, S as SlotAnimation, a as SlotChangeCallback, c as SlotRenderConfig, U as UISlotManager, u as useUISlotManager } from '../useUISlots-BesZYMks.cjs';
16
16
  export { ALMADAR_DND_MIME, AuthContextValue, AuthUser, CanvasGestureCallbacks, CanvasGestureHandlers, CompileResult, CompileStage, DragReorderResult, DraggablePayload, Extension, ExtensionManifest, FileSystemFile, FileSystemStatus, GitHubRepo, GitHubStatus, HistoryChangeSummary, HistoryTimelineItem, I18nContextValue, I18nProvider, InfiniteScrollOptions, InfiniteScrollResult, LongPressHandlers, LongPressOptions, OpenFile, Positioned, PullToRefreshOptions, PullToRefreshResult, QuerySingletonEntity, QuerySingletonResult, QuerySingletonState, QueryState, RenderInterpolationHandle, RenderInterpolationOptions, RevertResult, SelectedFile, SharedEntityStore, SharedEntityStoreContext, SharedEntitySubscriber, SharedEntityWriter, SwipeGestureOptions, SwipeGestureResult, SwipeHandlers, TapRevealOptions, TapRevealResult, TraitListenSpec, TranslateFunction, UseCanvasGesturesOptions, UseCompileResult, UseDraggableOptions, UseDraggableResult, UseDropZoneOptions, UseDropZoneResult, UseExtensionsOptions, UseExtensionsResult, UseFileEditorOptions, UseFileEditorResult, UseFileSystemResult, UseOrbitalHistoryOptions, UseOrbitalHistoryResult, createSharedEntityStore, createTranslate, parseQueryBinding, runTickFrame, useAgentChat, useAuthContext, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useLongPress, useMediaQuery, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate, useUIEvents, useValidation } from '../hooks/index.cjs';
@@ -6,11 +6,11 @@ import { LucideIcon } from 'lucide-react';
6
6
  import { C as ColorToken, U as UiError, P as Point, L as LinkAction, I as ImageSource } from '../GameAudioProvider-CPGwD49P.js';
7
7
  export { A as AudioManifest, G as GameAudioContext, a as GameAudioContextValue, e as GameAudioControls, b as GameAudioProvider, c as GameAudioProviderProps, R as Rect, S as SoundEntry, f as UseGameAudioOptions, g as useGameAudio, u as useGameAudioContext } from '../GameAudioProvider-CPGwD49P.js';
8
8
  import { SExpr } from '@almadar/evaluator';
9
- import { U as UnitAnimationState, F as FacingDirection, S as SpriteSheetUrls, g as SpriteFrameDims, R as ResolvedFrame, h as CanvasLighting, i as CanvasPost, a as IsometricUnit, j as CameraState, k as FieldInfo, l as OrbitalTraitInfo, m as OrbitalPageInfo, T as TraitLevelData, E as ExternalLink } from '../avl-schema-parser-DAs12kxP.js';
10
- export { B as BoardTile, G as GameAction, n as GamePhase, o as GameState, p as GameUnit, b as IsometricFeature, I as IsometricTile, P as Position, q as UnitTrait, r as calculateAttackTargets, s as calculateValidMoves, t as createInitialGameState } from '../avl-schema-parser-DAs12kxP.js';
11
- import { D as DrawableNode } from '../paintDispatch-BQn5Lyx1.js';
12
- import { C as ContentSegment, b as DomLayoutData, d as DomStateNode, V as VisualizerConfig, e as DomTransitionLabel } from '../cn-BDwC4QpH.js';
13
- export { n as cn } from '../cn-BDwC4QpH.js';
9
+ import { U as UnitAnimationState, F as FacingDirection, S as SpriteSheetUrls, g as SpriteFrameDims, R as ResolvedFrame, h as CanvasLighting, i as CanvasPost, a as IsometricUnit, j as CameraState, k as FieldInfo, l as OrbitalTraitInfo, m as OrbitalPageInfo, T as TraitLevelData, E as ExternalLink } from '../avl-schema-parser-0hkiHOq3.js';
10
+ export { B as BoardTile, G as GameAction, n as GamePhase, o as GameState, p as GameUnit, b as IsometricFeature, I as IsometricTile, P as Position, q as UnitTrait, r as calculateAttackTargets, s as calculateValidMoves, t as createInitialGameState } from '../avl-schema-parser-0hkiHOq3.js';
11
+ import { D as DrawableNode } from '../paintDispatch-D3-5_cOb.js';
12
+ import { C as ContentSegment, b as DomLayoutData, d as DomStateNode, V as VisualizerConfig, e as DomTransitionLabel } from '../cn-DryTiahe.js';
13
+ export { n as cn } from '../cn-DryTiahe.js';
14
14
  import { b as SlotContent } from '../useUISlots-BesZYMks.js';
15
15
  export { D as DEFAULT_SLOTS, S as SlotAnimation, a as SlotChangeCallback, c as SlotRenderConfig, U as UISlotManager, u as useUISlotManager } from '../useUISlots-BesZYMks.js';
16
16
  export { ALMADAR_DND_MIME, AuthContextValue, AuthUser, CanvasGestureCallbacks, CanvasGestureHandlers, CompileResult, CompileStage, DragReorderResult, DraggablePayload, Extension, ExtensionManifest, FileSystemFile, FileSystemStatus, GitHubRepo, GitHubStatus, HistoryChangeSummary, HistoryTimelineItem, I18nContextValue, I18nProvider, InfiniteScrollOptions, InfiniteScrollResult, LongPressHandlers, LongPressOptions, OpenFile, Positioned, PullToRefreshOptions, PullToRefreshResult, QuerySingletonEntity, QuerySingletonResult, QuerySingletonState, QueryState, RenderInterpolationHandle, RenderInterpolationOptions, RevertResult, SelectedFile, SharedEntityStore, SharedEntityStoreContext, SharedEntitySubscriber, SharedEntityWriter, SwipeGestureOptions, SwipeGestureResult, SwipeHandlers, TapRevealOptions, TapRevealResult, TraitListenSpec, TranslateFunction, UseCanvasGesturesOptions, UseCompileResult, UseDraggableOptions, UseDraggableResult, UseDropZoneOptions, UseDropZoneResult, UseExtensionsOptions, UseExtensionsResult, UseFileEditorOptions, UseFileEditorResult, UseFileSystemResult, UseOrbitalHistoryOptions, UseOrbitalHistoryResult, createSharedEntityStore, createTranslate, parseQueryBinding, runTickFrame, useAgentChat, useAuthContext, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useLongPress, useMediaQuery, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate, useUIEvents, useValidation } from '../hooks/index.js';