@almadar/ui 5.95.0 → 5.97.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.
@@ -1,6 +1,6 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import * as React74 from 'react';
3
- import React74__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, Suspense, lazy, useLayoutEffect, useId, useSyncExternalStore } from 'react';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import * as React75 from 'react';
3
+ import React75__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, Suspense, lazy, useLayoutEffect, useId, useSyncExternalStore } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { EventBusContext, useTraitScope, useCurrentPagePath, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
@@ -227,7 +227,7 @@ var init_SvgFlow = __esm({
227
227
  width = 100,
228
228
  height = 100
229
229
  }) => {
230
- const markerId = React74__default.useMemo(() => {
230
+ const markerId = React75__default.useMemo(() => {
231
231
  flowIdCounter += 1;
232
232
  return `almadar-flow-arrow-${flowIdCounter}`;
233
233
  }, []);
@@ -820,7 +820,7 @@ var init_SvgRing = __esm({
820
820
  width = 100,
821
821
  height = 100
822
822
  }) => {
823
- const gradientId = React74__default.useMemo(() => {
823
+ const gradientId = React75__default.useMemo(() => {
824
824
  ringIdCounter += 1;
825
825
  return `almadar-ring-glow-${ringIdCounter}`;
826
826
  }, []);
@@ -1232,7 +1232,7 @@ function loadLib(key, importer) {
1232
1232
  return p;
1233
1233
  }
1234
1234
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1235
- const Lazy = React74__default.lazy(async () => {
1235
+ const Lazy = React75__default.lazy(async () => {
1236
1236
  const lib = await loadLib(libKey, importer);
1237
1237
  const Comp = pick(lib);
1238
1238
  if (!Comp) {
@@ -1242,7 +1242,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1242
1242
  return { default: Comp };
1243
1243
  });
1244
1244
  const Wrapped = (props) => /* @__PURE__ */ jsx(
1245
- React74__default.Suspense,
1245
+ React75__default.Suspense,
1246
1246
  {
1247
1247
  fallback: /* @__PURE__ */ jsx(
1248
1248
  "span",
@@ -1973,7 +1973,7 @@ var init_Icon = __esm({
1973
1973
  const directIcon = typeof icon === "string" ? void 0 : icon;
1974
1974
  const effectiveName = typeof icon === "string" ? icon : name;
1975
1975
  const family = useIconFamily();
1976
- const RenderedComponent = React74__default.useMemo(() => {
1976
+ const RenderedComponent = React75__default.useMemo(() => {
1977
1977
  if (directIcon) return null;
1978
1978
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1979
1979
  }, [directIcon, effectiveName, family]);
@@ -2023,6 +2023,210 @@ var init_Icon = __esm({
2023
2023
  Icon.displayName = "Icon";
2024
2024
  }
2025
2025
  });
2026
+
2027
+ // lib/atlasSlice.ts
2028
+ function isTilesheet(a) {
2029
+ return typeof a.tileWidth === "number";
2030
+ }
2031
+ function getAtlas(url, onReady) {
2032
+ if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
2033
+ atlasCache.set(url, void 0);
2034
+ fetch(url).then((r) => r.json()).then((json) => {
2035
+ atlasCache.set(url, json);
2036
+ onReady();
2037
+ }).catch(() => {
2038
+ atlasCache.set(url, null);
2039
+ });
2040
+ return void 0;
2041
+ }
2042
+ function subRectFor(atlas, sprite) {
2043
+ if (isTilesheet(atlas)) {
2044
+ let col;
2045
+ let row;
2046
+ if (sprite.includes(",")) {
2047
+ const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
2048
+ col = c;
2049
+ row = r;
2050
+ } else {
2051
+ const i = Number(sprite);
2052
+ if (!Number.isFinite(i)) return null;
2053
+ col = i % atlas.columns;
2054
+ row = Math.floor(i / atlas.columns);
2055
+ }
2056
+ if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
2057
+ const margin = atlas.margin ?? 0;
2058
+ const spacing = atlas.spacing ?? 0;
2059
+ return {
2060
+ sx: margin + col * (atlas.tileWidth + spacing),
2061
+ sy: margin + row * (atlas.tileHeight + spacing),
2062
+ sw: atlas.tileWidth,
2063
+ sh: atlas.tileHeight
2064
+ };
2065
+ }
2066
+ const st = atlas.subTextures[sprite];
2067
+ if (!st) return null;
2068
+ return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
2069
+ }
2070
+ function isAtlasAsset(asset) {
2071
+ return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
2072
+ }
2073
+ function resolveAssetSource(img, asset, onReady) {
2074
+ if (isAtlasAsset(asset)) {
2075
+ const atlas = getAtlas(asset.atlas, onReady);
2076
+ if (!atlas) return null;
2077
+ const rect = subRectFor(atlas, asset.sprite);
2078
+ if (!rect) return null;
2079
+ return { img, rect, aspect: rect.sw / rect.sh };
2080
+ }
2081
+ const natW = img.naturalWidth || 1;
2082
+ const natH = img.naturalHeight || 1;
2083
+ return { img, rect: null, aspect: natW / natH };
2084
+ }
2085
+ function blit(ctx, src, dx, dy, dw, dh) {
2086
+ if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
2087
+ else ctx.drawImage(src.img, dx, dy, dw, dh);
2088
+ }
2089
+ var atlasCache;
2090
+ var init_atlasSlice = __esm({
2091
+ "lib/atlasSlice.ts"() {
2092
+ "use client";
2093
+ atlasCache = /* @__PURE__ */ new Map();
2094
+ }
2095
+ });
2096
+ function useAtlasSliceDataUrl(asset) {
2097
+ const [, bump] = React75.useReducer((x) => x + 1, 0);
2098
+ if (!isAtlasAsset(asset)) return void 0;
2099
+ const key = `${asset.atlas}#${asset.sprite}`;
2100
+ const cached = sliceDataUrlCache.get(key);
2101
+ if (cached) return cached;
2102
+ const atlas = getAtlas(asset.atlas, bump);
2103
+ const img = asset?.url ? getSheetImage(asset.url, bump) : null;
2104
+ if (!atlas || !img) return void 0;
2105
+ const rect = subRectFor(atlas, asset.sprite);
2106
+ if (!rect) return void 0;
2107
+ const canvas = document.createElement("canvas");
2108
+ canvas.width = rect.sw;
2109
+ canvas.height = rect.sh;
2110
+ const ctx = canvas.getContext("2d");
2111
+ if (!ctx) return void 0;
2112
+ ctx.imageSmoothingEnabled = false;
2113
+ ctx.drawImage(img, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
2114
+ const url = canvas.toDataURL();
2115
+ sliceDataUrlCache.set(key, url);
2116
+ return url;
2117
+ }
2118
+ function AtlasPanel({ asset, borderSlice = 16, borderWidth = 16, mode = "nineSlice", className, style, children, "aria-hidden": ariaHidden }) {
2119
+ const dataUrl = useAtlasSliceDataUrl(asset);
2120
+ const skin = !dataUrl ? {} : mode === "repeat" ? { backgroundImage: `url(${dataUrl})`, backgroundRepeat: "repeat" } : {
2121
+ borderStyle: "solid",
2122
+ borderWidth,
2123
+ borderImageSource: `url(${dataUrl})`,
2124
+ borderImageSlice: `${borderSlice} fill`,
2125
+ borderImageWidth: borderWidth,
2126
+ borderImageRepeat: "stretch",
2127
+ imageRendering: "pixelated"
2128
+ };
2129
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": ariaHidden, className: cn("inline-block", className), style: { ...skin, ...style }, children });
2130
+ }
2131
+ function getSheetImage(url, onReady) {
2132
+ const cached = imageCache.get(url);
2133
+ if (cached) return cached;
2134
+ (imageWaiters.get(url) ?? imageWaiters.set(url, /* @__PURE__ */ new Set()).get(url)).add(onReady);
2135
+ if (!imageCache.has(url)) {
2136
+ imageCache.set(url, null);
2137
+ const img = new Image();
2138
+ img.crossOrigin = "anonymous";
2139
+ img.onload = () => {
2140
+ imageCache.set(url, img);
2141
+ imageWaiters.get(url)?.forEach((fn) => fn());
2142
+ imageWaiters.delete(url);
2143
+ };
2144
+ img.src = url;
2145
+ }
2146
+ return null;
2147
+ }
2148
+ function AtlasImage({
2149
+ asset,
2150
+ size,
2151
+ width,
2152
+ height,
2153
+ fill = false,
2154
+ fit = "contain",
2155
+ alt,
2156
+ className,
2157
+ style,
2158
+ "aria-hidden": ariaHidden
2159
+ }) {
2160
+ const [, bump] = React75.useReducer((x) => x + 1, 0);
2161
+ const canvasRef = React75.useRef(null);
2162
+ const sliced = isAtlasAsset(asset);
2163
+ const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
2164
+ const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
2165
+ const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
2166
+ React75.useEffect(() => {
2167
+ const canvas = canvasRef.current;
2168
+ if (!canvas || !img || !rect) return;
2169
+ canvas.width = rect.sw;
2170
+ canvas.height = rect.sh;
2171
+ const ctx = canvas.getContext("2d");
2172
+ if (!ctx) return;
2173
+ ctx.imageSmoothingEnabled = false;
2174
+ ctx.clearRect(0, 0, rect.sw, rect.sh);
2175
+ ctx.drawImage(img, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
2176
+ }, [img, rect?.sx, rect?.sy, rect?.sw, rect?.sh]);
2177
+ const w = fill ? "100%" : width ?? size;
2178
+ const h = fill ? "100%" : height ?? size;
2179
+ const boxStyle = {
2180
+ ...fill ? { position: "absolute", inset: 0 } : {},
2181
+ width: w,
2182
+ height: h,
2183
+ objectFit: fit,
2184
+ imageRendering: "pixelated",
2185
+ ...style
2186
+ };
2187
+ if (!asset?.url) return null;
2188
+ if (sliced) {
2189
+ if (!rect || !img) {
2190
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("inline-block flex-shrink-0", className), style: { ...boxStyle, objectFit: void 0 } });
2191
+ }
2192
+ return /* @__PURE__ */ jsx(
2193
+ "canvas",
2194
+ {
2195
+ ref: canvasRef,
2196
+ role: ariaHidden ? void 0 : "img",
2197
+ "aria-hidden": ariaHidden,
2198
+ "aria-label": ariaHidden ? void 0 : alt ?? asset.name ?? asset.category ?? "",
2199
+ className: cn("flex-shrink-0", className),
2200
+ style: boxStyle
2201
+ }
2202
+ );
2203
+ }
2204
+ return /* @__PURE__ */ jsx(
2205
+ "img",
2206
+ {
2207
+ src: asset.url,
2208
+ alt: alt ?? asset.name ?? asset.category ?? "",
2209
+ "aria-hidden": ariaHidden,
2210
+ ...typeof w === "number" ? { width: w } : {},
2211
+ ...typeof h === "number" ? { height: h } : {},
2212
+ className: cn("flex-shrink-0", className),
2213
+ style: boxStyle
2214
+ }
2215
+ );
2216
+ }
2217
+ var sliceDataUrlCache, imageCache, imageWaiters;
2218
+ var init_AtlasImage = __esm({
2219
+ "components/core/atoms/AtlasImage.tsx"() {
2220
+ "use client";
2221
+ init_atlasSlice();
2222
+ init_cn();
2223
+ sliceDataUrlCache = /* @__PURE__ */ new Map();
2224
+ AtlasPanel.displayName = "AtlasPanel";
2225
+ imageCache = /* @__PURE__ */ new Map();
2226
+ imageWaiters = /* @__PURE__ */ new Map();
2227
+ AtlasImage.displayName = "AtlasImage";
2228
+ }
2229
+ });
2026
2230
  function isIconLike(v) {
2027
2231
  return typeof v.render === "function";
2028
2232
  }
@@ -2035,7 +2239,7 @@ function resolveIconProp(value, sizeClass) {
2035
2239
  const IconComp = value;
2036
2240
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
2037
2241
  }
2038
- if (React74__default.isValidElement(value)) {
2242
+ if (React75__default.isValidElement(value)) {
2039
2243
  return value;
2040
2244
  }
2041
2245
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -2051,6 +2255,7 @@ var init_Button = __esm({
2051
2255
  init_cn();
2052
2256
  init_useEventBus();
2053
2257
  init_Icon();
2258
+ init_AtlasImage();
2054
2259
  variantStyles = {
2055
2260
  primary: [
2056
2261
  "bg-primary text-primary-foreground",
@@ -2111,7 +2316,7 @@ var init_Button = __esm({
2111
2316
  md: "h-icon-default w-icon-default",
2112
2317
  lg: "h-icon-default w-icon-default"
2113
2318
  };
2114
- Button = React74__default.forwardRef(
2319
+ Button = React75__default.forwardRef(
2115
2320
  ({
2116
2321
  className,
2117
2322
  variant = "primary",
@@ -2135,7 +2340,7 @@ var init_Button = __esm({
2135
2340
  const leftIconValue = leftIcon || iconProp;
2136
2341
  const rightIconValue = rightIcon || iconRightProp;
2137
2342
  const px = size === "sm" ? 16 : size === "lg" ? 20 : 16;
2138
- const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: px, height: px, style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px }, className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
2343
+ const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx(AtlasImage, { asset: iconAsset, size: px, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
2139
2344
  const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
2140
2345
  const handleClick = (e) => {
2141
2346
  if (action) {
@@ -2181,7 +2386,7 @@ var init_Input = __esm({
2181
2386
  init_cn();
2182
2387
  init_Icon();
2183
2388
  init_useEventBus();
2184
- Input = React74__default.forwardRef(
2389
+ Input = React75__default.forwardRef(
2185
2390
  ({
2186
2391
  className,
2187
2392
  inputType,
@@ -2341,7 +2546,7 @@ var Label;
2341
2546
  var init_Label = __esm({
2342
2547
  "components/core/atoms/Label.tsx"() {
2343
2548
  init_cn();
2344
- Label = React74__default.forwardRef(
2549
+ Label = React75__default.forwardRef(
2345
2550
  ({ className, required, children, ...props }, ref) => {
2346
2551
  return /* @__PURE__ */ jsxs(
2347
2552
  "label",
@@ -2368,7 +2573,7 @@ var init_Textarea = __esm({
2368
2573
  "components/core/atoms/Textarea.tsx"() {
2369
2574
  init_cn();
2370
2575
  init_useEventBus();
2371
- Textarea = React74__default.forwardRef(
2576
+ Textarea = React75__default.forwardRef(
2372
2577
  ({ className, error, onChange, ...props }, ref) => {
2373
2578
  const eventBus = useEventBus();
2374
2579
  const handleChange = (e) => {
@@ -2607,7 +2812,7 @@ var init_Select = __esm({
2607
2812
  init_cn();
2608
2813
  init_Icon();
2609
2814
  init_useEventBus();
2610
- Select = React74__default.forwardRef(
2815
+ Select = React75__default.forwardRef(
2611
2816
  (props, _ref) => {
2612
2817
  const { multiple, searchable, clearable } = props;
2613
2818
  if (multiple || searchable || clearable) {
@@ -2624,7 +2829,7 @@ var init_Checkbox = __esm({
2624
2829
  "components/core/atoms/Checkbox.tsx"() {
2625
2830
  init_cn();
2626
2831
  init_useEventBus();
2627
- Checkbox = React74__default.forwardRef(
2832
+ Checkbox = React75__default.forwardRef(
2628
2833
  ({ className, label, id, onChange, ...props }, ref) => {
2629
2834
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
2630
2835
  const eventBus = useEventBus();
@@ -2678,7 +2883,7 @@ var init_Spinner = __esm({
2678
2883
  md: "h-6 w-6",
2679
2884
  lg: "h-8 w-8"
2680
2885
  };
2681
- Spinner = React74__default.forwardRef(
2886
+ Spinner = React75__default.forwardRef(
2682
2887
  ({ className, size = "md", overlay, ...props }, ref) => {
2683
2888
  if (overlay) {
2684
2889
  return /* @__PURE__ */ jsx(
@@ -2768,7 +2973,7 @@ var init_Card = __esm({
2768
2973
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
2769
2974
  "tile-image-first": "p-0 overflow-hidden"
2770
2975
  };
2771
- Card = React74__default.forwardRef(
2976
+ Card = React75__default.forwardRef(
2772
2977
  ({
2773
2978
  className,
2774
2979
  variant = "bordered",
@@ -2816,9 +3021,9 @@ var init_Card = __esm({
2816
3021
  }
2817
3022
  );
2818
3023
  Card.displayName = "Card";
2819
- CardHeader = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3024
+ CardHeader = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
2820
3025
  CardHeader.displayName = "CardHeader";
2821
- CardTitle = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3026
+ CardTitle = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2822
3027
  "h3",
2823
3028
  {
2824
3029
  ref,
@@ -2831,11 +3036,11 @@ var init_Card = __esm({
2831
3036
  }
2832
3037
  ));
2833
3038
  CardTitle.displayName = "CardTitle";
2834
- CardContent = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3039
+ CardContent = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
2835
3040
  CardContent.displayName = "CardContent";
2836
3041
  CardBody = CardContent;
2837
3042
  CardBody.displayName = "CardBody";
2838
- CardFooter = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3043
+ CardFooter = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2839
3044
  "div",
2840
3045
  {
2841
3046
  ref,
@@ -2851,6 +3056,7 @@ var init_Badge = __esm({
2851
3056
  "components/core/atoms/Badge.tsx"() {
2852
3057
  init_cn();
2853
3058
  init_Icon();
3059
+ init_AtlasImage();
2854
3060
  variantStyles3 = {
2855
3061
  default: [
2856
3062
  "bg-muted text-foreground",
@@ -2888,7 +3094,7 @@ var init_Badge = __esm({
2888
3094
  md: "px-2.5 py-1 text-sm",
2889
3095
  lg: "px-3 py-1.5 text-base"
2890
3096
  };
2891
- Badge = React74__default.forwardRef(
3097
+ Badge = React75__default.forwardRef(
2892
3098
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2893
3099
  const iconSizes3 = {
2894
3100
  sm: "h-icon-default w-icon-default",
@@ -2896,7 +3102,7 @@ var init_Badge = __esm({
2896
3102
  lg: "h-icon-default w-icon-default"
2897
3103
  };
2898
3104
  const iconPx = size === "lg" ? 20 : 16;
2899
- const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: iconPx, height: iconPx, style: { imageRendering: "pixelated", objectFit: "contain", width: iconPx, height: iconPx }, className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
3105
+ const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx(AtlasImage, { asset: iconAsset, size: iconPx, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2900
3106
  return /* @__PURE__ */ jsxs(
2901
3107
  "span",
2902
3108
  {
@@ -2982,7 +3188,7 @@ var init_FilterPill = __esm({
2982
3188
  md: "w-3.5 h-3.5",
2983
3189
  lg: "w-4 h-4"
2984
3190
  };
2985
- FilterPill = React74__default.forwardRef(
3191
+ FilterPill = React75__default.forwardRef(
2986
3192
  ({
2987
3193
  className,
2988
3194
  variant = "default",
@@ -3111,8 +3317,8 @@ var init_Avatar = __esm({
3111
3317
  actionPayload
3112
3318
  }) => {
3113
3319
  const eventBus = useEventBus();
3114
- const [imgFailed, setImgFailed] = React74__default.useState(false);
3115
- React74__default.useEffect(() => {
3320
+ const [imgFailed, setImgFailed] = React75__default.useState(false);
3321
+ React75__default.useEffect(() => {
3116
3322
  setImgFailed(false);
3117
3323
  }, [src]);
3118
3324
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -3364,7 +3570,7 @@ var init_Box = __esm({
3364
3570
  fixed: "fixed",
3365
3571
  sticky: "sticky"
3366
3572
  };
3367
- Box = React74__default.forwardRef(
3573
+ Box = React75__default.forwardRef(
3368
3574
  ({
3369
3575
  padding,
3370
3576
  paddingX,
@@ -3429,7 +3635,7 @@ var init_Box = __esm({
3429
3635
  onPointerDown?.(e);
3430
3636
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
3431
3637
  const isClickable = action || onClick;
3432
- return React74__default.createElement(
3638
+ return React75__default.createElement(
3433
3639
  Component,
3434
3640
  {
3435
3641
  ref,
@@ -3483,7 +3689,7 @@ var init_Center = __esm({
3483
3689
  as: Component = "div"
3484
3690
  }) => {
3485
3691
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
3486
- return React74__default.createElement(Component, {
3692
+ return React75__default.createElement(Component, {
3487
3693
  className: cn(
3488
3694
  inline ? "inline-flex" : "flex",
3489
3695
  horizontal && "justify-center",
@@ -3751,7 +3957,7 @@ var init_Radio = __esm({
3751
3957
  md: "w-2.5 h-2.5",
3752
3958
  lg: "w-3 h-3"
3753
3959
  };
3754
- Radio = React74__default.forwardRef(
3960
+ Radio = React75__default.forwardRef(
3755
3961
  ({
3756
3962
  label,
3757
3963
  helperText,
@@ -3768,12 +3974,12 @@ var init_Radio = __esm({
3768
3974
  onChange,
3769
3975
  ...props
3770
3976
  }, ref) => {
3771
- const reactId = React74__default.useId();
3977
+ const reactId = React75__default.useId();
3772
3978
  const baseId = id || `radio-${reactId}`;
3773
3979
  const hasError = !!error;
3774
3980
  const eventBus = useEventBus();
3775
- const [selected, setSelected] = React74__default.useState(value);
3776
- React74__default.useEffect(() => {
3981
+ const [selected, setSelected] = React75__default.useState(value);
3982
+ React75__default.useEffect(() => {
3777
3983
  if (value !== void 0) setSelected(value);
3778
3984
  }, [value]);
3779
3985
  const pick = (next, e) => {
@@ -3955,7 +4161,7 @@ var init_Switch = __esm({
3955
4161
  "components/core/atoms/Switch.tsx"() {
3956
4162
  "use client";
3957
4163
  init_cn();
3958
- Switch = React74.forwardRef(
4164
+ Switch = React75.forwardRef(
3959
4165
  ({
3960
4166
  checked,
3961
4167
  defaultChecked = false,
@@ -3966,10 +4172,10 @@ var init_Switch = __esm({
3966
4172
  name,
3967
4173
  className
3968
4174
  }, ref) => {
3969
- const [isChecked, setIsChecked] = React74.useState(
4175
+ const [isChecked, setIsChecked] = React75.useState(
3970
4176
  checked !== void 0 ? checked : defaultChecked
3971
4177
  );
3972
- React74.useEffect(() => {
4178
+ React75.useEffect(() => {
3973
4179
  if (checked !== void 0) {
3974
4180
  setIsChecked(checked);
3975
4181
  }
@@ -4132,7 +4338,7 @@ var init_Stack = __esm({
4132
4338
  };
4133
4339
  const isHorizontal = direction === "horizontal";
4134
4340
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4135
- return React74__default.createElement(
4341
+ return React75__default.createElement(
4136
4342
  Component,
4137
4343
  {
4138
4344
  className: cn(
@@ -4328,7 +4534,7 @@ var init_Typography = __esm({
4328
4534
  }) => {
4329
4535
  const variant = variantProp ?? (level ? `h${level}` : "body1");
4330
4536
  const Component = as || defaultElements[variant];
4331
- return React74__default.createElement(
4537
+ return React75__default.createElement(
4332
4538
  Component,
4333
4539
  {
4334
4540
  id,
@@ -4487,7 +4693,7 @@ var Dialog;
4487
4693
  var init_Dialog = __esm({
4488
4694
  "components/core/atoms/Dialog.tsx"() {
4489
4695
  init_cn();
4490
- Dialog = React74__default.forwardRef(
4696
+ Dialog = React75__default.forwardRef(
4491
4697
  ({
4492
4698
  role = "dialog",
4493
4699
  "aria-modal": ariaModal = true,
@@ -4513,7 +4719,7 @@ var Aside;
4513
4719
  var init_Aside = __esm({
4514
4720
  "components/core/atoms/Aside.tsx"() {
4515
4721
  init_cn();
4516
- Aside = React74__default.forwardRef(
4722
+ Aside = React75__default.forwardRef(
4517
4723
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4518
4724
  );
4519
4725
  Aside.displayName = "Aside";
@@ -4592,9 +4798,9 @@ var init_LawReferenceTooltip = __esm({
4592
4798
  className
4593
4799
  }) => {
4594
4800
  const { t } = useTranslate();
4595
- const [isVisible, setIsVisible] = React74__default.useState(false);
4596
- const timeoutRef = React74__default.useRef(null);
4597
- const triggerRef = React74__default.useRef(null);
4801
+ const [isVisible, setIsVisible] = React75__default.useState(false);
4802
+ const timeoutRef = React75__default.useRef(null);
4803
+ const triggerRef = React75__default.useRef(null);
4598
4804
  const handleMouseEnter = () => {
4599
4805
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4600
4806
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -4605,7 +4811,7 @@ var init_LawReferenceTooltip = __esm({
4605
4811
  };
4606
4812
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
4607
4813
  const open = isVisible || revealed;
4608
- React74__default.useEffect(() => {
4814
+ React75__default.useEffect(() => {
4609
4815
  return () => {
4610
4816
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4611
4817
  };
@@ -4815,7 +5021,7 @@ var init_StatusDot = __esm({
4815
5021
  md: "w-2.5 h-2.5",
4816
5022
  lg: "w-3 h-3"
4817
5023
  };
4818
- StatusDot = React74__default.forwardRef(
5024
+ StatusDot = React75__default.forwardRef(
4819
5025
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
4820
5026
  return /* @__PURE__ */ jsx(
4821
5027
  "span",
@@ -4869,7 +5075,7 @@ var init_TrendIndicator = __esm({
4869
5075
  down: "trending-down",
4870
5076
  flat: "arrow-right"
4871
5077
  };
4872
- TrendIndicator = React74__default.forwardRef(
5078
+ TrendIndicator = React75__default.forwardRef(
4873
5079
  ({
4874
5080
  className,
4875
5081
  value,
@@ -4936,7 +5142,7 @@ var init_RangeSlider = __esm({
4936
5142
  md: "w-4 h-4",
4937
5143
  lg: "w-5 h-5"
4938
5144
  };
4939
- RangeSlider = React74__default.forwardRef(
5145
+ RangeSlider = React75__default.forwardRef(
4940
5146
  ({
4941
5147
  className,
4942
5148
  min = 0,
@@ -5530,7 +5736,7 @@ var init_ContentSection = __esm({
5530
5736
  md: "py-16",
5531
5737
  lg: "py-24"
5532
5738
  };
5533
- ContentSection = React74__default.forwardRef(
5739
+ ContentSection = React75__default.forwardRef(
5534
5740
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5535
5741
  return /* @__PURE__ */ jsx(
5536
5742
  Box,
@@ -6064,7 +6270,7 @@ var init_AnimatedReveal = __esm({
6064
6270
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6065
6271
  "none": {}
6066
6272
  };
6067
- AnimatedReveal = React74__default.forwardRef(
6273
+ AnimatedReveal = React75__default.forwardRef(
6068
6274
  ({
6069
6275
  trigger = "scroll",
6070
6276
  animation = "fade-up",
@@ -6224,7 +6430,7 @@ var init_AnimatedGraphic = __esm({
6224
6430
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6225
6431
  "use client";
6226
6432
  init_cn();
6227
- AnimatedGraphic = React74__default.forwardRef(
6433
+ AnimatedGraphic = React75__default.forwardRef(
6228
6434
  ({
6229
6435
  src,
6230
6436
  svgContent,
@@ -6247,7 +6453,7 @@ var init_AnimatedGraphic = __esm({
6247
6453
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6248
6454
  const resolvedSvg = svgContent ?? fetchedSvg;
6249
6455
  const prevAnimateRef = useRef(animate);
6250
- const setRef = React74__default.useCallback(
6456
+ const setRef = React75__default.useCallback(
6251
6457
  (node) => {
6252
6458
  containerRef.current = node;
6253
6459
  if (typeof ref === "function") ref(node);
@@ -6920,7 +7126,7 @@ var init_ErrorBoundary = __esm({
6920
7126
  }
6921
7127
  );
6922
7128
  };
6923
- ErrorBoundary = class extends React74__default.Component {
7129
+ ErrorBoundary = class extends React75__default.Component {
6924
7130
  constructor(props) {
6925
7131
  super(props);
6926
7132
  __publicField(this, "reset", () => {
@@ -7216,7 +7422,7 @@ var init_Container = __esm({
7216
7422
  as: Component = "div"
7217
7423
  }) => {
7218
7424
  const resolvedSize = maxWidth ?? size ?? "lg";
7219
- return React74__default.createElement(
7425
+ return React75__default.createElement(
7220
7426
  Component,
7221
7427
  {
7222
7428
  className: cn(
@@ -7933,13 +8139,11 @@ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
7933
8139
  const px = typeof size === "number" ? size : sizeMap[size];
7934
8140
  if (assetUrl?.url) {
7935
8141
  return /* @__PURE__ */ jsx(
7936
- "img",
8142
+ AtlasImage,
7937
8143
  {
7938
- src: assetUrl.url,
8144
+ asset: assetUrl,
8145
+ size: px,
7939
8146
  alt: alt ?? assetUrl.category ?? "",
7940
- width: px,
7941
- height: px,
7942
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
7943
8147
  className: cn("flex-shrink-0", className)
7944
8148
  }
7945
8149
  );
@@ -7953,6 +8157,7 @@ var init_GameIcon = __esm({
7953
8157
  "use client";
7954
8158
  init_cn();
7955
8159
  init_Icon();
8160
+ init_AtlasImage();
7956
8161
  sizeMap = {
7957
8162
  sm: 16,
7958
8163
  md: 24,
@@ -10557,7 +10762,7 @@ var init_CodeBlock = __esm({
10557
10762
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
10558
10763
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
10559
10764
  HIDDEN_LINE_NUMBERS = { display: "none" };
10560
- CodeBlock = React74__default.memo(
10765
+ CodeBlock = React75__default.memo(
10561
10766
  ({
10562
10767
  code: rawCode,
10563
10768
  language = "text",
@@ -11144,7 +11349,7 @@ var init_MarkdownContent = __esm({
11144
11349
  init_Box();
11145
11350
  init_CodeBlock();
11146
11351
  init_cn();
11147
- MarkdownContent = React74__default.memo(
11352
+ MarkdownContent = React75__default.memo(
11148
11353
  ({ content, direction = "ltr", className }) => {
11149
11354
  const { t: _t } = useTranslate();
11150
11355
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -12471,7 +12676,7 @@ var init_StateMachineView = __esm({
12471
12676
  style: { top: title ? 30 : 0 },
12472
12677
  children: [
12473
12678
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
12474
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React74__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
12679
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React75__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
12475
12680
  StateNode,
12476
12681
  {
12477
12682
  state,
@@ -15095,8 +15300,8 @@ function MiniMap({
15095
15300
  tileAssets,
15096
15301
  unitAssets
15097
15302
  }) {
15098
- const canvasRef = React74.useRef(null);
15099
- const imgCacheRef = React74.useRef(/* @__PURE__ */ new Map());
15303
+ const canvasRef = React75.useRef(null);
15304
+ const imgCacheRef = React75.useRef(/* @__PURE__ */ new Map());
15100
15305
  function loadImg(url) {
15101
15306
  const cached = imgCacheRef.current.get(url);
15102
15307
  if (cached) return cached.complete ? cached : null;
@@ -15111,7 +15316,7 @@ function MiniMap({
15111
15316
  imgCacheRef.current.set(url, img);
15112
15317
  return null;
15113
15318
  }
15114
- React74.useEffect(() => {
15319
+ React75.useEffect(() => {
15115
15320
  const canvas = canvasRef.current;
15116
15321
  if (!canvas) return;
15117
15322
  const ctx = canvas.getContext("2d");
@@ -15558,76 +15763,6 @@ var init_useImageCache = __esm({
15558
15763
  init_verificationRegistry();
15559
15764
  }
15560
15765
  });
15561
-
15562
- // components/game/shared/atlasSlice.ts
15563
- function isTilesheet(a) {
15564
- return typeof a.tileWidth === "number";
15565
- }
15566
- function getAtlas(url, onReady) {
15567
- if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
15568
- atlasCache.set(url, void 0);
15569
- fetch(url).then((r) => r.json()).then((json) => {
15570
- atlasCache.set(url, json);
15571
- onReady();
15572
- }).catch(() => {
15573
- atlasCache.set(url, null);
15574
- });
15575
- return void 0;
15576
- }
15577
- function subRectFor(atlas, sprite) {
15578
- if (isTilesheet(atlas)) {
15579
- let col;
15580
- let row;
15581
- if (sprite.includes(",")) {
15582
- const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
15583
- col = c;
15584
- row = r;
15585
- } else {
15586
- const i = Number(sprite);
15587
- if (!Number.isFinite(i)) return null;
15588
- col = i % atlas.columns;
15589
- row = Math.floor(i / atlas.columns);
15590
- }
15591
- if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
15592
- const margin = atlas.margin ?? 0;
15593
- const spacing = atlas.spacing ?? 0;
15594
- return {
15595
- sx: margin + col * (atlas.tileWidth + spacing),
15596
- sy: margin + row * (atlas.tileHeight + spacing),
15597
- sw: atlas.tileWidth,
15598
- sh: atlas.tileHeight
15599
- };
15600
- }
15601
- const st = atlas.subTextures[sprite];
15602
- if (!st) return null;
15603
- return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
15604
- }
15605
- function isAtlasAsset(asset) {
15606
- return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
15607
- }
15608
- function resolveAssetSource(img, asset, onReady) {
15609
- if (isAtlasAsset(asset)) {
15610
- const atlas = getAtlas(asset.atlas, onReady);
15611
- if (!atlas) return null;
15612
- const rect = subRectFor(atlas, asset.sprite);
15613
- if (!rect) return null;
15614
- return { img, rect, aspect: rect.sw / rect.sh };
15615
- }
15616
- const natW = img.naturalWidth || 1;
15617
- const natH = img.naturalHeight || 1;
15618
- return { img, rect: null, aspect: natW / natH };
15619
- }
15620
- function blit(ctx, src, dx, dy, dw, dh) {
15621
- if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
15622
- else ctx.drawImage(src.img, dx, dy, dw, dh);
15623
- }
15624
- var atlasCache;
15625
- var init_atlasSlice = __esm({
15626
- "components/game/shared/atlasSlice.ts"() {
15627
- "use client";
15628
- atlasCache = /* @__PURE__ */ new Map();
15629
- }
15630
- });
15631
15766
  function useCamera() {
15632
15767
  const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
15633
15768
  const targetCameraRef = useRef(null);
@@ -16155,7 +16290,7 @@ function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
16155
16290
  }
16156
16291
  if (layout === "flat") {
16157
16292
  const screenX2 = tileX * scaledTileWidth + baseOffsetX;
16158
- const screenY2 = tileY * scaledFloorHeight;
16293
+ const screenY2 = tileY * scaledTileWidth;
16159
16294
  return { x: screenX2, y: screenY2 };
16160
16295
  }
16161
16296
  const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
@@ -16172,7 +16307,7 @@ function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric")
16172
16307
  }
16173
16308
  if (layout === "flat") {
16174
16309
  const col = Math.round((screenX - baseOffsetX) / scaledTileWidth);
16175
- const row = Math.round(screenY / scaledFloorHeight);
16310
+ const row = Math.round(screenY / scaledTileWidth);
16176
16311
  return { x: col, y: row };
16177
16312
  }
16178
16313
  const adjustedX = screenX - baseOffsetX;
@@ -16219,11 +16354,11 @@ function SideView({
16219
16354
  const canvasRef = useRef(null);
16220
16355
  const eventBus = useEventBus();
16221
16356
  const keysRef = useRef(/* @__PURE__ */ new Set());
16222
- const imageCache = useRef(/* @__PURE__ */ new Map());
16357
+ const imageCache2 = useRef(/* @__PURE__ */ new Map());
16223
16358
  const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
16224
16359
  const loadImage = useCallback((url) => {
16225
16360
  if (!url) return null;
16226
- const cached = imageCache.current.get(url);
16361
+ const cached = imageCache2.current.get(url);
16227
16362
  if (cached?.complete && cached.naturalWidth > 0) {
16228
16363
  if (!loadedImages.has(url)) setLoadedImages((prev) => new Set(prev).add(url));
16229
16364
  return cached;
@@ -16233,7 +16368,7 @@ function SideView({
16233
16368
  img.crossOrigin = "anonymous";
16234
16369
  img.src = url;
16235
16370
  img.onload = () => setLoadedImages((prev) => new Set(prev).add(url));
16236
- imageCache.current.set(url, img);
16371
+ imageCache2.current.set(url, img);
16237
16372
  }
16238
16373
  return null;
16239
16374
  }, [loadedImages]);
@@ -16350,7 +16485,10 @@ function SideView({
16350
16485
  camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
16351
16486
  }
16352
16487
  const bgImage = bgImg ? loadImage(bgImg.url) : null;
16353
- if (bgImage) {
16488
+ const bgSrc = bgImage ? resolveAssetSource(bgImage, bgImg, NOOP) : null;
16489
+ if (bgSrc) {
16490
+ blit(ctx, bgSrc, 0, 0, cw, ch);
16491
+ } else if (bgImage) {
16354
16492
  ctx.drawImage(bgImage, 0, 0, cw, ch);
16355
16493
  } else if (bg) {
16356
16494
  ctx.fillStyle = bg;
@@ -16548,6 +16686,7 @@ function Canvas2D({
16548
16686
  const isSide = projection === "side";
16549
16687
  const isFree = projection === "free";
16550
16688
  const flatLike = projection === "hex" || projection === "flat" || isFree;
16689
+ const squareGrid = projection === "flat";
16551
16690
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
16552
16691
  const unitsProp = Array.isArray(_unitsPropRaw) ? _unitsPropRaw : [];
16553
16692
  const featuresProp = Array.isArray(_featuresPropRaw) ? _featuresPropRaw : [];
@@ -16630,9 +16769,9 @@ function Canvas2D({
16630
16769
  const effectiveDiamondTopY = diamondTopYProp ?? DIAMOND_TOP_Y;
16631
16770
  const scaledDiamondTopY = effectiveDiamondTopY * scale;
16632
16771
  const baseOffsetX = useMemo(() => {
16633
- if (isFree) return 0;
16772
+ if (isFree || projection === "flat") return 0;
16634
16773
  return (gridHeight - 1) * (scaledTileWidth / 2);
16635
- }, [isFree, gridHeight, scaledTileWidth]);
16774
+ }, [isFree, projection, gridHeight, scaledTileWidth]);
16636
16775
  const validMoveSet = useMemo(() => new Set(validMoves.map((p) => `${p.x},${p.y}`)), [validMoves]);
16637
16776
  const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
16638
16777
  const spriteUrls = useMemo(() => {
@@ -16753,7 +16892,13 @@ function Canvas2D({
16753
16892
  ctx.clearRect(0, 0, viewportSize.width, viewportSize.height);
16754
16893
  if (backgroundImage) {
16755
16894
  const bgImg = getImage(backgroundImage.url);
16756
- if (bgImg) {
16895
+ const bgSrc = bgImg ? resolveAssetSource(bgImg, backgroundImage, bumpAtlas) : null;
16896
+ if (bgSrc?.rect) {
16897
+ const k = Math.max(viewportSize.width / bgSrc.rect.sw, viewportSize.height / bgSrc.rect.sh);
16898
+ const dw = bgSrc.rect.sw * k;
16899
+ const dh = bgSrc.rect.sh * k;
16900
+ blit(ctx, bgSrc, (viewportSize.width - dw) / 2, (viewportSize.height - dh) / 2, dw, dh);
16901
+ } else if (bgImg) {
16757
16902
  const cam2 = cameraRef.current;
16758
16903
  const patW = bgImg.naturalWidth;
16759
16904
  const patH = bgImg.naturalHeight;
@@ -16789,12 +16934,18 @@ function Canvas2D({
16789
16934
  const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
16790
16935
  if (src) {
16791
16936
  const drawW = scaledTileWidth;
16792
- const drawH = scaledTileWidth / src.aspect;
16937
+ const drawH = squareGrid ? scaledTileWidth : scaledTileWidth / src.aspect;
16793
16938
  const drawX = pos.x;
16794
16939
  const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
16795
16940
  blit(ctx, src, drawX, drawY, drawW, drawH);
16796
16941
  } else if (img && img.naturalWidth === 0) {
16797
16942
  ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
16943
+ } else if (squareGrid) {
16944
+ ctx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : tile.terrain === "stone" ? "#9ca3af" : "#4ade80";
16945
+ ctx.fillRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
16946
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
16947
+ ctx.lineWidth = 1;
16948
+ ctx.strokeRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
16798
16949
  } else {
16799
16950
  const centerX = pos.x + scaledTileWidth / 2;
16800
16951
  const topY = pos.y + scaledDiamondTopY;
@@ -16811,9 +16962,13 @@ function Canvas2D({
16811
16962
  ctx.stroke();
16812
16963
  }
16813
16964
  const drawHighlight = (color) => {
16965
+ ctx.fillStyle = color;
16966
+ if (squareGrid) {
16967
+ ctx.fillRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
16968
+ return;
16969
+ }
16814
16970
  const centerX = pos.x + scaledTileWidth / 2;
16815
16971
  const topY = pos.y + scaledDiamondTopY;
16816
- ctx.fillStyle = color;
16817
16972
  ctx.beginPath();
16818
16973
  ctx.moveTo(centerX, topY);
16819
16974
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -16830,7 +16985,7 @@ function Canvas2D({
16830
16985
  if (attackTargetSet.has(tileKey)) drawHighlight("rgba(239, 68, 68, 0.35)");
16831
16986
  if (debug2) {
16832
16987
  const centerX = pos.x + scaledTileWidth / 2;
16833
- const centerY = pos.y + scaledFloorHeight / 2 + scaledDiamondTopY;
16988
+ const centerY = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledFloorHeight / 2 + scaledDiamondTopY;
16834
16989
  ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
16835
16990
  ctx.font = `${12 * scale * 2}px monospace`;
16836
16991
  ctx.textAlign = "center";
@@ -16852,9 +17007,9 @@ function Canvas2D({
16852
17007
  const img = featureAsset?.url ? getImage(featureAsset.url) : null;
16853
17008
  const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
16854
17009
  const centerX = pos.x + scaledTileWidth / 2;
16855
- const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17010
+ const featureGroundY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
16856
17011
  const isCastle = feature.type === "castle";
16857
- const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
17012
+ const featureDrawH = squareGrid ? isCastle ? scaledTileWidth * 1.4 : scaledTileWidth * 0.8 : isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
16858
17013
  const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
16859
17014
  if (src) {
16860
17015
  const ar = src.aspect;
@@ -16893,11 +17048,11 @@ function Canvas2D({
16893
17048
  }
16894
17049
  const isSelected = unit.id === selectedUnitId;
16895
17050
  const centerX = pos.x + scaledTileWidth / 2;
16896
- const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17051
+ const groundY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
16897
17052
  const breatheOffset = 0;
16898
17053
  const unitAsset = resolveUnitAsset(unit);
16899
17054
  const img = unitAsset?.url ? getImage(unitAsset.url) : null;
16900
- const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
17055
+ const unitDrawH = squareGrid ? scaledTileWidth * 0.55 * spriteHeightRatio * unitScale : scaledFloorHeight * spriteHeightRatio * unitScale;
16901
17056
  const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
16902
17057
  const unitIsSheet = unit.spriteSheet?.url !== void 0;
16903
17058
  const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
@@ -16916,7 +17071,7 @@ function Canvas2D({
16916
17071
  if (unit.previousPosition && (unit.previousPosition.x !== unit.position.x || unit.previousPosition.y !== unit.position.y)) {
16917
17072
  const ghostPos = project(unit.previousPosition.x, unit.previousPosition.y, baseOffsetX);
16918
17073
  const ghostCenterX = ghostPos.x + scaledTileWidth / 2;
16919
- const ghostGroundY = ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17074
+ const ghostGroundY = squareGrid ? ghostPos.y + scaledTileWidth * 0.92 : ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
16920
17075
  ctx.save();
16921
17076
  ctx.globalAlpha = 0.25;
16922
17077
  if (img) {
@@ -16999,17 +17154,24 @@ function Canvas2D({
16999
17154
  }
17000
17155
  }
17001
17156
  for (const fx of effects) {
17002
- const spriteUrl = assetManifest?.effects?.[fx.key]?.url;
17003
- if (!spriteUrl) continue;
17004
- const img = getImage(spriteUrl);
17157
+ const fxAsset = assetManifest?.effects?.[fx.key];
17158
+ if (!fxAsset?.url) continue;
17159
+ const img = getImage(fxAsset.url);
17005
17160
  if (!img) continue;
17161
+ const src = resolveAssetSource(img, fxAsset, bumpAtlas);
17006
17162
  const pos = project(fx.x, fx.y, baseOffsetX);
17007
17163
  const cx = pos.x + scaledTileWidth / 2;
17008
- const cy = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17164
+ const cy = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17009
17165
  const alpha = Math.min(1, fx.ttl / 4);
17010
17166
  const prev = ctx.globalAlpha;
17011
17167
  ctx.globalAlpha = alpha;
17012
- ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
17168
+ if (src?.rect) {
17169
+ const dw = scaledTileWidth;
17170
+ const dh = dw / src.aspect;
17171
+ blit(ctx, src, cx - dw / 2, cy - dh / 2, dw, dh);
17172
+ } else {
17173
+ ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
17174
+ }
17013
17175
  ctx.globalAlpha = prev;
17014
17176
  }
17015
17177
  onDrawEffects?.(ctx, 0, getImage);
@@ -17022,6 +17184,7 @@ function Canvas2D({
17022
17184
  effects,
17023
17185
  project,
17024
17186
  flatLike,
17187
+ squareGrid,
17025
17188
  scale,
17026
17189
  debug2,
17027
17190
  resolveTerrainAsset,
@@ -17055,12 +17218,12 @@ function Canvas2D({
17055
17218
  if (!unit?.position) return;
17056
17219
  const pos = project(unit.position.x, unit.position.y, baseOffsetX);
17057
17220
  const centerX = pos.x + scaledTileWidth / 2;
17058
- const centerY = pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
17221
+ const centerY = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
17059
17222
  targetCameraRef.current = {
17060
17223
  x: centerX - viewportSize.width / 2,
17061
17224
  y: centerY - viewportSize.height / 2
17062
17225
  };
17063
- }, [camera, selectedUnitId, units, project, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
17226
+ }, [camera, selectedUnitId, units, project, baseOffsetX, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
17064
17227
  useEffect(() => {
17065
17228
  if (isSide || !interpolateUnits) return;
17066
17229
  unitInterp.onSnapshot(
@@ -17131,11 +17294,11 @@ function Canvas2D({
17131
17294
  if (!tileHoverEvent || !canvasRef.current) return;
17132
17295
  const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
17133
17296
  const adjustedX = world.x - scaledTileWidth / 2;
17134
- const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
17297
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
17135
17298
  const isoPos = unproject(adjustedX, adjustedY, baseOffsetX);
17136
17299
  const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
17137
17300
  if (tileExists) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
17138
- }, [screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
17301
+ }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
17139
17302
  const handleCanvasPointerUp = useCallback((e) => {
17140
17303
  singlePointerActiveRef.current = false;
17141
17304
  if (enableCamera) handlePointerUp();
@@ -17143,7 +17306,7 @@ function Canvas2D({
17143
17306
  if (!canvasRef.current) return;
17144
17307
  const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
17145
17308
  const adjustedX = world.x - scaledTileWidth / 2;
17146
- const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
17309
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
17147
17310
  const isoPos = unproject(adjustedX, adjustedY, baseOffsetX);
17148
17311
  const clickedUnit = units.find((u) => u.position?.x === isoPos.x && u.position?.y === isoPos.y);
17149
17312
  if (clickedUnit && unitClickEvent) {
@@ -17152,7 +17315,7 @@ function Canvas2D({
17152
17315
  const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
17153
17316
  if (tileExists) eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
17154
17317
  }
17155
- }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, units, tilesProp, unitClickEvent, tileClickEvent, eventBus]);
17318
+ }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, units, tilesProp, unitClickEvent, tileClickEvent, eventBus]);
17156
17319
  const handleCanvasPointerLeave = useCallback(() => {
17157
17320
  handleMouseLeave();
17158
17321
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
@@ -17202,11 +17365,12 @@ function Canvas2D({
17202
17365
  return units.filter((u) => !!u.position).map((u) => {
17203
17366
  const pos = project(u.position.x, u.position.y, baseOffsetX);
17204
17367
  const cam = cameraRef.current;
17368
+ const anchorY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
17205
17369
  const screenX = (pos.x + scaledTileWidth / 2 - (cam.x + viewportSize.width / 2)) * cam.zoom + viewportSize.width / 2;
17206
- const screenY = (pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5 - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
17370
+ const screenY = (anchorY - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
17207
17371
  return { unit: u, screenX, screenY };
17208
17372
  });
17209
- }, [units, project, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
17373
+ }, [units, project, baseOffsetX, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
17210
17374
  if (error) {
17211
17375
  return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
17212
17376
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -19903,9 +20067,9 @@ function ControlButton({
19903
20067
  className
19904
20068
  }) {
19905
20069
  const eventBus = useEventBus();
19906
- const [isPressed, setIsPressed] = React74.useState(false);
20070
+ const [isPressed, setIsPressed] = React75.useState(false);
19907
20071
  const actualPressed = pressed ?? isPressed;
19908
- const handlePointerDown = React74.useCallback(
20072
+ const handlePointerDown = React75.useCallback(
19909
20073
  (e) => {
19910
20074
  e.preventDefault();
19911
20075
  if (disabled) return;
@@ -19915,7 +20079,7 @@ function ControlButton({
19915
20079
  },
19916
20080
  [disabled, pressEvent, eventBus, onPress]
19917
20081
  );
19918
- const handlePointerUp = React74.useCallback(
20082
+ const handlePointerUp = React75.useCallback(
19919
20083
  (e) => {
19920
20084
  e.preventDefault();
19921
20085
  if (disabled) return;
@@ -19925,7 +20089,7 @@ function ControlButton({
19925
20089
  },
19926
20090
  [disabled, releaseEvent, eventBus, onRelease]
19927
20091
  );
19928
- const handlePointerLeave = React74.useCallback(
20092
+ const handlePointerLeave = React75.useCallback(
19929
20093
  (e) => {
19930
20094
  if (isPressed) {
19931
20095
  setIsPressed(false);
@@ -20018,8 +20182,8 @@ function ControlGrid({
20018
20182
  className
20019
20183
  }) {
20020
20184
  const eventBus = useEventBus();
20021
- const [active, setActive] = React74.useState(/* @__PURE__ */ new Set());
20022
- const handlePress = React74.useCallback(
20185
+ const [active, setActive] = React75.useState(/* @__PURE__ */ new Set());
20186
+ const handlePress = React75.useCallback(
20023
20187
  (id) => {
20024
20188
  setActive((prev) => new Set(prev).add(id));
20025
20189
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -20033,7 +20197,7 @@ function ControlGrid({
20033
20197
  },
20034
20198
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
20035
20199
  );
20036
- const handleRelease = React74.useCallback(
20200
+ const handleRelease = React75.useCallback(
20037
20201
  (id) => {
20038
20202
  setActive((prev) => {
20039
20203
  const next = new Set(prev);
@@ -21299,8 +21463,8 @@ var init_Menu = __esm({
21299
21463
  "bottom-end": "bottom-start"
21300
21464
  };
21301
21465
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
21302
- const triggerChild = React74__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
21303
- const triggerElement = React74__default.cloneElement(
21466
+ const triggerChild = React75__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
21467
+ const triggerElement = React75__default.cloneElement(
21304
21468
  triggerChild,
21305
21469
  {
21306
21470
  ref: triggerRef,
@@ -21395,14 +21559,14 @@ function useDataDnd(args) {
21395
21559
  const isZone = Boolean(dragGroup || accepts || sortable);
21396
21560
  const enabled = isZone || Boolean(dndRoot);
21397
21561
  const eventBus = useEventBus();
21398
- const parentRoot = React74__default.useContext(RootCtx);
21562
+ const parentRoot = React75__default.useContext(RootCtx);
21399
21563
  const isRoot = enabled && parentRoot === null;
21400
- const zoneId = React74__default.useId();
21564
+ const zoneId = React75__default.useId();
21401
21565
  const ownGroup = dragGroup ?? accepts ?? zoneId;
21402
- const [optimisticOrders, setOptimisticOrders] = React74__default.useState(() => /* @__PURE__ */ new Map());
21403
- const optimisticOrdersRef = React74__default.useRef(optimisticOrders);
21566
+ const [optimisticOrders, setOptimisticOrders] = React75__default.useState(() => /* @__PURE__ */ new Map());
21567
+ const optimisticOrdersRef = React75__default.useRef(optimisticOrders);
21404
21568
  optimisticOrdersRef.current = optimisticOrders;
21405
- const clearOptimisticOrder = React74__default.useCallback((group) => {
21569
+ const clearOptimisticOrder = React75__default.useCallback((group) => {
21406
21570
  setOptimisticOrders((prev) => {
21407
21571
  if (!prev.has(group)) return prev;
21408
21572
  const next = new Map(prev);
@@ -21427,7 +21591,7 @@ function useDataDnd(args) {
21427
21591
  const raw = it[dndItemIdField];
21428
21592
  return raw != null ? String(raw) : `__idx_${idx}`;
21429
21593
  }).join("|");
21430
- const itemIds = React74__default.useMemo(
21594
+ const itemIds = React75__default.useMemo(
21431
21595
  () => orderedItems.map((it, idx) => {
21432
21596
  const raw = it[dndItemIdField];
21433
21597
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -21438,7 +21602,7 @@ function useDataDnd(args) {
21438
21602
  const raw = it[dndItemIdField];
21439
21603
  return raw != null ? String(raw) : `__${idx}`;
21440
21604
  }).join("|");
21441
- React74__default.useEffect(() => {
21605
+ React75__default.useEffect(() => {
21442
21606
  const root = isRoot ? null : parentRoot;
21443
21607
  if (root) {
21444
21608
  root.clearOptimisticOrder(ownGroup);
@@ -21446,20 +21610,20 @@ function useDataDnd(args) {
21446
21610
  clearOptimisticOrder(ownGroup);
21447
21611
  }
21448
21612
  }, [itemsContentSig, ownGroup]);
21449
- const zonesRef = React74__default.useRef(/* @__PURE__ */ new Map());
21450
- const registerZone = React74__default.useCallback((zoneId2, meta2) => {
21613
+ const zonesRef = React75__default.useRef(/* @__PURE__ */ new Map());
21614
+ const registerZone = React75__default.useCallback((zoneId2, meta2) => {
21451
21615
  zonesRef.current.set(zoneId2, meta2);
21452
21616
  }, []);
21453
- const unregisterZone = React74__default.useCallback((zoneId2) => {
21617
+ const unregisterZone = React75__default.useCallback((zoneId2) => {
21454
21618
  zonesRef.current.delete(zoneId2);
21455
21619
  }, []);
21456
- const [activeDrag, setActiveDrag] = React74__default.useState(null);
21457
- const [overZoneGroup, setOverZoneGroup] = React74__default.useState(null);
21458
- const meta = React74__default.useMemo(
21620
+ const [activeDrag, setActiveDrag] = React75__default.useState(null);
21621
+ const [overZoneGroup, setOverZoneGroup] = React75__default.useState(null);
21622
+ const meta = React75__default.useMemo(
21459
21623
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
21460
21624
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
21461
21625
  );
21462
- React74__default.useEffect(() => {
21626
+ React75__default.useEffect(() => {
21463
21627
  const target = isRoot ? null : parentRoot;
21464
21628
  if (!target) {
21465
21629
  zonesRef.current.set(zoneId, meta);
@@ -21478,7 +21642,7 @@ function useDataDnd(args) {
21478
21642
  }, [parentRoot, isRoot, zoneId, meta]);
21479
21643
  const sensors = useAlmadarDndSensors(true);
21480
21644
  const collisionDetection = almadarDndCollisionDetection;
21481
- const findZoneByItem = React74__default.useCallback(
21645
+ const findZoneByItem = React75__default.useCallback(
21482
21646
  (id) => {
21483
21647
  for (const z of zonesRef.current.values()) {
21484
21648
  if (z.itemIds.includes(id)) return z;
@@ -21487,7 +21651,7 @@ function useDataDnd(args) {
21487
21651
  },
21488
21652
  []
21489
21653
  );
21490
- React74__default.useCallback(
21654
+ React75__default.useCallback(
21491
21655
  (group) => {
21492
21656
  for (const z of zonesRef.current.values()) {
21493
21657
  if (z.group === group) return z;
@@ -21496,7 +21660,7 @@ function useDataDnd(args) {
21496
21660
  },
21497
21661
  []
21498
21662
  );
21499
- const handleDragEnd = React74__default.useCallback(
21663
+ const handleDragEnd = React75__default.useCallback(
21500
21664
  (event) => {
21501
21665
  const { active, over } = event;
21502
21666
  const activeIdStr = String(active.id);
@@ -21587,8 +21751,8 @@ function useDataDnd(args) {
21587
21751
  },
21588
21752
  [eventBus]
21589
21753
  );
21590
- const sortableData = React74__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
21591
- const SortableItem = React74__default.useCallback(
21754
+ const sortableData = React75__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
21755
+ const SortableItem = React75__default.useCallback(
21592
21756
  ({ id, children }) => {
21593
21757
  const {
21594
21758
  attributes,
@@ -21628,7 +21792,7 @@ function useDataDnd(args) {
21628
21792
  id: droppableId,
21629
21793
  data: sortableData
21630
21794
  });
21631
- const ctx = React74__default.useContext(RootCtx);
21795
+ const ctx = React75__default.useContext(RootCtx);
21632
21796
  const activeDrag2 = ctx?.activeDrag ?? null;
21633
21797
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
21634
21798
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -21643,7 +21807,7 @@ function useDataDnd(args) {
21643
21807
  showForeignPlaceholder,
21644
21808
  ctxAvailable: ctx != null
21645
21809
  });
21646
- React74__default.useEffect(() => {
21810
+ React75__default.useEffect(() => {
21647
21811
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
21648
21812
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
21649
21813
  return /* @__PURE__ */ jsx(
@@ -21657,11 +21821,11 @@ function useDataDnd(args) {
21657
21821
  }
21658
21822
  );
21659
21823
  };
21660
- const rootContextValue = React74__default.useMemo(
21824
+ const rootContextValue = React75__default.useMemo(
21661
21825
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
21662
21826
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
21663
21827
  );
21664
- const handleDragStart = React74__default.useCallback((event) => {
21828
+ const handleDragStart = React75__default.useCallback((event) => {
21665
21829
  const sourceZone = findZoneByItem(event.active.id);
21666
21830
  const rect = event.active.rect.current.initial;
21667
21831
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -21680,7 +21844,7 @@ function useDataDnd(args) {
21680
21844
  isRoot
21681
21845
  });
21682
21846
  }, [findZoneByItem, isRoot, zoneId]);
21683
- const handleDragOver = React74__default.useCallback((event) => {
21847
+ const handleDragOver = React75__default.useCallback((event) => {
21684
21848
  const { active, over } = event;
21685
21849
  const overData = over?.data?.current;
21686
21850
  const overGroup = overData?.dndGroup ?? null;
@@ -21750,7 +21914,7 @@ function useDataDnd(args) {
21750
21914
  return next;
21751
21915
  });
21752
21916
  }, []);
21753
- const handleDragCancel = React74__default.useCallback((event) => {
21917
+ const handleDragCancel = React75__default.useCallback((event) => {
21754
21918
  setActiveDrag(null);
21755
21919
  setOverZoneGroup(null);
21756
21920
  dndLog.warn("dragCancel", {
@@ -21758,12 +21922,12 @@ function useDataDnd(args) {
21758
21922
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
21759
21923
  });
21760
21924
  }, []);
21761
- const handleDragEndWithCleanup = React74__default.useCallback((event) => {
21925
+ const handleDragEndWithCleanup = React75__default.useCallback((event) => {
21762
21926
  handleDragEnd(event);
21763
21927
  setActiveDrag(null);
21764
21928
  setOverZoneGroup(null);
21765
21929
  }, [handleDragEnd]);
21766
- const wrapContainer = React74__default.useCallback(
21930
+ const wrapContainer = React75__default.useCallback(
21767
21931
  (children) => {
21768
21932
  if (!enabled) return children;
21769
21933
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -21817,7 +21981,7 @@ var init_useDataDnd = __esm({
21817
21981
  init_useAlmadarDndCollision();
21818
21982
  init_Box();
21819
21983
  dndLog = createLogger("almadar:ui:dnd");
21820
- RootCtx = React74__default.createContext(null);
21984
+ RootCtx = React75__default.createContext(null);
21821
21985
  }
21822
21986
  });
21823
21987
  function renderIconInput(icon, props) {
@@ -22343,7 +22507,7 @@ function DataList({
22343
22507
  }) {
22344
22508
  const eventBus = useEventBus();
22345
22509
  const { t } = useTranslate();
22346
- const [visibleCount, setVisibleCount] = React74__default.useState(pageSize || Infinity);
22510
+ const [visibleCount, setVisibleCount] = React75__default.useState(pageSize || Infinity);
22347
22511
  const fieldDefs = fields ?? columns ?? [];
22348
22512
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
22349
22513
  const dnd = useDataDnd({
@@ -22362,7 +22526,7 @@ function DataList({
22362
22526
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
22363
22527
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
22364
22528
  const hasRenderProp = typeof children === "function";
22365
- React74__default.useEffect(() => {
22529
+ React75__default.useEffect(() => {
22366
22530
  const renderItemTypeOf = typeof schemaRenderItem;
22367
22531
  const childrenTypeOf = typeof children;
22368
22532
  if (data.length > 0 && !hasRenderProp) {
@@ -22466,7 +22630,7 @@ function DataList({
22466
22630
  const items2 = [...data];
22467
22631
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
22468
22632
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
22469
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
22633
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
22470
22634
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
22471
22635
  group.items.map((itemData, index) => {
22472
22636
  const id = itemData.id || `${gi}-${index}`;
@@ -22607,7 +22771,7 @@ function DataList({
22607
22771
  className
22608
22772
  ),
22609
22773
  children: [
22610
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
22774
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
22611
22775
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
22612
22776
  group.items.map(
22613
22777
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -22714,8 +22878,8 @@ function ScalarControl({
22714
22878
  }
22715
22879
  const numeric = typeof value === "number";
22716
22880
  const initial = value === null ? "" : String(value);
22717
- const [draft, setDraft] = React74__default.useState(initial);
22718
- React74__default.useEffect(() => setDraft(initial), [initial]);
22881
+ const [draft, setDraft] = React75__default.useState(initial);
22882
+ React75__default.useEffect(() => setDraft(initial), [initial]);
22719
22883
  const commit = () => {
22720
22884
  if (numeric) {
22721
22885
  const n = draft.trim() === "" ? 0 : Number(draft);
@@ -22783,8 +22947,8 @@ function Row({
22783
22947
  onRemove,
22784
22948
  readonly
22785
22949
  }) {
22786
- const [keyDraft, setKeyDraft] = React74__default.useState(rowKey);
22787
- React74__default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
22950
+ const [keyDraft, setKeyDraft] = React75__default.useState(rowKey);
22951
+ React75__default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
22788
22952
  const container = isObj(value) || isArr(value);
22789
22953
  return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "group w-max min-w-full", children: [
22790
22954
  /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
@@ -22827,7 +22991,7 @@ function ContainerNode({
22827
22991
  depth,
22828
22992
  readonly
22829
22993
  }) {
22830
- const [open, setOpen] = React74__default.useState(depth < 2);
22994
+ const [open, setOpen] = React75__default.useState(depth < 2);
22831
22995
  const array = isArr(value);
22832
22996
  const entries = array ? value.map((v, i) => [String(i), v]) : Object.entries(value);
22833
22997
  const setObjValue = (key, next) => {
@@ -22969,7 +23133,7 @@ var init_FormSection = __esm({
22969
23133
  columns = 1,
22970
23134
  className
22971
23135
  }) => {
22972
- const [collapsed, setCollapsed] = React74__default.useState(defaultCollapsed);
23136
+ const [collapsed, setCollapsed] = React75__default.useState(defaultCollapsed);
22973
23137
  const { t } = useTranslate();
22974
23138
  const eventBus = useEventBus();
22975
23139
  const gridClass = {
@@ -22977,7 +23141,7 @@ var init_FormSection = __esm({
22977
23141
  2: "grid-cols-1 md:grid-cols-2",
22978
23142
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
22979
23143
  }[columns];
22980
- React74__default.useCallback(() => {
23144
+ React75__default.useCallback(() => {
22981
23145
  if (collapsible) {
22982
23146
  setCollapsed((prev) => !prev);
22983
23147
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -23385,8 +23549,8 @@ function TextLikeControl({
23385
23549
  onCommit
23386
23550
  }) {
23387
23551
  const initial = value === void 0 || value === null ? "" : String(value);
23388
- const [draft, setDraft] = React74__default.useState(initial);
23389
- React74__default.useEffect(() => setDraft(initial), [initial]);
23552
+ const [draft, setDraft] = React75__default.useState(initial);
23553
+ React75__default.useEffect(() => setDraft(initial), [initial]);
23390
23554
  const commit = () => {
23391
23555
  if (numeric) {
23392
23556
  const n = draft.trim() === "" ? 0 : Number(draft);
@@ -23571,14 +23735,14 @@ var init_NodeSlotEditor = __esm({
23571
23735
  isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
23572
23736
  NodeSlotEditor = ({ value, onChange, className }) => {
23573
23737
  const { type, props, wasArray } = normalize(value);
23574
- const patterns = React74__default.useMemo(() => {
23738
+ const patterns = React75__default.useMemo(() => {
23575
23739
  try {
23576
23740
  return [...getKnownPatterns()].sort();
23577
23741
  } catch {
23578
23742
  return [];
23579
23743
  }
23580
23744
  }, []);
23581
- const options = React74__default.useMemo(
23745
+ const options = React75__default.useMemo(
23582
23746
  () => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((p) => ({ value: p, label: p }))],
23583
23747
  [patterns]
23584
23748
  );
@@ -23590,7 +23754,7 @@ var init_NodeSlotEditor = __esm({
23590
23754
  const pattern = { type: nextType, ...nextProps };
23591
23755
  onChange(wasArray || value === void 0 ? [pattern] : pattern);
23592
23756
  };
23593
- const schemaEntries = React74__default.useMemo(() => {
23757
+ const schemaEntries = React75__default.useMemo(() => {
23594
23758
  if (!type) return [];
23595
23759
  const def = getPatternDefinition(type);
23596
23760
  if (!def?.propsSchema) return [];
@@ -24492,7 +24656,7 @@ var init_Flex = __esm({
24492
24656
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
24493
24657
  }
24494
24658
  }
24495
- return React74__default.createElement(Component, {
24659
+ return React75__default.createElement(Component, {
24496
24660
  className: cn(
24497
24661
  inline ? "inline-flex" : "flex",
24498
24662
  directionStyles[direction],
@@ -24611,7 +24775,7 @@ var init_Grid = __esm({
24611
24775
  as: Component = "div"
24612
24776
  }) => {
24613
24777
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
24614
- return React74__default.createElement(
24778
+ return React75__default.createElement(
24615
24779
  Component,
24616
24780
  {
24617
24781
  className: cn(
@@ -24807,9 +24971,9 @@ var init_Popover = __esm({
24807
24971
  onMouseLeave: handleClose,
24808
24972
  onPointerDown: tapTriggerProps.onPointerDown
24809
24973
  };
24810
- const childElement = React74__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24974
+ const childElement = React75__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24811
24975
  const childPointerDown = childElement.props.onPointerDown;
24812
- const triggerElement = React74__default.cloneElement(
24976
+ const triggerElement = React75__default.cloneElement(
24813
24977
  childElement,
24814
24978
  {
24815
24979
  ref: triggerRef,
@@ -25661,9 +25825,9 @@ var init_Tooltip = __esm({
25661
25825
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
25662
25826
  };
25663
25827
  }, []);
25664
- const triggerElement = React74__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25828
+ const triggerElement = React75__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25665
25829
  const childPointerDown = triggerElement.props.onPointerDown;
25666
- const trigger = React74__default.cloneElement(triggerElement, {
25830
+ const trigger = React75__default.cloneElement(triggerElement, {
25667
25831
  ref: triggerRef,
25668
25832
  onMouseEnter: handleMouseEnter,
25669
25833
  onMouseLeave: handleMouseLeave,
@@ -25753,7 +25917,7 @@ var init_WizardProgress = __esm({
25753
25917
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
25754
25918
  const isActive = index === currentStep;
25755
25919
  const isCompleted = index < currentStep;
25756
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
25920
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
25757
25921
  /* @__PURE__ */ jsx(
25758
25922
  "button",
25759
25923
  {
@@ -26867,13 +27031,12 @@ function GameCard({
26867
27031
  className
26868
27032
  }) {
26869
27033
  const eventBus = useEventBus();
26870
- const handleClick = React74.useCallback(() => {
27034
+ const handleClick = React75.useCallback(() => {
26871
27035
  if (disabled) return;
26872
27036
  onClick?.(id);
26873
27037
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
26874
27038
  }, [disabled, id, onClick, clickEvent, eventBus]);
26875
27039
  const artPx = artPxMap[size];
26876
- const frameStyle = frameAsset?.url ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%", backgroundRepeat: "no-repeat" } : {};
26877
27040
  return /* @__PURE__ */ jsxs(
26878
27041
  Button,
26879
27042
  {
@@ -26881,11 +27044,10 @@ function GameCard({
26881
27044
  onClick: handleClick,
26882
27045
  disabled,
26883
27046
  title: name,
26884
- style: frameStyle,
26885
27047
  className: cn(
26886
- "relative flex flex-col items-center rounded-interactive",
26887
- "bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
26888
- frameAsset?.url ? "border-0" : "border-2",
27048
+ "relative isolate flex flex-col items-center rounded-interactive",
27049
+ "px-1.5 pt-1.5 pb-1 transition-all duration-150",
27050
+ frameAsset?.url ? "border-0" : "border-2 bg-card/90",
26889
27051
  cardSizeMap[size],
26890
27052
  disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
26891
27053
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1",
@@ -26893,6 +27055,7 @@ function GameCard({
26893
27055
  className
26894
27056
  ),
26895
27057
  children: [
27058
+ frameAsset?.url && /* @__PURE__ */ jsx(AtlasImage, { asset: frameAsset, fill: true, fit: "fill", "aria-hidden": true, style: { zIndex: -1 } }),
26896
27059
  cost != null && /* @__PURE__ */ jsx(
26897
27060
  Typography,
26898
27061
  {
@@ -26931,6 +27094,7 @@ var init_GameCard = __esm({
26931
27094
  init_Box();
26932
27095
  init_Button();
26933
27096
  init_Typography();
27097
+ init_AtlasImage();
26934
27098
  init_GameIcon();
26935
27099
  cardSizeMap = {
26936
27100
  sm: "w-16 h-24",
@@ -26948,7 +27112,7 @@ var init_GameCard = __esm({
26948
27112
  }
26949
27113
  });
26950
27114
  function ScoreDisplay({
26951
- assetUrl = DEFAULT_ASSET_URL5,
27115
+ assetUrl,
26952
27116
  value,
26953
27117
  score,
26954
27118
  label,
@@ -26975,7 +27139,7 @@ function ScoreDisplay({
26975
27139
  }
26976
27140
  );
26977
27141
  }
26978
- var sizeMap8, DEFAULT_ASSET_URL5;
27142
+ var sizeMap8;
26979
27143
  var init_ScoreDisplay = __esm({
26980
27144
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
26981
27145
  init_cn();
@@ -26989,11 +27153,6 @@ var init_ScoreDisplay = __esm({
26989
27153
  lg: "text-2xl",
26990
27154
  xl: "text-4xl"
26991
27155
  };
26992
- DEFAULT_ASSET_URL5 = {
26993
- url: "https://almadar-kflow-assets.web.app/shared/effects/particles/star_01.png",
26994
- role: "effect",
26995
- category: "effect"
26996
- };
26997
27156
  ScoreDisplay.displayName = "ScoreDisplay";
26998
27157
  }
26999
27158
  });
@@ -27117,7 +27276,7 @@ function isKnownState(s) {
27117
27276
  return s in DEFAULT_STATE_STYLES;
27118
27277
  }
27119
27278
  function StateIndicator({
27120
- assetUrl = DEFAULT_ASSET_URL6,
27279
+ assetUrl = DEFAULT_ASSET_URL5,
27121
27280
  state = "idle",
27122
27281
  label,
27123
27282
  size = "md",
@@ -27147,14 +27306,14 @@ function StateIndicator({
27147
27306
  }
27148
27307
  );
27149
27308
  }
27150
- var DEFAULT_ASSET_URL6, DEFAULT_STATE_STYLES, DEFAULT_STYLE, STATIC_STATES, SIZE_CLASSES;
27309
+ var DEFAULT_ASSET_URL5, DEFAULT_STATE_STYLES, DEFAULT_STYLE, STATIC_STATES, SIZE_CLASSES;
27151
27310
  var init_StateIndicator = __esm({
27152
27311
  "components/game/2d/atoms/StateIndicator.tsx"() {
27153
27312
  init_Box();
27154
27313
  init_Icon();
27155
27314
  init_cn();
27156
27315
  init_GameIcon();
27157
- DEFAULT_ASSET_URL6 = {
27316
+ DEFAULT_ASSET_URL5 = {
27158
27317
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
27159
27318
  role: "ui",
27160
27319
  category: "state"
@@ -27240,7 +27399,7 @@ var init_TimerDisplay = __esm({
27240
27399
  }
27241
27400
  });
27242
27401
  function ResourceCounter({
27243
- assetUrl = DEFAULT_ASSET_URL7,
27402
+ assetUrl = DEFAULT_ASSET_URL6,
27244
27403
  icon,
27245
27404
  label = "Gold",
27246
27405
  value = 250,
@@ -27273,7 +27432,7 @@ function ResourceCounter({
27273
27432
  }
27274
27433
  );
27275
27434
  }
27276
- var colorTokenClasses2, DEFAULT_ASSET_URL7, sizeMap10;
27435
+ var colorTokenClasses2, DEFAULT_ASSET_URL6, sizeMap10;
27277
27436
  var init_ResourceCounter = __esm({
27278
27437
  "components/game/2d/atoms/ResourceCounter.tsx"() {
27279
27438
  init_cn();
@@ -27289,7 +27448,7 @@ var init_ResourceCounter = __esm({
27289
27448
  error: "text-error",
27290
27449
  muted: "text-muted-foreground"
27291
27450
  };
27292
- DEFAULT_ASSET_URL7 = {
27451
+ DEFAULT_ASSET_URL6 = {
27293
27452
  url: "https://almadar-kflow-assets.web.app/shared/world-map/gold_mine.png",
27294
27453
  role: "ui",
27295
27454
  category: "coin"
@@ -27303,7 +27462,7 @@ var init_ResourceCounter = __esm({
27303
27462
  }
27304
27463
  });
27305
27464
  function ItemSlot({
27306
- assetUrl = DEFAULT_ASSET_URL8,
27465
+ assetUrl = DEFAULT_ASSET_URL7,
27307
27466
  icon = "sword",
27308
27467
  label = "Iron Sword",
27309
27468
  quantity,
@@ -27358,7 +27517,7 @@ function ItemSlot({
27358
27517
  }
27359
27518
  );
27360
27519
  }
27361
- var sizeMap11, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL8, assetSizeMap;
27520
+ var sizeMap11, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL7, assetSizeMap;
27362
27521
  var init_ItemSlot = __esm({
27363
27522
  "components/game/2d/atoms/ItemSlot.tsx"() {
27364
27523
  "use client";
@@ -27388,7 +27547,7 @@ var init_ItemSlot = __esm({
27388
27547
  epic: "shadow-lg",
27389
27548
  legendary: "shadow-lg"
27390
27549
  };
27391
- DEFAULT_ASSET_URL8 = {
27550
+ DEFAULT_ASSET_URL7 = {
27392
27551
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
27393
27552
  role: "item",
27394
27553
  category: "item"
@@ -27402,7 +27561,7 @@ var init_ItemSlot = __esm({
27402
27561
  }
27403
27562
  });
27404
27563
  function TurnIndicator({
27405
- assetUrl = DEFAULT_ASSET_URL9,
27564
+ assetUrl = DEFAULT_ASSET_URL8,
27406
27565
  currentTurn = 1,
27407
27566
  maxTurns,
27408
27567
  activeTeam,
@@ -27442,7 +27601,7 @@ function TurnIndicator({
27442
27601
  }
27443
27602
  );
27444
27603
  }
27445
- var sizeMap12, DEFAULT_ASSET_URL9;
27604
+ var sizeMap12, DEFAULT_ASSET_URL8;
27446
27605
  var init_TurnIndicator = __esm({
27447
27606
  "components/game/2d/atoms/TurnIndicator.tsx"() {
27448
27607
  init_cn();
@@ -27454,7 +27613,7 @@ var init_TurnIndicator = __esm({
27454
27613
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
27455
27614
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
27456
27615
  };
27457
- DEFAULT_ASSET_URL9 = {
27616
+ DEFAULT_ASSET_URL8 = {
27458
27617
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/symbol_01.png",
27459
27618
  role: "ui",
27460
27619
  category: "turn"
@@ -27463,7 +27622,7 @@ var init_TurnIndicator = __esm({
27463
27622
  }
27464
27623
  });
27465
27624
  function WaypointMarker({
27466
- assetUrl = DEFAULT_ASSET_URL10,
27625
+ assetUrl = DEFAULT_ASSET_URL9,
27467
27626
  label,
27468
27627
  icon,
27469
27628
  active = true,
@@ -27523,7 +27682,7 @@ function WaypointMarker({
27523
27682
  )
27524
27683
  ] });
27525
27684
  }
27526
- var DEFAULT_ASSET_URL10, sizeMap13, checkIcon;
27685
+ var DEFAULT_ASSET_URL9, sizeMap13, checkIcon;
27527
27686
  var init_WaypointMarker = __esm({
27528
27687
  "components/game/2d/atoms/WaypointMarker.tsx"() {
27529
27688
  init_cn();
@@ -27531,7 +27690,7 @@ var init_WaypointMarker = __esm({
27531
27690
  init_Box();
27532
27691
  init_Typography();
27533
27692
  init_GameIcon();
27534
- DEFAULT_ASSET_URL10 = {
27693
+ DEFAULT_ASSET_URL9 = {
27535
27694
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
27536
27695
  role: "ui",
27537
27696
  category: "waypoint"
@@ -27552,7 +27711,7 @@ function formatDuration(seconds) {
27552
27711
  return `${Math.round(seconds)}s`;
27553
27712
  }
27554
27713
  function StatusEffect({
27555
- assetUrl = DEFAULT_ASSET_URL11,
27714
+ assetUrl = DEFAULT_ASSET_URL10,
27556
27715
  icon,
27557
27716
  label = "Shield",
27558
27717
  duration = 30,
@@ -27603,7 +27762,7 @@ function StatusEffect({
27603
27762
  label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
27604
27763
  ] });
27605
27764
  }
27606
- var DEFAULT_ASSET_URL11, sizeMap14, variantStyles8;
27765
+ var DEFAULT_ASSET_URL10, sizeMap14, variantStyles8;
27607
27766
  var init_StatusEffect = __esm({
27608
27767
  "components/game/2d/atoms/StatusEffect.tsx"() {
27609
27768
  init_cn();
@@ -27611,7 +27770,7 @@ var init_StatusEffect = __esm({
27611
27770
  init_Box();
27612
27771
  init_Typography();
27613
27772
  init_GameIcon();
27614
- DEFAULT_ASSET_URL11 = {
27773
+ DEFAULT_ASSET_URL10 = {
27615
27774
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
27616
27775
  role: "ui",
27617
27776
  category: "effect"
@@ -27775,7 +27934,7 @@ function InventoryGrid({
27775
27934
  const eventBus = useEventBus();
27776
27935
  const slotCount = totalSlots ?? items.length;
27777
27936
  const emptySlotCount = Math.max(0, slotCount - items.length);
27778
- const handleSelect = React74.useCallback(
27937
+ const handleSelect = React75.useCallback(
27779
27938
  (id) => {
27780
27939
  onSelect?.(id);
27781
27940
  if (selectEvent) {
@@ -27992,7 +28151,7 @@ function GameMenu({
27992
28151
  }) {
27993
28152
  const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
27994
28153
  const eventBus = useEventBus();
27995
- const handleOptionClick = React74.useCallback(
28154
+ const handleOptionClick = React75.useCallback(
27996
28155
  (option) => {
27997
28156
  if (option.event) {
27998
28157
  eventBus.emit(`UI:${option.event}`, { option });
@@ -28218,7 +28377,7 @@ function StateGraph({
28218
28377
  }) {
28219
28378
  const eventBus = useEventBus();
28220
28379
  const nodes = states ?? [];
28221
- const positions = React74.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
28380
+ const positions = React75.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
28222
28381
  return /* @__PURE__ */ jsxs(
28223
28382
  Box,
28224
28383
  {
@@ -28654,7 +28813,7 @@ function LinearView({
28654
28813
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
28655
28814
  const isDone = i < currentIdx;
28656
28815
  const isCurrent = i === currentIdx;
28657
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
28816
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
28658
28817
  i > 0 && /* @__PURE__ */ jsx(
28659
28818
  Typography,
28660
28819
  {
@@ -29287,7 +29446,7 @@ function SequenceBar({
29287
29446
  else onSlotRemove?.(index);
29288
29447
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
29289
29448
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
29290
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
29449
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
29291
29450
  i > 0 && /* @__PURE__ */ jsx(
29292
29451
  Typography,
29293
29452
  {
@@ -31173,82 +31332,167 @@ var init_GameTemplate = __esm({
31173
31332
  GameTemplate.displayName = "GameTemplate";
31174
31333
  }
31175
31334
  });
31176
- var GameShell;
31335
+ var FONT_BASE, GAME_FONTS, FONT_FACES, GameShell;
31177
31336
  var init_GameShell = __esm({
31178
31337
  "components/game/2d/templates/GameShell.tsx"() {
31179
31338
  init_cn();
31180
31339
  init_Box();
31181
- init_Stack();
31182
31340
  init_Typography();
31341
+ init_AtlasImage();
31342
+ FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
31343
+ GAME_FONTS = {
31344
+ future: "Kenney Future",
31345
+ "future-narrow": "Kenney Future Narrow",
31346
+ pixel: "Kenney Pixel",
31347
+ blocks: "Kenney Blocks",
31348
+ mini: "Kenney Mini"
31349
+ };
31350
+ FONT_FACES = `
31351
+ @font-face { font-family: 'Kenney Future'; src: url('${FONT_BASE}/Kenney%20Future.ttf') format('truetype'); font-display: swap; }
31352
+ @font-face { font-family: 'Kenney Future Narrow'; src: url('${FONT_BASE}/Kenney%20Future%20Narrow.ttf') format('truetype'); font-display: swap; }
31353
+ @font-face { font-family: 'Kenney Pixel'; src: url('${FONT_BASE}/Kenney%20Pixel.ttf') format('truetype'); font-display: swap; }
31354
+ @font-face { font-family: 'Kenney Blocks'; src: url('${FONT_BASE}/Kenney%20Blocks.ttf') format('truetype'); font-display: swap; }
31355
+ @font-face { font-family: 'Kenney Mini'; src: url('${FONT_BASE}/Kenney%20Mini.ttf') format('truetype'); font-display: swap; }
31356
+ .game-shell, .game-shell * { font-family: inherit; }
31357
+ `;
31183
31358
  GameShell = ({
31184
31359
  appName = "Game",
31185
31360
  hud,
31361
+ addons,
31362
+ controls,
31363
+ overlay,
31186
31364
  className,
31187
31365
  showTopBar = true,
31188
31366
  children,
31189
31367
  backgroundAsset,
31190
- hudBackgroundAsset
31368
+ hudBackgroundAsset,
31369
+ fontFamily = "future"
31191
31370
  }) => {
31371
+ const font = GAME_FONTS[fontFamily] ?? fontFamily;
31192
31372
  return /* @__PURE__ */ jsxs(
31193
31373
  Box,
31194
31374
  {
31195
- display: "flex",
31196
- className: cn(
31197
- "game-shell",
31198
- "flex-col w-full h-screen overflow-hidden",
31199
- className
31200
- ),
31375
+ className: cn("game-shell", className),
31201
31376
  style: {
31377
+ position: "relative",
31202
31378
  width: "100vw",
31203
31379
  height: "100vh",
31204
31380
  overflow: "hidden",
31205
- background: backgroundAsset ? `url(${backgroundAsset.url}) center/cover no-repeat` : "var(--color-background, #0a0a0f)",
31206
- color: "var(--color-text, #e0e0e0)"
31381
+ background: "var(--color-background, #0a0a0f)",
31382
+ color: "var(--color-text, #e0e0e0)",
31383
+ fontFamily: `'${font}', system-ui, sans-serif`
31207
31384
  },
31208
31385
  children: [
31209
- showTopBar && /* @__PURE__ */ jsxs(
31386
+ /* @__PURE__ */ jsx("style", { children: FONT_FACES }),
31387
+ backgroundAsset && /* @__PURE__ */ jsx(
31388
+ AtlasPanel,
31389
+ {
31390
+ asset: backgroundAsset,
31391
+ mode: "repeat",
31392
+ "aria-hidden": true,
31393
+ className: "game-shell__bg",
31394
+ style: { position: "absolute", inset: 0, opacity: 0.18, zIndex: 0, display: "block" }
31395
+ }
31396
+ ),
31397
+ /* @__PURE__ */ jsx(Box, { className: "game-shell__content", style: { position: "absolute", inset: 0, zIndex: 1 }, children }),
31398
+ (showTopBar || hud) && /* @__PURE__ */ jsxs(
31210
31399
  Box,
31211
31400
  {
31212
- className: "game-shell__header",
31401
+ className: "game-shell__top pointer-events-none",
31213
31402
  style: {
31214
- flexShrink: 0,
31215
- background: hudBackgroundAsset ? `url(${hudBackgroundAsset.url}) center/cover no-repeat` : "var(--color-surface, #12121f)",
31216
- borderBottom: "1px solid var(--color-border, #2a2a3a)"
31403
+ position: "absolute",
31404
+ top: 12,
31405
+ left: 12,
31406
+ right: 12,
31407
+ zIndex: 2,
31408
+ display: "flex",
31409
+ alignItems: "flex-start",
31410
+ gap: 12
31217
31411
  },
31218
31412
  children: [
31219
- /* @__PURE__ */ jsx(
31220
- HStack,
31413
+ showTopBar && /* @__PURE__ */ jsx(
31414
+ AtlasPanel,
31221
31415
  {
31222
- align: "center",
31223
- justify: "between",
31224
- style: { padding: "0.375rem 1rem" },
31416
+ asset: hudBackgroundAsset,
31417
+ borderSlice: 12,
31418
+ borderWidth: 10,
31419
+ className: "game-shell__title pointer-events-auto",
31420
+ style: {
31421
+ padding: "6px 16px",
31422
+ background: hudBackgroundAsset ? void 0 : "rgba(18, 18, 31, 0.85)",
31423
+ borderRadius: hudBackgroundAsset ? void 0 : 10,
31424
+ boxShadow: "0 4px 14px rgba(0,0,0,0.45)",
31425
+ flexShrink: 0
31426
+ },
31225
31427
  children: /* @__PURE__ */ jsx(
31226
31428
  Typography,
31227
31429
  {
31228
- variant: "h6",
31430
+ as: "span",
31229
31431
  style: {
31230
31432
  fontWeight: 700,
31231
- letterSpacing: "0.02em"
31433
+ fontSize: "1.05rem",
31434
+ letterSpacing: "0.06em",
31435
+ textShadow: "0 2px 0 rgba(0,0,0,0.5)",
31436
+ whiteSpace: "nowrap"
31232
31437
  },
31233
31438
  children: appName
31234
31439
  }
31235
31440
  )
31236
31441
  }
31237
31442
  ),
31238
- hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: hud })
31443
+ hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud pointer-events-auto", style: { flex: 1, minWidth: 0 }, children: hud })
31239
31444
  ]
31240
31445
  }
31241
31446
  ),
31242
- /* @__PURE__ */ jsx(
31447
+ controls && /* @__PURE__ */ jsx(
31243
31448
  Box,
31244
31449
  {
31245
- className: "game-shell__content",
31450
+ className: "game-shell__controls pointer-events-auto",
31246
31451
  style: {
31247
- flex: 1,
31248
- overflow: "hidden",
31249
- position: "relative"
31452
+ position: "absolute",
31453
+ left: 16,
31454
+ bottom: 16,
31455
+ zIndex: 2,
31456
+ display: "flex",
31457
+ flexDirection: "column",
31458
+ alignItems: "flex-start",
31459
+ gap: 10,
31460
+ filter: "drop-shadow(0 6px 12px rgba(0,0,0,0.5))"
31250
31461
  },
31251
- children
31462
+ children: controls
31463
+ }
31464
+ ),
31465
+ addons && /* @__PURE__ */ jsx(
31466
+ Box,
31467
+ {
31468
+ className: "game-shell__actions pointer-events-auto",
31469
+ style: {
31470
+ position: "absolute",
31471
+ right: 16,
31472
+ bottom: 16,
31473
+ zIndex: 2,
31474
+ display: "flex",
31475
+ flexDirection: "column",
31476
+ alignItems: "flex-end",
31477
+ gap: 10,
31478
+ filter: "drop-shadow(0 6px 12px rgba(0,0,0,0.5))"
31479
+ },
31480
+ children: addons
31481
+ }
31482
+ ),
31483
+ overlay && /* @__PURE__ */ jsx(
31484
+ Box,
31485
+ {
31486
+ className: "game-shell__overlay pointer-events-none",
31487
+ style: {
31488
+ position: "absolute",
31489
+ inset: 0,
31490
+ zIndex: 3,
31491
+ display: "flex",
31492
+ alignItems: "center",
31493
+ justifyContent: "center"
31494
+ },
31495
+ children: /* @__PURE__ */ jsx(Box, { className: "pointer-events-auto", children: overlay })
31252
31496
  }
31253
31497
  )
31254
31498
  ]
@@ -31921,13 +32165,13 @@ var init_MapView = __esm({
31921
32165
  shadowSize: [41, 41]
31922
32166
  });
31923
32167
  L.Marker.prototype.options.icon = defaultIcon;
31924
- const { useEffect: useEffect69, useRef: useRef64, useCallback: useCallback113, useState: useState108 } = React74__default;
32168
+ const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback113, useState: useState108 } = React75__default;
31925
32169
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
31926
32170
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
31927
32171
  function MapUpdater({ centerLat, centerLng, zoom }) {
31928
32172
  const map = useMap();
31929
- const prevRef = useRef64({ centerLat, centerLng, zoom });
31930
- useEffect69(() => {
32173
+ const prevRef = useRef65({ centerLat, centerLng, zoom });
32174
+ useEffect70(() => {
31931
32175
  const prev = prevRef.current;
31932
32176
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
31933
32177
  map.setView([centerLat, centerLng], zoom);
@@ -31938,7 +32182,7 @@ var init_MapView = __esm({
31938
32182
  }
31939
32183
  function MapClickHandler({ onMapClick }) {
31940
32184
  const map = useMap();
31941
- useEffect69(() => {
32185
+ useEffect70(() => {
31942
32186
  if (!onMapClick) return;
31943
32187
  const handler = (e) => {
31944
32188
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -32836,8 +33080,8 @@ function TableView({
32836
33080
  }) {
32837
33081
  const eventBus = useEventBus();
32838
33082
  const { t } = useTranslate();
32839
- const [visibleCount, setVisibleCount] = React74__default.useState(pageSize > 0 ? pageSize : Infinity);
32840
- const [localSelected, setLocalSelected] = React74__default.useState(/* @__PURE__ */ new Set());
33083
+ const [visibleCount, setVisibleCount] = React75__default.useState(pageSize > 0 ? pageSize : Infinity);
33084
+ const [localSelected, setLocalSelected] = React75__default.useState(/* @__PURE__ */ new Set());
32841
33085
  const colDefs = columns ?? fields ?? [];
32842
33086
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
32843
33087
  const dnd = useDataDnd({
@@ -33032,12 +33276,12 @@ function TableView({
33032
33276
  ]
33033
33277
  }
33034
33278
  );
33035
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React74__default.Fragment, { children: rowInner }, id);
33279
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React75__default.Fragment, { children: rowInner }, id);
33036
33280
  };
33037
33281
  const items = Array.from(data);
33038
33282
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
33039
33283
  let runningIndex = 0;
33040
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
33284
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
33041
33285
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
33042
33286
  group.items.map((row) => renderRow(row, runningIndex++))
33043
33287
  ] }, gi)) });
@@ -34394,7 +34638,7 @@ var init_StepFlow = __esm({
34394
34638
  className
34395
34639
  }) => {
34396
34640
  if (orientation === "vertical") {
34397
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React74__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
34641
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React75__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
34398
34642
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
34399
34643
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
34400
34644
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -34405,7 +34649,7 @@ var init_StepFlow = __esm({
34405
34649
  ] })
34406
34650
  ] }) }, index)) });
34407
34651
  }
34408
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
34652
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
34409
34653
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
34410
34654
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
34411
34655
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -35390,7 +35634,7 @@ var init_LikertScale = __esm({
35390
35634
  md: "text-base",
35391
35635
  lg: "text-lg"
35392
35636
  };
35393
- LikertScale = React74__default.forwardRef(
35637
+ LikertScale = React75__default.forwardRef(
35394
35638
  ({
35395
35639
  question,
35396
35640
  options = DEFAULT_LIKERT_OPTIONS,
@@ -35402,7 +35646,7 @@ var init_LikertScale = __esm({
35402
35646
  variant = "radios",
35403
35647
  className
35404
35648
  }, ref) => {
35405
- const groupId = React74__default.useId();
35649
+ const groupId = React75__default.useId();
35406
35650
  const eventBus = useEventBus();
35407
35651
  const handleSelect = useCallback(
35408
35652
  (next) => {
@@ -37684,7 +37928,7 @@ var init_DocBreadcrumb = __esm({
37684
37928
  "aria-label": t("aria.breadcrumb"),
37685
37929
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
37686
37930
  const isLast = idx === items.length - 1;
37687
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
37931
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
37688
37932
  idx > 0 && /* @__PURE__ */ jsx(
37689
37933
  Icon,
37690
37934
  {
@@ -38553,7 +38797,7 @@ var init_MiniStateMachine = __esm({
38553
38797
  const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
38554
38798
  const tc = transitionCounts[s.name] ?? 0;
38555
38799
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
38556
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
38800
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
38557
38801
  /* @__PURE__ */ jsx(
38558
38802
  AvlState,
38559
38803
  {
@@ -38757,7 +39001,7 @@ var init_PageHeader = __esm({
38757
39001
  info: "bg-info/10 text-info"
38758
39002
  };
38759
39003
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
38760
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
39004
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
38761
39005
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
38762
39006
  crumb.href ? /* @__PURE__ */ jsx(
38763
39007
  "a",
@@ -39115,7 +39359,7 @@ var init_Section = __esm({
39115
39359
  as: Component = "section"
39116
39360
  }) => {
39117
39361
  const hasHeader = title || description || action;
39118
- return React74__default.createElement(
39362
+ return React75__default.createElement(
39119
39363
  Component,
39120
39364
  {
39121
39365
  className: cn(
@@ -39489,7 +39733,7 @@ var init_WizardContainer = __esm({
39489
39733
  const isCompleted = index < currentStep;
39490
39734
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
39491
39735
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
39492
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
39736
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
39493
39737
  /* @__PURE__ */ jsx(
39494
39738
  Button,
39495
39739
  {
@@ -42139,7 +42383,7 @@ var init_DetailPanel = __esm({
42139
42383
  }
42140
42384
  });
42141
42385
  function extractTitle(children) {
42142
- if (!React74__default.isValidElement(children)) return void 0;
42386
+ if (!React75__default.isValidElement(children)) return void 0;
42143
42387
  const props = children.props;
42144
42388
  if (typeof props.title === "string") {
42145
42389
  return props.title;
@@ -42489,12 +42733,12 @@ var init_Form = __esm({
42489
42733
  const isSchemaEntity = isOrbitalEntitySchema(entity);
42490
42734
  const resolvedEntity = isSchemaEntity ? entity : void 0;
42491
42735
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
42492
- const normalizedInitialData = React74__default.useMemo(() => {
42736
+ const normalizedInitialData = React75__default.useMemo(() => {
42493
42737
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
42494
42738
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
42495
42739
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
42496
42740
  }, [entity, initialData]);
42497
- const entityDerivedFields = React74__default.useMemo(() => {
42741
+ const entityDerivedFields = React75__default.useMemo(() => {
42498
42742
  if (fields && fields.length > 0) return void 0;
42499
42743
  if (!resolvedEntity) return void 0;
42500
42744
  return resolvedEntity.fields.map(
@@ -42515,16 +42759,16 @@ var init_Form = __esm({
42515
42759
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
42516
42760
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
42517
42761
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
42518
- const [formData, setFormData] = React74__default.useState(
42762
+ const [formData, setFormData] = React75__default.useState(
42519
42763
  normalizedInitialData
42520
42764
  );
42521
- const [collapsedSections, setCollapsedSections] = React74__default.useState(
42765
+ const [collapsedSections, setCollapsedSections] = React75__default.useState(
42522
42766
  /* @__PURE__ */ new Set()
42523
42767
  );
42524
- const [submitError, setSubmitError] = React74__default.useState(null);
42525
- const formRef = React74__default.useRef(null);
42768
+ const [submitError, setSubmitError] = React75__default.useState(null);
42769
+ const formRef = React75__default.useRef(null);
42526
42770
  const formMode = props.mode;
42527
- const mountedRef = React74__default.useRef(false);
42771
+ const mountedRef = React75__default.useRef(false);
42528
42772
  if (!mountedRef.current) {
42529
42773
  mountedRef.current = true;
42530
42774
  debug("forms", "mount", {
@@ -42537,7 +42781,7 @@ var init_Form = __esm({
42537
42781
  });
42538
42782
  }
42539
42783
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
42540
- const evalContext = React74__default.useMemo(
42784
+ const evalContext = React75__default.useMemo(
42541
42785
  () => ({
42542
42786
  formValues: formData,
42543
42787
  globalVariables: externalContext?.globalVariables ?? {},
@@ -42546,7 +42790,7 @@ var init_Form = __esm({
42546
42790
  }),
42547
42791
  [formData, externalContext]
42548
42792
  );
42549
- React74__default.useEffect(() => {
42793
+ React75__default.useEffect(() => {
42550
42794
  debug("forms", "initialData-sync", {
42551
42795
  mode: formMode,
42552
42796
  normalizedInitialData,
@@ -42557,7 +42801,7 @@ var init_Form = __esm({
42557
42801
  setFormData(normalizedInitialData);
42558
42802
  }
42559
42803
  }, [normalizedInitialData]);
42560
- const processCalculations = React74__default.useCallback(
42804
+ const processCalculations = React75__default.useCallback(
42561
42805
  (changedFieldId, newFormData) => {
42562
42806
  if (!hiddenCalculations.length) return;
42563
42807
  const context = {
@@ -42582,7 +42826,7 @@ var init_Form = __esm({
42582
42826
  },
42583
42827
  [hiddenCalculations, externalContext, eventBus]
42584
42828
  );
42585
- const checkViolations = React74__default.useCallback(
42829
+ const checkViolations = React75__default.useCallback(
42586
42830
  (changedFieldId, newFormData) => {
42587
42831
  if (!violationTriggers.length) return;
42588
42832
  const context = {
@@ -42620,7 +42864,7 @@ var init_Form = __esm({
42620
42864
  processCalculations(name, newFormData);
42621
42865
  checkViolations(name, newFormData);
42622
42866
  };
42623
- const isFieldVisible = React74__default.useCallback(
42867
+ const isFieldVisible = React75__default.useCallback(
42624
42868
  (fieldName) => {
42625
42869
  const condition = conditionalFields[fieldName];
42626
42870
  if (!condition) return true;
@@ -42628,7 +42872,7 @@ var init_Form = __esm({
42628
42872
  },
42629
42873
  [conditionalFields, evalContext]
42630
42874
  );
42631
- const isSectionVisible = React74__default.useCallback(
42875
+ const isSectionVisible = React75__default.useCallback(
42632
42876
  (section) => {
42633
42877
  if (!section.condition) return true;
42634
42878
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -42704,7 +42948,7 @@ var init_Form = __esm({
42704
42948
  eventBus.emit(`UI:${onCancel}`);
42705
42949
  }
42706
42950
  };
42707
- const renderField = React74__default.useCallback(
42951
+ const renderField = React75__default.useCallback(
42708
42952
  (field) => {
42709
42953
  const fieldName = field.name || field.field;
42710
42954
  if (!fieldName) return null;
@@ -42725,7 +42969,7 @@ var init_Form = __esm({
42725
42969
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
42726
42970
  );
42727
42971
  const effectiveFields = entityDerivedFields ?? fields;
42728
- const normalizedFields = React74__default.useMemo(() => {
42972
+ const normalizedFields = React75__default.useMemo(() => {
42729
42973
  if (!effectiveFields || effectiveFields.length === 0) return [];
42730
42974
  return effectiveFields.map((field) => {
42731
42975
  if (typeof field === "string") {
@@ -42749,7 +42993,7 @@ var init_Form = __esm({
42749
42993
  return field;
42750
42994
  });
42751
42995
  }, [effectiveFields, resolvedEntity]);
42752
- const schemaFields = React74__default.useMemo(() => {
42996
+ const schemaFields = React75__default.useMemo(() => {
42753
42997
  if (normalizedFields.length === 0) return null;
42754
42998
  if (isDebugEnabled()) {
42755
42999
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -42759,7 +43003,7 @@ var init_Form = __esm({
42759
43003
  }
42760
43004
  return normalizedFields.map(renderField).filter(Boolean);
42761
43005
  }, [normalizedFields, renderField, entityName, conditionalFields]);
42762
- const sectionElements = React74__default.useMemo(() => {
43006
+ const sectionElements = React75__default.useMemo(() => {
42763
43007
  if (!sections || sections.length === 0) return null;
42764
43008
  return sections.map((section) => {
42765
43009
  if (!isSectionVisible(section)) {
@@ -43484,7 +43728,7 @@ var init_List = __esm({
43484
43728
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
43485
43729
  return [];
43486
43730
  }, [entity]);
43487
- const getItemActions = React74__default.useCallback(
43731
+ const getItemActions = React75__default.useCallback(
43488
43732
  (item) => {
43489
43733
  if (!itemActions) return [];
43490
43734
  if (typeof itemActions === "function") {
@@ -43959,7 +44203,7 @@ var init_MediaGallery = __esm({
43959
44203
  [selectable, selectedItems, selectionEvent, eventBus]
43960
44204
  );
43961
44205
  const entityData = Array.isArray(entity) ? entity : [];
43962
- const items = React74__default.useMemo(() => {
44206
+ const items = React75__default.useMemo(() => {
43963
44207
  if (propItems) return propItems;
43964
44208
  if (entityData.length === 0) return [];
43965
44209
  return entityData.map((record, idx) => {
@@ -44122,7 +44366,7 @@ var init_MediaGallery = __esm({
44122
44366
  }
44123
44367
  });
44124
44368
  function extractTitle2(children) {
44125
- if (!React74__default.isValidElement(children)) return void 0;
44369
+ if (!React75__default.isValidElement(children)) return void 0;
44126
44370
  const props = children.props;
44127
44371
  if (typeof props.title === "string") {
44128
44372
  return props.title;
@@ -44377,7 +44621,7 @@ var init_debugRegistry = __esm({
44377
44621
  }
44378
44622
  });
44379
44623
  function useDebugData() {
44380
- const [data, setData] = React74.useState(() => ({
44624
+ const [data, setData] = React75.useState(() => ({
44381
44625
  traits: [],
44382
44626
  ticks: [],
44383
44627
  guards: [],
@@ -44391,7 +44635,7 @@ function useDebugData() {
44391
44635
  },
44392
44636
  lastUpdate: Date.now()
44393
44637
  }));
44394
- React74.useEffect(() => {
44638
+ React75.useEffect(() => {
44395
44639
  const updateData = () => {
44396
44640
  setData({
44397
44641
  traits: getAllTraits(),
@@ -44500,12 +44744,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
44500
44744
  return positions;
44501
44745
  }
44502
44746
  function WalkMinimap() {
44503
- const [walkStep, setWalkStep] = React74.useState(null);
44504
- const [traits2, setTraits] = React74.useState([]);
44505
- const [coveredEdges, setCoveredEdges] = React74.useState([]);
44506
- const [completedTraits, setCompletedTraits] = React74.useState(/* @__PURE__ */ new Set());
44507
- const prevTraitRef = React74.useRef(null);
44508
- React74.useEffect(() => {
44747
+ const [walkStep, setWalkStep] = React75.useState(null);
44748
+ const [traits2, setTraits] = React75.useState([]);
44749
+ const [coveredEdges, setCoveredEdges] = React75.useState([]);
44750
+ const [completedTraits, setCompletedTraits] = React75.useState(/* @__PURE__ */ new Set());
44751
+ const prevTraitRef = React75.useRef(null);
44752
+ React75.useEffect(() => {
44509
44753
  const interval = setInterval(() => {
44510
44754
  const w = window;
44511
44755
  const step = w.__orbitalWalkStep;
@@ -44941,15 +45185,15 @@ var init_EntitiesTab = __esm({
44941
45185
  });
44942
45186
  function EventFlowTab({ events: events2 }) {
44943
45187
  const { t } = useTranslate();
44944
- const [filter, setFilter] = React74.useState("all");
44945
- const containerRef = React74.useRef(null);
44946
- const [autoScroll, setAutoScroll] = React74.useState(true);
44947
- React74.useEffect(() => {
45188
+ const [filter, setFilter] = React75.useState("all");
45189
+ const containerRef = React75.useRef(null);
45190
+ const [autoScroll, setAutoScroll] = React75.useState(true);
45191
+ React75.useEffect(() => {
44948
45192
  if (autoScroll && containerRef.current) {
44949
45193
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
44950
45194
  }
44951
45195
  }, [events2.length, autoScroll]);
44952
- const filteredEvents = React74.useMemo(() => {
45196
+ const filteredEvents = React75.useMemo(() => {
44953
45197
  if (filter === "all") return events2;
44954
45198
  return events2.filter((e) => e.type === filter);
44955
45199
  }, [events2, filter]);
@@ -45065,7 +45309,7 @@ var init_EventFlowTab = __esm({
45065
45309
  });
45066
45310
  function GuardsPanel({ guards }) {
45067
45311
  const { t } = useTranslate();
45068
- const [filter, setFilter] = React74.useState("all");
45312
+ const [filter, setFilter] = React75.useState("all");
45069
45313
  if (guards.length === 0) {
45070
45314
  return /* @__PURE__ */ jsx(
45071
45315
  EmptyState,
@@ -45078,7 +45322,7 @@ function GuardsPanel({ guards }) {
45078
45322
  }
45079
45323
  const passedCount = guards.filter((g) => g.result).length;
45080
45324
  const failedCount = guards.length - passedCount;
45081
- const filteredGuards = React74.useMemo(() => {
45325
+ const filteredGuards = React75.useMemo(() => {
45082
45326
  if (filter === "all") return guards;
45083
45327
  if (filter === "passed") return guards.filter((g) => g.result);
45084
45328
  return guards.filter((g) => !g.result);
@@ -45241,10 +45485,10 @@ function EffectBadge({ effect }) {
45241
45485
  }
45242
45486
  function TransitionTimeline({ transitions }) {
45243
45487
  const { t } = useTranslate();
45244
- const containerRef = React74.useRef(null);
45245
- const [autoScroll, setAutoScroll] = React74.useState(true);
45246
- const [expandedId, setExpandedId] = React74.useState(null);
45247
- React74.useEffect(() => {
45488
+ const containerRef = React75.useRef(null);
45489
+ const [autoScroll, setAutoScroll] = React75.useState(true);
45490
+ const [expandedId, setExpandedId] = React75.useState(null);
45491
+ React75.useEffect(() => {
45248
45492
  if (autoScroll && containerRef.current) {
45249
45493
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
45250
45494
  }
@@ -45524,9 +45768,9 @@ function getAllEvents(traits2) {
45524
45768
  function EventDispatcherTab({ traits: traits2, schema }) {
45525
45769
  const eventBus = useEventBus();
45526
45770
  const { t } = useTranslate();
45527
- const [log18, setLog] = React74.useState([]);
45528
- const prevStatesRef = React74.useRef(/* @__PURE__ */ new Map());
45529
- React74.useEffect(() => {
45771
+ const [log18, setLog] = React75.useState([]);
45772
+ const prevStatesRef = React75.useRef(/* @__PURE__ */ new Map());
45773
+ React75.useEffect(() => {
45530
45774
  for (const trait of traits2) {
45531
45775
  const prev = prevStatesRef.current.get(trait.id);
45532
45776
  if (prev && prev !== trait.currentState) {
@@ -45695,10 +45939,10 @@ function VerifyModePanel({
45695
45939
  localCount
45696
45940
  }) {
45697
45941
  const { t } = useTranslate();
45698
- const [expanded, setExpanded] = React74.useState(true);
45699
- const scrollRef = React74.useRef(null);
45700
- const prevCountRef = React74.useRef(0);
45701
- React74.useEffect(() => {
45942
+ const [expanded, setExpanded] = React75.useState(true);
45943
+ const scrollRef = React75.useRef(null);
45944
+ const prevCountRef = React75.useRef(0);
45945
+ React75.useEffect(() => {
45702
45946
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
45703
45947
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
45704
45948
  }
@@ -45755,10 +45999,10 @@ function RuntimeDebugger({
45755
45999
  schema
45756
46000
  }) {
45757
46001
  const { t } = useTranslate();
45758
- const [isCollapsed, setIsCollapsed] = React74.useState(mode === "verify" ? true : defaultCollapsed);
45759
- const [isVisible, setIsVisible] = React74.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
46002
+ const [isCollapsed, setIsCollapsed] = React75.useState(mode === "verify" ? true : defaultCollapsed);
46003
+ const [isVisible, setIsVisible] = React75.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
45760
46004
  const debugData = useDebugData();
45761
- React74.useEffect(() => {
46005
+ React75.useEffect(() => {
45762
46006
  if (mode === "inline") return;
45763
46007
  return onDebugToggle((enabled) => {
45764
46008
  setIsVisible(enabled);
@@ -45767,7 +46011,7 @@ function RuntimeDebugger({
45767
46011
  }
45768
46012
  });
45769
46013
  }, [mode]);
45770
- React74.useEffect(() => {
46014
+ React75.useEffect(() => {
45771
46015
  if (mode === "inline") return;
45772
46016
  const handleKeyDown = (e) => {
45773
46017
  if (e.key === "`" && isVisible) {
@@ -46287,7 +46531,7 @@ var init_StatCard = __esm({
46287
46531
  const labelToUse = propLabel ?? propTitle;
46288
46532
  const eventBus = useEventBus();
46289
46533
  const { t } = useTranslate();
46290
- const handleActionClick = React74__default.useCallback(() => {
46534
+ const handleActionClick = React75__default.useCallback(() => {
46291
46535
  if (action?.event) {
46292
46536
  eventBus.emit(`UI:${action.event}`, {});
46293
46537
  }
@@ -46298,7 +46542,7 @@ var init_StatCard = __esm({
46298
46542
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
46299
46543
  const isLoading = externalLoading ?? false;
46300
46544
  const error = externalError;
46301
- const computeMetricValue = React74__default.useCallback(
46545
+ const computeMetricValue = React75__default.useCallback(
46302
46546
  (metric, items) => {
46303
46547
  if (metric.value !== void 0) {
46304
46548
  return metric.value;
@@ -46337,7 +46581,7 @@ var init_StatCard = __esm({
46337
46581
  },
46338
46582
  []
46339
46583
  );
46340
- const schemaStats = React74__default.useMemo(() => {
46584
+ const schemaStats = React75__default.useMemo(() => {
46341
46585
  if (!metrics || metrics.length === 0) return null;
46342
46586
  return metrics.map((metric) => ({
46343
46587
  label: metric.label,
@@ -46345,7 +46589,7 @@ var init_StatCard = __esm({
46345
46589
  format: metric.format
46346
46590
  }));
46347
46591
  }, [metrics, data, computeMetricValue]);
46348
- const calculatedTrend = React74__default.useMemo(() => {
46592
+ const calculatedTrend = React75__default.useMemo(() => {
46349
46593
  if (manualTrend !== void 0) return manualTrend;
46350
46594
  if (previousValue === void 0 || currentValue2 === void 0)
46351
46595
  return void 0;
@@ -46985,8 +47229,8 @@ var init_SubagentTracePanel = __esm({
46985
47229
  ] });
46986
47230
  };
46987
47231
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
46988
- const endRef = React74__default.useRef(null);
46989
- React74__default.useEffect(() => {
47232
+ const endRef = React75__default.useRef(null);
47233
+ React75__default.useEffect(() => {
46990
47234
  if (!autoScroll) return;
46991
47235
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
46992
47236
  }, [activities.length, autoScroll]);
@@ -47080,7 +47324,7 @@ var init_SubagentTracePanel = __esm({
47080
47324
  };
47081
47325
  SubagentRichCard = ({ subagent }) => {
47082
47326
  const { t } = useTranslate();
47083
- const activities = React74__default.useMemo(
47327
+ const activities = React75__default.useMemo(
47084
47328
  () => subagentMessagesToActivities(subagent.messages),
47085
47329
  [subagent.messages]
47086
47330
  );
@@ -47157,8 +47401,8 @@ var init_SubagentTracePanel = __esm({
47157
47401
  ] });
47158
47402
  };
47159
47403
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
47160
- const endRef = React74__default.useRef(null);
47161
- React74__default.useEffect(() => {
47404
+ const endRef = React75__default.useRef(null);
47405
+ React75__default.useEffect(() => {
47162
47406
  if (!autoScroll) return;
47163
47407
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
47164
47408
  }, [messages.length, autoScroll]);
@@ -47588,7 +47832,7 @@ var init_Timeline = __esm({
47588
47832
  }) => {
47589
47833
  const { t } = useTranslate();
47590
47834
  const entityData = entity ?? [];
47591
- const items = React74__default.useMemo(() => {
47835
+ const items = React75__default.useMemo(() => {
47592
47836
  if (propItems) return propItems;
47593
47837
  if (entityData.length === 0) return [];
47594
47838
  return entityData.map((record, idx) => {
@@ -47690,7 +47934,7 @@ var init_Timeline = __esm({
47690
47934
  }
47691
47935
  });
47692
47936
  function extractToastProps(children) {
47693
- if (!React74__default.isValidElement(children)) {
47937
+ if (!React75__default.isValidElement(children)) {
47694
47938
  if (typeof children === "string") {
47695
47939
  return { message: children };
47696
47940
  }
@@ -47732,7 +47976,7 @@ var init_ToastSlot = __esm({
47732
47976
  eventBus.emit(`${prefix}CLOSE`);
47733
47977
  };
47734
47978
  if (!isVisible) return null;
47735
- const isCustomContent = React74__default.isValidElement(children) && !message;
47979
+ const isCustomContent = React75__default.isValidElement(children) && !message;
47736
47980
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
47737
47981
  Toast,
47738
47982
  {
@@ -47749,7 +47993,7 @@ var init_ToastSlot = __esm({
47749
47993
  }
47750
47994
  });
47751
47995
  function lazyThree(name, loader) {
47752
- const Lazy = React74__default.lazy(
47996
+ const Lazy = React75__default.lazy(
47753
47997
  () => loader().then((m) => {
47754
47998
  const Resolved = m[name];
47755
47999
  if (!Resolved) {
@@ -47761,13 +48005,13 @@ function lazyThree(name, loader) {
47761
48005
  })
47762
48006
  );
47763
48007
  function ThreeWrapper(props) {
47764
- return React74__default.createElement(
48008
+ return React75__default.createElement(
47765
48009
  ThreeBoundary,
47766
48010
  { name },
47767
- React74__default.createElement(
47768
- React74__default.Suspense,
48011
+ React75__default.createElement(
48012
+ React75__default.Suspense,
47769
48013
  { fallback: null },
47770
- React74__default.createElement(Lazy, props)
48014
+ React75__default.createElement(Lazy, props)
47771
48015
  )
47772
48016
  );
47773
48017
  }
@@ -47790,6 +48034,7 @@ var init_component_registry_generated = __esm({
47790
48034
  init_AnimatedReveal();
47791
48035
  init_ArticleSection();
47792
48036
  init_Aside();
48037
+ init_AtlasImage();
47793
48038
  init_AuthLayout();
47794
48039
  init_Avatar();
47795
48040
  init_Badge();
@@ -48047,7 +48292,7 @@ var init_component_registry_generated = __esm({
48047
48292
  init_WizardContainer();
48048
48293
  init_WizardNavigation();
48049
48294
  init_WizardProgress();
48050
- ThreeBoundary = class extends React74__default.Component {
48295
+ ThreeBoundary = class extends React75__default.Component {
48051
48296
  constructor() {
48052
48297
  super(...arguments);
48053
48298
  __publicField(this, "state", { failed: false });
@@ -48057,7 +48302,7 @@ var init_component_registry_generated = __esm({
48057
48302
  }
48058
48303
  render() {
48059
48304
  if (this.state.failed) {
48060
- return React74__default.createElement(
48305
+ return React75__default.createElement(
48061
48306
  "div",
48062
48307
  {
48063
48308
  "data-testid": "three-unavailable",
@@ -48089,6 +48334,8 @@ var init_component_registry_generated = __esm({
48089
48334
  "AnimatedReveal": AnimatedReveal,
48090
48335
  "ArticleSection": ArticleSection,
48091
48336
  "Aside": Aside,
48337
+ "AtlasImage": AtlasImage,
48338
+ "AtlasPanel": AtlasPanel,
48092
48339
  "AuthLayout": AuthLayout,
48093
48340
  "Avatar": Avatar,
48094
48341
  "Badge": Badge,
@@ -48381,7 +48628,7 @@ function SuspenseConfigProvider({
48381
48628
  config,
48382
48629
  children
48383
48630
  }) {
48384
- return React74__default.createElement(
48631
+ return React75__default.createElement(
48385
48632
  SuspenseConfigContext.Provider,
48386
48633
  { value: config },
48387
48634
  children
@@ -48423,7 +48670,7 @@ function enrichFormFields(fields, entityDef) {
48423
48670
  }
48424
48671
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
48425
48672
  }
48426
- if (field && typeof field === "object" && !Array.isArray(field) && !React74__default.isValidElement(field) && !(field instanceof Date)) {
48673
+ if (field && typeof field === "object" && !Array.isArray(field) && !React75__default.isValidElement(field) && !(field instanceof Date)) {
48427
48674
  const obj = field;
48428
48675
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
48429
48676
  if (!fieldName) return field;
@@ -48876,7 +49123,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
48876
49123
  const key = `${parentId}-${index}-trait:${traitName}`;
48877
49124
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
48878
49125
  }
48879
- return /* @__PURE__ */ jsx(React74__default.Fragment, { children: child }, `${parentId}-${index}`);
49126
+ return /* @__PURE__ */ jsx(React75__default.Fragment, { children: child }, `${parentId}-${index}`);
48880
49127
  }
48881
49128
  if (!child || typeof child !== "object") return null;
48882
49129
  const childId = `${parentId}-${index}`;
@@ -48916,14 +49163,14 @@ function isPatternConfig(value) {
48916
49163
  if (value === null || value === void 0) return false;
48917
49164
  if (typeof value !== "object") return false;
48918
49165
  if (Array.isArray(value)) return false;
48919
- if (React74__default.isValidElement(value)) return false;
49166
+ if (React75__default.isValidElement(value)) return false;
48920
49167
  if (value instanceof Date) return false;
48921
49168
  if (typeof value === "function") return false;
48922
49169
  const record = value;
48923
49170
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
48924
49171
  }
48925
49172
  function isPlainConfigObject(value) {
48926
- if (React74__default.isValidElement(value)) return false;
49173
+ if (React75__default.isValidElement(value)) return false;
48927
49174
  if (value instanceof Date) return false;
48928
49175
  const proto = Object.getPrototypeOf(value);
48929
49176
  return proto === Object.prototype || proto === null;
@@ -49049,7 +49296,7 @@ function SlotContentRenderer({
49049
49296
  for (const slotKey of CONTENT_NODE_SLOTS) {
49050
49297
  const slotVal = restProps[slotKey];
49051
49298
  if (slotVal === void 0 || slotVal === null) continue;
49052
- if (React74__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
49299
+ if (React75__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
49053
49300
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
49054
49301
  nodeSlotOverrides[slotKey] = renderPatternChildren(
49055
49302
  slotVal,
@@ -49098,7 +49345,7 @@ function SlotContentRenderer({
49098
49345
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
49099
49346
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
49100
49347
  const sample = resolvedItems[0];
49101
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React74__default.isValidElement(sample) && !(sample instanceof Date)) {
49348
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React75__default.isValidElement(sample) && !(sample instanceof Date)) {
49102
49349
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
49103
49350
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
49104
49351
  }
@@ -49259,7 +49506,9 @@ var init_UISlotRenderer = __esm({
49259
49506
  "content",
49260
49507
  "addons",
49261
49508
  "hud",
49262
- "fallback"
49509
+ "fallback",
49510
+ "controls",
49511
+ "overlay"
49263
49512
  ]);
49264
49513
  PATTERNS_WITH_CHILDREN = /* @__PURE__ */ new Set([
49265
49514
  "stack",
@@ -49356,6 +49605,7 @@ var init_atoms = __esm({
49356
49605
  init_Checkbox();
49357
49606
  init_Card();
49358
49607
  init_Badge();
49608
+ init_AtlasImage();
49359
49609
  init_FilterPill();
49360
49610
  init_Spinner();
49361
49611
  init_Avatar();
@@ -51599,4 +51849,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
51599
51849
  });
51600
51850
  }
51601
51851
 
51602
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateGraph, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate127 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
51852
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateGraph, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate127 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };