@almadar/ui 5.54.0 → 5.56.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.
@@ -8379,6 +8379,16 @@ var init_Skeleton = __esm({
8379
8379
  Skeleton.displayName = "Skeleton";
8380
8380
  }
8381
8381
  });
8382
+ function isKnownPattern(type) {
8383
+ return type in componentMapping;
8384
+ }
8385
+ var componentMapping;
8386
+ var init_pattern_resolver = __esm({
8387
+ "renderer/pattern-resolver.ts"() {
8388
+ createLogger("almadar:ui:pattern-resolver");
8389
+ componentMapping = {};
8390
+ }
8391
+ });
8382
8392
  function executeClientEffects(effects, config) {
8383
8393
  if (!effects || effects.length === 0) {
8384
8394
  return;
@@ -8387,7 +8397,7 @@ function executeClientEffects(effects, config) {
8387
8397
  try {
8388
8398
  executeEffect(effect, config);
8389
8399
  } catch (error) {
8390
- log3.error("Error executing effect", () => ({
8400
+ log4.error("Error executing effect", () => ({
8391
8401
  effect: JSON.stringify(effect),
8392
8402
  error: error instanceof Error ? error : String(error)
8393
8403
  }));
@@ -8419,7 +8429,7 @@ function executeEffect(effect, config) {
8419
8429
  break;
8420
8430
  }
8421
8431
  default:
8422
- log3.warn("Unknown effect type", { effectType: String(effectType) });
8432
+ log4.warn("Unknown effect type", { effectType: String(effectType) });
8423
8433
  }
8424
8434
  }
8425
8435
  function executeRenderUI(slot, patternConfig, config) {
@@ -8434,10 +8444,10 @@ function executeNotify(message, options, config) {
8434
8444
  function executeEmit(event, payload, config) {
8435
8445
  config.eventBus.emit(event, payload);
8436
8446
  }
8437
- var log3;
8447
+ var log4;
8438
8448
  var init_client_effect_executor = __esm({
8439
8449
  "renderer/client-effect-executor.ts"() {
8440
- log3 = createLogger("almadar:ui:effects:client");
8450
+ log4 = createLogger("almadar:ui:effects:client");
8441
8451
  }
8442
8452
  });
8443
8453
 
@@ -8598,12 +8608,12 @@ function useOfflineExecutor(options) {
8598
8608
  clearQueue
8599
8609
  };
8600
8610
  }
8601
- var log4, effectIdCounter, OfflineExecutor;
8611
+ var log5, effectIdCounter, OfflineExecutor;
8602
8612
  var init_offline_executor = __esm({
8603
8613
  "renderer/offline-executor.ts"() {
8604
8614
  "use client";
8605
8615
  init_client_effect_executor();
8606
- log4 = createLogger("almadar:ui:effects:offline");
8616
+ log5 = createLogger("almadar:ui:effects:offline");
8607
8617
  effectIdCounter = 0;
8608
8618
  OfflineExecutor = class {
8609
8619
  constructor(config) {
@@ -8657,7 +8667,7 @@ var init_offline_executor = __esm({
8657
8667
  this.state.syncQueue = JSON.parse(stored);
8658
8668
  }
8659
8669
  } catch (error) {
8660
- log4.warn("Failed to load sync queue", { error: error instanceof Error ? error : String(error) });
8670
+ log5.warn("Failed to load sync queue", { error: error instanceof Error ? error : String(error) });
8661
8671
  }
8662
8672
  }
8663
8673
  /**
@@ -8668,7 +8678,7 @@ var init_offline_executor = __esm({
8668
8678
  try {
8669
8679
  this.storage.setItem("orbital-offline-queue", JSON.stringify(this.state.syncQueue));
8670
8680
  } catch (error) {
8671
- log4.warn("Failed to save sync queue", { error: error instanceof Error ? error : String(error) });
8681
+ log5.warn("Failed to save sync queue", { error: error instanceof Error ? error : String(error) });
8672
8682
  }
8673
8683
  }
8674
8684
  /**
@@ -8738,7 +8748,7 @@ var init_offline_executor = __esm({
8738
8748
  this.queueForSync(type, { args, event, payload });
8739
8749
  break;
8740
8750
  default:
8741
- log4.warn("Unknown effect type", { type });
8751
+ log5.warn("Unknown effect type", { type });
8742
8752
  }
8743
8753
  }
8744
8754
  }
@@ -8843,6 +8853,7 @@ var init_offline_executor = __esm({
8843
8853
  // renderer/index.ts
8844
8854
  var init_renderer = __esm({
8845
8855
  "renderer/index.ts"() {
8856
+ init_pattern_resolver();
8846
8857
  init_slot_definitions();
8847
8858
  }
8848
8859
  });
@@ -10546,7 +10557,7 @@ function recordTransition(trace) {
10546
10557
  ...trace,
10547
10558
  id: `t-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
10548
10559
  };
10549
- log5.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10560
+ log6.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10550
10561
  getState().transitions.push(entry);
10551
10562
  if (getState().transitions.length > MAX_TRANSITIONS) {
10552
10563
  getState().transitions.shift();
@@ -10615,7 +10626,7 @@ function getTraitSnapshots() {
10615
10626
  try {
10616
10627
  snapshots.push(getter());
10617
10628
  } catch (err) {
10618
- log5.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10629
+ log6.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10619
10630
  }
10620
10631
  }
10621
10632
  return snapshots;
@@ -10678,12 +10689,12 @@ function waitForTransition(event, timeoutMs = 1e4) {
10678
10689
  }
10679
10690
  function bindEventBus(eventBus) {
10680
10691
  if (typeof window === "undefined") return;
10681
- log5.info("bindEventBus", { hasOnAny: !!eventBus.onAny });
10692
+ log6.info("bindEventBus", { hasOnAny: !!eventBus.onAny });
10682
10693
  exposeOnWindow();
10683
10694
  if (window.__orbitalVerification) {
10684
10695
  window.__orbitalVerification.sendEvent = (event, payload, traitScope) => {
10685
10696
  const prefixed = event.startsWith("UI:") ? event : traitScope ? `UI:${traitScope}.${event}` : `UI:${event}`;
10686
- log5.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
10697
+ log6.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
10687
10698
  eventBus.emit(prefixed, payload);
10688
10699
  };
10689
10700
  const eventLog = [];
@@ -10732,10 +10743,10 @@ function updateAssetStatus(url, status) {
10732
10743
  window.__orbitalVerification.assetStatus[url] = status;
10733
10744
  }
10734
10745
  }
10735
- var log5, MAX_TRANSITIONS;
10746
+ var log6, MAX_TRANSITIONS;
10736
10747
  var init_verificationRegistry = __esm({
10737
10748
  "lib/verificationRegistry.ts"() {
10738
- log5 = createLogger("almadar:bridge");
10749
+ log6 = createLogger("almadar:bridge");
10739
10750
  MAX_TRANSITIONS = 500;
10740
10751
  exposeOnWindow();
10741
10752
  }
@@ -11086,6 +11097,8 @@ function IsometricCanvas({
11086
11097
  showMinimap = true,
11087
11098
  enableCamera = true,
11088
11099
  unitScale = 1,
11100
+ spriteHeightRatio = 1.5,
11101
+ spriteMaxWidthRatio = 0.6,
11089
11102
  // Asset resolution
11090
11103
  getTerrainSprite,
11091
11104
  getFeatureSprite,
@@ -11476,8 +11489,8 @@ function IsometricCanvas({
11476
11489
  const breatheOffset = 0.8 * scale * (1 + Math.sin(animTime * 2e-3 + (unit.position.x * 3.7 + unit.position.y * 5.3)));
11477
11490
  const unitSpriteUrl = resolveUnitSpriteUrl(unit);
11478
11491
  const img = unitSpriteUrl ? getImage(unitSpriteUrl) : null;
11479
- const unitDrawH = scaledFloorHeight * 1.5 * unitScale;
11480
- const maxUnitW = scaledTileWidth * 0.6 * unitScale;
11492
+ const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
11493
+ const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
11481
11494
  const ar = img ? img.naturalWidth / img.naturalHeight : 0.5;
11482
11495
  let drawH = unitDrawH;
11483
11496
  let drawW = unitDrawH * ar;
@@ -11861,6 +11874,8 @@ function BattleBoard({
11861
11874
  assetManifest: propAssetManifest,
11862
11875
  scale = 0.45,
11863
11876
  unitScale = 1,
11877
+ spriteHeightRatio = 1.5,
11878
+ spriteMaxWidthRatio = 0.6,
11864
11879
  header,
11865
11880
  sidebar,
11866
11881
  actions,
@@ -12151,7 +12166,9 @@ function BattleBoard({
12151
12166
  hasActiveEffects: hasActiveEffects2,
12152
12167
  effectSpriteUrls,
12153
12168
  resolveUnitFrame,
12154
- unitScale
12169
+ unitScale,
12170
+ spriteHeightRatio,
12171
+ spriteMaxWidthRatio
12155
12172
  }
12156
12173
  ),
12157
12174
  overlay && overlay(ctx)
@@ -13029,7 +13046,7 @@ var init_avl_elk_layout = __esm({
13029
13046
  elk = new ELK();
13030
13047
  }
13031
13048
  });
13032
- var log6, SWIM_GUTTER, CENTER_W, BehaviorView;
13049
+ var log7, SWIM_GUTTER, CENTER_W, BehaviorView;
13033
13050
  var init_BehaviorView = __esm({
13034
13051
  "components/avl/molecules/BehaviorView.tsx"() {
13035
13052
  "use client";
@@ -13038,7 +13055,7 @@ var init_BehaviorView = __esm({
13038
13055
  init_AvlSwimLane();
13039
13056
  init_types();
13040
13057
  init_avl_elk_layout();
13041
- log6 = createLogger("almadar:ui:avl:behavior-view");
13058
+ log7 = createLogger("almadar:ui:avl:behavior-view");
13042
13059
  SWIM_GUTTER = 120;
13043
13060
  CENTER_W = 360;
13044
13061
  BehaviorView = ({ data }) => {
@@ -13049,7 +13066,7 @@ var init_BehaviorView = __esm({
13049
13066
  const dataKey = useMemo(() => JSON.stringify(traitData), [traitData]);
13050
13067
  useEffect(() => {
13051
13068
  if (!traitData) return;
13052
- computeTraitLayout(traitData).then(setLayout).catch((err) => log6.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
13069
+ computeTraitLayout(traitData).then(setLayout).catch((err) => log7.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
13053
13070
  }, [dataKey]);
13054
13071
  if (!traitData) {
13055
13072
  return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("avl.noTraitData") });
@@ -13460,7 +13477,7 @@ function generateDiff(oldVal, newVal) {
13460
13477
  }
13461
13478
  return diff;
13462
13479
  }
13463
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13480
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log8, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13464
13481
  var init_CodeBlock = __esm({
13465
13482
  "components/core/molecules/markdown/CodeBlock.tsx"() {
13466
13483
  init_cn();
@@ -13543,7 +13560,7 @@ var init_CodeBlock = __esm({
13543
13560
  "lolo-op-async": { color: ORB_COLORS.dark.async }
13544
13561
  };
13545
13562
  loloStyle = { ...dark, ...loloStyleOverrides };
13546
- log7 = createLogger("almadar:ui:markdown-code");
13563
+ log8 = createLogger("almadar:ui:markdown-code");
13547
13564
  CODE_LANGUAGES = [
13548
13565
  "text",
13549
13566
  "json",
@@ -13807,7 +13824,7 @@ var init_CodeBlock = __esm({
13807
13824
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
13808
13825
  setTimeout(() => setCopied(false), 2e3);
13809
13826
  } catch (err) {
13810
- log7.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13827
+ log8.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13811
13828
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
13812
13829
  }
13813
13830
  };
@@ -17688,14 +17705,14 @@ function useSafeEventBus2() {
17688
17705
  } };
17689
17706
  }
17690
17707
  }
17691
- var log8, lookStyles4, ButtonGroup;
17708
+ var log9, lookStyles4, ButtonGroup;
17692
17709
  var init_ButtonGroup = __esm({
17693
17710
  "components/core/molecules/ButtonGroup.tsx"() {
17694
17711
  "use client";
17695
17712
  init_cn();
17696
17713
  init_atoms2();
17697
17714
  init_useEventBus();
17698
- log8 = createLogger("almadar:ui:button-group");
17715
+ log9 = createLogger("almadar:ui:button-group");
17699
17716
  lookStyles4 = {
17700
17717
  "right-aligned-buttons": "",
17701
17718
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -17776,7 +17793,7 @@ var init_ButtonGroup = __esm({
17776
17793
  {
17777
17794
  variant: "ghost",
17778
17795
  onClick: () => {
17779
- log8.debug("Filter clicked", { field: filter.field });
17796
+ log9.debug("Filter clicked", { field: filter.field });
17780
17797
  },
17781
17798
  children: filter.label
17782
17799
  },
@@ -25438,9 +25455,9 @@ function debug(...args) {
25438
25455
  const [first, ...rest] = args;
25439
25456
  const message = typeof first === "string" ? first : "<debug>";
25440
25457
  if (rest.length === 0 && typeof first === "string") {
25441
- log9.debug(message);
25458
+ log10.debug(message);
25442
25459
  } else {
25443
- log9.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25460
+ log10.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25444
25461
  }
25445
25462
  }
25446
25463
  function debugGroup(label) {
@@ -25468,11 +25485,11 @@ function toLogMetaValue(v) {
25468
25485
  }
25469
25486
  return String(v);
25470
25487
  }
25471
- var NAMESPACE, log9;
25488
+ var NAMESPACE, log10;
25472
25489
  var init_debug = __esm({
25473
25490
  "lib/debug.ts"() {
25474
25491
  NAMESPACE = "almadar:ui:debug";
25475
- log9 = createLogger(NAMESPACE);
25492
+ log10 = createLogger(NAMESPACE);
25476
25493
  createLogger("almadar:ui:debug:input");
25477
25494
  createLogger("almadar:ui:debug:collision");
25478
25495
  createLogger("almadar:ui:debug:physics");
@@ -41763,11 +41780,11 @@ var init_Canvas3DErrorBoundary = __esm({
41763
41780
  "components/game/molecules/three/components/Canvas3DErrorBoundary.css"() {
41764
41781
  }
41765
41782
  });
41766
- var log10, Canvas3DErrorBoundary;
41783
+ var log11, Canvas3DErrorBoundary;
41767
41784
  var init_Canvas3DErrorBoundary2 = __esm({
41768
41785
  "components/game/molecules/three/components/Canvas3DErrorBoundary.tsx"() {
41769
41786
  init_Canvas3DErrorBoundary();
41770
- log10 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41787
+ log11 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41771
41788
  Canvas3DErrorBoundary = class extends Component {
41772
41789
  constructor(props) {
41773
41790
  super(props);
@@ -41795,8 +41812,8 @@ var init_Canvas3DErrorBoundary2 = __esm({
41795
41812
  componentDidCatch(error, errorInfo) {
41796
41813
  this.setState({ errorInfo });
41797
41814
  this.props.onError?.(error, errorInfo);
41798
- log10.error("Error caught", { error });
41799
- log10.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41815
+ log11.error("Error caught", { error });
41816
+ log11.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41800
41817
  }
41801
41818
  render() {
41802
41819
  if (this.state.hasError) {
@@ -41859,7 +41876,7 @@ function useGLTFModel(url, resourceBasePath) {
41859
41876
  setState({ model: null, isLoading: false, error: null });
41860
41877
  return;
41861
41878
  }
41862
- log11.debug("Loading", { url });
41879
+ log12.debug("Loading", { url });
41863
41880
  setState((prev) => ({ ...prev, isLoading: true, error: null }));
41864
41881
  const assetRoot = resourceBasePath || detectAssetRoot2(url);
41865
41882
  const loader = new GLTFLoader$1();
@@ -41867,7 +41884,7 @@ function useGLTFModel(url, resourceBasePath) {
41867
41884
  loader.load(
41868
41885
  url,
41869
41886
  (gltf) => {
41870
- log11.debug("Loaded", { url });
41887
+ log12.debug("Loaded", { url });
41871
41888
  setState({
41872
41889
  model: gltf.scene,
41873
41890
  isLoading: false,
@@ -41876,7 +41893,7 @@ function useGLTFModel(url, resourceBasePath) {
41876
41893
  },
41877
41894
  void 0,
41878
41895
  (err) => {
41879
- log11.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
41896
+ log12.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
41880
41897
  setState({
41881
41898
  model: null,
41882
41899
  isLoading: false,
@@ -41992,11 +42009,11 @@ function ModelLoader({
41992
42009
  }
41993
42010
  );
41994
42011
  }
41995
- var log11;
42012
+ var log12;
41996
42013
  var init_ModelLoader = __esm({
41997
42014
  "components/game/molecules/three/components/ModelLoader.tsx"() {
41998
42015
  "use client";
41999
- log11 = createLogger("almadar:ui:game:model-loader");
42016
+ log12 = createLogger("almadar:ui:game:model-loader");
42000
42017
  }
42001
42018
  });
42002
42019
 
@@ -42122,6 +42139,8 @@ var init_GameCanvas3D2 = __esm({
42122
42139
  attackTargets = [],
42123
42140
  selectedTileIds = [],
42124
42141
  selectedUnitId = null,
42142
+ unitScale = 1,
42143
+ scale = 0.45,
42125
42144
  children
42126
42145
  }, ref) => {
42127
42146
  const containerRef = useRef(null);
@@ -42338,12 +42357,18 @@ var init_GameCanvas3D2 = __esm({
42338
42357
  },
42339
42358
  [selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
42340
42359
  );
42360
+ const UNIT_BASE_MODEL_SCALE = 0.5;
42361
+ const UNIT_BASE_BILLBOARD_HEIGHT = 1.2;
42362
+ const UNIT_BASE_PRIMITIVE_RADIUS = 0.3;
42341
42363
  const DefaultUnitRenderer = useCallback(
42342
42364
  ({ unit, position }) => {
42343
42365
  const isSelected = selectedUnitId === unit.id;
42344
42366
  const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
42345
42367
  const hasAtlas = unitAtlasUrl(unit) !== null;
42346
42368
  const initialFrame = hasAtlas ? resolveUnitFrame(unit.id) : null;
42369
+ const modelScale = UNIT_BASE_MODEL_SCALE * unitScale;
42370
+ const billboardHeight = UNIT_BASE_BILLBOARD_HEIGHT * unitScale;
42371
+ const primitiveRadius = UNIT_BASE_PRIMITIVE_RADIUS * unitScale;
42347
42372
  return /* @__PURE__ */ jsxs(
42348
42373
  "group",
42349
42374
  {
@@ -42361,7 +42386,8 @@ var init_GameCanvas3D2 = __esm({
42361
42386
  UnitSpriteBillboard,
42362
42387
  {
42363
42388
  sheetUrl: initialFrame.sheetUrl,
42364
- resolveFrame: () => resolveUnitFrame(unit.id)
42389
+ resolveFrame: () => resolveUnitFrame(unit.id),
42390
+ height: billboardHeight
42365
42391
  }
42366
42392
  ) })
42367
42393
  ) : unit.modelUrl ? (
@@ -42370,22 +42396,22 @@ var init_GameCanvas3D2 = __esm({
42370
42396
  ModelLoader,
42371
42397
  {
42372
42398
  url: unit.modelUrl,
42373
- scale: 0.5,
42399
+ scale: modelScale,
42374
42400
  fallbackGeometry: "box",
42375
42401
  castShadow: true
42376
42402
  }
42377
42403
  )
42378
42404
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
42379
- /* @__PURE__ */ jsxs("mesh", { position: [0, 0.3, 0], children: [
42380
- /* @__PURE__ */ jsx("cylinderGeometry", { args: [0.3, 0.3, 0.1, 8] }),
42405
+ /* @__PURE__ */ jsxs("mesh", { position: [0, primitiveRadius, 0], children: [
42406
+ /* @__PURE__ */ jsx("cylinderGeometry", { args: [primitiveRadius, primitiveRadius, primitiveRadius * 0.33, 8] }),
42381
42407
  /* @__PURE__ */ jsx("meshStandardMaterial", { color })
42382
42408
  ] }),
42383
- /* @__PURE__ */ jsxs("mesh", { position: [0, 0.6, 0], children: [
42384
- /* @__PURE__ */ jsx("capsuleGeometry", { args: [0.2, 0.4, 4, 8] }),
42409
+ /* @__PURE__ */ jsxs("mesh", { position: [0, primitiveRadius * 2, 0], children: [
42410
+ /* @__PURE__ */ jsx("capsuleGeometry", { args: [primitiveRadius * 0.67, primitiveRadius * 1.33, 4, 8] }),
42385
42411
  /* @__PURE__ */ jsx("meshStandardMaterial", { color })
42386
42412
  ] }),
42387
- /* @__PURE__ */ jsxs("mesh", { position: [0, 0.9, 0], children: [
42388
- /* @__PURE__ */ jsx("sphereGeometry", { args: [0.12, 8, 8] }),
42413
+ /* @__PURE__ */ jsxs("mesh", { position: [0, primitiveRadius * 3, 0], children: [
42414
+ /* @__PURE__ */ jsx("sphereGeometry", { args: [primitiveRadius * 0.4, 8, 8] }),
42389
42415
  /* @__PURE__ */ jsx("meshStandardMaterial", { color })
42390
42416
  ] })
42391
42417
  ] }),
@@ -42418,7 +42444,7 @@ var init_GameCanvas3D2 = __esm({
42418
42444
  }
42419
42445
  );
42420
42446
  },
42421
- [selectedUnitId, handleUnitClick, resolveUnitFrame]
42447
+ [selectedUnitId, handleUnitClick, resolveUnitFrame, unitScale]
42422
42448
  );
42423
42449
  const DefaultFeatureRenderer = useCallback(
42424
42450
  ({
@@ -42561,33 +42587,35 @@ var init_GameCanvas3D2 = __esm({
42561
42587
  fadeStrength: 1
42562
42588
  }
42563
42589
  ),
42564
- tiles.map((tile, index) => {
42565
- const position = gridToWorld(
42566
- tile.x,
42567
- tile.z ?? tile.y ?? 0,
42568
- tile.elevation ?? 0
42569
- );
42570
- const Renderer = CustomTileRenderer || DefaultTileRenderer;
42571
- return /* @__PURE__ */ jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
42572
- }),
42573
- features.map((feature, index) => {
42574
- const position = gridToWorld(
42575
- feature.x,
42576
- feature.z ?? feature.y ?? 0,
42577
- (feature.elevation ?? 0) + 0.5
42578
- );
42579
- const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
42580
- return /* @__PURE__ */ jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
42581
- }),
42582
- units.map((unit) => {
42583
- const position = gridToWorld(
42584
- unit.x ?? 0,
42585
- unit.z ?? unit.y ?? 0,
42586
- (unit.elevation ?? 0) + 0.5
42587
- );
42588
- const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
42589
- return /* @__PURE__ */ jsx(Renderer, { unit, position }, unit.id);
42590
- }),
42590
+ /* @__PURE__ */ jsxs("group", { scale, children: [
42591
+ tiles.map((tile, index) => {
42592
+ const position = gridToWorld(
42593
+ tile.x,
42594
+ tile.z ?? tile.y ?? 0,
42595
+ tile.elevation ?? 0
42596
+ );
42597
+ const Renderer = CustomTileRenderer || DefaultTileRenderer;
42598
+ return /* @__PURE__ */ jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
42599
+ }),
42600
+ features.map((feature, index) => {
42601
+ const position = gridToWorld(
42602
+ feature.x,
42603
+ feature.z ?? feature.y ?? 0,
42604
+ (feature.elevation ?? 0) + 0.5
42605
+ );
42606
+ const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
42607
+ return /* @__PURE__ */ jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
42608
+ }),
42609
+ units.map((unit) => {
42610
+ const position = gridToWorld(
42611
+ unit.x ?? 0,
42612
+ unit.z ?? unit.y ?? 0,
42613
+ (unit.elevation ?? 0) + 0.5
42614
+ );
42615
+ const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
42616
+ return /* @__PURE__ */ jsx(Renderer, { unit, position }, unit.id);
42617
+ })
42618
+ ] }),
42591
42619
  children,
42592
42620
  /* @__PURE__ */ jsx(
42593
42621
  OrbitControls,
@@ -42630,6 +42658,8 @@ function GameBoard3D({
42630
42658
  features = [],
42631
42659
  cameraMode = "perspective",
42632
42660
  backgroundColor = "#2a1a1a",
42661
+ unitScale = 1,
42662
+ scale = 0.45,
42633
42663
  tileClickEvent,
42634
42664
  unitClickEvent,
42635
42665
  attackEvent,
@@ -42730,6 +42760,8 @@ function GameBoard3D({
42730
42760
  selectedUnitId,
42731
42761
  validMoves,
42732
42762
  attackTargets,
42763
+ unitScale,
42764
+ scale,
42733
42765
  className: "game-board-3d__canvas w-full min-h-[85vh]"
42734
42766
  }
42735
42767
  ),
@@ -44715,6 +44747,8 @@ function RoguelikeBoard({
44715
44747
  assetManifest: propAssetManifest,
44716
44748
  scale = 0.45,
44717
44749
  unitScale = 1,
44750
+ spriteHeightRatio = 1.5,
44751
+ spriteMaxWidthRatio = 0.6,
44718
44752
  moveEvent,
44719
44753
  playAgainEvent,
44720
44754
  gameEndEvent,
@@ -44862,7 +44896,9 @@ function RoguelikeBoard({
44862
44896
  scale,
44863
44897
  assetBaseUrl: propAssetManifest?.baseUrl ?? CDN4,
44864
44898
  assetManifest: propAssetManifest,
44865
- unitScale
44899
+ unitScale,
44900
+ spriteHeightRatio,
44901
+ spriteMaxWidthRatio
44866
44902
  }
44867
44903
  ) }),
44868
44904
  !isGameOver && /* @__PURE__ */ jsx(HStack, { className: "justify-center gap-2 p-3", gap: "none", children: [
@@ -46282,7 +46318,7 @@ function getAllEvents(traits2) {
46282
46318
  function EventDispatcherTab({ traits: traits2, schema }) {
46283
46319
  const eventBus = useEventBus();
46284
46320
  const { t } = useTranslate();
46285
- const [log13, setLog] = React82.useState([]);
46321
+ const [log14, setLog] = React82.useState([]);
46286
46322
  const prevStatesRef = React82.useRef(/* @__PURE__ */ new Map());
46287
46323
  React82.useEffect(() => {
46288
46324
  for (const trait of traits2) {
@@ -46346,9 +46382,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
46346
46382
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
46347
46383
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
46348
46384
  ] }),
46349
- log13.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46385
+ log14.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46350
46386
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
46351
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log13.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46387
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log14.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46352
46388
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
46353
46389
  " ",
46354
46390
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -49215,6 +49251,9 @@ function TowerDefenseBoard({
49215
49251
  waveActive: propWaveActive,
49216
49252
  towerCost = 25,
49217
49253
  scale = 0.45,
49254
+ unitScale = 1,
49255
+ spriteHeightRatio = 1.5,
49256
+ spriteMaxWidthRatio = 0.6,
49218
49257
  placeTowerEvent,
49219
49258
  startWaveEvent,
49220
49259
  playAgainEvent,
@@ -49322,7 +49361,10 @@ function TowerDefenseBoard({
49322
49361
  onTileClick: handleTileClick,
49323
49362
  onTileHover: (x, y) => setHoveredTile({ x, y }),
49324
49363
  onTileLeave: () => setHoveredTile(null),
49325
- scale
49364
+ scale,
49365
+ unitScale,
49366
+ spriteHeightRatio,
49367
+ spriteMaxWidthRatio
49326
49368
  }
49327
49369
  ),
49328
49370
  hoveredTile && canPlaceTower && validMoves.some((m) => m.x === hoveredTile.x && m.y === hoveredTile.y) && /* @__PURE__ */ jsx(Box, { className: "absolute bottom-4 left-1/2 -translate-x-1/2 z-10 bg-background/80 rounded px-3 py-1 backdrop-blur-sm pointer-events-none", children: /* @__PURE__ */ jsx(Typography, { variant: "small", children: t("td.placeTower") ?? `Place tower (${towerCost} gold)` }) })
@@ -49658,6 +49700,8 @@ function WorldMapBoard({
49658
49700
  isLoading,
49659
49701
  scale = 0.4,
49660
49702
  unitScale = 2.5,
49703
+ spriteHeightRatio = 1.5,
49704
+ spriteMaxWidthRatio = 0.6,
49661
49705
  allowMoveAllHeroes = false,
49662
49706
  isInRange = defaultIsInRange,
49663
49707
  heroSelectEvent,
@@ -49895,6 +49939,8 @@ function WorldMapBoard({
49895
49939
  effectSpriteUrls,
49896
49940
  resolveUnitFrame,
49897
49941
  unitScale,
49942
+ spriteHeightRatio,
49943
+ spriteMaxWidthRatio,
49898
49944
  diamondTopY,
49899
49945
  enableCamera
49900
49946
  }
@@ -51213,7 +51259,7 @@ function isPatternConfig(value) {
51213
51259
  if (value instanceof Date) return false;
51214
51260
  if (typeof value === "function") return false;
51215
51261
  const record = value;
51216
- return "type" in record && typeof record.type === "string";
51262
+ return "type" in record && typeof record.type === "string" && isKnownPattern(record.type);
51217
51263
  }
51218
51264
  function isPlainConfigObject(value) {
51219
51265
  if (React82__default.isValidElement(value)) return false;
@@ -51807,7 +51853,7 @@ init_UISlotRenderer();
51807
51853
  // providers/VerificationProvider.tsx
51808
51854
  init_useEventBus();
51809
51855
  init_verificationRegistry();
51810
- var log12 = createLogger("almadar:verify");
51856
+ var log13 = createLogger("almadar:verify");
51811
51857
  var DISPATCH_SUFFIX = ":DISPATCH";
51812
51858
  var SUCCESS_SUFFIX = ":SUCCESS";
51813
51859
  var ERROR_SUFFIX = ":ERROR";
@@ -51854,7 +51900,7 @@ function VerificationProvider({
51854
51900
  const verificationProviderLifecycleListener = (evt) => {
51855
51901
  const parsed = parseLifecycleEvent(evt.type);
51856
51902
  if (!parsed) return;
51857
- log12.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
51903
+ log13.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
51858
51904
  const payload = evt.payload ?? {};
51859
51905
  if (parsed.kind === "dispatch") {
51860
51906
  const key = `${parsed.traitName}:${String(payload["event"] ?? "")}`;
@@ -51909,7 +51955,7 @@ function VerificationProvider({
51909
51955
  },
51910
51956
  timestamp: Date.now()
51911
51957
  });
51912
- log12.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
51958
+ log13.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
51913
51959
  } else if (parsed.kind === "error" && parsed.event) {
51914
51960
  const key = `${parsed.traitName}:${parsed.event}`;
51915
51961
  const pending = pendingRef.current.get(key);
@@ -51939,7 +51985,7 @@ function VerificationProvider({
51939
51985
  },
51940
51986
  timestamp: Date.now()
51941
51987
  });
51942
- log12.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
51988
+ log13.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
51943
51989
  }
51944
51990
  };
51945
51991
  Object.defineProperty(verificationProviderLifecycleListener, "name", {