@almadar/ui 5.103.0 → 5.105.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.
Files changed (80) hide show
  1. package/dist/avl/index.cjs +168 -88
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +168 -88
  4. package/dist/components/core/atoms/AtlasImage.d.ts +2 -2
  5. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  6. package/dist/components/core/molecules/Card.d.ts +1 -1
  7. package/dist/components/core/molecules/Chart.d.ts +3 -3
  8. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  9. package/dist/components/core/molecules/DataList.d.ts +1 -1
  10. package/dist/components/core/molecules/DocPagination.d.ts +8 -1
  11. package/dist/components/core/molecules/DocSearch.d.ts +8 -1
  12. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  13. package/dist/components/core/molecules/LineChart.d.ts +3 -1
  14. package/dist/components/core/molecules/MapView.d.ts +18 -1
  15. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  16. package/dist/components/core/molecules/TableView.d.ts +1 -1
  17. package/dist/components/core/organisms/DataTable.d.ts +7 -3
  18. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +10 -1
  19. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +2 -1
  20. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  21. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +6 -1
  22. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +6 -1
  23. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +12 -1
  24. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +2 -1
  25. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +2 -1
  26. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +11 -1
  27. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +8 -1
  28. package/dist/components/game/2d/atoms/ActionButton.d.ts +2 -1
  29. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +2 -1
  30. package/dist/components/game/2d/atoms/ComboCounter.d.ts +2 -1
  31. package/dist/components/game/2d/atoms/ControlButton.d.ts +2 -1
  32. package/dist/components/game/2d/atoms/DamageNumber.d.ts +2 -1
  33. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +2 -1
  34. package/dist/components/game/2d/atoms/GameIcon.d.ts +2 -1
  35. package/dist/components/game/2d/atoms/HealthBar.d.ts +2 -1
  36. package/dist/components/game/2d/atoms/ItemSlot.d.ts +2 -1
  37. package/dist/components/game/2d/atoms/MiniMap.d.ts +2 -1
  38. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +2 -1
  39. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +2 -1
  40. package/dist/components/game/2d/atoms/StatusEffect.d.ts +2 -1
  41. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +2 -1
  42. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +2 -1
  43. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +2 -1
  44. package/dist/components/game/2d/molecules/Canvas2D.d.ts +6 -5
  45. package/dist/components/game/2d/molecules/GameHud.d.ts +2 -1
  46. package/dist/components/game/2d/molecules/GameMenu.d.ts +2 -1
  47. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +2 -1
  48. package/dist/components/game/2d/molecules/ResourceBar.d.ts +2 -1
  49. package/dist/components/game/2d/molecules/SideCanvas2D.d.ts +36 -0
  50. package/dist/components/game/2d/molecules/StatBadge.d.ts +2 -1
  51. package/dist/components/game/3d/atoms/EventMarker3D.d.ts +17 -0
  52. package/dist/components/game/3d/atoms/SpriteBillboard3D.d.ts +18 -0
  53. package/dist/components/game/3d/index.cjs +539 -496
  54. package/dist/components/game/3d/index.js +367 -324
  55. package/dist/components/game/3d/molecules/FeatureMesh3D.d.ts +21 -0
  56. package/dist/components/game/3d/molecules/GameCamera3D.d.ts +35 -0
  57. package/dist/components/game/3d/molecules/Lighting3D.d.ts +10 -2
  58. package/dist/components/game/3d/molecules/SideScene3D.d.ts +31 -0
  59. package/dist/components/game/3d/molecules/TileMesh3D.d.ts +28 -0
  60. package/dist/components/game/3d/molecules/UnitMesh3D.d.ts +29 -0
  61. package/dist/components/game/shared/game3dTheme.d.ts +55 -0
  62. package/dist/components/game/shared/isometric.d.ts +38 -0
  63. package/dist/components/game/shared/isometricTypes.d.ts +4 -0
  64. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  65. package/dist/components/index.cjs +156 -83
  66. package/dist/components/index.css +3 -3
  67. package/dist/components/index.js +160 -87
  68. package/dist/hooks/useGitHub.d.ts +7 -7
  69. package/dist/marketing/index.cjs +2 -2
  70. package/dist/marketing/index.js +2 -2
  71. package/dist/providers/EventBusProvider.d.ts +1 -1
  72. package/dist/providers/SelectionProvider.d.ts +1 -1
  73. package/dist/providers/ServerBridge.d.ts +1 -1
  74. package/dist/providers/index.cjs +164 -84
  75. package/dist/providers/index.css +3 -3
  76. package/dist/providers/index.js +164 -84
  77. package/dist/runtime/index.cjs +164 -84
  78. package/dist/runtime/index.css +3 -3
  79. package/dist/runtime/index.js +164 -84
  80. package/package.json +10 -15
@@ -10322,9 +10322,9 @@ var init_BiologyCanvas = __esm({
10322
10322
  }
10323
10323
  });
10324
10324
 
10325
- // node_modules/katex/dist/katex.min.css
10325
+ // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
10326
10326
  var init_katex_min = __esm({
10327
- "node_modules/katex/dist/katex.min.css"() {
10327
+ "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
10328
10328
  }
10329
10329
  });
10330
10330
  exports.Tabs = void 0;
@@ -16361,7 +16361,7 @@ function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric")
16361
16361
  const tileY = (screenY / (scaledFloorHeight / 2) - adjustedX / (scaledTileWidth / 2)) / 2;
16362
16362
  return { x: Math.round(tileX), y: Math.round(tileY) };
16363
16363
  }
16364
- exports.TILE_WIDTH = void 0; exports.TILE_HEIGHT = void 0; exports.FLOOR_HEIGHT = void 0; exports.DIAMOND_TOP_Y = void 0; exports.FEATURE_COLORS = void 0;
16364
+ exports.TILE_WIDTH = void 0; exports.TILE_HEIGHT = void 0; exports.FLOOR_HEIGHT = void 0; exports.DIAMOND_TOP_Y = void 0; exports.FEATURE_COLORS = void 0; var TERRAIN_COLORS, TEAM_COLORS, TEAM_SHADOW_COLORS, HIGHLIGHT_COLORS, SELECTION_RING_COLOR, GRID_STROKE_COLOR, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS, MINIMAP_UNIT_COLORS, UNIT_LABEL_BG_COLORS, SIDE_PLATFORM_COLORS, SIDE_PLAYER_COLOR, SIDE_PLAYER_EYE_COLOR, SIDE_SKY_GRADIENT_TOP, SIDE_SKY_GRADIENT_BOTTOM, SIDE_GRID_COLOR, SIDE_FX_COLOR, SIDE_PLATFORM_BEVEL_COLOR, SIDE_PLATFORM_SHADOW_COLOR, SIDE_HAZARD_STRIPE_COLOR, SIDE_GOAL_GLOW_COLOR, DEFAULT_BG_COLOR;
16365
16365
  var init_isometric = __esm({
16366
16366
  "components/game/shared/isometric.ts"() {
16367
16367
  exports.TILE_WIDTH = 256;
@@ -16378,9 +16378,70 @@ var init_isometric = __esm({
16378
16378
  mountain: "#78716c",
16379
16379
  default: "#9ca3af"
16380
16380
  };
16381
+ TERRAIN_COLORS = {
16382
+ water: "#3b82f6",
16383
+ mountain: "#78716c",
16384
+ stone: "#9ca3af",
16385
+ default: "#4ade80"
16386
+ };
16387
+ TEAM_COLORS = {
16388
+ player: "#3b82f6",
16389
+ enemy: "#ef4444",
16390
+ neutral: "#6b7280",
16391
+ default: "#6b7280"
16392
+ };
16393
+ TEAM_SHADOW_COLORS = {
16394
+ player: "rgba(0,150,255,0.6)",
16395
+ default: "rgba(255,50,50,0.6)"
16396
+ };
16397
+ HIGHLIGHT_COLORS = {
16398
+ hover: "rgba(255,255,255,0.15)",
16399
+ validMove: "rgba(74,222,128,0.25)",
16400
+ attack: "rgba(239,68,68,0.35)"
16401
+ };
16402
+ SELECTION_RING_COLOR = "rgba(0,200,255,0.8)";
16403
+ GRID_STROKE_COLOR = "rgba(0,0,0,0.2)";
16404
+ BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
16405
+ MINIMAP_TERRAIN_COLORS = {
16406
+ water: "#3b82f6",
16407
+ mountain: "#78716c",
16408
+ default: "#4ade80"
16409
+ };
16410
+ MINIMAP_UNIT_COLORS = {
16411
+ player: "#60a5fa",
16412
+ enemy: "#f87171",
16413
+ neutral: "#9ca3af",
16414
+ default: "#9ca3af"
16415
+ };
16416
+ UNIT_LABEL_BG_COLORS = {
16417
+ player: "rgba(59,130,246,0.9)",
16418
+ enemy: "rgba(239,68,68,0.9)",
16419
+ neutral: "rgba(107,114,128,0.9)",
16420
+ default: "rgba(107,114,128,0.9)"
16421
+ };
16422
+ SIDE_PLATFORM_COLORS = {
16423
+ ground: "#4a7c59",
16424
+ platform: "#7c6b4a",
16425
+ hazard: "#c0392b",
16426
+ goal: "#f1c40f"
16427
+ };
16428
+ SIDE_PLAYER_COLOR = "#3498db";
16429
+ SIDE_PLAYER_EYE_COLOR = "#ffffff";
16430
+ SIDE_SKY_GRADIENT_TOP = "#1a1a2e";
16431
+ SIDE_SKY_GRADIENT_BOTTOM = "#16213e";
16432
+ SIDE_GRID_COLOR = "rgba(255, 255, 255, 0.03)";
16433
+ SIDE_FX_COLOR = "#ffe066";
16434
+ SIDE_PLATFORM_BEVEL_COLOR = "rgba(255,255,255,0.15)";
16435
+ SIDE_PLATFORM_SHADOW_COLOR = "rgba(0,0,0,0.3)";
16436
+ SIDE_HAZARD_STRIPE_COLOR = "#e74c3c";
16437
+ SIDE_GOAL_GLOW_COLOR = "rgba(241, 196, 15, 0.5)";
16438
+ DEFAULT_BG_COLOR = "#5c94fc";
16381
16439
  }
16382
16440
  });
16383
- function SideView({
16441
+ function normalizeBackdrop(bg) {
16442
+ return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
16443
+ }
16444
+ function SideCanvas2D({
16384
16445
  player,
16385
16446
  platforms,
16386
16447
  worldWidth,
@@ -16389,7 +16450,7 @@ function SideView({
16389
16450
  canvasHeight,
16390
16451
  follow,
16391
16452
  bgColor,
16392
- backgroundImage,
16453
+ backgroundImage: backgroundImageRaw,
16393
16454
  playerSprite,
16394
16455
  tileSprites,
16395
16456
  effects,
@@ -16397,27 +16458,22 @@ function SideView({
16397
16458
  keyUpMap,
16398
16459
  className
16399
16460
  }) {
16461
+ const backgroundImage = normalizeBackdrop(backgroundImageRaw);
16400
16462
  const canvasRef = React75.useRef(null);
16401
16463
  const eventBus = useEventBus();
16402
16464
  const keysRef = React75.useRef(/* @__PURE__ */ new Set());
16403
- const imageCache2 = React75.useRef(/* @__PURE__ */ new Map());
16404
- const [loadedImages, setLoadedImages] = React75.useState(/* @__PURE__ */ new Set());
16405
- const loadImage = React75.useCallback((url) => {
16406
- if (!url) return null;
16407
- const cached = imageCache2.current.get(url);
16408
- if (cached?.complete && cached.naturalWidth > 0) {
16409
- if (!loadedImages.has(url)) setLoadedImages((prev) => new Set(prev).add(url));
16410
- return cached;
16411
- }
16412
- if (!cached) {
16413
- const img = new Image();
16414
- img.crossOrigin = "anonymous";
16415
- img.src = url;
16416
- img.onload = () => setLoadedImages((prev) => new Set(prev).add(url));
16417
- imageCache2.current.set(url, img);
16465
+ const spriteUrls = React75.useMemo(() => {
16466
+ const urls = [];
16467
+ if (backgroundImage?.url) urls.push(backgroundImage.url);
16468
+ if (playerSprite?.url) urls.push(playerSprite.url);
16469
+ if (tileSprites) {
16470
+ for (const asset of Object.values(tileSprites)) {
16471
+ if (asset?.url) urls.push(asset.url);
16472
+ }
16418
16473
  }
16419
- return null;
16420
- }, [loadedImages]);
16474
+ return urls;
16475
+ }, [backgroundImage, playerSprite, tileSprites]);
16476
+ const { getImage } = useImageCache(spriteUrls);
16421
16477
  React75.useEffect(() => {
16422
16478
  if (typeof window === "undefined") return;
16423
16479
  const canvas = canvasRef.current;
@@ -16530,7 +16586,7 @@ function SideView({
16530
16586
  camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
16531
16587
  camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
16532
16588
  }
16533
- const bgImage = bgImg ? loadImage(bgImg.url) : null;
16589
+ const bgImage = bgImg ? getImage(bgImg.url) : void 0;
16534
16590
  const bgSrc = bgImage ? resolveAssetSource(bgImage, bgImg, NOOP) : null;
16535
16591
  if (bgSrc) {
16536
16592
  blit(ctx, bgSrc, 0, 0, cw, ch);
@@ -16541,12 +16597,12 @@ function SideView({
16541
16597
  ctx.fillRect(0, 0, cw, ch);
16542
16598
  } else {
16543
16599
  const grad = ctx.createLinearGradient(0, 0, 0, ch);
16544
- grad.addColorStop(0, SKY_GRADIENT_TOP);
16545
- grad.addColorStop(1, SKY_GRADIENT_BOTTOM);
16600
+ grad.addColorStop(0, SIDE_SKY_GRADIENT_TOP);
16601
+ grad.addColorStop(1, SIDE_SKY_GRADIENT_BOTTOM);
16546
16602
  ctx.fillStyle = grad;
16547
16603
  ctx.fillRect(0, 0, cw, ch);
16548
16604
  }
16549
- ctx.strokeStyle = GRID_COLOR;
16605
+ ctx.strokeStyle = SIDE_GRID_COLOR;
16550
16606
  ctx.lineWidth = 1;
16551
16607
  const gridSize = 32;
16552
16608
  for (let gx = -camX % gridSize; gx < cw; gx += gridSize) {
@@ -16566,7 +16622,7 @@ function SideView({
16566
16622
  const platY = plat.y - camY;
16567
16623
  const platType = plat.type ?? "ground";
16568
16624
  const spriteAsset = tSprites?.[platType];
16569
- const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
16625
+ const tileImg = spriteAsset ? getImage(spriteAsset.url) : void 0;
16570
16626
  const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
16571
16627
  if (tileSrc) {
16572
16628
  const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
@@ -16581,15 +16637,15 @@ function SideView({
16581
16637
  ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
16582
16638
  }
16583
16639
  } else {
16584
- const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
16640
+ const color = SIDE_PLATFORM_COLORS[platType] ?? SIDE_PLATFORM_COLORS.ground;
16585
16641
  ctx.fillStyle = color;
16586
16642
  ctx.fillRect(platX, platY, plat.width, plat.height);
16587
- ctx.fillStyle = "rgba(255, 255, 255, 0.15)";
16643
+ ctx.fillStyle = SIDE_PLATFORM_BEVEL_COLOR;
16588
16644
  ctx.fillRect(platX, platY, plat.width, 3);
16589
- ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
16645
+ ctx.fillStyle = SIDE_PLATFORM_SHADOW_COLOR;
16590
16646
  ctx.fillRect(platX, platY + plat.height - 2, plat.width, 2);
16591
16647
  if (platType === "hazard") {
16592
- ctx.strokeStyle = "#e74c3c";
16648
+ ctx.strokeStyle = SIDE_HAZARD_STRIPE_COLOR;
16593
16649
  ctx.lineWidth = 2;
16594
16650
  for (let sx = platX; sx < platX + plat.width; sx += 12) {
16595
16651
  ctx.beginPath();
@@ -16599,7 +16655,7 @@ function SideView({
16599
16655
  }
16600
16656
  }
16601
16657
  if (platType === "goal") {
16602
- ctx.fillStyle = "rgba(241, 196, 15, 0.5)";
16658
+ ctx.fillStyle = SIDE_GOAL_GLOW_COLOR;
16603
16659
  ctx.beginPath();
16604
16660
  ctx.arc(platX + plat.width / 2, platY - 10, 8, 0, Math.PI * 2);
16605
16661
  ctx.fill();
@@ -16611,7 +16667,7 @@ function SideView({
16611
16667
  const ppx = px - camX;
16612
16668
  const ppy = py - camY;
16613
16669
  const facingRight = auth.facingRight ?? true;
16614
- const playerImg = pSprite ? loadImage(pSprite.url) : null;
16670
+ const playerImg = pSprite ? getImage(pSprite.url) : void 0;
16615
16671
  const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
16616
16672
  if (playerSrc) {
16617
16673
  ctx.save();
@@ -16624,7 +16680,7 @@ function SideView({
16624
16680
  }
16625
16681
  ctx.restore();
16626
16682
  } else {
16627
- ctx.fillStyle = PLAYER_COLOR;
16683
+ ctx.fillStyle = SIDE_PLAYER_COLOR;
16628
16684
  const radius = Math.min(pw, ph) * 0.25;
16629
16685
  ctx.beginPath();
16630
16686
  ctx.moveTo(ppx + radius, ppy);
@@ -16640,7 +16696,7 @@ function SideView({
16640
16696
  const eyeY = ppy + ph * 0.3;
16641
16697
  const eyeSize = 3;
16642
16698
  const eyeOffsetX = facingRight ? pw * 0.55 : pw * 0.2;
16643
- ctx.fillStyle = PLAYER_EYE_COLOR;
16699
+ ctx.fillStyle = SIDE_PLAYER_EYE_COLOR;
16644
16700
  ctx.beginPath();
16645
16701
  ctx.arc(ppx + eyeOffsetX, eyeY, eyeSize, 0, Math.PI * 2);
16646
16702
  ctx.fill();
@@ -16654,7 +16710,7 @@ function SideView({
16654
16710
  const alpha = Math.min(1, fx.ttl / 4);
16655
16711
  const prev = ctx.globalAlpha;
16656
16712
  ctx.globalAlpha = alpha;
16657
- ctx.fillStyle = "#ffe066";
16713
+ ctx.fillStyle = SIDE_FX_COLOR;
16658
16714
  ctx.beginPath();
16659
16715
  ctx.arc(fxScreenX, fxScreenY, 12, 0, Math.PI * 2);
16660
16716
  ctx.fill();
@@ -16662,7 +16718,7 @@ function SideView({
16662
16718
  }
16663
16719
  };
16664
16720
  return interp.startLoop(drawFrame);
16665
- }, [interp.startLoop, loadImage]);
16721
+ }, [interp.startLoop, getImage]);
16666
16722
  return /* @__PURE__ */ jsxRuntime.jsx(
16667
16723
  "canvas",
16668
16724
  {
@@ -16674,6 +16730,33 @@ function SideView({
16674
16730
  }
16675
16731
  );
16676
16732
  }
16733
+ var NOOP;
16734
+ var init_SideCanvas2D = __esm({
16735
+ "components/game/2d/molecules/SideCanvas2D.tsx"() {
16736
+ "use client";
16737
+ init_cn();
16738
+ init_useEventBus();
16739
+ init_useImageCache();
16740
+ init_atlasSlice();
16741
+ init_useRenderInterpolation();
16742
+ init_verificationRegistry();
16743
+ init_isometric();
16744
+ NOOP = () => {
16745
+ };
16746
+ SideCanvas2D.displayName = "SideCanvas2D";
16747
+ }
16748
+ });
16749
+ function normalizeBackdrop2(bg) {
16750
+ return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
16751
+ }
16752
+ function resolveTileFallbackColor(tile) {
16753
+ const override = tile.color;
16754
+ return override ?? TERRAIN_COLORS[tile.terrain ?? ""] ?? TERRAIN_COLORS.default;
16755
+ }
16756
+ function resolveUnitTeamColor(unit) {
16757
+ const override = unit.tint;
16758
+ return override ?? TEAM_COLORS[unit.team ?? ""] ?? TEAM_COLORS.default;
16759
+ }
16677
16760
  function Canvas2D({
16678
16761
  // Closed-circuit
16679
16762
  className,
@@ -16688,7 +16771,7 @@ function Canvas2D({
16688
16771
  effects: _effectsPropRaw = [],
16689
16772
  platforms,
16690
16773
  player,
16691
- backgroundImage,
16774
+ backgroundImage: backgroundImageRaw,
16692
16775
  // Interaction state
16693
16776
  selectedUnitId = null,
16694
16777
  validMoves = [],
@@ -16723,12 +16806,13 @@ function Canvas2D({
16723
16806
  // Side-view asset resolution
16724
16807
  playerSprite,
16725
16808
  tileSprites,
16726
- bgColor = "#5c94fc",
16809
+ bgColor = DEFAULT_BG_COLOR,
16727
16810
  worldWidth = 800,
16728
16811
  worldHeight = 400,
16729
16812
  // Remote asset loading
16730
16813
  assetManifest
16731
16814
  }) {
16815
+ const backgroundImage = normalizeBackdrop2(backgroundImageRaw);
16732
16816
  const isSide = projection === "side";
16733
16817
  const isFree = projection === "free";
16734
16818
  const flatLike = projection === "hex" || projection === "flat" || isFree;
@@ -16912,7 +16996,7 @@ function Canvas2D({
16912
16996
  return sortedTiles.map((t2) => ({
16913
16997
  x: t2.x,
16914
16998
  y: t2.y,
16915
- color: t2.terrain === "water" ? "#3b82f6" : t2.terrain === "mountain" ? "#78716c" : "#4ade80"
16999
+ color: MINIMAP_TERRAIN_COLORS[t2.terrain ?? ""] ?? MINIMAP_TERRAIN_COLORS.default
16916
17000
  }));
16917
17001
  }, [showMinimap, sortedTiles]);
16918
17002
  const miniMapUnits = React75.useMemo(() => {
@@ -16920,7 +17004,7 @@ function Canvas2D({
16920
17004
  return units.filter((u) => u.position).map((u) => ({
16921
17005
  x: u.position.x,
16922
17006
  y: u.position.y,
16923
- color: u.team === "player" ? "#60a5fa" : u.team === "enemy" ? "#f87171" : "#9ca3af",
17007
+ color: MINIMAP_UNIT_COLORS[u.team ?? ""] ?? MINIMAP_UNIT_COLORS.default,
16924
17008
  isPlayer: u.team === "player"
16925
17009
  }));
16926
17010
  }, [showMinimap, units]);
@@ -16957,7 +17041,7 @@ function Canvas2D({
16957
17041
  }
16958
17042
  }
16959
17043
  } else {
16960
- ctx.fillStyle = "#1a1a2e";
17044
+ ctx.fillStyle = BACKGROUND_FALLBACK_COLOR;
16961
17045
  ctx.fillRect(0, 0, viewportSize.width, viewportSize.height);
16962
17046
  }
16963
17047
  if (sortedTiles.length === 0 && units.length === 0 && features.length === 0) return;
@@ -16987,15 +17071,15 @@ function Canvas2D({
16987
17071
  } else if (img && img.naturalWidth === 0) {
16988
17072
  ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
16989
17073
  } else if (squareGrid) {
16990
- ctx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : tile.terrain === "stone" ? "#9ca3af" : "#4ade80";
17074
+ ctx.fillStyle = resolveTileFallbackColor(tile);
16991
17075
  ctx.fillRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
16992
- ctx.strokeStyle = "rgba(0,0,0,0.2)";
17076
+ ctx.strokeStyle = GRID_STROKE_COLOR;
16993
17077
  ctx.lineWidth = 1;
16994
17078
  ctx.strokeRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
16995
17079
  } else {
16996
17080
  const centerX = pos.x + scaledTileWidth / 2;
16997
17081
  const topY = pos.y + scaledDiamondTopY;
16998
- ctx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : tile.terrain === "stone" ? "#9ca3af" : "#4ade80";
17082
+ ctx.fillStyle = resolveTileFallbackColor(tile);
16999
17083
  ctx.beginPath();
17000
17084
  ctx.moveTo(centerX, topY);
17001
17085
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -17003,7 +17087,7 @@ function Canvas2D({
17003
17087
  ctx.lineTo(pos.x, topY + scaledFloorHeight / 2);
17004
17088
  ctx.closePath();
17005
17089
  ctx.fill();
17006
- ctx.strokeStyle = "rgba(0,0,0,0.2)";
17090
+ ctx.strokeStyle = GRID_STROKE_COLOR;
17007
17091
  ctx.lineWidth = 1;
17008
17092
  ctx.stroke();
17009
17093
  }
@@ -17024,11 +17108,11 @@ function Canvas2D({
17024
17108
  ctx.fill();
17025
17109
  };
17026
17110
  if (hoveredTile && hoveredTile.x === tile.x && hoveredTile.y === tile.y) {
17027
- drawHighlight("rgba(255, 255, 255, 0.15)");
17111
+ drawHighlight(HIGHLIGHT_COLORS.hover);
17028
17112
  }
17029
17113
  const tileKey = `${tile.x},${tile.y}`;
17030
- if (validMoveSet.has(tileKey)) drawHighlight("rgba(74, 222, 128, 0.25)");
17031
- if (attackTargetSet.has(tileKey)) drawHighlight("rgba(239, 68, 68, 0.35)");
17114
+ if (validMoveSet.has(tileKey)) drawHighlight(HIGHLIGHT_COLORS.validMove);
17115
+ if (attackTargetSet.has(tileKey)) drawHighlight(HIGHLIGHT_COLORS.attack);
17032
17116
  if (debug2) {
17033
17117
  const centerX = pos.x + scaledTileWidth / 2;
17034
17118
  const centerY = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledFloorHeight / 2 + scaledDiamondTopY;
@@ -17102,9 +17186,9 @@ function Canvas2D({
17102
17186
  const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
17103
17187
  const unitIsSheet = unit.spriteSheet?.url !== void 0;
17104
17188
  const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
17105
- const SHEET_ROWS = 5;
17106
17189
  const sheetFrameW = img ? img.naturalWidth / exports.SHEET_COLUMNS : 0;
17107
- const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
17190
+ const sheetFrameH = img ? img.naturalHeight / LEGACY_SHEET_ROWS : 0;
17191
+ const legacyFrame = frameRect(0, 0, exports.SHEET_COLUMNS, sheetFrameW, sheetFrameH);
17108
17192
  const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
17109
17193
  const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
17110
17194
  const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
@@ -17122,17 +17206,16 @@ function Canvas2D({
17122
17206
  ctx.globalAlpha = 0.25;
17123
17207
  if (img) {
17124
17208
  if (unitIsSheet) {
17125
- ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
17209
+ ctx.drawImage(img, legacyFrame.sx, legacyFrame.sy, legacyFrame.sw, legacyFrame.sh, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
17126
17210
  } else if (unitSrc) {
17127
17211
  blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
17128
17212
  } else {
17129
17213
  ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
17130
17214
  }
17131
17215
  } else {
17132
- const color = unit.team === "player" ? "#3b82f6" : unit.team === "enemy" ? "#ef4444" : "#6b7280";
17133
17216
  ctx.beginPath();
17134
17217
  ctx.arc(ghostCenterX, ghostGroundY - 16 * scale, 20 * scale, 0, Math.PI * 2);
17135
- ctx.fillStyle = color;
17218
+ ctx.fillStyle = resolveUnitTeamColor(unit);
17136
17219
  ctx.fill();
17137
17220
  }
17138
17221
  ctx.restore();
@@ -17140,7 +17223,7 @@ function Canvas2D({
17140
17223
  if (isSelected) {
17141
17224
  ctx.beginPath();
17142
17225
  ctx.ellipse(centerX, groundY, drawW / 2 + 4 * scale, 12 * scale, 0, 0, Math.PI * 2);
17143
- ctx.strokeStyle = "rgba(0, 200, 255, 0.8)";
17226
+ ctx.strokeStyle = SELECTION_RING_COLOR;
17144
17227
  ctx.lineWidth = 3;
17145
17228
  ctx.stroke();
17146
17229
  }
@@ -17157,7 +17240,7 @@ function Canvas2D({
17157
17240
  const spriteY = groundY - fDrawH - (frame.applyBreathing ? breatheOffset : 0);
17158
17241
  ctx.save();
17159
17242
  if (unit.team) {
17160
- ctx.shadowColor = unit.team === "player" ? "rgba(0, 150, 255, 0.6)" : "rgba(255, 50, 50, 0.6)";
17243
+ ctx.shadowColor = TEAM_SHADOW_COLORS[unit.team] ?? TEAM_SHADOW_COLORS.default;
17161
17244
  ctx.shadowBlur = 12 * scale;
17162
17245
  }
17163
17246
  if (frame.flipX) {
@@ -17172,7 +17255,7 @@ function Canvas2D({
17172
17255
  const spriteY = groundY - drawH - breatheOffset;
17173
17256
  const drawUnit = (x) => {
17174
17257
  if (unitIsSheet) {
17175
- ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
17258
+ ctx.drawImage(img, legacyFrame.sx, legacyFrame.sy, legacyFrame.sw, legacyFrame.sh, x, spriteY, drawW, drawH);
17176
17259
  } else if (unitSrc) {
17177
17260
  blit(ctx, unitSrc, x, spriteY, drawW, drawH);
17178
17261
  } else {
@@ -17181,7 +17264,7 @@ function Canvas2D({
17181
17264
  };
17182
17265
  if (unit.team) {
17183
17266
  ctx.save();
17184
- ctx.shadowColor = unit.team === "player" ? "rgba(0, 150, 255, 0.6)" : "rgba(255, 50, 50, 0.6)";
17267
+ ctx.shadowColor = TEAM_SHADOW_COLORS[unit.team] ?? TEAM_SHADOW_COLORS.default;
17185
17268
  ctx.shadowBlur = 12 * scale;
17186
17269
  drawUnit(centerX - drawW / 2);
17187
17270
  ctx.restore();
@@ -17189,10 +17272,9 @@ function Canvas2D({
17189
17272
  drawUnit(centerX - drawW / 2);
17190
17273
  }
17191
17274
  } else {
17192
- const color = unit.team === "player" ? "#3b82f6" : unit.team === "enemy" ? "#ef4444" : "#6b7280";
17193
17275
  ctx.beginPath();
17194
17276
  ctx.arc(centerX, groundY - 20 * scale - breatheOffset, 20 * scale, 0, Math.PI * 2);
17195
- ctx.fillStyle = color;
17277
+ ctx.fillStyle = resolveUnitTeamColor(unit);
17196
17278
  ctx.fill();
17197
17279
  ctx.strokeStyle = "rgba(255,255,255,0.8)";
17198
17280
  ctx.lineWidth = 2;
@@ -17431,7 +17513,7 @@ function Canvas2D({
17431
17513
  }
17432
17514
  if (isSide) {
17433
17515
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { ref: containerRef, className: cn("relative overflow-hidden w-full h-full", className), children: /* @__PURE__ */ jsxRuntime.jsx(
17434
- SideView,
17516
+ SideCanvas2D,
17435
17517
  {
17436
17518
  player,
17437
17519
  platforms: platforms && platforms.length ? platforms : DEFAULT_PLATFORMS,
@@ -17529,7 +17611,7 @@ function Canvas2D({
17529
17611
  {
17530
17612
  as: "span",
17531
17613
  className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
17532
- style: { background: unit.team === "player" ? "rgba(59,130,246,0.9)" : unit.team === "enemy" ? "rgba(239,68,68,0.9)" : "rgba(107,114,128,0.9)" },
17614
+ style: { background: UNIT_LABEL_BG_COLORS[unit.team ?? ""] ?? UNIT_LABEL_BG_COLORS.default },
17533
17615
  children: unit.name
17534
17616
  }
17535
17617
  ),
@@ -17553,7 +17635,7 @@ function Canvas2D({
17553
17635
  }
17554
17636
  );
17555
17637
  }
17556
- var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
17638
+ var LEGACY_SHEET_ROWS, DEFAULT_PLATFORMS;
17557
17639
  var init_Canvas2D = __esm({
17558
17640
  "components/game/2d/molecules/Canvas2D.tsx"() {
17559
17641
  "use client";
@@ -17575,19 +17657,9 @@ var init_Canvas2D = __esm({
17575
17657
  init_verificationRegistry();
17576
17658
  init_isometric();
17577
17659
  init_spriteSheetConstants();
17578
- PLATFORM_COLORS = {
17579
- ground: "#4a7c59",
17580
- platform: "#7c6b4a",
17581
- hazard: "#c0392b",
17582
- goal: "#f1c40f"
17583
- };
17584
- NOOP = () => {
17585
- };
17586
- PLAYER_COLOR = "#3498db";
17587
- PLAYER_EYE_COLOR = "#ffffff";
17588
- SKY_GRADIENT_TOP = "#1a1a2e";
17589
- SKY_GRADIENT_BOTTOM = "#16213e";
17590
- GRID_COLOR = "rgba(255, 255, 255, 0.03)";
17660
+ init_spriteAnimation();
17661
+ init_SideCanvas2D();
17662
+ LEGACY_SHEET_ROWS = Object.keys(exports.SPRITE_SHEET_LAYOUT).length;
17591
17663
  DEFAULT_PLATFORMS = [
17592
17664
  { x: 0, y: 368, width: 800, height: 32, type: "ground" },
17593
17665
  { x: 150, y: 280, width: 160, height: 16, type: "platform" },
@@ -26768,8 +26840,9 @@ var init_LineChart = __esm({
26768
26840
  const safeData = data ?? [];
26769
26841
  const sortedData = React75.useMemo(() => {
26770
26842
  if (safeData.length === 0) return [];
26843
+ if (!safeData.some((d) => d.date != null)) return [...safeData];
26771
26844
  return [...safeData].sort(
26772
- (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
26845
+ (a, b) => new Date(a.date ?? 0).getTime() - new Date(b.date ?? 0).getTime()
26773
26846
  );
26774
26847
  }, [safeData]);
26775
26848
  const points = React75.useMemo(() => {
@@ -32208,13 +32281,13 @@ var init_MapView = __esm({
32208
32281
  shadowSize: [41, 41]
32209
32282
  });
32210
32283
  L.Marker.prototype.options.icon = defaultIcon;
32211
- const { useEffect: useEffect70, useRef: useRef66, useCallback: useCallback113, useState: useState108 } = React75__namespace.default;
32284
+ const { useEffect: useEffect71, useRef: useRef67, useCallback: useCallback114, useState: useState108 } = React75__namespace.default;
32212
32285
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
32213
32286
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
32214
32287
  function MapUpdater({ centerLat, centerLng, zoom }) {
32215
32288
  const map = useMap();
32216
- const prevRef = useRef66({ centerLat, centerLng, zoom });
32217
- useEffect70(() => {
32289
+ const prevRef = useRef67({ centerLat, centerLng, zoom });
32290
+ useEffect71(() => {
32218
32291
  const prev = prevRef.current;
32219
32292
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
32220
32293
  map.setView([centerLat, centerLng], zoom);
@@ -32225,7 +32298,7 @@ var init_MapView = __esm({
32225
32298
  }
32226
32299
  function MapClickHandler({ onMapClick }) {
32227
32300
  const map = useMap();
32228
- useEffect70(() => {
32301
+ useEffect71(() => {
32229
32302
  if (!onMapClick) return;
32230
32303
  const handler = (e) => {
32231
32304
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -32254,7 +32327,7 @@ var init_MapView = __esm({
32254
32327
  }) {
32255
32328
  const eventBus = useEventBus2();
32256
32329
  const [clickedPosition, setClickedPosition] = useState108(null);
32257
- const handleMapClick = useCallback113((lat, lng) => {
32330
+ const handleMapClick = useCallback114((lat, lng) => {
32258
32331
  if (showClickedPin) {
32259
32332
  setClickedPosition({ lat, lng });
32260
32333
  }
@@ -32263,7 +32336,7 @@ var init_MapView = __esm({
32263
32336
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
32264
32337
  }
32265
32338
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
32266
- const handleMarkerClick = useCallback113((marker) => {
32339
+ const handleMarkerClick = useCallback114((marker) => {
32267
32340
  onMarkerClick?.(marker);
32268
32341
  if (markerClickEvent) {
32269
32342
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -1,4 +1,4 @@
1
- /* node_modules/katex/dist/katex.min.css */
1
+ /* node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css */
2
2
  @font-face {
3
3
  font-display: block;
4
4
  font-family: KaTeX_AMS;
@@ -214,11 +214,11 @@
214
214
  border-color: currentColor;
215
215
  }
216
216
  .katex .katex-version:after {
217
- content: "0.16.45";
217
+ content: "0.16.47";
218
218
  }
219
219
  .katex .katex-mathml {
220
- clip: rect(1px, 1px, 1px, 1px);
221
220
  border: 0;
221
+ clip-path: inset(50%);
222
222
  height: 1px;
223
223
  overflow: hidden;
224
224
  padding: 0;