@almadar/ui 5.94.1 → 5.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +284 -40
- package/dist/avl/index.js +284 -40
- package/dist/components/core/molecules/index.d.ts +1 -0
- package/dist/components/game/2d/molecules/Canvas2D.d.ts +6 -6
- package/dist/components/game/shared/atlasSlice.d.ts +58 -0
- package/dist/components/index.cjs +594 -349
- package/dist/components/index.js +595 -350
- package/dist/components/learning/molecules/AlgorithmCanvas.d.ts +58 -0
- package/dist/providers/index.cjs +284 -40
- package/dist/providers/index.js +284 -40
- package/dist/runtime/index.cjs +284 -40
- package/dist/runtime/index.js +284 -40
- package/package.json +2 -2
package/dist/avl/index.cjs
CHANGED
|
@@ -13416,6 +13416,76 @@ var init_StateGraph = __esm({
|
|
|
13416
13416
|
init_TransitionArrow();
|
|
13417
13417
|
}
|
|
13418
13418
|
});
|
|
13419
|
+
|
|
13420
|
+
// components/game/shared/atlasSlice.ts
|
|
13421
|
+
function isTilesheet(a) {
|
|
13422
|
+
return typeof a.tileWidth === "number";
|
|
13423
|
+
}
|
|
13424
|
+
function getAtlas(url, onReady) {
|
|
13425
|
+
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
13426
|
+
atlasCache.set(url, void 0);
|
|
13427
|
+
fetch(url).then((r2) => r2.json()).then((json) => {
|
|
13428
|
+
atlasCache.set(url, json);
|
|
13429
|
+
onReady();
|
|
13430
|
+
}).catch(() => {
|
|
13431
|
+
atlasCache.set(url, null);
|
|
13432
|
+
});
|
|
13433
|
+
return void 0;
|
|
13434
|
+
}
|
|
13435
|
+
function subRectFor(atlas, sprite) {
|
|
13436
|
+
if (isTilesheet(atlas)) {
|
|
13437
|
+
let col;
|
|
13438
|
+
let row;
|
|
13439
|
+
if (sprite.includes(",")) {
|
|
13440
|
+
const [c, r2] = sprite.split(",").map((n) => Number(n.trim()));
|
|
13441
|
+
col = c;
|
|
13442
|
+
row = r2;
|
|
13443
|
+
} else {
|
|
13444
|
+
const i = Number(sprite);
|
|
13445
|
+
if (!Number.isFinite(i)) return null;
|
|
13446
|
+
col = i % atlas.columns;
|
|
13447
|
+
row = Math.floor(i / atlas.columns);
|
|
13448
|
+
}
|
|
13449
|
+
if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
|
|
13450
|
+
const margin = atlas.margin ?? 0;
|
|
13451
|
+
const spacing = atlas.spacing ?? 0;
|
|
13452
|
+
return {
|
|
13453
|
+
sx: margin + col * (atlas.tileWidth + spacing),
|
|
13454
|
+
sy: margin + row * (atlas.tileHeight + spacing),
|
|
13455
|
+
sw: atlas.tileWidth,
|
|
13456
|
+
sh: atlas.tileHeight
|
|
13457
|
+
};
|
|
13458
|
+
}
|
|
13459
|
+
const st = atlas.subTextures[sprite];
|
|
13460
|
+
if (!st) return null;
|
|
13461
|
+
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
13462
|
+
}
|
|
13463
|
+
function isAtlasAsset(asset) {
|
|
13464
|
+
return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
|
|
13465
|
+
}
|
|
13466
|
+
function resolveAssetSource(img, asset, onReady) {
|
|
13467
|
+
if (isAtlasAsset(asset)) {
|
|
13468
|
+
const atlas = getAtlas(asset.atlas, onReady);
|
|
13469
|
+
if (!atlas) return null;
|
|
13470
|
+
const rect = subRectFor(atlas, asset.sprite);
|
|
13471
|
+
if (!rect) return null;
|
|
13472
|
+
return { img, rect, aspect: rect.sw / rect.sh };
|
|
13473
|
+
}
|
|
13474
|
+
const natW = img.naturalWidth || 1;
|
|
13475
|
+
const natH = img.naturalHeight || 1;
|
|
13476
|
+
return { img, rect: null, aspect: natW / natH };
|
|
13477
|
+
}
|
|
13478
|
+
function blit(ctx, src, dx, dy, dw, dh) {
|
|
13479
|
+
if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
|
|
13480
|
+
else ctx.drawImage(src.img, dx, dy, dw, dh);
|
|
13481
|
+
}
|
|
13482
|
+
var atlasCache;
|
|
13483
|
+
var init_atlasSlice = __esm({
|
|
13484
|
+
"components/game/shared/atlasSlice.ts"() {
|
|
13485
|
+
"use client";
|
|
13486
|
+
atlasCache = /* @__PURE__ */ new Map();
|
|
13487
|
+
}
|
|
13488
|
+
});
|
|
13419
13489
|
function useCamera() {
|
|
13420
13490
|
const cameraRef = React104.useRef({ x: 0, y: 0, zoom: 1 });
|
|
13421
13491
|
const targetCameraRef = React104.useRef(null);
|
|
@@ -13987,15 +14057,18 @@ function SideView({
|
|
|
13987
14057
|
const platType = plat.type ?? "ground";
|
|
13988
14058
|
const spriteAsset = tSprites?.[platType];
|
|
13989
14059
|
const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
const
|
|
14060
|
+
const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
|
|
14061
|
+
if (tileSrc) {
|
|
14062
|
+
const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
|
|
14063
|
+
const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
|
|
14064
|
+
const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
|
|
14065
|
+
const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
|
|
13993
14066
|
const scaleH = plat.height / tileH;
|
|
13994
14067
|
const scaledW = tileW * scaleH;
|
|
13995
14068
|
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
13996
14069
|
const drawW = Math.min(scaledW, plat.width - tx);
|
|
13997
14070
|
const srcW = drawW / scaleH;
|
|
13998
|
-
ctx.drawImage(tileImg,
|
|
14071
|
+
ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
13999
14072
|
}
|
|
14000
14073
|
} else {
|
|
14001
14074
|
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
@@ -14029,14 +14102,15 @@ function SideView({
|
|
|
14029
14102
|
const ppy = py - camY;
|
|
14030
14103
|
const facingRight = auth.facingRight ?? true;
|
|
14031
14104
|
const playerImg = pSprite ? loadImage(pSprite.url) : null;
|
|
14032
|
-
|
|
14105
|
+
const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
|
|
14106
|
+
if (playerSrc) {
|
|
14033
14107
|
ctx.save();
|
|
14034
14108
|
if (!facingRight) {
|
|
14035
14109
|
ctx.translate(ppx + pw, ppy);
|
|
14036
14110
|
ctx.scale(-1, 1);
|
|
14037
|
-
ctx
|
|
14111
|
+
blit(ctx, playerSrc, 0, 0, pw, ph);
|
|
14038
14112
|
} else {
|
|
14039
|
-
ctx
|
|
14113
|
+
blit(ctx, playerSrc, ppx, ppy, pw, ph);
|
|
14040
14114
|
}
|
|
14041
14115
|
ctx.restore();
|
|
14042
14116
|
} else {
|
|
@@ -14237,10 +14311,11 @@ function Canvas2D({
|
|
|
14237
14311
|
const attackTargetSet = React104.useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
14238
14312
|
const spriteUrls = React104.useMemo(() => {
|
|
14239
14313
|
const urls = [];
|
|
14314
|
+
const toUrl = (x) => typeof x === "string" ? x : x?.url;
|
|
14240
14315
|
for (const tile of sortedTiles) {
|
|
14241
14316
|
if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
|
|
14242
14317
|
else if (getTerrainSprite) {
|
|
14243
|
-
const url = getTerrainSprite(tile.terrain ?? "");
|
|
14318
|
+
const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
|
|
14244
14319
|
if (url) urls.push(url);
|
|
14245
14320
|
} else {
|
|
14246
14321
|
const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
|
|
@@ -14250,7 +14325,7 @@ function Canvas2D({
|
|
|
14250
14325
|
for (const feature of features) {
|
|
14251
14326
|
if (feature.sprite) urls.push(feature.sprite.url);
|
|
14252
14327
|
else if (getFeatureSprite) {
|
|
14253
|
-
const url = getFeatureSprite(feature.type);
|
|
14328
|
+
const url = toUrl(getFeatureSprite(feature.type));
|
|
14254
14329
|
if (url) urls.push(url);
|
|
14255
14330
|
} else {
|
|
14256
14331
|
const url = assetManifest?.features?.[feature.type]?.url;
|
|
@@ -14260,7 +14335,7 @@ function Canvas2D({
|
|
|
14260
14335
|
for (const unit of units) {
|
|
14261
14336
|
if (unit.sprite) urls.push(unit.sprite.url);
|
|
14262
14337
|
else if (getUnitSprite) {
|
|
14263
|
-
const url = getUnitSprite(unit);
|
|
14338
|
+
const url = toUrl(getUnitSprite(unit));
|
|
14264
14339
|
if (url) urls.push(url);
|
|
14265
14340
|
} else if (unit.unitType) {
|
|
14266
14341
|
const url = assetManifest?.units?.[unit.unitType]?.url;
|
|
@@ -14301,14 +14376,25 @@ function Canvas2D({
|
|
|
14301
14376
|
screenToWorld,
|
|
14302
14377
|
lerpToTarget
|
|
14303
14378
|
} = useCamera();
|
|
14304
|
-
const
|
|
14305
|
-
|
|
14379
|
+
const [, setAtlasVersion] = React104.useState(0);
|
|
14380
|
+
const bumpAtlas = React104.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
14381
|
+
const resolveTerrainAsset = React104.useCallback((tile) => {
|
|
14382
|
+
if (tile.terrainSprite) return tile.terrainSprite;
|
|
14383
|
+
const s = getTerrainSprite?.(tile.terrain ?? "");
|
|
14384
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
14385
|
+
return assetManifest?.terrains?.[tile.terrain ?? ""];
|
|
14306
14386
|
}, [getTerrainSprite, assetManifest]);
|
|
14307
|
-
const
|
|
14308
|
-
|
|
14387
|
+
const resolveFeatureAsset = React104.useCallback((feature) => {
|
|
14388
|
+
if (feature.sprite) return feature.sprite;
|
|
14389
|
+
const s = getFeatureSprite?.(feature.type);
|
|
14390
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
14391
|
+
return assetManifest?.features?.[feature.type];
|
|
14309
14392
|
}, [getFeatureSprite, assetManifest]);
|
|
14310
|
-
const
|
|
14311
|
-
|
|
14393
|
+
const resolveUnitAsset = React104.useCallback((unit) => {
|
|
14394
|
+
if (unit.sprite) return unit.sprite;
|
|
14395
|
+
const s = getUnitSprite?.(unit);
|
|
14396
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
14397
|
+
return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
|
|
14312
14398
|
}, [getUnitSprite, assetManifest]);
|
|
14313
14399
|
const miniMapTiles = React104.useMemo(() => {
|
|
14314
14400
|
if (!showMinimap) return [];
|
|
@@ -14372,18 +14458,17 @@ function Canvas2D({
|
|
|
14372
14458
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
14373
14459
|
continue;
|
|
14374
14460
|
}
|
|
14375
|
-
const
|
|
14376
|
-
const img =
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
|
|
14386
|
-
}
|
|
14461
|
+
const terrainAsset = resolveTerrainAsset(tile);
|
|
14462
|
+
const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
|
|
14463
|
+
const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
|
|
14464
|
+
if (src) {
|
|
14465
|
+
const drawW = scaledTileWidth;
|
|
14466
|
+
const drawH = scaledTileWidth / src.aspect;
|
|
14467
|
+
const drawX = pos.x;
|
|
14468
|
+
const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
|
|
14469
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
14470
|
+
} else if (img && img.naturalWidth === 0) {
|
|
14471
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
14387
14472
|
} else {
|
|
14388
14473
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
14389
14474
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -14437,15 +14522,16 @@ function Canvas2D({
|
|
|
14437
14522
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
14438
14523
|
continue;
|
|
14439
14524
|
}
|
|
14440
|
-
const
|
|
14441
|
-
const img =
|
|
14525
|
+
const featureAsset = resolveFeatureAsset(feature);
|
|
14526
|
+
const img = featureAsset?.url ? getImage(featureAsset.url) : null;
|
|
14527
|
+
const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
|
|
14442
14528
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
14443
14529
|
const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
14444
14530
|
const isCastle = feature.type === "castle";
|
|
14445
14531
|
const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
|
|
14446
14532
|
const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
|
|
14447
|
-
if (
|
|
14448
|
-
const ar =
|
|
14533
|
+
if (src) {
|
|
14534
|
+
const ar = src.aspect;
|
|
14449
14535
|
let drawH = featureDrawH;
|
|
14450
14536
|
let drawW = featureDrawH * ar;
|
|
14451
14537
|
if (drawW > maxFeatureW) {
|
|
@@ -14454,7 +14540,7 @@ function Canvas2D({
|
|
|
14454
14540
|
}
|
|
14455
14541
|
const drawX = centerX - drawW / 2;
|
|
14456
14542
|
const drawY = featureGroundY - drawH;
|
|
14457
|
-
ctx
|
|
14543
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
14458
14544
|
} else {
|
|
14459
14545
|
const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
|
|
14460
14546
|
ctx.beginPath();
|
|
@@ -14483,17 +14569,18 @@ function Canvas2D({
|
|
|
14483
14569
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
14484
14570
|
const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
14485
14571
|
const breatheOffset = 0;
|
|
14486
|
-
const
|
|
14487
|
-
const img =
|
|
14572
|
+
const unitAsset = resolveUnitAsset(unit);
|
|
14573
|
+
const img = unitAsset?.url ? getImage(unitAsset.url) : null;
|
|
14488
14574
|
const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
|
|
14489
14575
|
const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
|
|
14490
14576
|
const unitIsSheet = unit.spriteSheet?.url !== void 0;
|
|
14577
|
+
const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
|
|
14491
14578
|
const SHEET_ROWS = 5;
|
|
14492
14579
|
const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
|
|
14493
14580
|
const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
|
|
14494
14581
|
const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
|
|
14495
14582
|
const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
|
|
14496
|
-
const ar = frameW / (frameH || 1);
|
|
14583
|
+
const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
|
|
14497
14584
|
let drawH = unitDrawH;
|
|
14498
14585
|
let drawW = unitDrawH * ar;
|
|
14499
14586
|
if (drawW > maxUnitW) {
|
|
@@ -14509,6 +14596,8 @@ function Canvas2D({
|
|
|
14509
14596
|
if (img) {
|
|
14510
14597
|
if (unitIsSheet) {
|
|
14511
14598
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
14599
|
+
} else if (unitSrc) {
|
|
14600
|
+
blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
14512
14601
|
} else {
|
|
14513
14602
|
ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
14514
14603
|
}
|
|
@@ -14557,6 +14646,8 @@ function Canvas2D({
|
|
|
14557
14646
|
const drawUnit = (x) => {
|
|
14558
14647
|
if (unitIsSheet) {
|
|
14559
14648
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
|
|
14649
|
+
} else if (unitSrc) {
|
|
14650
|
+
blit(ctx, unitSrc, x, spriteY, drawW, drawH);
|
|
14560
14651
|
} else {
|
|
14561
14652
|
ctx.drawImage(img, x, spriteY, drawW, drawH);
|
|
14562
14653
|
}
|
|
@@ -14607,11 +14698,12 @@ function Canvas2D({
|
|
|
14607
14698
|
flatLike,
|
|
14608
14699
|
scale,
|
|
14609
14700
|
debug2,
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14701
|
+
resolveTerrainAsset,
|
|
14702
|
+
resolveFeatureAsset,
|
|
14703
|
+
resolveUnitAsset,
|
|
14613
14704
|
resolveFrameForUnit,
|
|
14614
14705
|
getImage,
|
|
14706
|
+
bumpAtlas,
|
|
14615
14707
|
baseOffsetX,
|
|
14616
14708
|
scaledTileWidth,
|
|
14617
14709
|
scaledTileHeight,
|
|
@@ -14925,7 +15017,7 @@ function Canvas2D({
|
|
|
14925
15017
|
}
|
|
14926
15018
|
);
|
|
14927
15019
|
}
|
|
14928
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
15020
|
+
var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
14929
15021
|
var init_Canvas2D = __esm({
|
|
14930
15022
|
"components/game/2d/molecules/Canvas2D.tsx"() {
|
|
14931
15023
|
"use client";
|
|
@@ -14939,6 +15031,7 @@ var init_Canvas2D = __esm({
|
|
|
14939
15031
|
init_MiniMap();
|
|
14940
15032
|
init_HealthBar();
|
|
14941
15033
|
init_useImageCache();
|
|
15034
|
+
init_atlasSlice();
|
|
14942
15035
|
init_useCamera();
|
|
14943
15036
|
init_useCanvasGestures();
|
|
14944
15037
|
init_useRenderInterpolation();
|
|
@@ -14952,6 +15045,8 @@ var init_Canvas2D = __esm({
|
|
|
14952
15045
|
hazard: "#c0392b",
|
|
14953
15046
|
goal: "#f1c40f"
|
|
14954
15047
|
};
|
|
15048
|
+
NOOP = () => {
|
|
15049
|
+
};
|
|
14955
15050
|
PLAYER_COLOR = "#3498db";
|
|
14956
15051
|
PLAYER_EYE_COLOR = "#ffffff";
|
|
14957
15052
|
SKY_GRADIENT_TOP = "#1a1a2e";
|
|
@@ -19610,6 +19705,153 @@ var init_ComponentPatterns = __esm({
|
|
|
19610
19705
|
AlertPattern.displayName = "AlertPattern";
|
|
19611
19706
|
}
|
|
19612
19707
|
});
|
|
19708
|
+
var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
|
|
19709
|
+
var init_AlgorithmCanvas = __esm({
|
|
19710
|
+
"components/learning/molecules/AlgorithmCanvas.tsx"() {
|
|
19711
|
+
"use client";
|
|
19712
|
+
init_atoms();
|
|
19713
|
+
init_Stack();
|
|
19714
|
+
init_LearningCanvas();
|
|
19715
|
+
DEFAULT_BAR_COLOR = "#3b82f6";
|
|
19716
|
+
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
19717
|
+
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
19718
|
+
POINTER_BAND = 34;
|
|
19719
|
+
TOP_PAD = 12;
|
|
19720
|
+
AlgorithmCanvas = ({
|
|
19721
|
+
className,
|
|
19722
|
+
width = 600,
|
|
19723
|
+
height = 400,
|
|
19724
|
+
title,
|
|
19725
|
+
backgroundColor,
|
|
19726
|
+
bars = [],
|
|
19727
|
+
cells = [],
|
|
19728
|
+
pointers = [],
|
|
19729
|
+
shapes = [],
|
|
19730
|
+
interactive = false,
|
|
19731
|
+
animate = false,
|
|
19732
|
+
onShapeClick,
|
|
19733
|
+
isLoading,
|
|
19734
|
+
error
|
|
19735
|
+
}) => {
|
|
19736
|
+
const derivedShapes = React104.useMemo(() => {
|
|
19737
|
+
const out = [];
|
|
19738
|
+
if (bars.length > 0) {
|
|
19739
|
+
const slot = width / bars.length;
|
|
19740
|
+
const barW = slot * 0.8;
|
|
19741
|
+
const gap = slot * 0.1;
|
|
19742
|
+
const baseline = height - POINTER_BAND;
|
|
19743
|
+
const usableH = baseline - TOP_PAD;
|
|
19744
|
+
const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
|
|
19745
|
+
bars.forEach((bar, i) => {
|
|
19746
|
+
const v = Number.isFinite(bar.value) ? bar.value : 0;
|
|
19747
|
+
const bh = Math.max(0, v / maxV * usableH);
|
|
19748
|
+
const x = i * slot + gap;
|
|
19749
|
+
const color = bar.color ?? DEFAULT_BAR_COLOR;
|
|
19750
|
+
out.push({
|
|
19751
|
+
type: "rect",
|
|
19752
|
+
id: `bar-${i}`,
|
|
19753
|
+
x,
|
|
19754
|
+
y: baseline - bh,
|
|
19755
|
+
width: barW,
|
|
19756
|
+
height: bh,
|
|
19757
|
+
color,
|
|
19758
|
+
fill: color
|
|
19759
|
+
});
|
|
19760
|
+
const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
|
|
19761
|
+
if (label) {
|
|
19762
|
+
out.push({
|
|
19763
|
+
type: "text",
|
|
19764
|
+
x: x + barW / 2,
|
|
19765
|
+
y: baseline - bh - 8,
|
|
19766
|
+
text: label,
|
|
19767
|
+
color: "#374151",
|
|
19768
|
+
fontSize: 11,
|
|
19769
|
+
align: "center"
|
|
19770
|
+
});
|
|
19771
|
+
}
|
|
19772
|
+
});
|
|
19773
|
+
pointers.forEach((p) => {
|
|
19774
|
+
if (p.index < 0 || p.index >= bars.length) return;
|
|
19775
|
+
const cx = p.index * slot + slot / 2;
|
|
19776
|
+
const color = p.color ?? DEFAULT_POINTER_COLOR;
|
|
19777
|
+
out.push({
|
|
19778
|
+
type: "arrow",
|
|
19779
|
+
x1: cx,
|
|
19780
|
+
y1: height - 6,
|
|
19781
|
+
x2: cx,
|
|
19782
|
+
y2: baseline + 4,
|
|
19783
|
+
color,
|
|
19784
|
+
lineWidth: 2
|
|
19785
|
+
});
|
|
19786
|
+
if (p.label) {
|
|
19787
|
+
out.push({
|
|
19788
|
+
type: "text",
|
|
19789
|
+
x: cx,
|
|
19790
|
+
y: height - 22,
|
|
19791
|
+
text: p.label,
|
|
19792
|
+
color,
|
|
19793
|
+
fontSize: 11,
|
|
19794
|
+
align: "center"
|
|
19795
|
+
});
|
|
19796
|
+
}
|
|
19797
|
+
});
|
|
19798
|
+
}
|
|
19799
|
+
if (cells.length > 0) {
|
|
19800
|
+
const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
|
|
19801
|
+
const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
|
|
19802
|
+
const cw = width / maxCol;
|
|
19803
|
+
const ch = height / maxRow;
|
|
19804
|
+
cells.forEach((c, i) => {
|
|
19805
|
+
const x = c.col * cw;
|
|
19806
|
+
const y = c.row * ch;
|
|
19807
|
+
const color = c.color ?? DEFAULT_CELL_COLOR;
|
|
19808
|
+
out.push({
|
|
19809
|
+
type: "rect",
|
|
19810
|
+
id: `cell-${i}`,
|
|
19811
|
+
x: x + 1,
|
|
19812
|
+
y: y + 1,
|
|
19813
|
+
width: cw - 2,
|
|
19814
|
+
height: ch - 2,
|
|
19815
|
+
color: "#9ca3af",
|
|
19816
|
+
fill: color
|
|
19817
|
+
});
|
|
19818
|
+
const label = c.label ?? (c.value != null ? String(c.value) : void 0);
|
|
19819
|
+
if (label && cw >= 18 && ch >= 14) {
|
|
19820
|
+
out.push({
|
|
19821
|
+
type: "text",
|
|
19822
|
+
x: x + cw / 2,
|
|
19823
|
+
y: y + ch / 2,
|
|
19824
|
+
text: label,
|
|
19825
|
+
color: "#111827",
|
|
19826
|
+
fontSize: 12,
|
|
19827
|
+
align: "center"
|
|
19828
|
+
});
|
|
19829
|
+
}
|
|
19830
|
+
});
|
|
19831
|
+
}
|
|
19832
|
+
out.push(...shapes);
|
|
19833
|
+
return out;
|
|
19834
|
+
}, [bars, cells, pointers, shapes, width, height]);
|
|
19835
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
19836
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
|
|
19837
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19838
|
+
LearningCanvas,
|
|
19839
|
+
{
|
|
19840
|
+
width,
|
|
19841
|
+
height,
|
|
19842
|
+
backgroundColor,
|
|
19843
|
+
shapes: derivedShapes,
|
|
19844
|
+
interactive,
|
|
19845
|
+
animate,
|
|
19846
|
+
onShapeClick,
|
|
19847
|
+
isLoading,
|
|
19848
|
+
error
|
|
19849
|
+
}
|
|
19850
|
+
)
|
|
19851
|
+
] }) });
|
|
19852
|
+
};
|
|
19853
|
+
}
|
|
19854
|
+
});
|
|
19613
19855
|
var AuthLayout;
|
|
19614
19856
|
var init_AuthLayout = __esm({
|
|
19615
19857
|
"components/marketing/templates/AuthLayout.tsx"() {
|
|
@@ -48065,6 +48307,7 @@ var init_component_registry_generated = __esm({
|
|
|
48065
48307
|
init_ActionTile();
|
|
48066
48308
|
init_ActivationBlock();
|
|
48067
48309
|
init_ComponentPatterns();
|
|
48310
|
+
init_AlgorithmCanvas();
|
|
48068
48311
|
init_AnimatedCounter();
|
|
48069
48312
|
init_AnimatedGraphic();
|
|
48070
48313
|
init_AnimatedReveal();
|
|
@@ -48363,6 +48606,7 @@ var init_component_registry_generated = __esm({
|
|
|
48363
48606
|
"ActivationBlock": ActivationBlock,
|
|
48364
48607
|
"Alert": AlertPattern,
|
|
48365
48608
|
"AlertPattern": AlertPattern,
|
|
48609
|
+
"AlgorithmCanvas": AlgorithmCanvas,
|
|
48366
48610
|
"AnimatedCounter": AnimatedCounter,
|
|
48367
48611
|
"AnimatedGraphic": AnimatedGraphic,
|
|
48368
48612
|
"AnimatedReveal": AnimatedReveal,
|