@neta-art/cohub-cli 10.1.0 → 10.2.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/README.md +2 -2
- package/dist/board-kernel.js +2030 -1607
- package/dist/command-input.d.ts +4 -0
- package/dist/command-input.js +16 -0
- package/dist/commands/app-commerce.js +1 -3
- package/dist/commands/decision.d.ts +4 -0
- package/dist/commands/decision.js +113 -0
- package/dist/commands/spaces.js +4 -15
- package/dist/index.js +2 -1
- package/package.json +3 -3
package/dist/board-kernel.js
CHANGED
|
@@ -9341,13 +9341,47 @@ function filePreviewKind(snapshot) {
|
|
|
9341
9341
|
if (snapshot.excerpt) return "text";
|
|
9342
9342
|
return "blank";
|
|
9343
9343
|
}
|
|
9344
|
-
/** Short uppercase type label for a file card (`MD`, `JSON`, `FILE`). */
|
|
9345
9344
|
function fileTypeLabel(path) {
|
|
9345
|
+
if (isWebPageUrl(path)) return "LINK";
|
|
9346
9346
|
const name = fileBaseName(path);
|
|
9347
9347
|
const dot = name.lastIndexOf(".");
|
|
9348
9348
|
if (dot <= 0) return (name.replace(/^\./, "") || "file").toUpperCase();
|
|
9349
9349
|
return name.slice(dot + 1).toUpperCase();
|
|
9350
9350
|
}
|
|
9351
|
+
function isWebPageUrl(path) {
|
|
9352
|
+
if (!/^https?:\/\//i.test(path)) return false;
|
|
9353
|
+
try {
|
|
9354
|
+
const last = new URL(path).pathname.split("/").filter(Boolean).pop() ?? "";
|
|
9355
|
+
return !/\.[a-z\d]{1,8}$/i.test(last);
|
|
9356
|
+
} catch {
|
|
9357
|
+
return false;
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9360
|
+
/** Human-readable byte size. Kept as a public helper for custom card renderers. */
|
|
9361
|
+
function formatFileSize(bytes) {
|
|
9362
|
+
if (bytes === void 0 || !Number.isFinite(bytes) || bytes < 0) return "";
|
|
9363
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
9364
|
+
const units = [
|
|
9365
|
+
"KB",
|
|
9366
|
+
"MB",
|
|
9367
|
+
"GB",
|
|
9368
|
+
"TB"
|
|
9369
|
+
];
|
|
9370
|
+
let value = bytes / 1024;
|
|
9371
|
+
let unit = 0;
|
|
9372
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
9373
|
+
value /= 1024;
|
|
9374
|
+
unit += 1;
|
|
9375
|
+
}
|
|
9376
|
+
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;
|
|
9377
|
+
}
|
|
9378
|
+
/** `MD · 12 KB` — empty when neither fact is available. */
|
|
9379
|
+
function fileMetaLine(path, size) {
|
|
9380
|
+
const type = fileTypeLabel(path);
|
|
9381
|
+
const formatted = formatFileSize(size);
|
|
9382
|
+
if (type && formatted) return `${type} · ${formatted}`;
|
|
9383
|
+
return formatted || type;
|
|
9384
|
+
}
|
|
9351
9385
|
/** Map a file category onto an existing palette token. */
|
|
9352
9386
|
function fileCategoryAccent(category, palette) {
|
|
9353
9387
|
switch (category) {
|
|
@@ -27011,8 +27045,8 @@ const DARK = {
|
|
|
27011
27045
|
legendary: 16096779
|
|
27012
27046
|
};
|
|
27013
27047
|
const LIGHT = {
|
|
27014
|
-
bg:
|
|
27015
|
-
surface:
|
|
27048
|
+
bg: 16251129,
|
|
27049
|
+
surface: 16777215,
|
|
27016
27050
|
hover: 15329772,
|
|
27017
27051
|
border: 14079706,
|
|
27018
27052
|
brand: 15222030,
|
|
@@ -27195,6 +27229,298 @@ function inspectBoardScene(scene, limit = 100) {
|
|
|
27195
27229
|
return diagnostics;
|
|
27196
27230
|
}
|
|
27197
27231
|
//#endregion
|
|
27232
|
+
//#region ../sdk/src/board/render/text-fit.ts
|
|
27233
|
+
function fitLineWithEllipsis(line, wrapWidth, measureWidth) {
|
|
27234
|
+
const trimmed = line.replace(/\s+$/u, "");
|
|
27235
|
+
if (!trimmed) return "…";
|
|
27236
|
+
const full = `${trimmed}…`;
|
|
27237
|
+
if (measureWidth(full) <= wrapWidth) return full;
|
|
27238
|
+
let lo = 0;
|
|
27239
|
+
let hi = trimmed.length;
|
|
27240
|
+
let best = "…";
|
|
27241
|
+
while (lo <= hi) {
|
|
27242
|
+
const mid = lo + hi >> 1;
|
|
27243
|
+
const candidate = mid > 0 ? `${trimmed.slice(0, mid)}…` : "…";
|
|
27244
|
+
if (measureWidth(candidate) <= wrapWidth) {
|
|
27245
|
+
best = candidate;
|
|
27246
|
+
lo = mid + 1;
|
|
27247
|
+
} else hi = mid - 1;
|
|
27248
|
+
}
|
|
27249
|
+
return best;
|
|
27250
|
+
}
|
|
27251
|
+
function fitTextToLines(text, value, maxLines, wrapWidth) {
|
|
27252
|
+
const width = Math.max(1, wrapWidth);
|
|
27253
|
+
text.style.wordWrapWidth = width;
|
|
27254
|
+
if (!value || maxLines <= 0) {
|
|
27255
|
+
if (text.text !== "") text.text = "";
|
|
27256
|
+
return;
|
|
27257
|
+
}
|
|
27258
|
+
const charCap = Math.max(maxLines * Math.ceil(width), maxLines * 4);
|
|
27259
|
+
const sample = value.length > charCap ? value.slice(0, charCap) : value;
|
|
27260
|
+
const metrics = CanvasTextMetrics.measureText(sample, text.style);
|
|
27261
|
+
if (!(metrics.lines.length > maxLines || sample !== value)) {
|
|
27262
|
+
if (text.text !== value) text.text = value;
|
|
27263
|
+
return;
|
|
27264
|
+
}
|
|
27265
|
+
const keptCount = Math.min(maxLines, metrics.lines.length);
|
|
27266
|
+
const kept = metrics.lines.slice(0, keptCount);
|
|
27267
|
+
const lastIndex = kept.length - 1;
|
|
27268
|
+
const probe = text.style.clone();
|
|
27269
|
+
probe.wordWrap = false;
|
|
27270
|
+
kept[lastIndex] = fitLineWithEllipsis(kept[lastIndex] ?? "", width, (candidate) => CanvasTextMetrics.measureText(candidate, probe).width);
|
|
27271
|
+
const fitted = kept.join("\n");
|
|
27272
|
+
if (text.text !== fitted) text.text = fitted;
|
|
27273
|
+
}
|
|
27274
|
+
function fitTextToWidth(text, value, width) {
|
|
27275
|
+
text.style.wordWrap = false;
|
|
27276
|
+
const measure = (candidate) => CanvasTextMetrics.measureText(candidate, text.style).width;
|
|
27277
|
+
const fitted = !value || measure(value) <= width ? value : fitLineWithEllipsis(value, width, measure);
|
|
27278
|
+
if (text.text !== fitted) text.text = fitted;
|
|
27279
|
+
}
|
|
27280
|
+
//#endregion
|
|
27281
|
+
//#region ../sdk/src/board/render/text-resolution.ts
|
|
27282
|
+
const MAX_BOARD_RESOLUTION = 2;
|
|
27283
|
+
function getBoardResolution() {
|
|
27284
|
+
return Math.min(globalThis.devicePixelRatio || 1, MAX_BOARD_RESOLUTION);
|
|
27285
|
+
}
|
|
27286
|
+
/**
|
|
27287
|
+
* Zoom buckets for text re-rasterisation. Pixi Text is a bitmap: at high zoom it
|
|
27288
|
+
* looks soft unless we raise its resolution. We quantise zoom into a few
|
|
27289
|
+
* buckets so small zoom changes don't thrash texture regeneration.
|
|
27290
|
+
*/
|
|
27291
|
+
const TEXT_ZOOM_BUCKETS = [
|
|
27292
|
+
.5,
|
|
27293
|
+
1,
|
|
27294
|
+
1.5,
|
|
27295
|
+
2,
|
|
27296
|
+
3,
|
|
27297
|
+
4
|
|
27298
|
+
];
|
|
27299
|
+
function textZoomBucket(zoom) {
|
|
27300
|
+
const clamped = Math.max(.1, Math.min(4, zoom));
|
|
27301
|
+
for (const bucket of TEXT_ZOOM_BUCKETS) if (clamped <= bucket) return bucket;
|
|
27302
|
+
return TEXT_ZOOM_BUCKETS[TEXT_ZOOM_BUCKETS.length - 1] ?? 4;
|
|
27303
|
+
}
|
|
27304
|
+
function boardCardDetailed(zoom) {
|
|
27305
|
+
return textZoomBucket(zoom) >= 1;
|
|
27306
|
+
}
|
|
27307
|
+
/** Effective text resolution for a given camera zoom. */
|
|
27308
|
+
function textResolutionForZoom(zoom) {
|
|
27309
|
+
const bucket = textZoomBucket(zoom);
|
|
27310
|
+
return Math.min(getBoardResolution() * Math.max(1, bucket), 6);
|
|
27311
|
+
}
|
|
27312
|
+
/** Update a Pixi text texture only when zoom crosses a resolution bucket. */
|
|
27313
|
+
function syncTextResolution(text, state, zoom) {
|
|
27314
|
+
const resolution = textResolutionForZoom(zoom);
|
|
27315
|
+
if (resolution === state.resolution) return;
|
|
27316
|
+
text.resolution = resolution;
|
|
27317
|
+
state.resolution = resolution;
|
|
27318
|
+
}
|
|
27319
|
+
/** Defer expensive Pixi word-wrap rasterisation during a live resize. */
|
|
27320
|
+
function syncTextWrapWidth(text, state, width, defer) {
|
|
27321
|
+
if (defer || width === state.wrapWidth) return;
|
|
27322
|
+
text.style.wordWrapWidth = width;
|
|
27323
|
+
state.wrapWidth = width;
|
|
27324
|
+
}
|
|
27325
|
+
const ICON = 12;
|
|
27326
|
+
const GAP$2 = 5;
|
|
27327
|
+
const MAX_GROWTH = 1.25;
|
|
27328
|
+
const MIN_READABLE = 7;
|
|
27329
|
+
const SECOND$1 = 1e3;
|
|
27330
|
+
function formatBoardDuration(ms) {
|
|
27331
|
+
const total = Math.max(0, Math.floor(ms / SECOND$1));
|
|
27332
|
+
const hours = Math.floor(total / 3600);
|
|
27333
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
27334
|
+
const seconds = String(total % 60).padStart(2, "0");
|
|
27335
|
+
return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}` : `${minutes}:${seconds}`;
|
|
27336
|
+
}
|
|
27337
|
+
const PIXEL_GLYPHS = {
|
|
27338
|
+
image: [
|
|
27339
|
+
"######",
|
|
27340
|
+
"#....#",
|
|
27341
|
+
"#.#..#",
|
|
27342
|
+
"#.##.#",
|
|
27343
|
+
"######",
|
|
27344
|
+
"......"
|
|
27345
|
+
],
|
|
27346
|
+
video: [
|
|
27347
|
+
"######",
|
|
27348
|
+
"#.#..#",
|
|
27349
|
+
"#.##.#",
|
|
27350
|
+
"#.#..#",
|
|
27351
|
+
"######",
|
|
27352
|
+
"......"
|
|
27353
|
+
],
|
|
27354
|
+
audio: [
|
|
27355
|
+
"...#..",
|
|
27356
|
+
"...##.",
|
|
27357
|
+
"...#.#",
|
|
27358
|
+
"...#..",
|
|
27359
|
+
".###..",
|
|
27360
|
+
".###.."
|
|
27361
|
+
],
|
|
27362
|
+
file: [
|
|
27363
|
+
"####..",
|
|
27364
|
+
"#..##.",
|
|
27365
|
+
"#...##",
|
|
27366
|
+
"#....#",
|
|
27367
|
+
"#....#",
|
|
27368
|
+
"######"
|
|
27369
|
+
],
|
|
27370
|
+
task: [
|
|
27371
|
+
"..#...",
|
|
27372
|
+
".###..",
|
|
27373
|
+
"#####.",
|
|
27374
|
+
".###..",
|
|
27375
|
+
"..#...",
|
|
27376
|
+
"......"
|
|
27377
|
+
]
|
|
27378
|
+
};
|
|
27379
|
+
function drawLineGlyph(graphics, glyph, color) {
|
|
27380
|
+
const line = {
|
|
27381
|
+
color,
|
|
27382
|
+
width: 1.25,
|
|
27383
|
+
alpha: 1,
|
|
27384
|
+
cap: "round",
|
|
27385
|
+
join: "round"
|
|
27386
|
+
};
|
|
27387
|
+
switch (glyph) {
|
|
27388
|
+
case "image":
|
|
27389
|
+
graphics.roundRect(1, 2, 10, 8, 1.5).stroke(line);
|
|
27390
|
+
graphics.moveTo(2.5, 9).lineTo(5, 6).lineTo(7, 8).lineTo(8.5, 6.5).lineTo(10, 8).stroke(line);
|
|
27391
|
+
return;
|
|
27392
|
+
case "video":
|
|
27393
|
+
graphics.roundRect(1, 2.5, 10, 7, 1.5).stroke(line);
|
|
27394
|
+
graphics.poly([
|
|
27395
|
+
5,
|
|
27396
|
+
4.5,
|
|
27397
|
+
5,
|
|
27398
|
+
7.5,
|
|
27399
|
+
7.5,
|
|
27400
|
+
6
|
|
27401
|
+
]).fill({ color });
|
|
27402
|
+
return;
|
|
27403
|
+
case "audio":
|
|
27404
|
+
for (const [x, height] of [
|
|
27405
|
+
[2.5, 3],
|
|
27406
|
+
[5, 7],
|
|
27407
|
+
[7.5, 9],
|
|
27408
|
+
[10, 5]
|
|
27409
|
+
]) graphics.moveTo(x, 6 - height / 2).lineTo(x, 6 + height / 2);
|
|
27410
|
+
graphics.stroke(line);
|
|
27411
|
+
return;
|
|
27412
|
+
case "file":
|
|
27413
|
+
graphics.poly([
|
|
27414
|
+
2.5,
|
|
27415
|
+
1,
|
|
27416
|
+
7.5,
|
|
27417
|
+
1,
|
|
27418
|
+
9.5,
|
|
27419
|
+
3,
|
|
27420
|
+
9.5,
|
|
27421
|
+
11,
|
|
27422
|
+
2.5,
|
|
27423
|
+
11
|
|
27424
|
+
]).stroke(line);
|
|
27425
|
+
graphics.moveTo(7.5, 1).lineTo(7.5, 3).lineTo(9.5, 3).stroke(line);
|
|
27426
|
+
return;
|
|
27427
|
+
case "task":
|
|
27428
|
+
graphics.poly([
|
|
27429
|
+
6,
|
|
27430
|
+
1,
|
|
27431
|
+
7.3,
|
|
27432
|
+
4.7,
|
|
27433
|
+
11,
|
|
27434
|
+
6,
|
|
27435
|
+
7.3,
|
|
27436
|
+
7.3,
|
|
27437
|
+
6,
|
|
27438
|
+
11,
|
|
27439
|
+
4.7,
|
|
27440
|
+
7.3,
|
|
27441
|
+
1,
|
|
27442
|
+
6,
|
|
27443
|
+
4.7,
|
|
27444
|
+
4.7
|
|
27445
|
+
]).fill({ color });
|
|
27446
|
+
return;
|
|
27447
|
+
}
|
|
27448
|
+
}
|
|
27449
|
+
function drawCardGlyph(graphics, glyph, color, pixel) {
|
|
27450
|
+
if (!pixel) {
|
|
27451
|
+
drawLineGlyph(graphics, glyph, color);
|
|
27452
|
+
return;
|
|
27453
|
+
}
|
|
27454
|
+
PIXEL_GLYPHS[glyph].forEach((row, y) => {
|
|
27455
|
+
for (let x = 0; x < row.length; x += 1) if (row[x] === "#") graphics.rect(x * 2, y * 2, 2, 2);
|
|
27456
|
+
});
|
|
27457
|
+
graphics.fill({ color });
|
|
27458
|
+
}
|
|
27459
|
+
function createCardTag() {
|
|
27460
|
+
const root = new Container({ label: "card-tag" });
|
|
27461
|
+
const icon = new Graphics();
|
|
27462
|
+
root.addChild(icon);
|
|
27463
|
+
root.visible = false;
|
|
27464
|
+
return {
|
|
27465
|
+
root,
|
|
27466
|
+
icon,
|
|
27467
|
+
text: null,
|
|
27468
|
+
sig: "",
|
|
27469
|
+
resolution: 0,
|
|
27470
|
+
width: 0
|
|
27471
|
+
};
|
|
27472
|
+
}
|
|
27473
|
+
function zoomCardTag(tag, zoom) {
|
|
27474
|
+
if (!tag.text || !tag.sig) return;
|
|
27475
|
+
const scale = Math.min(MAX_GROWTH, Math.max(1, 1 / Math.max(zoom, .01)));
|
|
27476
|
+
const span = 17 + tag.text.width;
|
|
27477
|
+
tag.root.scale.set(scale);
|
|
27478
|
+
tag.root.position.set(0, -18 * scale);
|
|
27479
|
+
tag.root.visible = 11 * scale * zoom >= MIN_READABLE && span * scale <= tag.width + .5;
|
|
27480
|
+
}
|
|
27481
|
+
function syncCardTag(tag, input, context) {
|
|
27482
|
+
tag.width = input.width;
|
|
27483
|
+
if (!input.text || input.width <= 24) {
|
|
27484
|
+
tag.sig = "";
|
|
27485
|
+
tag.root.visible = false;
|
|
27486
|
+
return;
|
|
27487
|
+
}
|
|
27488
|
+
if (!tag.text) {
|
|
27489
|
+
tag.resolution = textResolutionForZoom(context.zoom);
|
|
27490
|
+
tag.text = new Text({
|
|
27491
|
+
text: "",
|
|
27492
|
+
style: {
|
|
27493
|
+
fontFamily: context.style.font,
|
|
27494
|
+
fontSize: 11,
|
|
27495
|
+
fontWeight: "500"
|
|
27496
|
+
},
|
|
27497
|
+
resolution: tag.resolution,
|
|
27498
|
+
roundPixels: true
|
|
27499
|
+
});
|
|
27500
|
+
tag.root.addChild(tag.text);
|
|
27501
|
+
}
|
|
27502
|
+
syncTextResolution(tag.text, tag, context.zoom);
|
|
27503
|
+
const sig = [
|
|
27504
|
+
input.glyph,
|
|
27505
|
+
input.text,
|
|
27506
|
+
input.width,
|
|
27507
|
+
context.themeKey
|
|
27508
|
+
].join("|");
|
|
27509
|
+
if (sig === tag.sig) {
|
|
27510
|
+
zoomCardTag(tag, context.zoom);
|
|
27511
|
+
return;
|
|
27512
|
+
}
|
|
27513
|
+
tag.sig = sig;
|
|
27514
|
+
const color = context.palette.muted;
|
|
27515
|
+
const pixel = context.style.icons === "pixel";
|
|
27516
|
+
drawCardGlyph(tag.icon.clear(), input.glyph, color, pixel);
|
|
27517
|
+
tag.text.style.fill = color;
|
|
27518
|
+
tag.text.style.fontFamily = context.style.font;
|
|
27519
|
+
fitTextToWidth(tag.text, input.text, Math.max(1, input.width - ICON - GAP$2));
|
|
27520
|
+
tag.text.position.set(17, (ICON - tag.text.height) / 2);
|
|
27521
|
+
zoomCardTag(tag, context.zoom);
|
|
27522
|
+
}
|
|
27523
|
+
//#endregion
|
|
27198
27524
|
//#region ../sdk/src/board/render/clip.ts
|
|
27199
27525
|
function isClippingFrame(item) {
|
|
27200
27526
|
return item.type === "frame" && item.props.clip !== false;
|
|
@@ -27258,7 +27584,7 @@ function audioWaveformBars(seed, count) {
|
|
|
27258
27584
|
}
|
|
27259
27585
|
return bars;
|
|
27260
27586
|
}
|
|
27261
|
-
function drawAudioWaveform(graphics, seed, rect, color, alpha = .72) {
|
|
27587
|
+
function drawAudioWaveform(graphics, seed, rect, color, alpha = .72, square = false) {
|
|
27262
27588
|
const count = Math.max(8, Math.min(DEFAULT_BARS, Math.floor(rect.width / 4)));
|
|
27263
27589
|
const step = rect.width / count;
|
|
27264
27590
|
const barWidth = Math.max(1.5, step - BAR_GAP);
|
|
@@ -27267,53 +27593,225 @@ function drawAudioWaveform(graphics, seed, rect, color, alpha = .72) {
|
|
|
27267
27593
|
const bars = audioWaveformBars(seed, count);
|
|
27268
27594
|
for (let index = 0; index < count; index += 1) {
|
|
27269
27595
|
const height = Math.max(2, (bars[index] ?? .4) * maxHeight);
|
|
27270
|
-
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
});
|
|
27596
|
+
const x = rect.x + index * step;
|
|
27597
|
+
if (square) graphics.rect(x, centerY - height / 2, barWidth, height);
|
|
27598
|
+
else graphics.roundRect(x, centerY - height / 2, barWidth, height, barWidth / 2);
|
|
27274
27599
|
}
|
|
27600
|
+
graphics.fill({
|
|
27601
|
+
color,
|
|
27602
|
+
alpha
|
|
27603
|
+
});
|
|
27275
27604
|
}
|
|
27276
27605
|
//#endregion
|
|
27277
|
-
//#region ../sdk/src/board/render/
|
|
27278
|
-
const
|
|
27279
|
-
function
|
|
27280
|
-
return Math.
|
|
27606
|
+
//#region ../sdk/src/board/render/stroke.ts
|
|
27607
|
+
const HEAD_SPREAD = Math.PI / 6;
|
|
27608
|
+
function dashPattern(dash, width) {
|
|
27609
|
+
if (dash === "dashed") return [Math.max(6, width * 4), Math.max(4, width * 3)];
|
|
27610
|
+
if (dash === "dotted") return [Math.max(.5, width * .01), Math.max(3, width * 2)];
|
|
27611
|
+
return null;
|
|
27281
27612
|
}
|
|
27282
|
-
|
|
27283
|
-
|
|
27284
|
-
|
|
27285
|
-
|
|
27286
|
-
|
|
27287
|
-
const
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
|
|
27291
|
-
|
|
27292
|
-
|
|
27293
|
-
|
|
27294
|
-
];
|
|
27295
|
-
|
|
27296
|
-
|
|
27297
|
-
|
|
27298
|
-
|
|
27613
|
+
function trimPolyline(path, trim) {
|
|
27614
|
+
if (trim === void 0 || trim >= 1 || path.length < 2) return path;
|
|
27615
|
+
if (trim <= 0) return [];
|
|
27616
|
+
let total = 0;
|
|
27617
|
+
for (let index = 1; index < path.length; index += 1) {
|
|
27618
|
+
const a = path[index - 1];
|
|
27619
|
+
const b = path[index];
|
|
27620
|
+
total += Math.hypot(b.x - a.x, b.y - a.y);
|
|
27621
|
+
}
|
|
27622
|
+
let remaining = total * trim;
|
|
27623
|
+
const out = [path[0]];
|
|
27624
|
+
for (let index = 1; index < path.length; index += 1) {
|
|
27625
|
+
const a = path[index - 1];
|
|
27626
|
+
const b = path[index];
|
|
27627
|
+
const length = Math.hypot(b.x - a.x, b.y - a.y);
|
|
27628
|
+
if (length >= remaining) {
|
|
27629
|
+
const t = length > 0 ? remaining / length : 0;
|
|
27630
|
+
out.push(worldPoint(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t));
|
|
27631
|
+
return out;
|
|
27632
|
+
}
|
|
27633
|
+
out.push(b);
|
|
27634
|
+
remaining -= length;
|
|
27635
|
+
}
|
|
27636
|
+
return out;
|
|
27299
27637
|
}
|
|
27300
|
-
|
|
27301
|
-
|
|
27302
|
-
|
|
27303
|
-
|
|
27638
|
+
function tracePolyline(graphics, path, pattern, closed = false, offset = 0) {
|
|
27639
|
+
const points = closed && path.length > 2 ? [...path, path[0]] : path;
|
|
27640
|
+
if (points.length < 2) return;
|
|
27641
|
+
if (!pattern) {
|
|
27642
|
+
const first = points[0];
|
|
27643
|
+
graphics.moveTo(first.x, first.y);
|
|
27644
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
27645
|
+
const point = points[index];
|
|
27646
|
+
graphics.lineTo(point.x, point.y);
|
|
27647
|
+
}
|
|
27648
|
+
if (closed) graphics.closePath();
|
|
27649
|
+
return;
|
|
27650
|
+
}
|
|
27651
|
+
const [dash, gap] = pattern;
|
|
27652
|
+
const phase = Math.max(0, offset) % (dash + gap);
|
|
27653
|
+
let penDown = phase < dash;
|
|
27654
|
+
let fresh = penDown;
|
|
27655
|
+
let remaining = penDown ? dash - phase : dash + gap - phase;
|
|
27656
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
27657
|
+
const a = points[index - 1];
|
|
27658
|
+
const b = points[index];
|
|
27659
|
+
const dx = b.x - a.x;
|
|
27660
|
+
const dy = b.y - a.y;
|
|
27661
|
+
const length = Math.hypot(dx, dy);
|
|
27662
|
+
let travelled = 0;
|
|
27663
|
+
while (length - travelled > 1e-4) {
|
|
27664
|
+
const step = Math.min(length - travelled, remaining);
|
|
27665
|
+
if (penDown) {
|
|
27666
|
+
const t0 = travelled / length;
|
|
27667
|
+
const t1 = (travelled + step) / length;
|
|
27668
|
+
if (fresh) graphics.moveTo(a.x + dx * t0, a.y + dy * t0);
|
|
27669
|
+
fresh = false;
|
|
27670
|
+
graphics.lineTo(a.x + dx * t1, a.y + dy * t1);
|
|
27671
|
+
}
|
|
27672
|
+
travelled += step;
|
|
27673
|
+
remaining -= step;
|
|
27674
|
+
if (remaining <= 1e-4) {
|
|
27675
|
+
penDown = !penDown;
|
|
27676
|
+
fresh = penDown;
|
|
27677
|
+
remaining = penDown ? dash : gap;
|
|
27678
|
+
}
|
|
27679
|
+
}
|
|
27680
|
+
}
|
|
27304
27681
|
}
|
|
27305
|
-
|
|
27306
|
-
|
|
27307
|
-
const resolution = textResolutionForZoom(zoom);
|
|
27308
|
-
if (resolution === state.resolution) return;
|
|
27309
|
-
text.resolution = resolution;
|
|
27310
|
-
state.resolution = resolution;
|
|
27682
|
+
function traceArrowhead(graphics, tip, angle, size) {
|
|
27683
|
+
graphics.moveTo(tip.x - size * Math.cos(angle - HEAD_SPREAD), tip.y - size * Math.sin(angle - HEAD_SPREAD)).lineTo(tip.x, tip.y).lineTo(tip.x - size * Math.cos(angle + HEAD_SPREAD), tip.y - size * Math.sin(angle + HEAD_SPREAD));
|
|
27311
27684
|
}
|
|
27312
|
-
|
|
27313
|
-
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
27685
|
+
function endAngle(path, atStart) {
|
|
27686
|
+
if (path.length < 2) return null;
|
|
27687
|
+
const tip = atStart ? path[0] : path[path.length - 1];
|
|
27688
|
+
for (let offset = 1; offset < path.length; offset += 1) {
|
|
27689
|
+
const other = atStart ? path[offset] : path[path.length - 1 - offset];
|
|
27690
|
+
if (Math.hypot(tip.x - other.x, tip.y - other.y) > .001) return Math.atan2(tip.y - other.y, tip.x - other.x);
|
|
27691
|
+
}
|
|
27692
|
+
return null;
|
|
27693
|
+
}
|
|
27694
|
+
function roundRectPoints(width, height, radius) {
|
|
27695
|
+
const r = Math.min(radius, width / 2, height / 2);
|
|
27696
|
+
if (r <= 0) return [
|
|
27697
|
+
worldPoint(0, 0),
|
|
27698
|
+
worldPoint(width, 0),
|
|
27699
|
+
worldPoint(width, height),
|
|
27700
|
+
worldPoint(0, height),
|
|
27701
|
+
worldPoint(0, 0)
|
|
27702
|
+
];
|
|
27703
|
+
const corner = (cx, cy, from) => Array.from({ length: 9 }, (_, index) => {
|
|
27704
|
+
const angle = from + index / 8 * (Math.PI / 2);
|
|
27705
|
+
return worldPoint(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);
|
|
27706
|
+
});
|
|
27707
|
+
return [
|
|
27708
|
+
...corner(width - r, r, -Math.PI / 2),
|
|
27709
|
+
...corner(width - r, height - r, 0),
|
|
27710
|
+
...corner(r, height - r, Math.PI / 2),
|
|
27711
|
+
...corner(r, r, Math.PI),
|
|
27712
|
+
worldPoint(width - r, 0)
|
|
27713
|
+
];
|
|
27714
|
+
}
|
|
27715
|
+
const SHADOW_LAYERS = 5;
|
|
27716
|
+
function traceCardOutline(graphics, rect, style, grow = 0) {
|
|
27717
|
+
const x = rect.x - grow;
|
|
27718
|
+
const y = rect.y - grow;
|
|
27719
|
+
const width = Math.max(0, rect.width + grow * 2);
|
|
27720
|
+
const height = Math.max(0, rect.height + grow * 2);
|
|
27721
|
+
if (style.corner === "pixel") return tracePixelRect(graphics, x, y, width, height, 2);
|
|
27722
|
+
const radius = Math.min(Math.max(0, style.radius + grow), width / 2, height / 2);
|
|
27723
|
+
return radius > 0 ? graphics.roundRect(x, y, width, height, radius) : graphics.rect(x, y, width, height);
|
|
27724
|
+
}
|
|
27725
|
+
function tracePixelRect(graphics, x, y, width, height, step) {
|
|
27726
|
+
const s = Math.min(step, width / 4, height / 4);
|
|
27727
|
+
if (s <= 0) return graphics.rect(x, y, width, height);
|
|
27728
|
+
return graphics.poly(pixelRectPoints(x, y, width, height, s).flatMap((point) => [point.x, point.y]));
|
|
27729
|
+
}
|
|
27730
|
+
function pixelRectPoints(x, y, width, height, s) {
|
|
27731
|
+
const r = x + width;
|
|
27732
|
+
const b = y + height;
|
|
27733
|
+
const p = worldPoint;
|
|
27734
|
+
return [
|
|
27735
|
+
p(x, y + s * 2),
|
|
27736
|
+
p(x + s, y + s * 2),
|
|
27737
|
+
p(x + s, y + s),
|
|
27738
|
+
p(x + s * 2, y + s),
|
|
27739
|
+
p(x + s * 2, y),
|
|
27740
|
+
p(r - s * 2, y),
|
|
27741
|
+
p(r - s * 2, y + s),
|
|
27742
|
+
p(r - s, y + s),
|
|
27743
|
+
p(r - s, y + s * 2),
|
|
27744
|
+
p(r, y + s * 2),
|
|
27745
|
+
p(r, b - s * 2),
|
|
27746
|
+
p(r - s, b - s * 2),
|
|
27747
|
+
p(r - s, b - s),
|
|
27748
|
+
p(r - s * 2, b - s),
|
|
27749
|
+
p(r - s * 2, b),
|
|
27750
|
+
p(x + s * 2, b),
|
|
27751
|
+
p(x + s * 2, b - s),
|
|
27752
|
+
p(x + s, b - s),
|
|
27753
|
+
p(x + s, b - s * 2),
|
|
27754
|
+
p(x, b - s * 2)
|
|
27755
|
+
];
|
|
27756
|
+
}
|
|
27757
|
+
function drawCardShadow(graphics, rect, style, shadow) {
|
|
27758
|
+
if (!shadow || shadow.alpha <= 0 || shadow.blur <= 0) return;
|
|
27759
|
+
const offset = {
|
|
27760
|
+
...rect,
|
|
27761
|
+
y: rect.y + shadow.y
|
|
27762
|
+
};
|
|
27763
|
+
const reach = (index) => (1 - index / SHADOW_LAYERS) ** 2;
|
|
27764
|
+
for (let index = SHADOW_LAYERS; index >= 1; index -= 1) {
|
|
27765
|
+
const alpha = shadow.alpha * (reach(index - 1) - reach(index));
|
|
27766
|
+
traceCardOutline(graphics, offset, style, shadow.blur * index / SHADOW_LAYERS).fill({
|
|
27767
|
+
color: shadow.color,
|
|
27768
|
+
alpha
|
|
27769
|
+
});
|
|
27770
|
+
traceCardOutline(graphics, rect, style).cut();
|
|
27771
|
+
}
|
|
27772
|
+
}
|
|
27773
|
+
function cardShadow(style, elevation) {
|
|
27774
|
+
const shadow = style.shadow;
|
|
27775
|
+
if (!shadow || elevation === 0) return null;
|
|
27776
|
+
if (elevation === 1) return shadow;
|
|
27777
|
+
return {
|
|
27778
|
+
...shadow,
|
|
27779
|
+
alpha: Math.min(1, shadow.alpha * 1.6),
|
|
27780
|
+
blur: shadow.blur * 1.6,
|
|
27781
|
+
y: shadow.y * 2 + 4
|
|
27782
|
+
};
|
|
27783
|
+
}
|
|
27784
|
+
function drawCardSurface(graphics, rect, style, surface) {
|
|
27785
|
+
drawCardShadow(graphics, rect, style, cardShadow(style, surface.elevation ?? 0));
|
|
27786
|
+
traceCardOutline(graphics, rect, style).fill({
|
|
27787
|
+
color: surface.fill,
|
|
27788
|
+
alpha: surface.fillAlpha ?? 1
|
|
27789
|
+
});
|
|
27790
|
+
if (surface.border != null) traceCardOutline(graphics, rect, style).stroke({
|
|
27791
|
+
color: surface.border,
|
|
27792
|
+
width: 1,
|
|
27793
|
+
alpha: surface.borderAlpha ?? 1,
|
|
27794
|
+
alignment: 1
|
|
27795
|
+
});
|
|
27796
|
+
return graphics;
|
|
27797
|
+
}
|
|
27798
|
+
function containRect(width, height, imageWidth, imageHeight) {
|
|
27799
|
+
if (width <= 0 || height <= 0 || imageWidth <= 0 || imageHeight <= 0) return {
|
|
27800
|
+
x: 0,
|
|
27801
|
+
y: 0,
|
|
27802
|
+
width: 0,
|
|
27803
|
+
height: 0
|
|
27804
|
+
};
|
|
27805
|
+
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27806
|
+
return {
|
|
27807
|
+
x: (width - imageWidth * scale) / 2,
|
|
27808
|
+
y: (height - imageHeight * scale) / 2,
|
|
27809
|
+
width: imageWidth * scale,
|
|
27810
|
+
height: imageHeight * scale
|
|
27811
|
+
};
|
|
27812
|
+
}
|
|
27813
|
+
function cardElevation(context, id) {
|
|
27814
|
+
return context.liftedIds.has(id) ? 2 : 1;
|
|
27317
27815
|
}
|
|
27318
27816
|
//#endregion
|
|
27319
27817
|
//#region ../sdk/src/board/render/renderers/base-card-renderer.ts
|
|
@@ -27325,7 +27823,10 @@ function createLabel(text, style) {
|
|
|
27325
27823
|
return new Text({
|
|
27326
27824
|
...TEXT_OPTIONS,
|
|
27327
27825
|
text,
|
|
27328
|
-
style
|
|
27826
|
+
style: {
|
|
27827
|
+
fontFamily: BOARD_FONT_STACK,
|
|
27828
|
+
...style
|
|
27829
|
+
}
|
|
27329
27830
|
});
|
|
27330
27831
|
}
|
|
27331
27832
|
function positionShell(root, item) {
|
|
@@ -27407,1201 +27908,310 @@ function drawFarStroke(graphics, points, style) {
|
|
|
27407
27908
|
});
|
|
27408
27909
|
}
|
|
27409
27910
|
//#endregion
|
|
27410
|
-
//#region ../sdk/src/board/render/renderers/
|
|
27411
|
-
const
|
|
27412
|
-
const
|
|
27413
|
-
|
|
27414
|
-
const
|
|
27415
|
-
const
|
|
27416
|
-
|
|
27417
|
-
const
|
|
27418
|
-
|
|
27419
|
-
|
|
27420
|
-
|
|
27421
|
-
|
|
27422
|
-
const
|
|
27423
|
-
const
|
|
27424
|
-
const
|
|
27425
|
-
|
|
27426
|
-
|
|
27427
|
-
const partsByContainer$12 = /* @__PURE__ */ new WeakMap();
|
|
27428
|
-
function detailFor(zoom) {
|
|
27429
|
-
if (zoom < LOD_TITLE_ZOOM) return "plate";
|
|
27430
|
-
if (zoom < LOD_BODY_ZOOM) return "title";
|
|
27431
|
-
return "full";
|
|
27432
|
-
}
|
|
27433
|
-
function coverHeight(item, height) {
|
|
27434
|
-
if (filePreviewKind(item.props.snapshot) !== "cover") return 0;
|
|
27435
|
-
const ideal = Math.round(height * COVER_RATIO);
|
|
27436
|
-
return Math.max(0, Math.min(ideal, height - MIN_BODY_FOR_COVER));
|
|
27437
|
-
}
|
|
27438
|
-
function fitLineWithEllipsis(line, wrapWidth, measureWidth) {
|
|
27439
|
-
const trimmed = line.replace(/\s+$/u, "");
|
|
27440
|
-
if (!trimmed) return "…";
|
|
27441
|
-
const full = `${trimmed}…`;
|
|
27442
|
-
if (measureWidth(full) <= wrapWidth) return full;
|
|
27443
|
-
let lo = 0;
|
|
27444
|
-
let hi = trimmed.length;
|
|
27445
|
-
let best = "…";
|
|
27446
|
-
while (lo <= hi) {
|
|
27447
|
-
const mid = lo + hi >> 1;
|
|
27448
|
-
const candidate = mid > 0 ? `${trimmed.slice(0, mid)}…` : "…";
|
|
27449
|
-
if (measureWidth(candidate) <= wrapWidth) {
|
|
27450
|
-
best = candidate;
|
|
27451
|
-
lo = mid + 1;
|
|
27452
|
-
} else hi = mid - 1;
|
|
27453
|
-
}
|
|
27454
|
-
return best;
|
|
27455
|
-
}
|
|
27456
|
-
function fitTextToLines(text, value, maxLines, wrapWidth) {
|
|
27457
|
-
const width = Math.max(1, wrapWidth);
|
|
27458
|
-
text.style.wordWrapWidth = width;
|
|
27459
|
-
if (!value || maxLines <= 0) {
|
|
27460
|
-
if (text.text !== "") text.text = "";
|
|
27461
|
-
return;
|
|
27462
|
-
}
|
|
27463
|
-
const charCap = Math.max(maxLines * Math.ceil(width), maxLines * 4);
|
|
27464
|
-
const sample = value.length > charCap ? value.slice(0, charCap) : value;
|
|
27465
|
-
const metrics = CanvasTextMetrics.measureText(sample, text.style);
|
|
27466
|
-
if (!(metrics.lines.length > maxLines || sample !== value)) {
|
|
27467
|
-
if (text.text !== value) text.text = value;
|
|
27911
|
+
//#region ../sdk/src/board/render/renderers/media-key.ts
|
|
27912
|
+
const MEDIA_SCRIM = 0;
|
|
27913
|
+
const MEDIA_INK = 16777215;
|
|
27914
|
+
function drawMediaPlayKey(graphics, cx, cy, radius, context, solid = false) {
|
|
27915
|
+
const face = solid ? context.palette.text : MEDIA_SCRIM;
|
|
27916
|
+
const ink = solid ? context.palette.surface : MEDIA_INK;
|
|
27917
|
+
if (context.style.corner === "pixel") {
|
|
27918
|
+
const size = Math.round(radius * 1.6);
|
|
27919
|
+
tracePixelRect(graphics, Math.round(cx - size / 2), Math.round(cy - size / 2), size, size, 2).fill({
|
|
27920
|
+
color: face,
|
|
27921
|
+
alpha: solid ? 1 : .62
|
|
27922
|
+
});
|
|
27923
|
+
const cell = Math.max(1, Math.round(size / 14));
|
|
27924
|
+
const x = Math.round(cx - cell * 1.5);
|
|
27925
|
+
const y = Math.round(cy - cell * 3.5);
|
|
27926
|
+
for (let row = 0; row < 7; row += 1) graphics.rect(x, y + row * cell, (4 - Math.abs(row - 3)) * cell, cell);
|
|
27927
|
+
graphics.fill({ color: ink });
|
|
27468
27928
|
return;
|
|
27469
27929
|
}
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27930
|
+
graphics.circle(cx, cy, radius).fill({
|
|
27931
|
+
color: face,
|
|
27932
|
+
alpha: solid ? 1 : .45
|
|
27933
|
+
});
|
|
27934
|
+
const size = radius * .5;
|
|
27935
|
+
graphics.poly([
|
|
27936
|
+
cx - size * .45,
|
|
27937
|
+
cy - size * .75,
|
|
27938
|
+
cx + size * .8,
|
|
27939
|
+
cy,
|
|
27940
|
+
cx - size * .45,
|
|
27941
|
+
cy + size * .75
|
|
27942
|
+
]).fill({
|
|
27943
|
+
color: ink,
|
|
27944
|
+
alpha: .96
|
|
27945
|
+
});
|
|
27482
27946
|
}
|
|
27483
|
-
|
|
27484
|
-
|
|
27485
|
-
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
height: 0
|
|
27489
|
-
};
|
|
27490
|
-
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27491
|
-
const renderedWidth = imageWidth * scale;
|
|
27492
|
-
const renderedHeight = imageHeight * scale;
|
|
27947
|
+
const GAP$1 = 12;
|
|
27948
|
+
const WAVE_HEIGHT = 16;
|
|
27949
|
+
const partsByContainer$12 = /* @__PURE__ */ new WeakMap();
|
|
27950
|
+
function audioKeyCenter(width, height) {
|
|
27951
|
+
const radius = Math.min(16, Math.max(8, height / 2 - 8), width / 4);
|
|
27493
27952
|
return {
|
|
27494
|
-
x:
|
|
27495
|
-
y:
|
|
27496
|
-
|
|
27497
|
-
height: renderedHeight
|
|
27953
|
+
x: 14 + radius,
|
|
27954
|
+
y: height / 2,
|
|
27955
|
+
radius
|
|
27498
27956
|
};
|
|
27499
27957
|
}
|
|
27500
|
-
function layoutCover(sprite, width, height, texture) {
|
|
27501
|
-
const rect = containCoverRect(width, height, texture.width, texture.height);
|
|
27502
|
-
sprite.position.set(rect.x, rect.y);
|
|
27503
|
-
sprite.width = rect.width;
|
|
27504
|
-
sprite.height = rect.height;
|
|
27505
|
-
}
|
|
27506
|
-
function syncClip(parts, width, height) {
|
|
27507
|
-
parts.clip.clear().roundRect(0, 0, Math.max(1, width), Math.max(1, height), RADIUS$5).fill({ color: 16777215 });
|
|
27508
|
-
}
|
|
27509
27958
|
function sync$12(container, item, context) {
|
|
27510
27959
|
const parts = partsByContainer$12.get(container);
|
|
27511
27960
|
if (!parts) return;
|
|
27512
27961
|
positionShell(parts.root, item);
|
|
27513
27962
|
const { width, height } = item.frame;
|
|
27514
|
-
const
|
|
27515
|
-
const
|
|
27516
|
-
const
|
|
27517
|
-
|
|
27518
|
-
const
|
|
27519
|
-
const
|
|
27520
|
-
const fileState = context.fileState(item.props.src);
|
|
27521
|
-
const band = coverHeight(item, height);
|
|
27522
|
-
const kind = filePreviewKind(item.props.snapshot);
|
|
27523
|
-
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
27524
|
-
const accent = fileCategoryAccent(category, context.palette);
|
|
27525
|
-
syncTextResolution(parts.title, parts.titleRes, context.zoom);
|
|
27526
|
-
syncTextResolution(parts.excerpt, parts.excerptRes, context.zoom);
|
|
27527
|
-
syncTextResolution(parts.typeMark, parts.typeMarkRes, context.zoom);
|
|
27528
|
-
const visualSig = [
|
|
27529
|
-
key ?? "",
|
|
27963
|
+
const title = item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
27964
|
+
const durationMs = item.props.snapshot?.durationMs;
|
|
27965
|
+
const detailed = boardCardDetailed(context.zoom);
|
|
27966
|
+
syncTextResolution(parts.title, parts, context.zoom);
|
|
27967
|
+
const elevation = cardElevation(context, item.id);
|
|
27968
|
+
const sig = [
|
|
27530
27969
|
width,
|
|
27531
27970
|
height,
|
|
27532
|
-
|
|
27533
|
-
|
|
27534
|
-
|
|
27535
|
-
|
|
27536
|
-
|
|
27537
|
-
|
|
27538
|
-
|
|
27539
|
-
category,
|
|
27540
|
-
context.colorScheme,
|
|
27541
|
-
context.palette.surface,
|
|
27542
|
-
context.palette.hover,
|
|
27543
|
-
accent
|
|
27971
|
+
title,
|
|
27972
|
+
durationMs ?? "",
|
|
27973
|
+
detailed,
|
|
27974
|
+
elevation,
|
|
27975
|
+
item.props.src,
|
|
27976
|
+
item.props.snapshot?.mtimeMs ?? "",
|
|
27977
|
+
context.themeKey
|
|
27544
27978
|
].join("|");
|
|
27545
|
-
if (
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
|
|
27550
|
-
|
|
27551
|
-
|
|
27552
|
-
|
|
27553
|
-
|
|
27554
|
-
|
|
27555
|
-
|
|
27979
|
+
if (sig === parts.sig) return;
|
|
27980
|
+
parts.sig = sig;
|
|
27981
|
+
drawCardSurface(parts.plate.clear(), {
|
|
27982
|
+
x: 0,
|
|
27983
|
+
y: 0,
|
|
27984
|
+
width,
|
|
27985
|
+
height
|
|
27986
|
+
}, context.style, {
|
|
27987
|
+
fill: context.palette.surface,
|
|
27988
|
+
border: context.palette.border,
|
|
27989
|
+
borderAlpha: .85,
|
|
27990
|
+
elevation
|
|
27991
|
+
});
|
|
27992
|
+
const key = audioKeyCenter(width, height);
|
|
27993
|
+
drawMediaPlayKey(parts.plate, key.x, key.y, key.radius, context, true);
|
|
27994
|
+
const left = key.x + key.radius + GAP$1;
|
|
27995
|
+
const room = width - 14 - left;
|
|
27996
|
+
parts.title.visible = detailed && room > 24;
|
|
27997
|
+
parts.wave.clear();
|
|
27998
|
+
if (!parts.title.visible) return;
|
|
27999
|
+
parts.title.style.fontFamily = context.style.font;
|
|
28000
|
+
parts.title.style.fill = context.palette.text;
|
|
28001
|
+
fitTextToWidth(parts.title, durationMs ? `${title} · ${formatBoardDuration(durationMs)}` : title, room);
|
|
28002
|
+
const withWave = height >= 56;
|
|
28003
|
+
const top = (height - (parts.title.height + (withWave ? 22 : 0))) / 2;
|
|
28004
|
+
parts.title.position.set(left, top);
|
|
28005
|
+
if (withWave) drawAudioWaveform(parts.wave, `${item.props.src}:${item.props.snapshot?.mtimeMs ?? "unknown"}`, {
|
|
28006
|
+
x: left,
|
|
28007
|
+
y: top + parts.title.height + 6,
|
|
28008
|
+
width: room,
|
|
28009
|
+
height: WAVE_HEIGHT
|
|
28010
|
+
}, context.palette.muted, .45, context.style.corner === "pixel");
|
|
28011
|
+
}
|
|
28012
|
+
const audioCardRenderer = {
|
|
28013
|
+
id: "audio-card",
|
|
28014
|
+
canRender: (item) => item.type === "audio",
|
|
28015
|
+
create: (item, context) => {
|
|
28016
|
+
const root = new Container();
|
|
28017
|
+
const plate = new Graphics();
|
|
28018
|
+
const wave = new Graphics();
|
|
28019
|
+
const resolution = textResolutionForZoom(context.zoom);
|
|
28020
|
+
const title = new Text({
|
|
28021
|
+
text: "",
|
|
28022
|
+
style: {
|
|
28023
|
+
fontSize: 13,
|
|
28024
|
+
fontWeight: "600"
|
|
28025
|
+
},
|
|
28026
|
+
resolution,
|
|
28027
|
+
roundPixels: true
|
|
27556
28028
|
});
|
|
27557
|
-
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
|
|
27561
|
-
|
|
27562
|
-
|
|
27563
|
-
|
|
27564
|
-
|
|
27565
|
-
}
|
|
27566
|
-
const showCover = band > 0 && Boolean(texture);
|
|
27567
|
-
if (band > 0) parts.plate.rect(1, 1, width - 2, band - 1).fill({
|
|
27568
|
-
color: context.palette.hover,
|
|
27569
|
-
alpha: coverFailed ? .35 : .6
|
|
28029
|
+
root.addChild(plate, wave, title);
|
|
28030
|
+
partsByContainer$12.set(root, {
|
|
28031
|
+
root,
|
|
28032
|
+
plate,
|
|
28033
|
+
wave,
|
|
28034
|
+
title,
|
|
28035
|
+
sig: "",
|
|
28036
|
+
resolution
|
|
27570
28037
|
});
|
|
27571
|
-
if (
|
|
27572
|
-
|
|
27573
|
-
|
|
27574
|
-
|
|
27575
|
-
|
|
27576
|
-
|
|
27577
|
-
|
|
27578
|
-
|
|
27579
|
-
|
|
27580
|
-
|
|
27581
|
-
|
|
28038
|
+
if (item.type === "audio") sync$12(root, item, context);
|
|
28039
|
+
return root;
|
|
28040
|
+
},
|
|
28041
|
+
update: (container, item, context) => {
|
|
28042
|
+
if (item.type === "audio") sync$12(container, item, context);
|
|
28043
|
+
},
|
|
28044
|
+
renderFar: (graphics, item, context) => {
|
|
28045
|
+
drawFarPlate(graphics, item.frame, {
|
|
28046
|
+
fill: context.palette.surface,
|
|
28047
|
+
fillAlpha: .96,
|
|
28048
|
+
accent: context.palette.brand,
|
|
28049
|
+
accentAlpha: .72
|
|
27582
28050
|
});
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27586
|
-
|
|
27587
|
-
if (detail === "plate") {
|
|
27588
|
-
parts.typeMark.visible = false;
|
|
27589
|
-
return;
|
|
28051
|
+
},
|
|
28052
|
+
destroy: (container) => {
|
|
28053
|
+
partsByContainer$12.get(container)?.root.destroy({ children: true });
|
|
28054
|
+
partsByContainer$12.delete(container);
|
|
27590
28055
|
}
|
|
27591
|
-
|
|
27592
|
-
|
|
27593
|
-
|
|
27594
|
-
|
|
27595
|
-
|
|
27596
|
-
const
|
|
27597
|
-
|
|
27598
|
-
|
|
27599
|
-
|
|
27600
|
-
|
|
27601
|
-
|
|
27602
|
-
|
|
27603
|
-
|
|
27604
|
-
|
|
27605
|
-
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
|
|
27609
|
-
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
|
|
27613
|
-
|
|
27614
|
-
|
|
27615
|
-
|
|
27616
|
-
|
|
27617
|
-
parts.
|
|
27618
|
-
parts.
|
|
27619
|
-
|
|
27620
|
-
|
|
27621
|
-
|
|
27622
|
-
|
|
27623
|
-
|
|
27624
|
-
|
|
27625
|
-
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27629
|
-
|
|
27630
|
-
|
|
27631
|
-
|
|
28056
|
+
};
|
|
28057
|
+
//#endregion
|
|
28058
|
+
//#region ../sdk/src/board/render/renderers/arrow-card-renderer.ts
|
|
28059
|
+
const partsByContainer$11 = /* @__PURE__ */ new WeakMap();
|
|
28060
|
+
function sync$11(container, item, context) {
|
|
28061
|
+
const parts = partsByContainer$11.get(container);
|
|
28062
|
+
if (!parts) return;
|
|
28063
|
+
parts.root.position.set(0, 0);
|
|
28064
|
+
parts.root.rotation = 0;
|
|
28065
|
+
parts.root.scale.set(1);
|
|
28066
|
+
const { props, style } = item;
|
|
28067
|
+
parts.line.alpha = itemAlpha(context, style.stroke);
|
|
28068
|
+
const color = itemColor(context, style.stroke, "brand");
|
|
28069
|
+
const size = style.strokeWidth ?? 2.5;
|
|
28070
|
+
syncTextResolution(parts.label, parts, context.zoom);
|
|
28071
|
+
const resolved = resolveSceneArrow(item, context.scene);
|
|
28072
|
+
const path = trimPolyline(resolved.path, style.trim);
|
|
28073
|
+
const lineSig = [
|
|
28074
|
+
path.map((point) => `${point.x},${point.y}`).join(";"),
|
|
28075
|
+
color,
|
|
28076
|
+
size,
|
|
28077
|
+
style.dash,
|
|
28078
|
+
props.arrowStart,
|
|
28079
|
+
props.arrowEnd
|
|
28080
|
+
].join("|");
|
|
28081
|
+
if (lineSig !== parts.lineSig) {
|
|
28082
|
+
parts.lineSig = lineSig;
|
|
28083
|
+
parts.line.clear();
|
|
28084
|
+
const width = size;
|
|
28085
|
+
const stroke = {
|
|
28086
|
+
color,
|
|
28087
|
+
width,
|
|
28088
|
+
alpha: .92,
|
|
28089
|
+
cap: "round",
|
|
28090
|
+
join: "round"
|
|
28091
|
+
};
|
|
28092
|
+
tracePolyline(parts.line, path, dashPattern(style.dash, width));
|
|
28093
|
+
parts.line.stroke(stroke);
|
|
28094
|
+
const first = path[0];
|
|
28095
|
+
const last = path[path.length - 1];
|
|
28096
|
+
if (first && last) {
|
|
28097
|
+
const span = Math.hypot(last.x - first.x, last.y - first.y);
|
|
28098
|
+
const headSize = Math.min(Math.max(14, size * 5.5), Math.max(10, span * .28));
|
|
28099
|
+
const complete = style.trim === void 0 || style.trim >= 1;
|
|
28100
|
+
const endDirection = endAngle(path, false);
|
|
28101
|
+
const startDirection = endAngle(path, true);
|
|
28102
|
+
if (props.arrowEnd && endDirection !== null && path.length > 1) traceArrowhead(parts.line, last, endDirection, headSize);
|
|
28103
|
+
if (props.arrowStart && startDirection !== null && complete) traceArrowhead(parts.line, first, startDirection, headSize);
|
|
28104
|
+
parts.line.stroke({
|
|
28105
|
+
...stroke,
|
|
28106
|
+
width: Math.max(1.5, width)
|
|
28107
|
+
});
|
|
28108
|
+
}
|
|
27632
28109
|
}
|
|
27633
|
-
const
|
|
27634
|
-
|
|
27635
|
-
|
|
27636
|
-
|
|
27637
|
-
|
|
27638
|
-
|
|
27639
|
-
parts.
|
|
28110
|
+
const labelSig = [
|
|
28111
|
+
props.label,
|
|
28112
|
+
props.fontSize,
|
|
28113
|
+
context.themeKey
|
|
28114
|
+
].join("|");
|
|
28115
|
+
if (labelSig !== parts.labelSig) {
|
|
28116
|
+
parts.labelSig = labelSig;
|
|
28117
|
+
parts.label.text = props.label;
|
|
28118
|
+
parts.label.style.fill = context.palette.text;
|
|
28119
|
+
parts.label.style.fontSize = props.fontSize;
|
|
28120
|
+
const padX = props.fontSize * .5;
|
|
28121
|
+
const padY = props.fontSize * .25;
|
|
28122
|
+
const { width, height } = parts.label;
|
|
28123
|
+
const plate = {
|
|
28124
|
+
x: -width / 2 - padX,
|
|
28125
|
+
y: -height / 2 - padY,
|
|
28126
|
+
width: width + padX * 2,
|
|
28127
|
+
height: height + padY * 2
|
|
28128
|
+
};
|
|
28129
|
+
drawCardSurface(parts.backdrop.clear(), plate, {
|
|
28130
|
+
...context.style,
|
|
28131
|
+
radius: Math.min(context.style.radius, plate.height / 2)
|
|
28132
|
+
}, {
|
|
28133
|
+
fill: context.palette.surface,
|
|
28134
|
+
border: context.palette.border
|
|
28135
|
+
});
|
|
27640
28136
|
}
|
|
27641
|
-
|
|
28137
|
+
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
28138
|
+
parts.label.visible = visible;
|
|
28139
|
+
parts.backdrop.visible = visible;
|
|
28140
|
+
const mid = style.trim === void 0 ? resolved.mid : pathPointAt(resolved.path, .5);
|
|
28141
|
+
parts.label.position.set(mid.x, mid.y);
|
|
28142
|
+
parts.backdrop.position.set(mid.x, mid.y);
|
|
27642
28143
|
}
|
|
27643
|
-
const
|
|
27644
|
-
id: "
|
|
27645
|
-
canRender: (item) => item.type === "
|
|
28144
|
+
const arrowCardRenderer = {
|
|
28145
|
+
id: "arrow-card",
|
|
28146
|
+
canRender: (item) => item.type === "arrow",
|
|
27646
28147
|
create: (item, context) => {
|
|
27647
28148
|
const root = new Container();
|
|
27648
|
-
const
|
|
27649
|
-
const
|
|
27650
|
-
const
|
|
27651
|
-
const cover = new Sprite(Texture.EMPTY);
|
|
27652
|
-
const coverMask = new Graphics();
|
|
27653
|
-
cover.mask = coverMask;
|
|
27654
|
-
const resolution = 1;
|
|
27655
|
-
const title = new Text({
|
|
27656
|
-
text: "",
|
|
27657
|
-
style: {
|
|
27658
|
-
fill: context.palette.text,
|
|
27659
|
-
fontFamily: BOARD_FONT_STACK,
|
|
27660
|
-
fontSize: TITLE_SIZE,
|
|
27661
|
-
fontWeight: "600",
|
|
27662
|
-
wordWrap: true,
|
|
27663
|
-
breakWords: true,
|
|
27664
|
-
lineHeight: TITLE_LINE
|
|
27665
|
-
},
|
|
27666
|
-
resolution,
|
|
27667
|
-
roundPixels: true
|
|
27668
|
-
});
|
|
27669
|
-
const excerpt = new Text({
|
|
28149
|
+
const line = new Graphics();
|
|
28150
|
+
const resolution = textResolutionForZoom(context.zoom);
|
|
28151
|
+
const label = new Text({
|
|
27670
28152
|
text: "",
|
|
27671
28153
|
style: {
|
|
27672
|
-
fill:
|
|
28154
|
+
fill: 16777215,
|
|
27673
28155
|
fontFamily: BOARD_FONT_STACK,
|
|
27674
|
-
fontSize:
|
|
27675
|
-
fontWeight: "
|
|
27676
|
-
wordWrap: true,
|
|
27677
|
-
breakWords: true,
|
|
27678
|
-
lineHeight: EXCERPT_LINE
|
|
27679
|
-
},
|
|
27680
|
-
resolution,
|
|
27681
|
-
roundPixels: true
|
|
27682
|
-
});
|
|
27683
|
-
const typeMark = new Text({
|
|
27684
|
-
text: "",
|
|
27685
|
-
style: {
|
|
27686
|
-
fill: context.palette.muted,
|
|
27687
|
-
fontFamily: BOARD_MONO_FONT_STACK,
|
|
27688
|
-
fontSize: TYPE_MARK_SIZE,
|
|
27689
|
-
fontWeight: "700",
|
|
27690
|
-
lineHeight: TYPE_MARK_SIZE * 1.1
|
|
28156
|
+
fontSize: 14,
|
|
28157
|
+
fontWeight: "500"
|
|
27691
28158
|
},
|
|
27692
28159
|
resolution,
|
|
27693
28160
|
roundPixels: true
|
|
27694
28161
|
});
|
|
27695
|
-
|
|
27696
|
-
|
|
27697
|
-
root.addChild(
|
|
27698
|
-
partsByContainer$
|
|
28162
|
+
label.anchor.set(.5);
|
|
28163
|
+
const backdrop = new Graphics();
|
|
28164
|
+
root.addChild(line, backdrop, label);
|
|
28165
|
+
partsByContainer$11.set(root, {
|
|
27699
28166
|
root,
|
|
27700
|
-
|
|
27701
|
-
|
|
27702
|
-
|
|
27703
|
-
|
|
27704
|
-
|
|
27705
|
-
|
|
27706
|
-
title,
|
|
27707
|
-
excerpt,
|
|
27708
|
-
visualSig: "",
|
|
27709
|
-
textSig: "",
|
|
27710
|
-
titleRes: { resolution },
|
|
27711
|
-
excerptRes: { resolution },
|
|
27712
|
-
typeMarkRes: { resolution }
|
|
28167
|
+
line,
|
|
28168
|
+
backdrop,
|
|
28169
|
+
label,
|
|
28170
|
+
lineSig: "",
|
|
28171
|
+
labelSig: "",
|
|
28172
|
+
resolution
|
|
27713
28173
|
});
|
|
27714
|
-
if (item.type === "
|
|
28174
|
+
if (item.type === "arrow") sync$11(root, item, context);
|
|
27715
28175
|
return root;
|
|
27716
28176
|
},
|
|
27717
28177
|
update: (container, item, context) => {
|
|
27718
|
-
if (item.type === "
|
|
28178
|
+
if (item.type === "arrow") sync$11(container, item, context);
|
|
27719
28179
|
},
|
|
27720
28180
|
renderFar: (graphics, item, context) => {
|
|
27721
|
-
|
|
27722
|
-
|
|
27723
|
-
|
|
27724
|
-
|
|
27725
|
-
|
|
27726
|
-
|
|
28181
|
+
if (item.type !== "arrow") return;
|
|
28182
|
+
const arrow = item;
|
|
28183
|
+
drawFarStroke(graphics, trimPolyline(resolveSceneArrow(arrow, context.scene).path, arrow.style.trim), {
|
|
28184
|
+
color: itemColor(context, arrow.style.stroke, "brand"),
|
|
28185
|
+
width: arrow.style.strokeWidth ?? 2.5,
|
|
28186
|
+
alpha: .85 * itemAlpha(context, arrow.style.stroke)
|
|
27727
28187
|
});
|
|
27728
28188
|
},
|
|
27729
28189
|
destroy: (container) => {
|
|
27730
|
-
partsByContainer$
|
|
27731
|
-
partsByContainer$
|
|
28190
|
+
partsByContainer$11.get(container)?.root.destroy({ children: true });
|
|
28191
|
+
partsByContainer$11.delete(container);
|
|
27732
28192
|
}
|
|
27733
28193
|
};
|
|
27734
28194
|
//#endregion
|
|
27735
|
-
//#region ../sdk/src/board/render/renderers/
|
|
27736
|
-
const
|
|
27737
|
-
|
|
27738
|
-
const
|
|
27739
|
-
|
|
27740
|
-
const
|
|
27741
|
-
const
|
|
27742
|
-
const
|
|
27743
|
-
|
|
27744
|
-
const SECOND = 1e3;
|
|
27745
|
-
const partsByContainer$11 = /* @__PURE__ */ new WeakMap();
|
|
27746
|
-
function previewKindFor(artifact) {
|
|
27747
|
-
if (!artifact) return "empty";
|
|
27748
|
-
if (artifact.type === "image" || artifact.type === "video") return "texture";
|
|
27749
|
-
if (artifact.type === "audio") return artifact.previewUrl ? "texture" : "waveform";
|
|
27750
|
-
return artifact.textExcerpt ? "text" : "empty";
|
|
27751
|
-
}
|
|
27752
|
-
function liveStatus(item, context) {
|
|
27753
|
-
const { snapshot } = item.props;
|
|
27754
|
-
const live = snapshot.status === "completed" ? null : context.taskRun(item.props.taskRunId);
|
|
27755
|
-
const liveStart = Date.parse(live?.startedAt ?? "");
|
|
27756
|
-
const working = live?.status === "pending" || live?.status === "running";
|
|
27757
|
-
const adopt = snapshot.status === "failed" ? working && liveStart > Date.parse(snapshot.updatedAt ?? "") : live?.status === "running" || live?.status === "pending" && snapshot.status === "pending";
|
|
27758
|
-
const status = adopt && live ? live.status : snapshot.status;
|
|
27759
|
-
const started = adopt ? liveStart : Date.parse(snapshot.startedAt ?? "");
|
|
27760
|
-
return {
|
|
27761
|
-
status,
|
|
27762
|
-
startedAt: Number.isFinite(started) ? started : null
|
|
27763
|
-
};
|
|
27764
|
-
}
|
|
27765
|
-
function stateSurfaceFor(status, kind, hasTexture, previewFailed) {
|
|
27766
|
-
if (kind === "texture" && !hasTexture) {
|
|
27767
|
-
if (status === "failed") return "failed";
|
|
27768
|
-
return previewFailed ? "unavailable" : "media-loading";
|
|
28195
|
+
//#region ../sdk/src/board/render/renderers/draw-card-renderer.ts
|
|
28196
|
+
const partsByContainer$10 = /* @__PURE__ */ new WeakMap();
|
|
28197
|
+
function fillRibbon(graphics, ribbon, color) {
|
|
28198
|
+
const { positions, indices } = ribbon;
|
|
28199
|
+
for (let offset = 0; offset < indices.length; offset += 3) {
|
|
28200
|
+
const a = (indices[offset] ?? 0) * 2;
|
|
28201
|
+
const b = (indices[offset + 1] ?? 0) * 2;
|
|
28202
|
+
const c = (indices[offset + 2] ?? 0) * 2;
|
|
28203
|
+
graphics.moveTo(positions[a] ?? 0, positions[a + 1] ?? 0).lineTo(positions[b] ?? 0, positions[b + 1] ?? 0).lineTo(positions[c] ?? 0, positions[c + 1] ?? 0).closePath();
|
|
27769
28204
|
}
|
|
27770
|
-
|
|
27771
|
-
if (status === "failed") return "failed";
|
|
27772
|
-
if (status === "running") return "generating";
|
|
27773
|
-
if (status === "pending") return "queued";
|
|
27774
|
-
return "empty";
|
|
28205
|
+
return graphics.fill({ color });
|
|
27775
28206
|
}
|
|
27776
|
-
function
|
|
27777
|
-
|
|
27778
|
-
|
|
27779
|
-
|
|
27780
|
-
case "failed": return context.labels.failed;
|
|
27781
|
-
case "unavailable": return context.labels.previewUnavailable;
|
|
27782
|
-
case "empty": return context.labels.noPreview;
|
|
27783
|
-
default: return "";
|
|
28207
|
+
function replaceStroke(parts, next) {
|
|
28208
|
+
if (parts.stroke) {
|
|
28209
|
+
parts.root.removeChild(parts.stroke);
|
|
28210
|
+
parts.stroke.destroy();
|
|
27784
28211
|
}
|
|
27785
|
-
|
|
27786
|
-
|
|
27787
|
-
|
|
27788
|
-
if (status === "running") return context.colors.brand.stroke;
|
|
27789
|
-
return context.colors.neutral.stroke;
|
|
27790
|
-
}
|
|
27791
|
-
function formatTaskElapsed(ms) {
|
|
27792
|
-
const total = Math.max(0, Math.floor(ms / SECOND));
|
|
27793
|
-
const hours = Math.floor(total / 3600);
|
|
27794
|
-
const minutes = Math.floor(total % 3600 / 60);
|
|
27795
|
-
const seconds = String(total % 60).padStart(2, "0");
|
|
27796
|
-
return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}` : `${minutes}:${seconds}`;
|
|
27797
|
-
}
|
|
27798
|
-
function containTaskPreviewRect(width, height, imageWidth, imageHeight) {
|
|
27799
|
-
if (width <= 0 || height <= 0 || imageWidth <= 0 || imageHeight <= 0) return {
|
|
27800
|
-
x: 0,
|
|
27801
|
-
y: 0,
|
|
27802
|
-
width: 0,
|
|
27803
|
-
height: 0
|
|
27804
|
-
};
|
|
27805
|
-
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27806
|
-
const renderedWidth = imageWidth * scale;
|
|
27807
|
-
const renderedHeight = imageHeight * scale;
|
|
27808
|
-
return {
|
|
27809
|
-
x: (width - renderedWidth) / 2,
|
|
27810
|
-
y: (height - renderedHeight) / 2,
|
|
27811
|
-
width: renderedWidth,
|
|
27812
|
-
height: renderedHeight
|
|
27813
|
-
};
|
|
27814
|
-
}
|
|
27815
|
-
function drawPlayBadge(graphics, rect, context) {
|
|
27816
|
-
const radius = Math.min(PLAY_BADGE_RADIUS, Math.max(8, Math.min(rect.width, rect.height) * .16));
|
|
27817
|
-
const cx = rect.x + rect.width / 2;
|
|
27818
|
-
const cy = rect.y + rect.height / 2;
|
|
27819
|
-
graphics.circle(cx, cy, radius).fill({
|
|
27820
|
-
color: context.palette.bg,
|
|
27821
|
-
alpha: .64
|
|
27822
|
-
});
|
|
27823
|
-
const size = radius * .72;
|
|
27824
|
-
graphics.moveTo(cx - size * .34, cy - size * .56).lineTo(cx + size * .62, cy).lineTo(cx - size * .34, cy + size * .56).closePath().fill({
|
|
27825
|
-
color: context.palette.text,
|
|
27826
|
-
alpha: .94
|
|
27827
|
-
});
|
|
27828
|
-
}
|
|
27829
|
-
function drawStateMark(graphics, surface, cx, cy, color) {
|
|
27830
|
-
if (surface === "generating" || surface === "media-loading") {
|
|
27831
|
-
graphics.circle(cx, cy, 4).fill({
|
|
27832
|
-
color,
|
|
27833
|
-
alpha: .9
|
|
27834
|
-
});
|
|
27835
|
-
graphics.circle(cx - 12, cy + 7, 2.5).fill({
|
|
27836
|
-
color,
|
|
27837
|
-
alpha: .48
|
|
27838
|
-
});
|
|
27839
|
-
graphics.circle(cx + 11, cy + 6, 3).fill({
|
|
27840
|
-
color,
|
|
27841
|
-
alpha: .68
|
|
27842
|
-
});
|
|
27843
|
-
graphics.circle(cx + 3, cy - 12, 2).fill({
|
|
27844
|
-
color,
|
|
27845
|
-
alpha: .36
|
|
27846
|
-
});
|
|
27847
|
-
return;
|
|
27848
|
-
}
|
|
27849
|
-
if (surface === "queued") {
|
|
27850
|
-
graphics.circle(cx, cy, 10).stroke({
|
|
27851
|
-
color,
|
|
27852
|
-
width: 1.5,
|
|
27853
|
-
alpha: .62
|
|
27854
|
-
}).circle(cx, cy, 3).fill({
|
|
27855
|
-
color,
|
|
27856
|
-
alpha: .78
|
|
27857
|
-
});
|
|
27858
|
-
return;
|
|
27859
|
-
}
|
|
27860
|
-
if (surface === "failed") {
|
|
27861
|
-
graphics.circle(cx, cy, 11).stroke({
|
|
27862
|
-
color,
|
|
27863
|
-
width: 1.5,
|
|
27864
|
-
alpha: .86
|
|
27865
|
-
});
|
|
27866
|
-
graphics.moveTo(cx - 4, cy - 4).lineTo(cx + 4, cy + 4).moveTo(cx + 4, cy - 4).lineTo(cx - 4, cy + 4).stroke({
|
|
27867
|
-
color,
|
|
27868
|
-
width: 1.5,
|
|
27869
|
-
alpha: .94,
|
|
27870
|
-
cap: "round"
|
|
27871
|
-
});
|
|
27872
|
-
return;
|
|
27873
|
-
}
|
|
27874
|
-
if (surface === "unavailable") graphics.roundRect(cx - 12, cy - 9, 24, 18, 3).stroke({
|
|
27875
|
-
color,
|
|
27876
|
-
width: 1.25,
|
|
27877
|
-
alpha: .62
|
|
27878
|
-
}).moveTo(cx - 8, cy + 5).lineTo(cx + 8, cy - 5).stroke({
|
|
27879
|
-
color,
|
|
27880
|
-
width: 1.25,
|
|
27881
|
-
alpha: .72,
|
|
27882
|
-
cap: "round"
|
|
27883
|
-
});
|
|
27884
|
-
}
|
|
27885
|
-
function drawFailedBadge(graphics, width, color, context) {
|
|
27886
|
-
const cx = Math.max(12, width - 12);
|
|
27887
|
-
graphics.circle(cx, 12, 8).fill({
|
|
27888
|
-
color: context.palette.bg,
|
|
27889
|
-
alpha: .72
|
|
27890
|
-
});
|
|
27891
|
-
graphics.moveTo(cx - 2.5, 9.5).lineTo(cx + 2.5, 14.5).moveTo(cx + 2.5, 9.5).lineTo(cx - 2.5, 14.5).stroke({
|
|
27892
|
-
color,
|
|
27893
|
-
width: 1.5,
|
|
27894
|
-
alpha: .96,
|
|
27895
|
-
cap: "round"
|
|
27896
|
-
});
|
|
27897
|
-
}
|
|
27898
|
-
const shimmerGradients = /* @__PURE__ */ new Map();
|
|
27899
|
-
function shimmerGradient(color) {
|
|
27900
|
-
let gradient = shimmerGradients.get(color);
|
|
27901
|
-
if (!gradient) {
|
|
27902
|
-
const rgb = `${color >> 16 & 255}, ${color >> 8 & 255}, ${color & 255}`;
|
|
27903
|
-
gradient = new FillGradient({
|
|
27904
|
-
type: "linear",
|
|
27905
|
-
start: {
|
|
27906
|
-
x: 0,
|
|
27907
|
-
y: 0
|
|
27908
|
-
},
|
|
27909
|
-
end: {
|
|
27910
|
-
x: 1,
|
|
27911
|
-
y: 0
|
|
27912
|
-
},
|
|
27913
|
-
textureSpace: "local",
|
|
27914
|
-
colorStops: [
|
|
27915
|
-
{
|
|
27916
|
-
offset: 0,
|
|
27917
|
-
color: `rgba(${rgb}, 0)`
|
|
27918
|
-
},
|
|
27919
|
-
{
|
|
27920
|
-
offset: .5,
|
|
27921
|
-
color: `rgba(${rgb}, 0.07)`
|
|
27922
|
-
},
|
|
27923
|
-
{
|
|
27924
|
-
offset: 1,
|
|
27925
|
-
color: `rgba(${rgb}, 0)`
|
|
27926
|
-
}
|
|
27927
|
-
]
|
|
27928
|
-
});
|
|
27929
|
-
shimmerGradients.set(color, gradient);
|
|
27930
|
-
}
|
|
27931
|
-
return gradient;
|
|
27932
|
-
}
|
|
27933
|
-
function drawShimmerBand(graphics, width, height, color) {
|
|
27934
|
-
const band = Math.max(48, width * .45);
|
|
27935
|
-
graphics.clear().rect(-band, 0, band, height).fill(shimmerGradient(color));
|
|
27936
|
-
}
|
|
27937
|
-
function advance(parts, clock) {
|
|
27938
|
-
const { motion } = parts;
|
|
27939
|
-
let next = null;
|
|
27940
|
-
if (motion.shimmer) {
|
|
27941
|
-
const travel = motion.width + parts.shimmer.width;
|
|
27942
|
-
parts.shimmer.x = clock % SHIMMER_PERIOD_MS / SHIMMER_PERIOD_MS * travel;
|
|
27943
|
-
next = SHIMMER_FRAME_MS;
|
|
27944
|
-
}
|
|
27945
|
-
if (motion.startedAt !== null) {
|
|
27946
|
-
const elapsedMs = Date.now() - motion.startedAt;
|
|
27947
|
-
const elapsed = formatTaskElapsed(elapsedMs);
|
|
27948
|
-
if (elapsed !== motion.elapsed) {
|
|
27949
|
-
motion.elapsed = elapsed;
|
|
27950
|
-
parts.body.text = `${motion.label} · ${elapsed}`;
|
|
27951
|
-
}
|
|
27952
|
-
const untilNextSecond = SECOND - Math.max(0, elapsedMs) % SECOND;
|
|
27953
|
-
next = next === null ? untilNextSecond : Math.min(next, untilNextSecond);
|
|
27954
|
-
}
|
|
27955
|
-
if (motion.revealFrom !== null) {
|
|
27956
|
-
const progress = Math.min(1, (clock - motion.revealFrom) / REVEAL_MS);
|
|
27957
|
-
parts.preview.alpha = progress * (2 - progress);
|
|
27958
|
-
if (progress >= 1) motion.revealFrom = null;
|
|
27959
|
-
else next = 0;
|
|
27960
|
-
}
|
|
27961
|
-
return next;
|
|
27962
|
-
}
|
|
27963
|
-
function sync$11(container, item, context) {
|
|
27964
|
-
const parts = partsByContainer$11.get(container);
|
|
27965
|
-
if (!parts) return;
|
|
27966
|
-
positionShell(parts.root, item);
|
|
27967
|
-
const { width, height } = item.frame;
|
|
27968
|
-
const { snapshot } = item.props;
|
|
27969
|
-
const { status, startedAt } = liveStatus(item, context);
|
|
27970
|
-
const selected = context.selectedIds.has(item.id);
|
|
27971
|
-
const hovered = context.hoveredId === item.id;
|
|
27972
|
-
const full = context.zoom >= TASK_CARD_FULL_DETAIL_ZOOM;
|
|
27973
|
-
const working = status === "pending" || status === "running";
|
|
27974
|
-
const color = statusColor(status, context);
|
|
27975
|
-
const key = context.assetKey(item);
|
|
27976
|
-
if (key !== parts.assetKey) {
|
|
27977
|
-
if (parts.assetKey) context.releaseTexture(parts.assetKey);
|
|
27978
|
-
parts.assetKey = key;
|
|
27979
|
-
if (key) context.acquireTexture(key);
|
|
27980
|
-
}
|
|
27981
|
-
const texture = key ? context.getTexture(key) : null;
|
|
27982
|
-
const previewFailed = Boolean(key && !texture && context.hasError(key));
|
|
27983
|
-
const artifact = featuredTaskArtifact(snapshot.artifacts);
|
|
27984
|
-
const kind = previewKindFor(artifact);
|
|
27985
|
-
const surface = stateSurfaceFor(status, kind, Boolean(texture), previewFailed);
|
|
27986
|
-
const frame = {
|
|
27987
|
-
x: 1,
|
|
27988
|
-
y: 1,
|
|
27989
|
-
width: Math.max(1, width - 2),
|
|
27990
|
-
height: Math.max(1, height - 2)
|
|
27991
|
-
};
|
|
27992
|
-
const metaText = artifact || working ? snapshot.model ?? "" : "";
|
|
27993
|
-
const showMeta = full && Boolean(metaText);
|
|
27994
|
-
const failedWithOutput = status === "failed" && kind !== "empty";
|
|
27995
|
-
const count = artifact && snapshot.artifactCount > 1 ? String(snapshot.artifactCount) : "";
|
|
27996
|
-
const showBadge = full && Boolean(count);
|
|
27997
|
-
const label = stateLabel(surface, context);
|
|
27998
|
-
const counting = full && working && startedAt !== null && surface !== null;
|
|
27999
|
-
const elapsed = counting ? formatTaskElapsed(Date.now() - startedAt) : "";
|
|
28000
|
-
const detailText = !full || !surface ? "" : status === "failed" ? snapshot.errorExcerpt ?? "" : working ? snapshot.promptExcerpt ?? "" : "";
|
|
28001
|
-
const textArtifact = kind === "text" && artifact?.type === "text";
|
|
28002
|
-
const bodyText = textArtifact ? artifact.textExcerpt : counting ? `${label} · ${elapsed}` : label;
|
|
28003
|
-
syncTextResolution(parts.body, parts, context.zoom);
|
|
28004
|
-
syncTextResolution(parts.detail, parts, context.zoom);
|
|
28005
|
-
syncTextResolution(parts.meta, parts, context.zoom);
|
|
28006
|
-
syncTextResolution(parts.badge, parts, context.zoom);
|
|
28007
|
-
const textSig = [
|
|
28008
|
-
counting ? label : bodyText,
|
|
28009
|
-
detailText,
|
|
28010
|
-
metaText,
|
|
28011
|
-
count,
|
|
28012
|
-
kind,
|
|
28013
|
-
surface,
|
|
28014
|
-
full,
|
|
28015
|
-
width,
|
|
28016
|
-
height,
|
|
28017
|
-
color,
|
|
28018
|
-
context.palette.text,
|
|
28019
|
-
context.palette.muted
|
|
28020
|
-
].join("|");
|
|
28021
|
-
if (textSig !== parts.textSig) {
|
|
28022
|
-
parts.textSig = textSig;
|
|
28023
|
-
const wrap = Math.max(24, width - 24);
|
|
28024
|
-
parts.body.style.fill = surface === "failed" ? color : context.palette.text;
|
|
28025
|
-
parts.body.anchor.set(textArtifact ? 0 : .5, 0);
|
|
28026
|
-
fitTextToLines(parts.body, bodyText, textArtifact ? Math.max(1, Math.floor((height - 24 - (showMeta ? META_HEIGHT : 0)) / 16)) : 1, wrap);
|
|
28027
|
-
parts.detail.style.fill = context.palette.muted;
|
|
28028
|
-
fitTextToLines(parts.detail, detailText, height - 24 > 120 ? 2 : 1, Math.min(wrap, 360));
|
|
28029
|
-
parts.meta.style.fill = context.palette.text;
|
|
28030
|
-
fitTextToLines(parts.meta, metaText, 1, wrap);
|
|
28031
|
-
parts.badge.style.fill = context.palette.text;
|
|
28032
|
-
if (parts.badge.text !== count) parts.badge.text = count;
|
|
28033
|
-
}
|
|
28034
|
-
const badgeWidth = Math.max(22, parts.badge.width + 12);
|
|
28035
|
-
const visualSig = [
|
|
28036
|
-
width,
|
|
28037
|
-
height,
|
|
28038
|
-
selected,
|
|
28039
|
-
hovered,
|
|
28040
|
-
full,
|
|
28041
|
-
color,
|
|
28042
|
-
kind,
|
|
28043
|
-
surface,
|
|
28044
|
-
showMeta,
|
|
28045
|
-
showBadge && badgeWidth,
|
|
28046
|
-
failedWithOutput,
|
|
28047
|
-
artifact?.type ?? "none",
|
|
28048
|
-
artifact?.id ?? "none",
|
|
28049
|
-
item.props.taskRunId,
|
|
28050
|
-
texture ? `${texture.width}x${texture.height}` : "none",
|
|
28051
|
-
context.palette.surface,
|
|
28052
|
-
context.palette.hover,
|
|
28053
|
-
context.palette.border,
|
|
28054
|
-
context.palette.bg,
|
|
28055
|
-
context.palette.text
|
|
28056
|
-
].join("|");
|
|
28057
|
-
if (visualSig !== parts.visualSig) {
|
|
28058
|
-
parts.visualSig = visualSig;
|
|
28059
|
-
parts.plate.clear().roundRect(0, 0, width, height, RADIUS$4).fill({
|
|
28060
|
-
color: context.palette.surface,
|
|
28061
|
-
alpha: .98
|
|
28062
|
-
}).roundRect(0, 0, width, height, RADIUS$4).stroke({
|
|
28063
|
-
color: selected ? context.palette.brand : hovered ? context.palette.muted : context.palette.border,
|
|
28064
|
-
width: selected ? 2 : 1,
|
|
28065
|
-
alpha: selected ? .96 : .82
|
|
28066
|
-
});
|
|
28067
|
-
parts.clip.clear().roundRect(1, 1, frame.width, frame.height, 3).fill({ color: 16777215 });
|
|
28068
|
-
parts.previewBg.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({
|
|
28069
|
-
color: context.palette.hover,
|
|
28070
|
-
alpha: .5
|
|
28071
|
-
});
|
|
28072
|
-
parts.previewMask.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({ color: 16777215 });
|
|
28073
|
-
drawShimmerBand(parts.shimmer, frame.width, frame.height, context.palette.text);
|
|
28074
|
-
parts.shimmer.y = frame.y;
|
|
28075
|
-
parts.previewArt.clear();
|
|
28076
|
-
if (kind === "waveform") {
|
|
28077
|
-
const bottomInset = showMeta ? META_HEIGHT : 0;
|
|
28078
|
-
drawAudioWaveform(parts.previewArt, item.props.taskRunId, {
|
|
28079
|
-
x: frame.x + PADDING,
|
|
28080
|
-
y: frame.y + PADDING,
|
|
28081
|
-
width: Math.max(1, frame.width - 24),
|
|
28082
|
-
height: Math.max(1, frame.height - 24 - bottomInset)
|
|
28083
|
-
}, context.colors.brand.stroke);
|
|
28084
|
-
}
|
|
28085
|
-
if (full && (artifact?.type === "audio" || artifact?.type === "video" && texture)) drawPlayBadge(parts.previewArt, frame, context);
|
|
28086
|
-
if (surface) {
|
|
28087
|
-
const markY = frame.y + frame.height / 2 - (full && label ? 18 : 0);
|
|
28088
|
-
drawStateMark(parts.previewArt, surface, frame.x + frame.width / 2, markY, surface === "failed" ? color : context.colors.neutral.stroke);
|
|
28089
|
-
}
|
|
28090
|
-
if (showMeta) parts.previewArt.rect(frame.x, frame.y + frame.height - META_HEIGHT, frame.width, META_HEIGHT).fill({
|
|
28091
|
-
color: context.palette.bg,
|
|
28092
|
-
alpha: .68
|
|
28093
|
-
});
|
|
28094
|
-
if (showBadge) parts.previewArt.roundRect(width - badgeWidth - 8, 8, badgeWidth, 20, 10).fill({
|
|
28095
|
-
color: context.palette.bg,
|
|
28096
|
-
alpha: .72
|
|
28097
|
-
});
|
|
28098
|
-
if (failedWithOutput) drawFailedBadge(parts.previewArt, width, color, context);
|
|
28099
|
-
}
|
|
28100
|
-
const showPreview = kind === "texture" && Boolean(texture);
|
|
28101
|
-
const revealKey = showPreview ? `${artifact?.id}:${texture?.uid}` : null;
|
|
28102
|
-
const sameCard = parts.motion.itemId === item.id;
|
|
28103
|
-
parts.motion.itemId = item.id;
|
|
28104
|
-
if (revealKey !== parts.motion.revealKey || !sameCard) {
|
|
28105
|
-
const appearing = sameCard && parts.motion.revealKey === null && revealKey !== null;
|
|
28106
|
-
parts.motion.revealKey = revealKey;
|
|
28107
|
-
parts.motion.revealFrom = appearing && !context.reducedMotion ? performance.now() : null;
|
|
28108
|
-
parts.preview.alpha = parts.motion.revealFrom === null ? 1 : 0;
|
|
28109
|
-
}
|
|
28110
|
-
parts.preview.visible = showPreview;
|
|
28111
|
-
if (showPreview && texture) {
|
|
28112
|
-
if (parts.preview.texture !== texture) parts.preview.texture = texture;
|
|
28113
|
-
const fitted = containTaskPreviewRect(frame.width, frame.height, texture.width, texture.height);
|
|
28114
|
-
parts.preview.position.set(frame.x + fitted.x, frame.y + fitted.y);
|
|
28115
|
-
parts.preview.width = fitted.width;
|
|
28116
|
-
parts.preview.height = fitted.height;
|
|
28117
|
-
}
|
|
28118
|
-
parts.body.visible = full && Boolean(bodyText);
|
|
28119
|
-
parts.detail.visible = full && Boolean(detailText);
|
|
28120
|
-
parts.meta.visible = showMeta;
|
|
28121
|
-
parts.badge.visible = showBadge;
|
|
28122
|
-
if (textArtifact) parts.body.position.set(PADDING, PADDING);
|
|
28123
|
-
else parts.body.position.set(width / 2, height / 2 + 2);
|
|
28124
|
-
parts.detail.position.set(width / 2, height / 2 + 2 + parts.body.height + 4);
|
|
28125
|
-
parts.meta.position.set(PADDING, height - META_HEIGHT + 7);
|
|
28126
|
-
parts.badge.position.set(width - 8 - badgeWidth / 2, 18);
|
|
28127
|
-
parts.motion.width = frame.width;
|
|
28128
|
-
parts.motion.shimmer = full && working && kind !== "texture" && !context.reducedMotion;
|
|
28129
|
-
parts.shimmer.visible = parts.motion.shimmer;
|
|
28130
|
-
parts.motion.startedAt = counting ? startedAt : null;
|
|
28131
|
-
parts.motion.label = label;
|
|
28132
|
-
parts.motion.elapsed = elapsed;
|
|
28133
|
-
}
|
|
28134
|
-
const taskCardRenderer = {
|
|
28135
|
-
id: "task-card",
|
|
28136
|
-
canRender: (item) => item.type === "task",
|
|
28137
|
-
create: (item, context) => {
|
|
28138
|
-
const root = new Container();
|
|
28139
|
-
const plate = new Graphics();
|
|
28140
|
-
const clip = new Graphics();
|
|
28141
|
-
const previewBg = new Graphics();
|
|
28142
|
-
const preview = new Sprite();
|
|
28143
|
-
const previewMask = new Graphics();
|
|
28144
|
-
const shimmer = new Graphics();
|
|
28145
|
-
const previewArt = new Graphics();
|
|
28146
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
28147
|
-
const text = (fontFamily, fontSize, fontWeight) => new Text({
|
|
28148
|
-
text: "",
|
|
28149
|
-
style: {
|
|
28150
|
-
fontFamily,
|
|
28151
|
-
fontSize,
|
|
28152
|
-
fontWeight,
|
|
28153
|
-
wordWrap: true,
|
|
28154
|
-
breakWords: true
|
|
28155
|
-
},
|
|
28156
|
-
resolution,
|
|
28157
|
-
roundPixels: true
|
|
28158
|
-
});
|
|
28159
|
-
const body = text(BOARD_FONT_STACK, 11.5, "500");
|
|
28160
|
-
const detail = text(BOARD_FONT_STACK, 10.5, "400");
|
|
28161
|
-
const meta = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
28162
|
-
const badge = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
28163
|
-
badge.style.wordWrap = false;
|
|
28164
|
-
badge.anchor.set(.5);
|
|
28165
|
-
detail.anchor.set(.5, 0);
|
|
28166
|
-
detail.style.align = "center";
|
|
28167
|
-
preview.mask = previewMask;
|
|
28168
|
-
root.mask = clip;
|
|
28169
|
-
root.addChild(plate, clip, previewBg, shimmer, preview, previewMask, previewArt, body, detail, meta, badge);
|
|
28170
|
-
partsByContainer$11.set(root, {
|
|
28171
|
-
root,
|
|
28172
|
-
plate,
|
|
28173
|
-
clip,
|
|
28174
|
-
previewBg,
|
|
28175
|
-
preview,
|
|
28176
|
-
previewMask,
|
|
28177
|
-
shimmer,
|
|
28178
|
-
previewArt,
|
|
28179
|
-
badge,
|
|
28180
|
-
body,
|
|
28181
|
-
detail,
|
|
28182
|
-
meta,
|
|
28183
|
-
assetKey: null,
|
|
28184
|
-
visualSig: "",
|
|
28185
|
-
textSig: "",
|
|
28186
|
-
resolution,
|
|
28187
|
-
motion: {
|
|
28188
|
-
itemId: "",
|
|
28189
|
-
width: 0,
|
|
28190
|
-
shimmer: false,
|
|
28191
|
-
startedAt: null,
|
|
28192
|
-
label: "",
|
|
28193
|
-
elapsed: "",
|
|
28194
|
-
revealFrom: null,
|
|
28195
|
-
revealKey: null
|
|
28196
|
-
}
|
|
28197
|
-
});
|
|
28198
|
-
if (item.type === "task") sync$11(root, item, context);
|
|
28199
|
-
return root;
|
|
28200
|
-
},
|
|
28201
|
-
update: (container, item, context) => {
|
|
28202
|
-
if (item.type === "task") sync$11(container, item, context);
|
|
28203
|
-
},
|
|
28204
|
-
tick: (container, clock) => {
|
|
28205
|
-
const parts = partsByContainer$11.get(container);
|
|
28206
|
-
return parts ? advance(parts, clock) : null;
|
|
28207
|
-
},
|
|
28208
|
-
renderFar: (graphics, item, context) => {
|
|
28209
|
-
if (item.type !== "task") return;
|
|
28210
|
-
const { status } = liveStatus(item, context);
|
|
28211
|
-
const active = status === "failed" || status === "running" || status === "pending";
|
|
28212
|
-
drawFarPlate(graphics, item.frame, {
|
|
28213
|
-
fill: context.palette.surface,
|
|
28214
|
-
fillAlpha: .82,
|
|
28215
|
-
...active ? {
|
|
28216
|
-
accent: statusColor(status, context),
|
|
28217
|
-
accentAlpha: .9
|
|
28218
|
-
} : {}
|
|
28219
|
-
});
|
|
28220
|
-
},
|
|
28221
|
-
destroy: (container, context) => {
|
|
28222
|
-
const parts = partsByContainer$11.get(container);
|
|
28223
|
-
if (parts?.assetKey) context.releaseTexture(parts.assetKey);
|
|
28224
|
-
parts?.root.destroy({ children: true });
|
|
28225
|
-
partsByContainer$11.delete(container);
|
|
28226
|
-
}
|
|
28227
|
-
};
|
|
28228
|
-
//#endregion
|
|
28229
|
-
//#region ../sdk/src/board/render/stroke.ts
|
|
28230
|
-
const HEAD_SPREAD = Math.PI / 6;
|
|
28231
|
-
function dashPattern(dash, width) {
|
|
28232
|
-
if (dash === "dashed") return [Math.max(6, width * 4), Math.max(4, width * 3)];
|
|
28233
|
-
if (dash === "dotted") return [Math.max(.5, width * .01), Math.max(3, width * 2)];
|
|
28234
|
-
return null;
|
|
28235
|
-
}
|
|
28236
|
-
function trimPolyline(path, trim) {
|
|
28237
|
-
if (trim === void 0 || trim >= 1 || path.length < 2) return path;
|
|
28238
|
-
if (trim <= 0) return [];
|
|
28239
|
-
let total = 0;
|
|
28240
|
-
for (let index = 1; index < path.length; index += 1) {
|
|
28241
|
-
const a = path[index - 1];
|
|
28242
|
-
const b = path[index];
|
|
28243
|
-
total += Math.hypot(b.x - a.x, b.y - a.y);
|
|
28244
|
-
}
|
|
28245
|
-
let remaining = total * trim;
|
|
28246
|
-
const out = [path[0]];
|
|
28247
|
-
for (let index = 1; index < path.length; index += 1) {
|
|
28248
|
-
const a = path[index - 1];
|
|
28249
|
-
const b = path[index];
|
|
28250
|
-
const length = Math.hypot(b.x - a.x, b.y - a.y);
|
|
28251
|
-
if (length >= remaining) {
|
|
28252
|
-
const t = length > 0 ? remaining / length : 0;
|
|
28253
|
-
out.push(worldPoint(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t));
|
|
28254
|
-
return out;
|
|
28255
|
-
}
|
|
28256
|
-
out.push(b);
|
|
28257
|
-
remaining -= length;
|
|
28258
|
-
}
|
|
28259
|
-
return out;
|
|
28260
|
-
}
|
|
28261
|
-
function tracePolyline(graphics, path, pattern, closed = false) {
|
|
28262
|
-
const points = closed && path.length > 2 ? [...path, path[0]] : path;
|
|
28263
|
-
if (points.length < 2) return;
|
|
28264
|
-
if (!pattern) {
|
|
28265
|
-
const first = points[0];
|
|
28266
|
-
graphics.moveTo(first.x, first.y);
|
|
28267
|
-
for (let index = 1; index < points.length; index += 1) {
|
|
28268
|
-
const point = points[index];
|
|
28269
|
-
graphics.lineTo(point.x, point.y);
|
|
28270
|
-
}
|
|
28271
|
-
if (closed) graphics.closePath();
|
|
28272
|
-
return;
|
|
28273
|
-
}
|
|
28274
|
-
const [dash, gap] = pattern;
|
|
28275
|
-
let penDown = true;
|
|
28276
|
-
let fresh = true;
|
|
28277
|
-
let remaining = dash;
|
|
28278
|
-
for (let index = 1; index < points.length; index += 1) {
|
|
28279
|
-
const a = points[index - 1];
|
|
28280
|
-
const b = points[index];
|
|
28281
|
-
const dx = b.x - a.x;
|
|
28282
|
-
const dy = b.y - a.y;
|
|
28283
|
-
const length = Math.hypot(dx, dy);
|
|
28284
|
-
let travelled = 0;
|
|
28285
|
-
while (length - travelled > 1e-4) {
|
|
28286
|
-
const step = Math.min(length - travelled, remaining);
|
|
28287
|
-
if (penDown) {
|
|
28288
|
-
const t0 = travelled / length;
|
|
28289
|
-
const t1 = (travelled + step) / length;
|
|
28290
|
-
if (fresh) graphics.moveTo(a.x + dx * t0, a.y + dy * t0);
|
|
28291
|
-
fresh = false;
|
|
28292
|
-
graphics.lineTo(a.x + dx * t1, a.y + dy * t1);
|
|
28293
|
-
}
|
|
28294
|
-
travelled += step;
|
|
28295
|
-
remaining -= step;
|
|
28296
|
-
if (remaining <= 1e-4) {
|
|
28297
|
-
penDown = !penDown;
|
|
28298
|
-
fresh = penDown;
|
|
28299
|
-
remaining = penDown ? dash : gap;
|
|
28300
|
-
}
|
|
28301
|
-
}
|
|
28302
|
-
}
|
|
28303
|
-
}
|
|
28304
|
-
function traceArrowhead(graphics, tip, angle, size) {
|
|
28305
|
-
graphics.moveTo(tip.x - size * Math.cos(angle - HEAD_SPREAD), tip.y - size * Math.sin(angle - HEAD_SPREAD)).lineTo(tip.x, tip.y).lineTo(tip.x - size * Math.cos(angle + HEAD_SPREAD), tip.y - size * Math.sin(angle + HEAD_SPREAD));
|
|
28306
|
-
}
|
|
28307
|
-
function endAngle(path, atStart) {
|
|
28308
|
-
if (path.length < 2) return null;
|
|
28309
|
-
const tip = atStart ? path[0] : path[path.length - 1];
|
|
28310
|
-
for (let offset = 1; offset < path.length; offset += 1) {
|
|
28311
|
-
const other = atStart ? path[offset] : path[path.length - 1 - offset];
|
|
28312
|
-
if (Math.hypot(tip.x - other.x, tip.y - other.y) > .001) return Math.atan2(tip.y - other.y, tip.x - other.x);
|
|
28313
|
-
}
|
|
28314
|
-
return null;
|
|
28315
|
-
}
|
|
28316
|
-
function roundRectPoints(width, height, radius) {
|
|
28317
|
-
const r = Math.min(radius, width / 2, height / 2);
|
|
28318
|
-
if (r <= 0) return [
|
|
28319
|
-
worldPoint(0, 0),
|
|
28320
|
-
worldPoint(width, 0),
|
|
28321
|
-
worldPoint(width, height),
|
|
28322
|
-
worldPoint(0, height),
|
|
28323
|
-
worldPoint(0, 0)
|
|
28324
|
-
];
|
|
28325
|
-
const corner = (cx, cy, from) => Array.from({ length: 9 }, (_, index) => {
|
|
28326
|
-
const angle = from + index / 8 * (Math.PI / 2);
|
|
28327
|
-
return worldPoint(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);
|
|
28328
|
-
});
|
|
28329
|
-
return [
|
|
28330
|
-
...corner(width - r, r, -Math.PI / 2),
|
|
28331
|
-
...corner(width - r, height - r, 0),
|
|
28332
|
-
...corner(r, height - r, Math.PI / 2),
|
|
28333
|
-
...corner(r, r, Math.PI),
|
|
28334
|
-
worldPoint(width - r, 0)
|
|
28335
|
-
];
|
|
28336
|
-
}
|
|
28337
|
-
//#endregion
|
|
28338
|
-
//#region ../sdk/src/board/render/renderers/arrow-card-renderer.ts
|
|
28339
|
-
const partsByContainer$10 = /* @__PURE__ */ new WeakMap();
|
|
28340
|
-
function sync$10(container, item, context) {
|
|
28341
|
-
const parts = partsByContainer$10.get(container);
|
|
28342
|
-
if (!parts) return;
|
|
28343
|
-
parts.root.position.set(0, 0);
|
|
28344
|
-
parts.root.rotation = 0;
|
|
28345
|
-
parts.root.scale.set(1);
|
|
28346
|
-
const { props, style } = item;
|
|
28347
|
-
const selected = context.selectedIds.has(item.id);
|
|
28348
|
-
const hovered = context.hoveredId === item.id;
|
|
28349
|
-
parts.line.alpha = itemAlpha(context, style.stroke);
|
|
28350
|
-
const color = itemColor(context, style.stroke, "brand");
|
|
28351
|
-
const size = style.strokeWidth ?? 2.5;
|
|
28352
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
28353
|
-
const resolved = resolveSceneArrow(item, context.scene);
|
|
28354
|
-
const path = trimPolyline(resolved.path, style.trim);
|
|
28355
|
-
const lineSig = [
|
|
28356
|
-
path.map((point) => `${point.x},${point.y}`).join(";"),
|
|
28357
|
-
selected,
|
|
28358
|
-
hovered,
|
|
28359
|
-
color,
|
|
28360
|
-
size,
|
|
28361
|
-
style.dash,
|
|
28362
|
-
props.arrowStart,
|
|
28363
|
-
props.arrowEnd
|
|
28364
|
-
].join("|");
|
|
28365
|
-
if (lineSig !== parts.lineSig) {
|
|
28366
|
-
parts.lineSig = lineSig;
|
|
28367
|
-
parts.line.clear();
|
|
28368
|
-
const width = selected ? size + 1 : size;
|
|
28369
|
-
const stroke = {
|
|
28370
|
-
color,
|
|
28371
|
-
width,
|
|
28372
|
-
alpha: selected || hovered ? 1 : .92,
|
|
28373
|
-
cap: "round",
|
|
28374
|
-
join: "round"
|
|
28375
|
-
};
|
|
28376
|
-
tracePolyline(parts.line, path, dashPattern(style.dash, width));
|
|
28377
|
-
parts.line.stroke(stroke);
|
|
28378
|
-
const first = path[0];
|
|
28379
|
-
const last = path[path.length - 1];
|
|
28380
|
-
if (first && last) {
|
|
28381
|
-
const span = Math.hypot(last.x - first.x, last.y - first.y);
|
|
28382
|
-
const headSize = Math.min(Math.max(14, size * 5.5), Math.max(10, span * .28));
|
|
28383
|
-
const complete = style.trim === void 0 || style.trim >= 1;
|
|
28384
|
-
const endDirection = endAngle(path, false);
|
|
28385
|
-
const startDirection = endAngle(path, true);
|
|
28386
|
-
if (props.arrowEnd && endDirection !== null && path.length > 1) traceArrowhead(parts.line, last, endDirection, headSize);
|
|
28387
|
-
if (props.arrowStart && startDirection !== null && complete) traceArrowhead(parts.line, first, startDirection, headSize);
|
|
28388
|
-
parts.line.stroke({
|
|
28389
|
-
...stroke,
|
|
28390
|
-
width: Math.max(1.5, width)
|
|
28391
|
-
});
|
|
28392
|
-
}
|
|
28393
|
-
}
|
|
28394
|
-
const labelSig = [
|
|
28395
|
-
props.label,
|
|
28396
|
-
context.palette.text,
|
|
28397
|
-
context.palette.bg,
|
|
28398
|
-
props.fontSize
|
|
28399
|
-
].join("|");
|
|
28400
|
-
if (labelSig !== parts.labelSig) {
|
|
28401
|
-
parts.labelSig = labelSig;
|
|
28402
|
-
parts.label.text = props.label;
|
|
28403
|
-
parts.label.style.fill = context.palette.text;
|
|
28404
|
-
parts.label.style.fontSize = props.fontSize;
|
|
28405
|
-
const padX = props.fontSize * .4;
|
|
28406
|
-
const padY = props.fontSize * .15;
|
|
28407
|
-
const { width, height } = parts.label;
|
|
28408
|
-
parts.backdrop.clear();
|
|
28409
|
-
parts.backdrop.roundRect(-width / 2 - padX, -height / 2 - padY, width + padX * 2, height + padY * 2, props.fontSize * .3).fill({
|
|
28410
|
-
color: context.palette.bg,
|
|
28411
|
-
alpha: .92
|
|
28412
|
-
});
|
|
28413
|
-
}
|
|
28414
|
-
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
28415
|
-
parts.label.visible = visible;
|
|
28416
|
-
parts.backdrop.visible = visible;
|
|
28417
|
-
const mid = style.trim === void 0 ? resolved.mid : pathPointAt(resolved.path, .5);
|
|
28418
|
-
parts.label.position.set(mid.x, mid.y);
|
|
28419
|
-
parts.backdrop.position.set(mid.x, mid.y);
|
|
28420
|
-
}
|
|
28421
|
-
const arrowCardRenderer = {
|
|
28422
|
-
id: "arrow-card",
|
|
28423
|
-
canRender: (item) => item.type === "arrow",
|
|
28424
|
-
create: (item, context) => {
|
|
28425
|
-
const root = new Container();
|
|
28426
|
-
const line = new Graphics();
|
|
28427
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
28428
|
-
const label = new Text({
|
|
28429
|
-
text: "",
|
|
28430
|
-
style: {
|
|
28431
|
-
fill: 16777215,
|
|
28432
|
-
fontFamily: BOARD_FONT_STACK,
|
|
28433
|
-
fontSize: 14,
|
|
28434
|
-
fontWeight: "500"
|
|
28435
|
-
},
|
|
28436
|
-
resolution,
|
|
28437
|
-
roundPixels: true
|
|
28438
|
-
});
|
|
28439
|
-
label.anchor.set(.5);
|
|
28440
|
-
const backdrop = new Graphics();
|
|
28441
|
-
root.addChild(line, backdrop, label);
|
|
28442
|
-
partsByContainer$10.set(root, {
|
|
28443
|
-
root,
|
|
28444
|
-
line,
|
|
28445
|
-
backdrop,
|
|
28446
|
-
label,
|
|
28447
|
-
lineSig: "",
|
|
28448
|
-
labelSig: "",
|
|
28449
|
-
resolution
|
|
28450
|
-
});
|
|
28451
|
-
if (item.type === "arrow") sync$10(root, item, context);
|
|
28452
|
-
return root;
|
|
28453
|
-
},
|
|
28454
|
-
update: (container, item, context) => {
|
|
28455
|
-
if (item.type === "arrow") sync$10(container, item, context);
|
|
28456
|
-
},
|
|
28457
|
-
renderFar: (graphics, item, context) => {
|
|
28458
|
-
if (item.type !== "arrow") return;
|
|
28459
|
-
const arrow = item;
|
|
28460
|
-
drawFarStroke(graphics, trimPolyline(resolveSceneArrow(arrow, context.scene).path, arrow.style.trim), {
|
|
28461
|
-
color: itemColor(context, arrow.style.stroke, "brand"),
|
|
28462
|
-
width: arrow.style.strokeWidth ?? 2.5,
|
|
28463
|
-
alpha: .85 * itemAlpha(context, arrow.style.stroke)
|
|
28464
|
-
});
|
|
28465
|
-
},
|
|
28466
|
-
destroy: (container) => {
|
|
28467
|
-
partsByContainer$10.get(container)?.root.destroy({ children: true });
|
|
28468
|
-
partsByContainer$10.delete(container);
|
|
28469
|
-
}
|
|
28470
|
-
};
|
|
28471
|
-
//#endregion
|
|
28472
|
-
//#region ../sdk/src/board/render/renderers/audio-card-renderer.ts
|
|
28473
|
-
const RADIUS$3 = 4;
|
|
28474
|
-
const PLAY_RADIUS = 18;
|
|
28475
|
-
const partsByContainer$9 = /* @__PURE__ */ new WeakMap();
|
|
28476
|
-
function sync$9(container, item, context) {
|
|
28477
|
-
const parts = partsByContainer$9.get(container);
|
|
28478
|
-
if (!parts) return;
|
|
28479
|
-
positionShell(parts.root, item);
|
|
28480
|
-
const { width, height } = item.frame;
|
|
28481
|
-
const selected = context.selectedIds.has(item.id);
|
|
28482
|
-
const hovered = context.hoveredId === item.id;
|
|
28483
|
-
const title = item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
28484
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
28485
|
-
if (parts.label.text !== title) parts.label.text = title;
|
|
28486
|
-
syncTextWrapWidth(parts.label, parts, Math.max(1, width - 24), false);
|
|
28487
|
-
parts.label.position.set(12, Math.max(8, height - parts.label.height - 8));
|
|
28488
|
-
const sig = [
|
|
28489
|
-
width,
|
|
28490
|
-
height,
|
|
28491
|
-
selected,
|
|
28492
|
-
hovered,
|
|
28493
|
-
title,
|
|
28494
|
-
parts.label.height,
|
|
28495
|
-
context.palette.surface,
|
|
28496
|
-
context.palette.brand,
|
|
28497
|
-
context.palette.border,
|
|
28498
|
-
context.palette.muted,
|
|
28499
|
-
context.palette.text
|
|
28500
|
-
].join("|");
|
|
28501
|
-
if (sig === parts.sig) return;
|
|
28502
|
-
parts.sig = sig;
|
|
28503
|
-
parts.plate.clear().roundRect(0, 0, width, height, RADIUS$3).fill({
|
|
28504
|
-
color: context.palette.surface,
|
|
28505
|
-
alpha: .98
|
|
28506
|
-
}).roundRect(0, 0, width, height, RADIUS$3).stroke({
|
|
28507
|
-
color: selected ? context.palette.brand : hovered ? context.palette.muted : context.palette.border,
|
|
28508
|
-
width: selected ? 2 : 1,
|
|
28509
|
-
alpha: selected ? .96 : .84
|
|
28510
|
-
});
|
|
28511
|
-
const labelBand = Math.min(height * .38, parts.label.height + 16);
|
|
28512
|
-
const waveformInset = Math.min(24, width * .08);
|
|
28513
|
-
parts.waveform.clear();
|
|
28514
|
-
drawAudioWaveform(parts.waveform, `${item.props.src}:${item.props.snapshot?.mtimeMs ?? "unknown"}`, {
|
|
28515
|
-
x: waveformInset,
|
|
28516
|
-
y: 10,
|
|
28517
|
-
width: Math.max(1, width - waveformInset * 2),
|
|
28518
|
-
height: Math.max(8, height - labelBand - 16)
|
|
28519
|
-
}, context.palette.brand);
|
|
28520
|
-
const cx = width / 2;
|
|
28521
|
-
const cy = Math.max(24, (height - labelBand) / 2);
|
|
28522
|
-
parts.chrome.clear().circle(cx, cy, PLAY_RADIUS).fill({
|
|
28523
|
-
color: selected ? context.palette.brand : context.palette.surface,
|
|
28524
|
-
alpha: .92
|
|
28525
|
-
});
|
|
28526
|
-
const triangle = PLAY_RADIUS * .58;
|
|
28527
|
-
parts.chrome.moveTo(cx - triangle * .35, cy - triangle * .62).lineTo(cx - triangle * .35, cy + triangle * .62).lineTo(cx + triangle * .72, cy).closePath().fill({
|
|
28528
|
-
color: context.palette.text,
|
|
28529
|
-
alpha: .96
|
|
28530
|
-
});
|
|
28531
|
-
parts.label.style.fill = context.palette.text;
|
|
28532
|
-
}
|
|
28533
|
-
const audioCardRenderer = {
|
|
28534
|
-
id: "audio-card",
|
|
28535
|
-
canRender: (item) => item.type === "audio",
|
|
28536
|
-
create: (item, context) => {
|
|
28537
|
-
const root = new Container();
|
|
28538
|
-
const plate = new Graphics();
|
|
28539
|
-
const waveform = new Graphics();
|
|
28540
|
-
const chrome = new Graphics();
|
|
28541
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
28542
|
-
const label = new Text({
|
|
28543
|
-
text: "",
|
|
28544
|
-
style: {
|
|
28545
|
-
fill: context.palette.text,
|
|
28546
|
-
fontFamily: BOARD_FONT_STACK,
|
|
28547
|
-
fontSize: 12,
|
|
28548
|
-
fontWeight: "500",
|
|
28549
|
-
wordWrap: true
|
|
28550
|
-
},
|
|
28551
|
-
resolution,
|
|
28552
|
-
roundPixels: true
|
|
28553
|
-
});
|
|
28554
|
-
root.addChild(plate, waveform, chrome, label);
|
|
28555
|
-
partsByContainer$9.set(root, {
|
|
28556
|
-
root,
|
|
28557
|
-
plate,
|
|
28558
|
-
waveform,
|
|
28559
|
-
chrome,
|
|
28560
|
-
label,
|
|
28561
|
-
sig: "",
|
|
28562
|
-
wrapWidth: 0,
|
|
28563
|
-
resolution
|
|
28564
|
-
});
|
|
28565
|
-
if (item.type === "audio") sync$9(root, item, context);
|
|
28566
|
-
return root;
|
|
28567
|
-
},
|
|
28568
|
-
update: (container, item, context) => {
|
|
28569
|
-
if (item.type === "audio") sync$9(container, item, context);
|
|
28570
|
-
},
|
|
28571
|
-
renderFar: (graphics, item, context) => {
|
|
28572
|
-
drawFarPlate(graphics, item.frame, {
|
|
28573
|
-
fill: context.palette.surface,
|
|
28574
|
-
fillAlpha: .96,
|
|
28575
|
-
accent: context.palette.brand,
|
|
28576
|
-
accentAlpha: .72
|
|
28577
|
-
});
|
|
28578
|
-
},
|
|
28579
|
-
destroy: (container) => {
|
|
28580
|
-
partsByContainer$9.get(container)?.root.destroy({ children: true });
|
|
28581
|
-
partsByContainer$9.delete(container);
|
|
28582
|
-
}
|
|
28583
|
-
};
|
|
28584
|
-
//#endregion
|
|
28585
|
-
//#region ../sdk/src/board/render/renderers/draw-card-renderer.ts
|
|
28586
|
-
const partsByContainer$8 = /* @__PURE__ */ new WeakMap();
|
|
28587
|
-
function fillRibbon(graphics, ribbon, color) {
|
|
28588
|
-
const { positions, indices } = ribbon;
|
|
28589
|
-
for (let offset = 0; offset < indices.length; offset += 3) {
|
|
28590
|
-
const a = (indices[offset] ?? 0) * 2;
|
|
28591
|
-
const b = (indices[offset + 1] ?? 0) * 2;
|
|
28592
|
-
const c = (indices[offset + 2] ?? 0) * 2;
|
|
28593
|
-
graphics.moveTo(positions[a] ?? 0, positions[a + 1] ?? 0).lineTo(positions[b] ?? 0, positions[b + 1] ?? 0).lineTo(positions[c] ?? 0, positions[c + 1] ?? 0).closePath();
|
|
28594
|
-
}
|
|
28595
|
-
return graphics.fill({ color });
|
|
28596
|
-
}
|
|
28597
|
-
function replaceStroke(parts, next) {
|
|
28598
|
-
if (parts.stroke) {
|
|
28599
|
-
parts.root.removeChild(parts.stroke);
|
|
28600
|
-
parts.stroke.destroy();
|
|
28601
|
-
}
|
|
28602
|
-
parts.stroke = next;
|
|
28603
|
-
parts.root.addChild(next);
|
|
28604
|
-
return next;
|
|
28212
|
+
parts.stroke = next;
|
|
28213
|
+
parts.root.addChild(next);
|
|
28214
|
+
return next;
|
|
28605
28215
|
}
|
|
28606
28216
|
function tessellate(parts, points, size, paint) {
|
|
28607
28217
|
parts.ribbon ??= createStrokeRibbonBuilder(size);
|
|
@@ -28634,8 +28244,8 @@ function tessellate(parts, points, size, paint) {
|
|
|
28634
28244
|
texture: Texture.WHITE
|
|
28635
28245
|
}));
|
|
28636
28246
|
}
|
|
28637
|
-
function sync$
|
|
28638
|
-
const parts = partsByContainer$
|
|
28247
|
+
function sync$10(container, item, context) {
|
|
28248
|
+
const parts = partsByContainer$10.get(container);
|
|
28639
28249
|
if (!parts) return;
|
|
28640
28250
|
positionShell(parts.root, item);
|
|
28641
28251
|
const { points } = item.props;
|
|
@@ -28668,7 +28278,7 @@ const drawCardRenderer = {
|
|
|
28668
28278
|
canRender: (item) => item.type === "draw",
|
|
28669
28279
|
create: (item, context) => {
|
|
28670
28280
|
const root = new Container();
|
|
28671
|
-
partsByContainer$
|
|
28281
|
+
partsByContainer$10.set(root, {
|
|
28672
28282
|
root,
|
|
28673
28283
|
stroke: null,
|
|
28674
28284
|
ribbon: null,
|
|
@@ -28685,11 +28295,11 @@ const drawCardRenderer = {
|
|
|
28685
28295
|
height: 1
|
|
28686
28296
|
}
|
|
28687
28297
|
});
|
|
28688
|
-
if (item.type === "draw") sync$
|
|
28298
|
+
if (item.type === "draw") sync$10(root, item, context);
|
|
28689
28299
|
return root;
|
|
28690
28300
|
},
|
|
28691
28301
|
update: (container, item, context) => {
|
|
28692
|
-
if (item.type === "draw") sync$
|
|
28302
|
+
if (item.type === "draw") sync$10(container, item, context);
|
|
28693
28303
|
},
|
|
28694
28304
|
renderFar: (graphics, item, context) => {
|
|
28695
28305
|
if (item.type !== "draw") return;
|
|
@@ -28702,15 +28312,15 @@ const drawCardRenderer = {
|
|
|
28702
28312
|
});
|
|
28703
28313
|
},
|
|
28704
28314
|
destroy: (container) => {
|
|
28705
|
-
partsByContainer$
|
|
28706
|
-
partsByContainer$
|
|
28315
|
+
partsByContainer$10.get(container)?.root.destroy({ children: true });
|
|
28316
|
+
partsByContainer$10.delete(container);
|
|
28707
28317
|
}
|
|
28708
28318
|
};
|
|
28709
28319
|
//#endregion
|
|
28710
28320
|
//#region ../sdk/src/board/render/renderers/effect-card-renderer.ts
|
|
28711
28321
|
const BOARD_EFFECT_MAX_PARTICLES = 4e3;
|
|
28712
28322
|
const TRAIL_SAMPLES = 64;
|
|
28713
|
-
const partsByContainer$
|
|
28323
|
+
const partsByContainer$9 = /* @__PURE__ */ new WeakMap();
|
|
28714
28324
|
function hashString(value) {
|
|
28715
28325
|
let hash = 2166136261;
|
|
28716
28326
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -28850,88 +28460,349 @@ function drawTrail(graphics, parts, item, context, color) {
|
|
|
28850
28460
|
cap: "round"
|
|
28851
28461
|
});
|
|
28852
28462
|
}
|
|
28853
|
-
}
|
|
28854
|
-
function sync$
|
|
28855
|
-
const parts = partsByContainer$
|
|
28856
|
-
if (!parts) return;
|
|
28857
|
-
positionShell(parts.root, item);
|
|
28858
|
-
const { width, height } = item.frame;
|
|
28859
|
-
const { props } = item;
|
|
28860
|
-
const color = itemColor(context, item.style.fill ?? item.style.stroke, "brand", "fill");
|
|
28861
|
-
const seed = hashString(props.seed ?? item.id);
|
|
28862
|
-
const time = Math.max(0, context.time);
|
|
28863
|
-
const graphics = parts.graphics;
|
|
28864
|
-
graphics.alpha = itemAlpha(context, item.style.fill ?? item.style.stroke);
|
|
28865
|
-
graphics.clear();
|
|
28866
|
-
switch (props.kind) {
|
|
28867
|
-
case "particles":
|
|
28868
|
-
drawParticles(graphics, props, width, height, time, seed, color);
|
|
28869
|
-
break;
|
|
28870
|
-
case "impact":
|
|
28871
|
-
drawImpact(graphics, props, width, height, time, seed, color);
|
|
28872
|
-
break;
|
|
28873
|
-
case "flash":
|
|
28874
|
-
drawFlash(graphics, props, width, height, time, color);
|
|
28875
|
-
break;
|
|
28876
|
-
case "glow":
|
|
28877
|
-
drawGlow(graphics, props, width, height, time, color);
|
|
28878
|
-
break;
|
|
28879
|
-
case "trail": drawTrail(graphics, parts, item, context, color);
|
|
28463
|
+
}
|
|
28464
|
+
function sync$9(container, item, context) {
|
|
28465
|
+
const parts = partsByContainer$9.get(container);
|
|
28466
|
+
if (!parts) return;
|
|
28467
|
+
positionShell(parts.root, item);
|
|
28468
|
+
const { width, height } = item.frame;
|
|
28469
|
+
const { props } = item;
|
|
28470
|
+
const color = itemColor(context, item.style.fill ?? item.style.stroke, "brand", "fill");
|
|
28471
|
+
const seed = hashString(props.seed ?? item.id);
|
|
28472
|
+
const time = Math.max(0, context.time);
|
|
28473
|
+
const graphics = parts.graphics;
|
|
28474
|
+
graphics.alpha = itemAlpha(context, item.style.fill ?? item.style.stroke);
|
|
28475
|
+
graphics.clear();
|
|
28476
|
+
switch (props.kind) {
|
|
28477
|
+
case "particles":
|
|
28478
|
+
drawParticles(graphics, props, width, height, time, seed, color);
|
|
28479
|
+
break;
|
|
28480
|
+
case "impact":
|
|
28481
|
+
drawImpact(graphics, props, width, height, time, seed, color);
|
|
28482
|
+
break;
|
|
28483
|
+
case "flash":
|
|
28484
|
+
drawFlash(graphics, props, width, height, time, color);
|
|
28485
|
+
break;
|
|
28486
|
+
case "glow":
|
|
28487
|
+
drawGlow(graphics, props, width, height, time, color);
|
|
28488
|
+
break;
|
|
28489
|
+
case "trail": drawTrail(graphics, parts, item, context, color);
|
|
28490
|
+
}
|
|
28491
|
+
}
|
|
28492
|
+
const effectCardRenderer = {
|
|
28493
|
+
id: "effect-card",
|
|
28494
|
+
canRender: (item) => item.type === "effect",
|
|
28495
|
+
animated: true,
|
|
28496
|
+
create: (item, context) => {
|
|
28497
|
+
const root = new Container();
|
|
28498
|
+
const graphics = new Graphics();
|
|
28499
|
+
root.addChild(graphics);
|
|
28500
|
+
partsByContainer$9.set(root, {
|
|
28501
|
+
root,
|
|
28502
|
+
graphics,
|
|
28503
|
+
trail: []
|
|
28504
|
+
});
|
|
28505
|
+
if (item.type === "effect") sync$9(root, item, context);
|
|
28506
|
+
return root;
|
|
28507
|
+
},
|
|
28508
|
+
update: (container, item, context) => {
|
|
28509
|
+
if (item.type === "effect") sync$9(container, item, context);
|
|
28510
|
+
},
|
|
28511
|
+
renderFar: (graphics, item, context) => {
|
|
28512
|
+
if (item.type !== "effect") return;
|
|
28513
|
+
drawFarPlate(graphics, item.frame, {
|
|
28514
|
+
fill: itemColor(context, item.style.fill, "brand", "fill"),
|
|
28515
|
+
fillAlpha: .08
|
|
28516
|
+
});
|
|
28517
|
+
},
|
|
28518
|
+
destroy: (container) => {
|
|
28519
|
+
partsByContainer$9.get(container)?.root.destroy({ children: true });
|
|
28520
|
+
partsByContainer$9.delete(container);
|
|
28521
|
+
}
|
|
28522
|
+
};
|
|
28523
|
+
//#endregion
|
|
28524
|
+
//#region ../sdk/src/board/render/renderers/file-card-renderer.ts
|
|
28525
|
+
const PADDING$1 = 10;
|
|
28526
|
+
const COVER_RATIO = .56;
|
|
28527
|
+
const MIN_BODY_FOR_COVER = 38;
|
|
28528
|
+
const TITLE_SIZE = 13;
|
|
28529
|
+
const TITLE_LINE = TITLE_SIZE * 1.35;
|
|
28530
|
+
const TITLE_MAX_LINES = 2;
|
|
28531
|
+
const EXCERPT_SIZE = 11;
|
|
28532
|
+
const EXCERPT_LINE = EXCERPT_SIZE * 1.45;
|
|
28533
|
+
const EXCERPT_MAX_LINES = 3;
|
|
28534
|
+
const TYPE_MARK_SIZE = 28;
|
|
28535
|
+
const GAP = 4;
|
|
28536
|
+
const STRIPE = 2;
|
|
28537
|
+
const MAX_DASHES = 40;
|
|
28538
|
+
const partsByContainer$8 = /* @__PURE__ */ new WeakMap();
|
|
28539
|
+
function detailFor(zoom) {
|
|
28540
|
+
return boardCardDetailed(zoom) ? "full" : "title";
|
|
28541
|
+
}
|
|
28542
|
+
function coverHeight(item, height) {
|
|
28543
|
+
if (filePreviewKind(item.props.snapshot) !== "cover") return 0;
|
|
28544
|
+
const ideal = Math.round(height * COVER_RATIO);
|
|
28545
|
+
return Math.max(0, Math.min(ideal, height - MIN_BODY_FOR_COVER));
|
|
28546
|
+
}
|
|
28547
|
+
function linesInRoom(room, lineHeight, max) {
|
|
28548
|
+
if (room < lineHeight * .85) return 0;
|
|
28549
|
+
return Math.max(0, Math.min(max, Math.floor((room + .5) / lineHeight)));
|
|
28550
|
+
}
|
|
28551
|
+
function layoutCover(sprite, width, height, texture) {
|
|
28552
|
+
const rect = containRect(width, height, texture.width, texture.height);
|
|
28553
|
+
sprite.position.set(rect.x, rect.y);
|
|
28554
|
+
sprite.width = rect.width;
|
|
28555
|
+
sprite.height = rect.height;
|
|
28556
|
+
}
|
|
28557
|
+
function syncClip(parts, rect, style) {
|
|
28558
|
+
traceCardOutline(parts.clip.clear(), rect, style).fill({ color: 16777215 });
|
|
28559
|
+
}
|
|
28560
|
+
function sync$8(container, item, context) {
|
|
28561
|
+
const parts = partsByContainer$8.get(container);
|
|
28562
|
+
if (!parts) return;
|
|
28563
|
+
positionShell(parts.root, item);
|
|
28564
|
+
const { width, height } = item.frame;
|
|
28565
|
+
const detail = detailFor(context.zoom);
|
|
28566
|
+
const elevation = cardElevation(context, item.id);
|
|
28567
|
+
syncCardTag(parts.tag, {
|
|
28568
|
+
glyph: "file",
|
|
28569
|
+
text: fileMetaLine(item.props.src, item.props.snapshot?.size),
|
|
28570
|
+
width
|
|
28571
|
+
}, context);
|
|
28572
|
+
const key = context.assetKey(item);
|
|
28573
|
+
const texture = key ? context.getTexture(key) : null;
|
|
28574
|
+
const coverFailed = Boolean(key && !texture && context.hasError(key));
|
|
28575
|
+
const fileState = context.fileState(item.props.src);
|
|
28576
|
+
const band = coverHeight(item, height);
|
|
28577
|
+
const kind = filePreviewKind(item.props.snapshot);
|
|
28578
|
+
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
28579
|
+
const accent = fileCategoryAccent(category, context.palette);
|
|
28580
|
+
syncTextResolution(parts.title, parts.titleRes, context.zoom);
|
|
28581
|
+
syncTextResolution(parts.excerpt, parts.excerptRes, context.zoom);
|
|
28582
|
+
syncTextResolution(parts.typeMark, parts.typeMarkRes, context.zoom);
|
|
28583
|
+
const visualSig = [
|
|
28584
|
+
key ?? "",
|
|
28585
|
+
width,
|
|
28586
|
+
height,
|
|
28587
|
+
detail,
|
|
28588
|
+
elevation,
|
|
28589
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
28590
|
+
coverFailed,
|
|
28591
|
+
fileState,
|
|
28592
|
+
kind,
|
|
28593
|
+
category,
|
|
28594
|
+
context.themeKey,
|
|
28595
|
+
accent
|
|
28596
|
+
].join("|");
|
|
28597
|
+
if (visualSig !== parts.visualSig) {
|
|
28598
|
+
parts.visualSig = visualSig;
|
|
28599
|
+
const rect = {
|
|
28600
|
+
x: 0,
|
|
28601
|
+
y: 0,
|
|
28602
|
+
width,
|
|
28603
|
+
height
|
|
28604
|
+
};
|
|
28605
|
+
syncClip(parts, rect, context.style);
|
|
28606
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
28607
|
+
fill: context.palette.surface,
|
|
28608
|
+
border: context.palette.border,
|
|
28609
|
+
borderAlpha: .85,
|
|
28610
|
+
elevation
|
|
28611
|
+
});
|
|
28612
|
+
if (fileState !== "ok") {
|
|
28613
|
+
const dash = Math.max(6, width / MAX_DASHES / 2);
|
|
28614
|
+
for (let x = 0; x < width; x += dash * 2) parts.plate.moveTo(x, .5).lineTo(Math.min(x + dash, width), .5);
|
|
28615
|
+
parts.plate.stroke({
|
|
28616
|
+
color: context.palette.muted,
|
|
28617
|
+
width: 2,
|
|
28618
|
+
alpha: fileState === "missing" ? .9 : .5
|
|
28619
|
+
});
|
|
28620
|
+
}
|
|
28621
|
+
const showCover = band > 0 && Boolean(texture);
|
|
28622
|
+
if (band > 0) parts.plate.rect(1, 1, width - 2, band - 1).fill({
|
|
28623
|
+
color: context.palette.hover,
|
|
28624
|
+
alpha: coverFailed ? .35 : .6
|
|
28625
|
+
});
|
|
28626
|
+
if (showCover && texture) {
|
|
28627
|
+
if (parts.cover.texture !== texture) parts.cover.texture = texture;
|
|
28628
|
+
layoutCover(parts.cover, width, band, texture);
|
|
28629
|
+
parts.coverMask.clear().rect(0, 0, width, band).fill({ color: 16777215 });
|
|
28630
|
+
}
|
|
28631
|
+
parts.cover.visible = showCover;
|
|
28632
|
+
parts.coverMask.visible = showCover;
|
|
28633
|
+
if (!band) parts.plate.rect(1, 1, STRIPE, height - 2).fill({
|
|
28634
|
+
color: accent,
|
|
28635
|
+
alpha: .55
|
|
28636
|
+
});
|
|
28637
|
+
parts.excerpt.visible = detail === "full";
|
|
28638
|
+
parts.typeMark.visible = kind === "blank";
|
|
28639
|
+
}
|
|
28640
|
+
const title = item.props.snapshot?.title || fileStem(item.props.src);
|
|
28641
|
+
const excerpt = item.props.snapshot?.excerpt ?? "";
|
|
28642
|
+
const mark = fileTypeLabel(item.props.src);
|
|
28643
|
+
const innerWidth = Math.max(1, width - 20);
|
|
28644
|
+
const showTypeMark = kind === "blank";
|
|
28645
|
+
const textSig = [
|
|
28646
|
+
title,
|
|
28647
|
+
excerpt,
|
|
28648
|
+
mark,
|
|
28649
|
+
detail,
|
|
28650
|
+
innerWidth,
|
|
28651
|
+
band,
|
|
28652
|
+
height,
|
|
28653
|
+
kind,
|
|
28654
|
+
context.palette.text,
|
|
28655
|
+
context.palette.muted,
|
|
28656
|
+
context.style.font,
|
|
28657
|
+
accent
|
|
28658
|
+
].join("|");
|
|
28659
|
+
if (textSig === parts.textSig) return;
|
|
28660
|
+
parts.textSig = textSig;
|
|
28661
|
+
parts.title.style.fontFamily = context.style.font;
|
|
28662
|
+
parts.excerpt.style.fontFamily = context.style.font;
|
|
28663
|
+
const top = band > 0 ? band + PADDING$1 * .8 : PADDING$1;
|
|
28664
|
+
const contentBottom = height - PADDING$1;
|
|
28665
|
+
let cursor = top;
|
|
28666
|
+
if (showTypeMark) {
|
|
28667
|
+
const markSize = Math.max(18, Math.min(TYPE_MARK_SIZE, Math.round(height * .22)));
|
|
28668
|
+
parts.typeMark.style.fill = accent;
|
|
28669
|
+
parts.typeMark.style.fontSize = markSize;
|
|
28670
|
+
parts.typeMark.style.lineHeight = markSize * 1.1;
|
|
28671
|
+
if (parts.typeMark.text !== mark) parts.typeMark.text = mark;
|
|
28672
|
+
parts.typeMark.position.set(PADDING$1, cursor);
|
|
28673
|
+
parts.typeMark.visible = true;
|
|
28674
|
+
cursor += parts.typeMark.height + GAP;
|
|
28675
|
+
} else parts.typeMark.visible = false;
|
|
28676
|
+
const titleLines = linesInRoom(Math.max(0, contentBottom - cursor), TITLE_LINE, TITLE_MAX_LINES);
|
|
28677
|
+
parts.title.style.fill = context.palette.text;
|
|
28678
|
+
fitTextToLines(parts.title, title, titleLines, innerWidth);
|
|
28679
|
+
parts.title.position.set(PADDING$1, cursor);
|
|
28680
|
+
parts.title.visible = titleLines > 0;
|
|
28681
|
+
if (detail !== "full") {
|
|
28682
|
+
parts.excerpt.visible = false;
|
|
28683
|
+
return;
|
|
28684
|
+
}
|
|
28685
|
+
const excerptTop = cursor + (titleLines > 0 ? parts.title.height + GAP : 0);
|
|
28686
|
+
const excerptLines = linesInRoom(contentBottom - excerptTop, EXCERPT_LINE, EXCERPT_MAX_LINES);
|
|
28687
|
+
const showExcerpt = Boolean(excerpt) && excerptLines > 0;
|
|
28688
|
+
if (showExcerpt) {
|
|
28689
|
+
parts.excerpt.style.fill = context.palette.muted;
|
|
28690
|
+
fitTextToLines(parts.excerpt, excerpt, excerptLines, innerWidth);
|
|
28691
|
+
parts.excerpt.position.set(PADDING$1, excerptTop);
|
|
28880
28692
|
}
|
|
28881
|
-
|
|
28882
|
-
color: context.palette.muted,
|
|
28883
|
-
width: 1,
|
|
28884
|
-
alpha: .6
|
|
28885
|
-
});
|
|
28693
|
+
parts.excerpt.visible = showExcerpt;
|
|
28886
28694
|
}
|
|
28887
|
-
const
|
|
28888
|
-
id: "
|
|
28889
|
-
canRender: (item) => item.type === "
|
|
28890
|
-
animated: true,
|
|
28695
|
+
const fileCardRenderer = {
|
|
28696
|
+
id: "file-card",
|
|
28697
|
+
canRender: (item) => item.type === "file",
|
|
28891
28698
|
create: (item, context) => {
|
|
28892
28699
|
const root = new Container();
|
|
28893
|
-
const
|
|
28894
|
-
|
|
28895
|
-
|
|
28700
|
+
const plate = new Graphics();
|
|
28701
|
+
const body = new Container();
|
|
28702
|
+
const clip = new Graphics();
|
|
28703
|
+
const cover = new Sprite(Texture.EMPTY);
|
|
28704
|
+
const coverMask = new Graphics();
|
|
28705
|
+
cover.mask = coverMask;
|
|
28706
|
+
const resolution = 1;
|
|
28707
|
+
const title = new Text({
|
|
28708
|
+
text: "",
|
|
28709
|
+
style: {
|
|
28710
|
+
fill: context.palette.text,
|
|
28711
|
+
fontFamily: BOARD_FONT_STACK,
|
|
28712
|
+
fontSize: TITLE_SIZE,
|
|
28713
|
+
fontWeight: "600",
|
|
28714
|
+
wordWrap: true,
|
|
28715
|
+
breakWords: true,
|
|
28716
|
+
lineHeight: TITLE_LINE
|
|
28717
|
+
},
|
|
28718
|
+
resolution,
|
|
28719
|
+
roundPixels: true
|
|
28720
|
+
});
|
|
28721
|
+
const excerpt = new Text({
|
|
28722
|
+
text: "",
|
|
28723
|
+
style: {
|
|
28724
|
+
fill: context.palette.muted,
|
|
28725
|
+
fontFamily: BOARD_FONT_STACK,
|
|
28726
|
+
fontSize: EXCERPT_SIZE,
|
|
28727
|
+
fontWeight: "400",
|
|
28728
|
+
wordWrap: true,
|
|
28729
|
+
breakWords: true,
|
|
28730
|
+
lineHeight: EXCERPT_LINE
|
|
28731
|
+
},
|
|
28732
|
+
resolution,
|
|
28733
|
+
roundPixels: true
|
|
28734
|
+
});
|
|
28735
|
+
const typeMark = new Text({
|
|
28736
|
+
text: "",
|
|
28737
|
+
style: {
|
|
28738
|
+
fill: context.palette.muted,
|
|
28739
|
+
fontFamily: BOARD_MONO_FONT_STACK,
|
|
28740
|
+
fontSize: TYPE_MARK_SIZE,
|
|
28741
|
+
fontWeight: "700",
|
|
28742
|
+
lineHeight: TYPE_MARK_SIZE * 1.1
|
|
28743
|
+
},
|
|
28744
|
+
resolution,
|
|
28745
|
+
roundPixels: true
|
|
28746
|
+
});
|
|
28747
|
+
body.mask = clip;
|
|
28748
|
+
body.addChild(cover, coverMask, typeMark, title, excerpt);
|
|
28749
|
+
const tag = createCardTag();
|
|
28750
|
+
root.addChild(plate, body, clip, tag.root);
|
|
28751
|
+
partsByContainer$8.set(root, {
|
|
28752
|
+
tag,
|
|
28896
28753
|
root,
|
|
28897
|
-
|
|
28898
|
-
|
|
28754
|
+
plate,
|
|
28755
|
+
body,
|
|
28756
|
+
clip,
|
|
28757
|
+
cover,
|
|
28758
|
+
coverMask,
|
|
28759
|
+
typeMark,
|
|
28760
|
+
title,
|
|
28761
|
+
excerpt,
|
|
28762
|
+
visualSig: "",
|
|
28763
|
+
textSig: "",
|
|
28764
|
+
titleRes: { resolution },
|
|
28765
|
+
excerptRes: { resolution },
|
|
28766
|
+
typeMarkRes: { resolution }
|
|
28899
28767
|
});
|
|
28900
|
-
if (item.type === "
|
|
28768
|
+
if (item.type === "file") sync$8(root, item, context);
|
|
28901
28769
|
return root;
|
|
28902
28770
|
},
|
|
28903
28771
|
update: (container, item, context) => {
|
|
28904
|
-
if (item.type === "
|
|
28772
|
+
if (item.type === "file") sync$8(container, item, context);
|
|
28773
|
+
},
|
|
28774
|
+
zoom: (container, zoom) => {
|
|
28775
|
+
const tag = partsByContainer$8.get(container)?.tag;
|
|
28776
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
28905
28777
|
},
|
|
28906
28778
|
renderFar: (graphics, item, context) => {
|
|
28907
|
-
|
|
28779
|
+
const category = fileCategory(item.type === "file" ? item.props.src : "", item.type === "file" ? item.props.snapshot?.mimeType : void 0);
|
|
28908
28780
|
drawFarPlate(graphics, item.frame, {
|
|
28909
|
-
fill:
|
|
28910
|
-
fillAlpha: .
|
|
28781
|
+
fill: context.palette.surface,
|
|
28782
|
+
fillAlpha: .96,
|
|
28783
|
+
accent: fileCategoryAccent(category, context.palette),
|
|
28784
|
+
accentAlpha: .45
|
|
28911
28785
|
});
|
|
28912
28786
|
},
|
|
28913
28787
|
destroy: (container) => {
|
|
28914
|
-
partsByContainer$
|
|
28915
|
-
partsByContainer$
|
|
28788
|
+
partsByContainer$8.get(container)?.root.destroy({ children: true });
|
|
28789
|
+
partsByContainer$8.delete(container);
|
|
28916
28790
|
}
|
|
28917
28791
|
};
|
|
28918
28792
|
//#endregion
|
|
28919
28793
|
//#region ../sdk/src/board/render/renderers/frame-card-renderer.ts
|
|
28920
|
-
const partsByContainer$
|
|
28794
|
+
const partsByContainer$7 = /* @__PURE__ */ new WeakMap();
|
|
28921
28795
|
const DEFAULT_WASH = .04;
|
|
28922
|
-
function sync$
|
|
28923
|
-
const parts = partsByContainer$
|
|
28796
|
+
function sync$7(container, item, context) {
|
|
28797
|
+
const parts = partsByContainer$7.get(container);
|
|
28924
28798
|
if (!parts) return;
|
|
28925
28799
|
const { frame, style, props, locked } = item;
|
|
28926
28800
|
positionShell(parts.root, item);
|
|
28927
28801
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
28928
|
-
const selected = context.selectedIds.has(item.id);
|
|
28929
|
-
const hovered = context.hoveredId === item.id;
|
|
28930
28802
|
const fill = itemColor(context, style.fill ?? style.stroke, "neutral", "fill");
|
|
28931
28803
|
const fillAlpha = (style.fillOpacity ?? (style.fill ? 1 : DEFAULT_WASH)) * itemAlpha(context, style.fill ?? style.stroke);
|
|
28932
28804
|
const baseStroke = itemColor(context, style.stroke, "neutral");
|
|
28933
|
-
const
|
|
28934
|
-
const alpha = (selected || style.stroke ? 1 : hovered ? .85 : .55) * itemAlpha(context, style.stroke);
|
|
28805
|
+
const alpha = (style.stroke ? 1 : .55) * itemAlpha(context, style.stroke);
|
|
28935
28806
|
const radius = style.radius ?? 4;
|
|
28936
28807
|
const strokeWidth = style.strokeWidth ?? 1.5;
|
|
28937
28808
|
const decorated = props.decoration !== "none";
|
|
@@ -28939,11 +28810,9 @@ function sync$6(container, item, context) {
|
|
|
28939
28810
|
props.decoration,
|
|
28940
28811
|
frame.width,
|
|
28941
28812
|
frame.height,
|
|
28942
|
-
selected,
|
|
28943
|
-
hovered,
|
|
28944
28813
|
fill,
|
|
28945
28814
|
fillAlpha,
|
|
28946
|
-
|
|
28815
|
+
baseStroke,
|
|
28947
28816
|
alpha,
|
|
28948
28817
|
radius,
|
|
28949
28818
|
strokeWidth,
|
|
@@ -28957,15 +28826,14 @@ function sync$6(container, item, context) {
|
|
|
28957
28826
|
color: fill,
|
|
28958
28827
|
alpha: fillAlpha
|
|
28959
28828
|
});
|
|
28960
|
-
const
|
|
28961
|
-
const
|
|
28962
|
-
|
|
28963
|
-
if ((decorated && strokeWidth > 0 || selected || hovered) && trim > 0) {
|
|
28829
|
+
const pattern = dashPattern(style.dash, strokeWidth);
|
|
28830
|
+
const trim = style.trim ?? 1;
|
|
28831
|
+
if (decorated && strokeWidth > 0 && trim > 0) {
|
|
28964
28832
|
if (pattern || trim < 1) tracePolyline(parts.box, trimPolyline(roundRectPoints(frame.width, frame.height, radius), trim), pattern);
|
|
28965
28833
|
else parts.box.roundRect(0, 0, frame.width, frame.height, radius);
|
|
28966
28834
|
parts.box.stroke({
|
|
28967
|
-
color:
|
|
28968
|
-
width,
|
|
28835
|
+
color: baseStroke,
|
|
28836
|
+
width: strokeWidth,
|
|
28969
28837
|
alpha,
|
|
28970
28838
|
cap: pattern || trim < 1 ? "round" : "butt",
|
|
28971
28839
|
join: "round"
|
|
@@ -28975,11 +28843,16 @@ function sync$6(container, item, context) {
|
|
|
28975
28843
|
parts.label.visible = decorated;
|
|
28976
28844
|
const title = locked ? `🔒 ${props.label}`.trim() : props.label;
|
|
28977
28845
|
const labelColor = style.stroke ? baseStroke : context.palette.muted;
|
|
28978
|
-
const textSig = [
|
|
28846
|
+
const textSig = [
|
|
28847
|
+
title,
|
|
28848
|
+
labelColor,
|
|
28849
|
+
context.style.font
|
|
28850
|
+
].join("|");
|
|
28979
28851
|
if (textSig !== parts.textSig) {
|
|
28980
28852
|
parts.textSig = textSig;
|
|
28981
28853
|
parts.label.text = title;
|
|
28982
28854
|
parts.label.style.fill = labelColor;
|
|
28855
|
+
parts.label.style.fontFamily = context.style.font;
|
|
28983
28856
|
}
|
|
28984
28857
|
parts.label.position.set(4, -18);
|
|
28985
28858
|
}
|
|
@@ -28996,7 +28869,7 @@ const frameCardRenderer = {
|
|
|
28996
28869
|
fontWeight: "600"
|
|
28997
28870
|
});
|
|
28998
28871
|
root.addChild(box, label);
|
|
28999
|
-
partsByContainer$
|
|
28872
|
+
partsByContainer$7.set(root, {
|
|
29000
28873
|
root,
|
|
29001
28874
|
box,
|
|
29002
28875
|
label,
|
|
@@ -29004,11 +28877,11 @@ const frameCardRenderer = {
|
|
|
29004
28877
|
textSig: "",
|
|
29005
28878
|
resolution: label.resolution
|
|
29006
28879
|
});
|
|
29007
|
-
if (item.type === "frame") sync$
|
|
28880
|
+
if (item.type === "frame") sync$7(root, item, context);
|
|
29008
28881
|
return root;
|
|
29009
28882
|
},
|
|
29010
28883
|
update: (container, item, context) => {
|
|
29011
|
-
if (item.type === "frame") sync$
|
|
28884
|
+
if (item.type === "frame") sync$7(container, item, context);
|
|
29012
28885
|
},
|
|
29013
28886
|
renderFar: (graphics, item, context) => {
|
|
29014
28887
|
if (item.type !== "frame" || item.props.decoration === "none") return;
|
|
@@ -29018,14 +28891,14 @@ const frameCardRenderer = {
|
|
|
29018
28891
|
});
|
|
29019
28892
|
},
|
|
29020
28893
|
destroy: (container) => {
|
|
29021
|
-
partsByContainer$
|
|
28894
|
+
partsByContainer$7.delete(container);
|
|
29022
28895
|
container.destroy({ children: true });
|
|
29023
28896
|
}
|
|
29024
28897
|
};
|
|
29025
28898
|
//#endregion
|
|
29026
28899
|
//#region ../sdk/src/board/render/renderers/shape-card-renderer.ts
|
|
29027
28900
|
const DEFAULT_ROUNDED_RADIUS = 8;
|
|
29028
|
-
const partsByContainer$
|
|
28901
|
+
const partsByContainer$6 = /* @__PURE__ */ new WeakMap();
|
|
29029
28902
|
const pathCache = /* @__PURE__ */ new Map();
|
|
29030
28903
|
function parsedPath(d) {
|
|
29031
28904
|
if (pathCache.has(d)) return pathCache.get(d) ?? null;
|
|
@@ -29106,14 +28979,12 @@ function outlinePoints(geometry, width, height, radius) {
|
|
|
29106
28979
|
default: return roundRectPoints(width, height, radius);
|
|
29107
28980
|
}
|
|
29108
28981
|
}
|
|
29109
|
-
function sync$
|
|
29110
|
-
const parts = partsByContainer$
|
|
28982
|
+
function sync$6(container, item, context) {
|
|
28983
|
+
const parts = partsByContainer$6.get(container);
|
|
29111
28984
|
if (!parts) return;
|
|
29112
28985
|
positionShell(parts.root, item);
|
|
29113
28986
|
const { width, height } = item.frame;
|
|
29114
28987
|
const { props, style } = item;
|
|
29115
|
-
const selected = context.selectedIds.has(item.id);
|
|
29116
|
-
const hovered = context.hoveredId === item.id;
|
|
29117
28988
|
const stroke = itemColor(context, style.stroke ?? style.fill, "brand");
|
|
29118
28989
|
const fill = itemColor(context, style.fill ?? style.stroke, "brand", "fill");
|
|
29119
28990
|
const fillOpacity = (style.fillOpacity ?? (style.fill ? 1 : 0)) * itemAlpha(context, style.fill ?? style.stroke);
|
|
@@ -29123,8 +28994,6 @@ function sync$5(container, item, context) {
|
|
|
29123
28994
|
const visualSig = [
|
|
29124
28995
|
width,
|
|
29125
28996
|
height,
|
|
29126
|
-
selected,
|
|
29127
|
-
hovered,
|
|
29128
28997
|
props.geometry,
|
|
29129
28998
|
props.path,
|
|
29130
28999
|
fill,
|
|
@@ -29134,8 +29003,7 @@ function sync$5(container, item, context) {
|
|
|
29134
29003
|
strokeWidth,
|
|
29135
29004
|
style.dash,
|
|
29136
29005
|
style.radius,
|
|
29137
|
-
style.trim
|
|
29138
|
-
context.palette.muted
|
|
29006
|
+
style.trim
|
|
29139
29007
|
].join("|");
|
|
29140
29008
|
if (visualSig !== parts.visualSig) {
|
|
29141
29009
|
parts.visualSig = visualSig;
|
|
@@ -29147,8 +29015,7 @@ function sync$5(container, item, context) {
|
|
|
29147
29015
|
alpha: fillOpacity
|
|
29148
29016
|
});
|
|
29149
29017
|
}
|
|
29150
|
-
const
|
|
29151
|
-
const pattern = dashPattern(style.dash, lineWidth);
|
|
29018
|
+
const pattern = dashPattern(style.dash, strokeWidth);
|
|
29152
29019
|
const partial = style.trim !== void 0 && style.trim < 1;
|
|
29153
29020
|
if (strokeWidth > 0 && (!partial || style.trim)) {
|
|
29154
29021
|
if ((pattern || partial) && props.geometry !== "path") {
|
|
@@ -29156,9 +29023,9 @@ function sync$5(container, item, context) {
|
|
|
29156
29023
|
tracePolyline(parts.shape, trimPolyline(outlinePoints(props.geometry, width, height, radius), style.trim), pattern);
|
|
29157
29024
|
} else traceShapeOutline(parts.shape, props, width, height, style.radius);
|
|
29158
29025
|
parts.shape.stroke({
|
|
29159
|
-
color:
|
|
29160
|
-
width:
|
|
29161
|
-
alpha:
|
|
29026
|
+
color: stroke,
|
|
29027
|
+
width: strokeWidth,
|
|
29028
|
+
alpha: .85 * strokeAlpha,
|
|
29162
29029
|
cap: partial || pattern ? "round" : "butt",
|
|
29163
29030
|
join: "round"
|
|
29164
29031
|
});
|
|
@@ -29189,305 +29056,814 @@ const shapeCardRenderer = {
|
|
|
29189
29056
|
canRender: (item) => item.type === "shape",
|
|
29190
29057
|
create: (item, context) => {
|
|
29191
29058
|
const root = new Container();
|
|
29192
|
-
const shape = new Graphics();
|
|
29193
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
29059
|
+
const shape = new Graphics();
|
|
29060
|
+
const resolution = textResolutionForZoom(context.zoom);
|
|
29061
|
+
const label = new Text({
|
|
29062
|
+
text: "",
|
|
29063
|
+
style: {
|
|
29064
|
+
fill: 16777215,
|
|
29065
|
+
fontFamily: BOARD_FONT_STACK,
|
|
29066
|
+
fontSize: 20,
|
|
29067
|
+
fontWeight: "500",
|
|
29068
|
+
align: "center",
|
|
29069
|
+
wordWrap: true,
|
|
29070
|
+
lineHeight: 28
|
|
29071
|
+
},
|
|
29072
|
+
resolution,
|
|
29073
|
+
roundPixels: true
|
|
29074
|
+
});
|
|
29075
|
+
label.anchor.set(.5);
|
|
29076
|
+
root.addChild(shape, label);
|
|
29077
|
+
partsByContainer$6.set(root, {
|
|
29078
|
+
root,
|
|
29079
|
+
shape,
|
|
29080
|
+
label,
|
|
29081
|
+
visualSig: "",
|
|
29082
|
+
textSig: "",
|
|
29083
|
+
wrapWidth: 0,
|
|
29084
|
+
resolution
|
|
29085
|
+
});
|
|
29086
|
+
if (item.type === "shape") sync$6(root, item, context);
|
|
29087
|
+
return root;
|
|
29088
|
+
},
|
|
29089
|
+
update: (container, item, context) => {
|
|
29090
|
+
if (item.type === "shape") sync$6(container, item, context);
|
|
29091
|
+
},
|
|
29092
|
+
renderFar: (graphics, item, context) => {
|
|
29093
|
+
if (item.type !== "shape") return;
|
|
29094
|
+
drawFarPlate(graphics, item.frame, {
|
|
29095
|
+
fill: itemColor(context, item.style.fill ?? item.style.stroke, "brand", "fill"),
|
|
29096
|
+
fillAlpha: Math.max(.18, item.style.fillOpacity ?? 0) * itemAlpha(context, item.style.fill ?? item.style.stroke),
|
|
29097
|
+
accent: itemColor(context, item.style.stroke, "brand"),
|
|
29098
|
+
accentAlpha: .9 * itemAlpha(context, item.style.stroke)
|
|
29099
|
+
});
|
|
29100
|
+
},
|
|
29101
|
+
destroy: (container) => {
|
|
29102
|
+
partsByContainer$6.get(container)?.root.destroy({ children: true });
|
|
29103
|
+
partsByContainer$6.delete(container);
|
|
29104
|
+
}
|
|
29105
|
+
};
|
|
29106
|
+
//#endregion
|
|
29107
|
+
//#region ../sdk/src/board/render/renderers/custom-card-renderer.ts
|
|
29108
|
+
const partsByContainer$5 = /* @__PURE__ */ new WeakMap();
|
|
29109
|
+
function sync$5(container, item, context) {
|
|
29110
|
+
const parts = partsByContainer$5.get(container);
|
|
29111
|
+
if (!parts) return;
|
|
29112
|
+
if (parts.id !== item.id) {
|
|
29113
|
+
context.scripts?.release(parts.id);
|
|
29114
|
+
parts.id = item.id;
|
|
29115
|
+
}
|
|
29116
|
+
positionShell(parts.root, item);
|
|
29117
|
+
const { width, height } = item.frame;
|
|
29118
|
+
const resolution = Math.min(4, Math.max(.25, context.zoom * getBoardResolution()));
|
|
29119
|
+
const texture = context.scripts?.frame(item, context.time, resolution) ?? null;
|
|
29120
|
+
const error = context.scripts?.error(item.id) ?? null;
|
|
29121
|
+
parts.sprite.visible = Boolean(texture);
|
|
29122
|
+
const display = texture ?? Texture.EMPTY;
|
|
29123
|
+
if (parts.sprite.texture !== display) parts.sprite.texture = display;
|
|
29124
|
+
parts.sprite.width = width;
|
|
29125
|
+
parts.sprite.height = height;
|
|
29126
|
+
const ready = Boolean(texture) || context.scripts?.ready?.(item.id) === true;
|
|
29127
|
+
const message = error ? `${item.script.src}\n${error}` : ready ? "" : item.script.src;
|
|
29128
|
+
const sig = [
|
|
29129
|
+
width,
|
|
29130
|
+
height,
|
|
29131
|
+
Boolean(texture),
|
|
29132
|
+
message,
|
|
29133
|
+
context.themeKey
|
|
29134
|
+
].join("|");
|
|
29135
|
+
if (sig === parts.sig) return;
|
|
29136
|
+
parts.sig = sig;
|
|
29137
|
+
parts.placeholder.clear();
|
|
29138
|
+
if (!ready || error) parts.placeholder.rect(0, 0, width, height).stroke({
|
|
29139
|
+
color: context.palette.border,
|
|
29140
|
+
width: 1,
|
|
29141
|
+
alpha: .8
|
|
29142
|
+
});
|
|
29143
|
+
parts.label.visible = !ready || Boolean(error);
|
|
29144
|
+
parts.label.text = message;
|
|
29145
|
+
parts.label.style.fill = error ? context.colors.rose.stroke : context.palette.muted;
|
|
29146
|
+
parts.label.style.wordWrapWidth = Math.max(40, width - 16);
|
|
29147
|
+
parts.label.position.set(width / 2, height / 2);
|
|
29148
|
+
}
|
|
29149
|
+
const customCardRenderer = {
|
|
29150
|
+
id: "custom-card",
|
|
29151
|
+
canRender: (item) => item.type === "custom",
|
|
29152
|
+
animated: false,
|
|
29153
|
+
create: (item, context) => {
|
|
29154
|
+
const root = new Container();
|
|
29155
|
+
const sprite = new Sprite(Texture.EMPTY);
|
|
29156
|
+
const placeholder = new Graphics();
|
|
29194
29157
|
const label = new Text({
|
|
29195
29158
|
text: "",
|
|
29196
29159
|
style: {
|
|
29197
|
-
|
|
29198
|
-
|
|
29199
|
-
fontSize: 20,
|
|
29200
|
-
fontWeight: "500",
|
|
29160
|
+
fontFamily: BOARD_MONO_FONT_STACK,
|
|
29161
|
+
fontSize: 12,
|
|
29201
29162
|
align: "center",
|
|
29202
29163
|
wordWrap: true,
|
|
29203
|
-
|
|
29164
|
+
breakWords: true
|
|
29204
29165
|
},
|
|
29205
|
-
resolution
|
|
29206
|
-
roundPixels: true
|
|
29166
|
+
resolution: getBoardResolution()
|
|
29207
29167
|
});
|
|
29208
29168
|
label.anchor.set(.5);
|
|
29209
|
-
root.addChild(
|
|
29169
|
+
root.addChild(sprite, placeholder, label);
|
|
29210
29170
|
partsByContainer$5.set(root, {
|
|
29171
|
+
id: item.id,
|
|
29211
29172
|
root,
|
|
29212
|
-
|
|
29173
|
+
sprite,
|
|
29174
|
+
placeholder,
|
|
29213
29175
|
label,
|
|
29214
|
-
|
|
29215
|
-
textSig: "",
|
|
29216
|
-
wrapWidth: 0,
|
|
29217
|
-
resolution
|
|
29176
|
+
sig: ""
|
|
29218
29177
|
});
|
|
29219
|
-
if (item.type === "
|
|
29178
|
+
if (item.type === "custom") sync$5(root, item, context);
|
|
29220
29179
|
return root;
|
|
29221
29180
|
},
|
|
29222
29181
|
update: (container, item, context) => {
|
|
29223
|
-
if (item.type === "
|
|
29182
|
+
if (item.type === "custom") sync$5(container, item, context);
|
|
29224
29183
|
},
|
|
29225
29184
|
renderFar: (graphics, item, context) => {
|
|
29226
|
-
if (item.type !== "shape") return;
|
|
29227
29185
|
drawFarPlate(graphics, item.frame, {
|
|
29228
|
-
fill:
|
|
29229
|
-
fillAlpha:
|
|
29230
|
-
accent: itemColor(context, item.style.stroke, "brand"),
|
|
29231
|
-
accentAlpha: .9 * itemAlpha(context, item.style.stroke)
|
|
29186
|
+
fill: context.palette.muted,
|
|
29187
|
+
fillAlpha: .12
|
|
29232
29188
|
});
|
|
29233
29189
|
},
|
|
29234
|
-
destroy: (container) => {
|
|
29235
|
-
partsByContainer$5.get(container)
|
|
29190
|
+
destroy: (container, context) => {
|
|
29191
|
+
const parts = partsByContainer$5.get(container);
|
|
29192
|
+
if (parts) context.scripts?.release(parts.id);
|
|
29193
|
+
parts?.root.destroy({ children: true });
|
|
29236
29194
|
partsByContainer$5.delete(container);
|
|
29237
29195
|
}
|
|
29238
29196
|
};
|
|
29239
29197
|
//#endregion
|
|
29240
|
-
//#region ../sdk/src/board/render/renderers/
|
|
29198
|
+
//#region ../sdk/src/board/render/renderers/image-card-renderer.ts
|
|
29241
29199
|
const partsByContainer$4 = /* @__PURE__ */ new WeakMap();
|
|
29200
|
+
function cropRect(crop) {
|
|
29201
|
+
if (!crop) return null;
|
|
29202
|
+
const w = Math.min(crop.w, 1 - crop.x);
|
|
29203
|
+
const h = Math.min(crop.h, 1 - crop.y);
|
|
29204
|
+
return w > 0 && h > 0 ? {
|
|
29205
|
+
x: crop.x,
|
|
29206
|
+
y: crop.y,
|
|
29207
|
+
w,
|
|
29208
|
+
h
|
|
29209
|
+
} : null;
|
|
29210
|
+
}
|
|
29211
|
+
function showTexture(parts, texture, crop) {
|
|
29212
|
+
const rect = texture ? cropRect(crop) : null;
|
|
29213
|
+
const key = rect ? `${rect.x}|${rect.y}|${rect.w}|${rect.h}` : "";
|
|
29214
|
+
const previous = parts.cropped;
|
|
29215
|
+
const reusable = previous && parts.cropSource === texture && parts.cropKey === key;
|
|
29216
|
+
if (texture && rect && !reusable) {
|
|
29217
|
+
const { frame } = texture;
|
|
29218
|
+
const width = Math.max(1, frame.width * rect.w);
|
|
29219
|
+
const height = Math.max(1, frame.height * rect.h);
|
|
29220
|
+
const x = frame.x + Math.min(frame.width * rect.x, frame.width - width);
|
|
29221
|
+
const y = frame.y + Math.min(frame.height * rect.y, frame.height - height);
|
|
29222
|
+
parts.cropped = new Texture({
|
|
29223
|
+
source: texture.source,
|
|
29224
|
+
frame: new Rectangle(x, y, width, height)
|
|
29225
|
+
});
|
|
29226
|
+
} else if (!rect) parts.cropped = null;
|
|
29227
|
+
parts.cropSource = rect ? texture : null;
|
|
29228
|
+
parts.cropKey = key;
|
|
29229
|
+
const display = parts.cropped ?? texture ?? Texture.EMPTY;
|
|
29230
|
+
if (parts.sprite.texture !== display) parts.sprite.texture = display;
|
|
29231
|
+
if (previous && previous !== parts.cropped) previous.destroy(false);
|
|
29232
|
+
}
|
|
29233
|
+
const PRINT_MARGIN = 6;
|
|
29242
29234
|
function sync$4(container, item, context) {
|
|
29243
29235
|
const parts = partsByContainer$4.get(container);
|
|
29244
29236
|
if (!parts) return;
|
|
29245
|
-
|
|
29246
|
-
|
|
29247
|
-
|
|
29237
|
+
positionShell(parts.root, item);
|
|
29238
|
+
const { width, height } = item.frame;
|
|
29239
|
+
const key = context.assetKey(item);
|
|
29240
|
+
const texture = key ? context.getTexture(key) : null;
|
|
29241
|
+
const failed = Boolean(key && !texture && context.hasError(key));
|
|
29242
|
+
const elevation = cardElevation(context, item.id);
|
|
29243
|
+
const sig = [
|
|
29244
|
+
key ?? "",
|
|
29245
|
+
width,
|
|
29246
|
+
height,
|
|
29247
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29248
|
+
JSON.stringify(item.props.crop ?? null),
|
|
29249
|
+
failed,
|
|
29250
|
+
elevation,
|
|
29251
|
+
context.themeKey
|
|
29252
|
+
].join("|");
|
|
29253
|
+
if (sig === parts.sig) return;
|
|
29254
|
+
parts.sig = sig;
|
|
29255
|
+
showTexture(parts, texture, item.props.crop);
|
|
29256
|
+
const display = parts.sprite.texture;
|
|
29257
|
+
const framed = context.style.media === "framed";
|
|
29258
|
+
const margin = framed ? Math.min(PRINT_MARGIN, width / 8, height / 8) : 0;
|
|
29259
|
+
const area = {
|
|
29260
|
+
x: margin,
|
|
29261
|
+
y: margin,
|
|
29262
|
+
width: width - margin * 2,
|
|
29263
|
+
height: height - margin * 2
|
|
29264
|
+
};
|
|
29265
|
+
const fitted = texture ? containRect(area.width, area.height, display.width, display.height) : {
|
|
29266
|
+
...area,
|
|
29267
|
+
x: 0,
|
|
29268
|
+
y: 0
|
|
29269
|
+
};
|
|
29270
|
+
const picture = {
|
|
29271
|
+
x: area.x + fitted.x,
|
|
29272
|
+
y: area.y + fitted.y,
|
|
29273
|
+
width: fitted.width,
|
|
29274
|
+
height: fitted.height
|
|
29275
|
+
};
|
|
29276
|
+
const card = framed ? {
|
|
29277
|
+
x: picture.x - margin,
|
|
29278
|
+
y: picture.y - margin,
|
|
29279
|
+
width: picture.width + margin * 2,
|
|
29280
|
+
height: picture.height + margin * 2
|
|
29281
|
+
} : picture;
|
|
29282
|
+
parts.sprite.visible = Boolean(texture);
|
|
29283
|
+
if (texture) {
|
|
29284
|
+
parts.sprite.position.set(picture.x, picture.y);
|
|
29285
|
+
parts.sprite.width = picture.width;
|
|
29286
|
+
parts.sprite.height = picture.height;
|
|
29287
|
+
}
|
|
29288
|
+
traceCardOutline(parts.mask.clear(), picture, framed ? {
|
|
29289
|
+
corner: "round",
|
|
29290
|
+
radius: 0
|
|
29291
|
+
} : context.style).fill({ color: 16777215 });
|
|
29292
|
+
parts.placeholder.clear();
|
|
29293
|
+
if (texture && !framed) return;
|
|
29294
|
+
drawCardSurface(parts.placeholder, card, context.style, {
|
|
29295
|
+
fill: context.palette.surface,
|
|
29296
|
+
border: texture ? null : failed ? context.palette.border : context.palette.hover,
|
|
29297
|
+
elevation
|
|
29298
|
+
});
|
|
29299
|
+
if (texture) return;
|
|
29300
|
+
const cx = width / 2;
|
|
29301
|
+
const cy = height / 2;
|
|
29302
|
+
if (failed) parts.placeholder.moveTo(cx - 10, cy - 10).lineTo(cx + 10, cy + 10).moveTo(cx + 10, cy - 10).lineTo(cx - 10, cy + 10).stroke({
|
|
29303
|
+
color: context.palette.muted,
|
|
29304
|
+
width: 1.5,
|
|
29305
|
+
alpha: .8
|
|
29306
|
+
});
|
|
29307
|
+
else parts.placeholder.circle(cx, cy, 6).stroke({
|
|
29308
|
+
color: context.palette.muted,
|
|
29309
|
+
width: 1.25,
|
|
29310
|
+
alpha: .55
|
|
29311
|
+
});
|
|
29312
|
+
}
|
|
29313
|
+
const imageCardRenderer = {
|
|
29314
|
+
id: "image-card",
|
|
29315
|
+
canRender: (item) => item.type === "image",
|
|
29316
|
+
create: (item, context) => {
|
|
29317
|
+
const root = new Container();
|
|
29318
|
+
const sprite = new Sprite(Texture.EMPTY);
|
|
29319
|
+
const placeholder = new Graphics();
|
|
29320
|
+
const mask = new Graphics();
|
|
29321
|
+
root.addChild(placeholder, sprite, mask);
|
|
29322
|
+
sprite.mask = mask;
|
|
29323
|
+
partsByContainer$4.set(root, {
|
|
29324
|
+
root,
|
|
29325
|
+
sprite,
|
|
29326
|
+
placeholder,
|
|
29327
|
+
mask,
|
|
29328
|
+
sig: "",
|
|
29329
|
+
cropped: null,
|
|
29330
|
+
cropSource: null,
|
|
29331
|
+
cropKey: ""
|
|
29332
|
+
});
|
|
29333
|
+
if (item.type === "image") sync$4(root, item, context);
|
|
29334
|
+
return root;
|
|
29335
|
+
},
|
|
29336
|
+
update: (container, item, context) => {
|
|
29337
|
+
if (item.type === "image") sync$4(container, item, context);
|
|
29338
|
+
},
|
|
29339
|
+
renderFar: (graphics, item, context) => {
|
|
29340
|
+
drawFarPlate(graphics, item.frame, {
|
|
29341
|
+
fill: context.palette.hover,
|
|
29342
|
+
fillAlpha: .9
|
|
29343
|
+
});
|
|
29344
|
+
},
|
|
29345
|
+
destroy: (container) => {
|
|
29346
|
+
const parts = partsByContainer$4.get(container);
|
|
29347
|
+
parts?.root.destroy({ children: true });
|
|
29348
|
+
parts?.cropped?.destroy(false);
|
|
29349
|
+
partsByContainer$4.delete(container);
|
|
29350
|
+
}
|
|
29351
|
+
};
|
|
29352
|
+
//#endregion
|
|
29353
|
+
//#region ../sdk/src/board/render/renderers/task-card-renderer.ts
|
|
29354
|
+
const PADDING = 12;
|
|
29355
|
+
const META_HEIGHT = 28;
|
|
29356
|
+
const PLAY_BADGE_RADIUS = 15;
|
|
29357
|
+
const SHIMMER_PERIOD_MS = 1600;
|
|
29358
|
+
const SHIMMER_FRAME_MS = 33;
|
|
29359
|
+
const REVEAL_MS = 180;
|
|
29360
|
+
const SECOND = 1e3;
|
|
29361
|
+
const partsByContainer$3 = /* @__PURE__ */ new WeakMap();
|
|
29362
|
+
function previewKindFor(artifact) {
|
|
29363
|
+
if (!artifact) return "empty";
|
|
29364
|
+
if (artifact.type === "image" || artifact.type === "video") return "texture";
|
|
29365
|
+
if (artifact.type === "audio") return artifact.previewUrl ? "texture" : "waveform";
|
|
29366
|
+
return artifact.textExcerpt ? "text" : "empty";
|
|
29367
|
+
}
|
|
29368
|
+
function liveStatus(item, context) {
|
|
29369
|
+
const { snapshot } = item.props;
|
|
29370
|
+
const live = snapshot.status === "completed" ? null : context.taskRun(item.props.taskRunId);
|
|
29371
|
+
const liveStart = Date.parse(live?.startedAt ?? "");
|
|
29372
|
+
const working = live?.status === "pending" || live?.status === "running";
|
|
29373
|
+
const adopt = snapshot.status === "failed" ? working && liveStart > Date.parse(snapshot.updatedAt ?? "") : live?.status === "running" || live?.status === "pending" && snapshot.status === "pending";
|
|
29374
|
+
const status = adopt && live ? live.status : snapshot.status;
|
|
29375
|
+
const started = adopt ? liveStart : Date.parse(snapshot.startedAt ?? "");
|
|
29376
|
+
return {
|
|
29377
|
+
status,
|
|
29378
|
+
startedAt: Number.isFinite(started) ? started : null
|
|
29379
|
+
};
|
|
29380
|
+
}
|
|
29381
|
+
function stateSurfaceFor(status, kind, hasTexture, previewFailed) {
|
|
29382
|
+
if (kind === "texture" && !hasTexture) {
|
|
29383
|
+
if (status === "failed") return "failed";
|
|
29384
|
+
return previewFailed ? "unavailable" : "media-loading";
|
|
29385
|
+
}
|
|
29386
|
+
if (kind !== "empty") return null;
|
|
29387
|
+
if (status === "failed") return "failed";
|
|
29388
|
+
if (status === "running") return "generating";
|
|
29389
|
+
if (status === "pending") return "queued";
|
|
29390
|
+
return "empty";
|
|
29391
|
+
}
|
|
29392
|
+
function stateLabel(surface, context) {
|
|
29393
|
+
switch (surface) {
|
|
29394
|
+
case "generating": return context.labels.generating;
|
|
29395
|
+
case "queued": return context.labels.queued;
|
|
29396
|
+
case "failed": return context.labels.failed;
|
|
29397
|
+
case "unavailable": return context.labels.previewUnavailable;
|
|
29398
|
+
case "empty": return context.labels.noPreview;
|
|
29399
|
+
default: return "";
|
|
29400
|
+
}
|
|
29401
|
+
}
|
|
29402
|
+
function statusColor(status, context) {
|
|
29403
|
+
if (status === "failed") return context.colors.rose.stroke;
|
|
29404
|
+
if (status === "running") return context.colors.brand.stroke;
|
|
29405
|
+
return context.colors.neutral.stroke;
|
|
29406
|
+
}
|
|
29407
|
+
function drawPlayBadge(graphics, rect, context) {
|
|
29408
|
+
const radius = Math.min(PLAY_BADGE_RADIUS, Math.max(8, Math.min(rect.width, rect.height) * .16));
|
|
29409
|
+
const cx = rect.x + rect.width / 2;
|
|
29410
|
+
const cy = rect.y + rect.height / 2;
|
|
29411
|
+
graphics.circle(cx, cy, radius).fill({
|
|
29412
|
+
color: context.palette.bg,
|
|
29413
|
+
alpha: .64
|
|
29414
|
+
});
|
|
29415
|
+
const size = radius * .72;
|
|
29416
|
+
graphics.moveTo(cx - size * .34, cy - size * .56).lineTo(cx + size * .62, cy).lineTo(cx - size * .34, cy + size * .56).closePath().fill({
|
|
29417
|
+
color: context.palette.text,
|
|
29418
|
+
alpha: .94
|
|
29419
|
+
});
|
|
29420
|
+
}
|
|
29421
|
+
function drawStateMark(graphics, surface, cx, cy, color) {
|
|
29422
|
+
if (surface === "generating" || surface === "media-loading") {
|
|
29423
|
+
graphics.circle(cx, cy, 4).fill({
|
|
29424
|
+
color,
|
|
29425
|
+
alpha: .9
|
|
29426
|
+
});
|
|
29427
|
+
graphics.circle(cx - 12, cy + 7, 2.5).fill({
|
|
29428
|
+
color,
|
|
29429
|
+
alpha: .48
|
|
29430
|
+
});
|
|
29431
|
+
graphics.circle(cx + 11, cy + 6, 3).fill({
|
|
29432
|
+
color,
|
|
29433
|
+
alpha: .68
|
|
29434
|
+
});
|
|
29435
|
+
graphics.circle(cx + 3, cy - 12, 2).fill({
|
|
29436
|
+
color,
|
|
29437
|
+
alpha: .36
|
|
29438
|
+
});
|
|
29439
|
+
return;
|
|
29440
|
+
}
|
|
29441
|
+
if (surface === "queued") {
|
|
29442
|
+
graphics.circle(cx, cy, 10).stroke({
|
|
29443
|
+
color,
|
|
29444
|
+
width: 1.5,
|
|
29445
|
+
alpha: .62
|
|
29446
|
+
}).circle(cx, cy, 3).fill({
|
|
29447
|
+
color,
|
|
29448
|
+
alpha: .78
|
|
29449
|
+
});
|
|
29450
|
+
return;
|
|
29451
|
+
}
|
|
29452
|
+
if (surface === "failed") {
|
|
29453
|
+
graphics.circle(cx, cy, 11).stroke({
|
|
29454
|
+
color,
|
|
29455
|
+
width: 1.5,
|
|
29456
|
+
alpha: .86
|
|
29457
|
+
});
|
|
29458
|
+
graphics.moveTo(cx - 4, cy - 4).lineTo(cx + 4, cy + 4).moveTo(cx + 4, cy - 4).lineTo(cx - 4, cy + 4).stroke({
|
|
29459
|
+
color,
|
|
29460
|
+
width: 1.5,
|
|
29461
|
+
alpha: .94,
|
|
29462
|
+
cap: "round"
|
|
29463
|
+
});
|
|
29464
|
+
return;
|
|
29248
29465
|
}
|
|
29249
|
-
|
|
29250
|
-
|
|
29251
|
-
|
|
29252
|
-
|
|
29253
|
-
|
|
29254
|
-
|
|
29255
|
-
|
|
29256
|
-
|
|
29257
|
-
|
|
29258
|
-
parts.sprite.height = height;
|
|
29259
|
-
const selected = context.selectedIds.has(item.id);
|
|
29260
|
-
const ready = Boolean(texture) || context.scripts?.ready?.(item.id) === true;
|
|
29261
|
-
const message = error ? `${item.script.src}\n${error}` : ready ? "" : item.script.src;
|
|
29262
|
-
const sig = [
|
|
29263
|
-
width,
|
|
29264
|
-
height,
|
|
29265
|
-
selected,
|
|
29266
|
-
Boolean(texture),
|
|
29267
|
-
message,
|
|
29268
|
-
context.palette.border,
|
|
29269
|
-
context.palette.muted
|
|
29270
|
-
].join("|");
|
|
29271
|
-
if (sig === parts.sig) return;
|
|
29272
|
-
parts.sig = sig;
|
|
29273
|
-
parts.placeholder.clear();
|
|
29274
|
-
if (!ready || selected || error) parts.placeholder.rect(0, 0, width, height).stroke({
|
|
29275
|
-
color: selected ? context.palette.brand : context.palette.border,
|
|
29276
|
-
width: selected ? 2 : 1,
|
|
29277
|
-
alpha: .8
|
|
29466
|
+
if (surface === "unavailable") graphics.roundRect(cx - 12, cy - 9, 24, 18, 3).stroke({
|
|
29467
|
+
color,
|
|
29468
|
+
width: 1.25,
|
|
29469
|
+
alpha: .62
|
|
29470
|
+
}).moveTo(cx - 8, cy + 5).lineTo(cx + 8, cy - 5).stroke({
|
|
29471
|
+
color,
|
|
29472
|
+
width: 1.25,
|
|
29473
|
+
alpha: .72,
|
|
29474
|
+
cap: "round"
|
|
29278
29475
|
});
|
|
29279
|
-
parts.label.visible = !ready || Boolean(error);
|
|
29280
|
-
parts.label.text = message;
|
|
29281
|
-
parts.label.style.fill = error ? context.colors.rose.stroke : context.palette.muted;
|
|
29282
|
-
parts.label.style.wordWrapWidth = Math.max(40, width - 16);
|
|
29283
|
-
parts.label.position.set(width / 2, height / 2);
|
|
29284
29476
|
}
|
|
29285
|
-
|
|
29286
|
-
|
|
29287
|
-
|
|
29288
|
-
|
|
29289
|
-
|
|
29290
|
-
|
|
29291
|
-
|
|
29292
|
-
|
|
29293
|
-
|
|
29294
|
-
|
|
29295
|
-
|
|
29296
|
-
|
|
29297
|
-
|
|
29298
|
-
|
|
29299
|
-
|
|
29300
|
-
|
|
29477
|
+
function drawFailedBadge(graphics, width, color, context) {
|
|
29478
|
+
const cx = Math.max(12, width - 12);
|
|
29479
|
+
graphics.circle(cx, 12, 8).fill({
|
|
29480
|
+
color: context.palette.bg,
|
|
29481
|
+
alpha: .72
|
|
29482
|
+
});
|
|
29483
|
+
graphics.moveTo(cx - 2.5, 9.5).lineTo(cx + 2.5, 14.5).moveTo(cx + 2.5, 9.5).lineTo(cx - 2.5, 14.5).stroke({
|
|
29484
|
+
color,
|
|
29485
|
+
width: 1.5,
|
|
29486
|
+
alpha: .96,
|
|
29487
|
+
cap: "round"
|
|
29488
|
+
});
|
|
29489
|
+
}
|
|
29490
|
+
const shimmerGradients = /* @__PURE__ */ new Map();
|
|
29491
|
+
function shimmerGradient(color) {
|
|
29492
|
+
let gradient = shimmerGradients.get(color);
|
|
29493
|
+
if (!gradient) {
|
|
29494
|
+
const rgb = `${color >> 16 & 255}, ${color >> 8 & 255}, ${color & 255}`;
|
|
29495
|
+
gradient = new FillGradient({
|
|
29496
|
+
type: "linear",
|
|
29497
|
+
start: {
|
|
29498
|
+
x: 0,
|
|
29499
|
+
y: 0
|
|
29301
29500
|
},
|
|
29302
|
-
|
|
29303
|
-
|
|
29304
|
-
|
|
29305
|
-
|
|
29306
|
-
|
|
29307
|
-
|
|
29308
|
-
|
|
29309
|
-
|
|
29310
|
-
|
|
29311
|
-
|
|
29312
|
-
|
|
29313
|
-
|
|
29314
|
-
|
|
29315
|
-
|
|
29316
|
-
|
|
29317
|
-
|
|
29318
|
-
|
|
29319
|
-
|
|
29320
|
-
|
|
29321
|
-
drawFarPlate(graphics, item.frame, {
|
|
29322
|
-
fill: context.palette.muted,
|
|
29323
|
-
fillAlpha: .12
|
|
29501
|
+
end: {
|
|
29502
|
+
x: 1,
|
|
29503
|
+
y: 0
|
|
29504
|
+
},
|
|
29505
|
+
textureSpace: "local",
|
|
29506
|
+
colorStops: [
|
|
29507
|
+
{
|
|
29508
|
+
offset: 0,
|
|
29509
|
+
color: `rgba(${rgb}, 0)`
|
|
29510
|
+
},
|
|
29511
|
+
{
|
|
29512
|
+
offset: .5,
|
|
29513
|
+
color: `rgba(${rgb}, 0.07)`
|
|
29514
|
+
},
|
|
29515
|
+
{
|
|
29516
|
+
offset: 1,
|
|
29517
|
+
color: `rgba(${rgb}, 0)`
|
|
29518
|
+
}
|
|
29519
|
+
]
|
|
29324
29520
|
});
|
|
29325
|
-
|
|
29326
|
-
destroy: (container, context) => {
|
|
29327
|
-
const parts = partsByContainer$4.get(container);
|
|
29328
|
-
if (parts) context.scripts?.release(parts.id);
|
|
29329
|
-
parts?.root.destroy({ children: true });
|
|
29330
|
-
partsByContainer$4.delete(container);
|
|
29521
|
+
shimmerGradients.set(color, gradient);
|
|
29331
29522
|
}
|
|
29332
|
-
|
|
29333
|
-
//#endregion
|
|
29334
|
-
//#region ../sdk/src/board/render/renderers/image-card-renderer.ts
|
|
29335
|
-
const partsByContainer$3 = /* @__PURE__ */ new WeakMap();
|
|
29336
|
-
const RADIUS$2 = 2;
|
|
29337
|
-
function layoutContain$1(sprite, width, height) {
|
|
29338
|
-
const texture = sprite.texture;
|
|
29339
|
-
const tw = texture.width;
|
|
29340
|
-
const th = texture.height;
|
|
29341
|
-
if (!tw || !th) return;
|
|
29342
|
-
const scale = Math.min(width / tw, height / th);
|
|
29343
|
-
sprite.width = tw * scale;
|
|
29344
|
-
sprite.height = th * scale;
|
|
29345
|
-
sprite.x = (width - sprite.width) / 2;
|
|
29346
|
-
sprite.y = (height - sprite.height) / 2;
|
|
29523
|
+
return gradient;
|
|
29347
29524
|
}
|
|
29348
|
-
function
|
|
29349
|
-
|
|
29350
|
-
|
|
29351
|
-
const h = Math.min(crop.h, 1 - crop.y);
|
|
29352
|
-
return w > 0 && h > 0 ? {
|
|
29353
|
-
x: crop.x,
|
|
29354
|
-
y: crop.y,
|
|
29355
|
-
w,
|
|
29356
|
-
h
|
|
29357
|
-
} : null;
|
|
29525
|
+
function drawShimmerBand(graphics, width, height, color) {
|
|
29526
|
+
const band = Math.max(48, width * .45);
|
|
29527
|
+
graphics.clear().rect(-band, 0, band, height).fill(shimmerGradient(color));
|
|
29358
29528
|
}
|
|
29359
|
-
|
|
29360
|
-
|
|
29361
|
-
|
|
29362
|
-
const
|
|
29363
|
-
const
|
|
29364
|
-
|
|
29365
|
-
|
|
29366
|
-
|
|
29367
|
-
|
|
29368
|
-
|
|
29369
|
-
|
|
29370
|
-
|
|
29371
|
-
|
|
29372
|
-
|
|
29529
|
+
const MOSAIC_FRAME_MS = 160;
|
|
29530
|
+
const MOSAIC_CELL = 8;
|
|
29531
|
+
function drawMosaic(graphics, width, height, color, frame) {
|
|
29532
|
+
const columns = Math.max(1, Math.floor(width / MOSAIC_CELL));
|
|
29533
|
+
const rows = Math.max(1, Math.floor(height / MOSAIC_CELL));
|
|
29534
|
+
const left = (width - columns * MOSAIC_CELL) / 2;
|
|
29535
|
+
const top = (height - rows * MOSAIC_CELL) / 2;
|
|
29536
|
+
graphics.clear();
|
|
29537
|
+
for (const [threshold, alpha] of [[.08, .16], [.02, .3]]) {
|
|
29538
|
+
for (let row = 0; row < rows; row += 1) for (let column = 0; column < columns; column += 1) {
|
|
29539
|
+
let hash = Math.imul(column + 1, 2654435761) ^ Math.imul(row + 1, 2246822507) ^ Math.imul(frame + 1, 3266489909);
|
|
29540
|
+
hash ^= hash >>> 15;
|
|
29541
|
+
hash = Math.imul(hash, 739982445);
|
|
29542
|
+
hash ^= hash >>> 12;
|
|
29543
|
+
if ((hash >>> 0) / 4294967295 < threshold) graphics.rect(left + column * MOSAIC_CELL + 1, top + row * MOSAIC_CELL + 1, 6, 6);
|
|
29544
|
+
}
|
|
29545
|
+
graphics.fill({
|
|
29546
|
+
color,
|
|
29547
|
+
alpha
|
|
29373
29548
|
});
|
|
29374
|
-
}
|
|
29375
|
-
|
|
29376
|
-
|
|
29377
|
-
const
|
|
29378
|
-
|
|
29379
|
-
if (
|
|
29549
|
+
}
|
|
29550
|
+
}
|
|
29551
|
+
function advance(parts, clock) {
|
|
29552
|
+
const { motion } = parts;
|
|
29553
|
+
let next = null;
|
|
29554
|
+
if (motion.mosaic) {
|
|
29555
|
+
const frame = Math.floor(clock / MOSAIC_FRAME_MS);
|
|
29556
|
+
if (frame !== motion.mosaic.step) {
|
|
29557
|
+
motion.mosaic.step = frame;
|
|
29558
|
+
drawMosaic(parts.shimmer, motion.width, motion.mosaic.height, motion.mosaic.color, frame);
|
|
29559
|
+
}
|
|
29560
|
+
next = MOSAIC_FRAME_MS - clock % MOSAIC_FRAME_MS;
|
|
29561
|
+
} else if (motion.shimmer) {
|
|
29562
|
+
const travel = motion.width + parts.shimmer.width;
|
|
29563
|
+
parts.shimmer.x = clock % SHIMMER_PERIOD_MS / SHIMMER_PERIOD_MS * travel;
|
|
29564
|
+
next = SHIMMER_FRAME_MS;
|
|
29565
|
+
}
|
|
29566
|
+
if (motion.startedAt !== null) {
|
|
29567
|
+
const elapsedMs = Date.now() - motion.startedAt;
|
|
29568
|
+
const elapsed = formatBoardDuration(elapsedMs);
|
|
29569
|
+
if (elapsed !== motion.elapsed) {
|
|
29570
|
+
motion.elapsed = elapsed;
|
|
29571
|
+
parts.body.text = `${motion.label} · ${elapsed}`;
|
|
29572
|
+
}
|
|
29573
|
+
const untilNextSecond = SECOND - Math.max(0, elapsedMs) % SECOND;
|
|
29574
|
+
next = next === null ? untilNextSecond : Math.min(next, untilNextSecond);
|
|
29575
|
+
}
|
|
29576
|
+
if (motion.revealFrom !== null) {
|
|
29577
|
+
const progress = Math.min(1, (clock - motion.revealFrom) / REVEAL_MS);
|
|
29578
|
+
parts.preview.alpha = progress * (2 - progress);
|
|
29579
|
+
if (progress >= 1) motion.revealFrom = null;
|
|
29580
|
+
else next = 0;
|
|
29581
|
+
}
|
|
29582
|
+
return next;
|
|
29380
29583
|
}
|
|
29381
29584
|
function sync$3(container, item, context) {
|
|
29382
29585
|
const parts = partsByContainer$3.get(container);
|
|
29383
29586
|
if (!parts) return;
|
|
29384
29587
|
positionShell(parts.root, item);
|
|
29385
29588
|
const { width, height } = item.frame;
|
|
29386
|
-
const
|
|
29387
|
-
const
|
|
29589
|
+
const { snapshot } = item.props;
|
|
29590
|
+
const { status, startedAt } = liveStatus(item, context);
|
|
29591
|
+
const full = boardCardDetailed(context.zoom);
|
|
29592
|
+
const elevation = cardElevation(context, item.id);
|
|
29593
|
+
syncCardTag(parts.tag, {
|
|
29594
|
+
glyph: "task",
|
|
29595
|
+
text: snapshot.title,
|
|
29596
|
+
width
|
|
29597
|
+
}, context);
|
|
29598
|
+
const working = status === "pending" || status === "running";
|
|
29599
|
+
const color = statusColor(status, context);
|
|
29388
29600
|
const key = context.assetKey(item);
|
|
29601
|
+
if (key !== parts.assetKey) {
|
|
29602
|
+
if (parts.assetKey) context.releaseTexture(parts.assetKey);
|
|
29603
|
+
parts.assetKey = key;
|
|
29604
|
+
if (key) context.acquireTexture(key);
|
|
29605
|
+
}
|
|
29389
29606
|
const texture = key ? context.getTexture(key) : null;
|
|
29390
|
-
const
|
|
29391
|
-
const
|
|
29392
|
-
const
|
|
29393
|
-
|
|
29607
|
+
const previewFailed = Boolean(key && !texture && context.hasError(key));
|
|
29608
|
+
const artifact = featuredTaskArtifact(snapshot.artifacts);
|
|
29609
|
+
const kind = previewKindFor(artifact);
|
|
29610
|
+
const surface = stateSurfaceFor(status, kind, Boolean(texture), previewFailed);
|
|
29611
|
+
const frame = {
|
|
29612
|
+
x: 1,
|
|
29613
|
+
y: 1,
|
|
29614
|
+
width: Math.max(1, width - 2),
|
|
29615
|
+
height: Math.max(1, height - 2)
|
|
29616
|
+
};
|
|
29617
|
+
const metaText = artifact || working ? snapshot.model ?? "" : "";
|
|
29618
|
+
const showMeta = full && Boolean(metaText);
|
|
29619
|
+
const failedWithOutput = status === "failed" && kind !== "empty";
|
|
29620
|
+
const count = artifact && snapshot.artifactCount > 1 ? String(snapshot.artifactCount) : "";
|
|
29621
|
+
const showBadge = full && Boolean(count);
|
|
29622
|
+
const label = stateLabel(surface, context);
|
|
29623
|
+
const counting = full && working && startedAt !== null && surface !== null;
|
|
29624
|
+
const elapsed = counting ? formatBoardDuration(Date.now() - startedAt) : "";
|
|
29625
|
+
const detailText = !full || !surface ? "" : status === "failed" ? snapshot.errorExcerpt ?? "" : working ? snapshot.promptExcerpt ?? "" : "";
|
|
29626
|
+
const textArtifact = kind === "text" && artifact?.type === "text";
|
|
29627
|
+
const bodyText = textArtifact ? artifact.textExcerpt : counting ? `${label} · ${elapsed}` : label;
|
|
29628
|
+
syncTextResolution(parts.body, parts, context.zoom);
|
|
29629
|
+
syncTextResolution(parts.detail, parts, context.zoom);
|
|
29630
|
+
syncTextResolution(parts.meta, parts, context.zoom);
|
|
29631
|
+
syncTextResolution(parts.badge, parts, context.zoom);
|
|
29632
|
+
const textSig = [
|
|
29633
|
+
counting ? label : bodyText,
|
|
29634
|
+
detailText,
|
|
29635
|
+
metaText,
|
|
29636
|
+
count,
|
|
29637
|
+
kind,
|
|
29638
|
+
surface,
|
|
29639
|
+
full,
|
|
29640
|
+
width,
|
|
29641
|
+
height,
|
|
29642
|
+
color,
|
|
29643
|
+
context.palette.text,
|
|
29644
|
+
context.palette.muted,
|
|
29645
|
+
context.style.font
|
|
29646
|
+
].join("|");
|
|
29647
|
+
if (textSig !== parts.textSig) {
|
|
29648
|
+
parts.textSig = textSig;
|
|
29649
|
+
parts.body.style.fontFamily = context.style.font;
|
|
29650
|
+
parts.detail.style.fontFamily = context.style.font;
|
|
29651
|
+
const wrap = Math.max(24, width - 24);
|
|
29652
|
+
parts.body.style.fill = surface === "failed" ? color : context.palette.text;
|
|
29653
|
+
parts.body.anchor.set(textArtifact ? 0 : .5, 0);
|
|
29654
|
+
fitTextToLines(parts.body, bodyText, textArtifact ? Math.max(1, Math.floor((height - 24 - (showMeta ? META_HEIGHT : 0)) / 16)) : 1, wrap);
|
|
29655
|
+
parts.detail.style.fill = context.palette.muted;
|
|
29656
|
+
fitTextToLines(parts.detail, detailText, height - 24 > 120 ? 2 : 1, Math.min(wrap, 360));
|
|
29657
|
+
parts.meta.style.fill = context.palette.text;
|
|
29658
|
+
fitTextToLines(parts.meta, metaText, 1, wrap);
|
|
29659
|
+
parts.badge.style.fill = context.palette.text;
|
|
29660
|
+
if (parts.badge.text !== count) parts.badge.text = count;
|
|
29661
|
+
}
|
|
29662
|
+
const badgeWidth = Math.max(22, parts.badge.width + 12);
|
|
29663
|
+
const visualSig = [
|
|
29394
29664
|
width,
|
|
29395
29665
|
height,
|
|
29396
|
-
|
|
29397
|
-
|
|
29398
|
-
|
|
29399
|
-
|
|
29400
|
-
|
|
29401
|
-
|
|
29666
|
+
full,
|
|
29667
|
+
elevation,
|
|
29668
|
+
color,
|
|
29669
|
+
kind,
|
|
29670
|
+
surface,
|
|
29671
|
+
showMeta,
|
|
29672
|
+
showBadge && badgeWidth,
|
|
29673
|
+
failedWithOutput,
|
|
29674
|
+
artifact?.type ?? "none",
|
|
29675
|
+
artifact?.id ?? "none",
|
|
29676
|
+
item.props.taskRunId,
|
|
29677
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29678
|
+
context.themeKey
|
|
29402
29679
|
].join("|");
|
|
29403
|
-
if (
|
|
29404
|
-
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
|
|
29409
|
-
|
|
29410
|
-
|
|
29411
|
-
|
|
29412
|
-
|
|
29413
|
-
|
|
29414
|
-
|
|
29415
|
-
|
|
29416
|
-
alpha: .9
|
|
29680
|
+
if (visualSig !== parts.visualSig) {
|
|
29681
|
+
parts.visualSig = visualSig;
|
|
29682
|
+
const rect = {
|
|
29683
|
+
x: 0,
|
|
29684
|
+
y: 0,
|
|
29685
|
+
width,
|
|
29686
|
+
height
|
|
29687
|
+
};
|
|
29688
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
29689
|
+
fill: context.palette.surface,
|
|
29690
|
+
border: context.palette.border,
|
|
29691
|
+
borderAlpha: .82,
|
|
29692
|
+
elevation
|
|
29417
29693
|
});
|
|
29418
|
-
|
|
29419
|
-
|
|
29420
|
-
|
|
29421
|
-
|
|
29422
|
-
width: 1.5,
|
|
29423
|
-
alpha: .8
|
|
29694
|
+
traceCardOutline(parts.clip.clear(), rect, context.style, -1).fill({ color: 16777215 });
|
|
29695
|
+
parts.previewBg.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({
|
|
29696
|
+
color: context.palette.hover,
|
|
29697
|
+
alpha: .5
|
|
29424
29698
|
});
|
|
29425
|
-
|
|
29426
|
-
|
|
29427
|
-
|
|
29428
|
-
|
|
29699
|
+
parts.previewMask.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({ color: 16777215 });
|
|
29700
|
+
if (context.style.progress === "shimmer") drawShimmerBand(parts.shimmer, frame.width, frame.height, context.palette.text);
|
|
29701
|
+
parts.shimmer.position.set(context.style.progress === "shimmer" ? 0 : frame.x, frame.y);
|
|
29702
|
+
parts.previewArt.clear();
|
|
29703
|
+
if (kind === "waveform") {
|
|
29704
|
+
const bottomInset = showMeta ? META_HEIGHT : 0;
|
|
29705
|
+
drawAudioWaveform(parts.previewArt, item.props.taskRunId, {
|
|
29706
|
+
x: frame.x + PADDING,
|
|
29707
|
+
y: frame.y + PADDING,
|
|
29708
|
+
width: Math.max(1, frame.width - 24),
|
|
29709
|
+
height: Math.max(1, frame.height - 24 - bottomInset)
|
|
29710
|
+
}, context.colors.brand.stroke);
|
|
29711
|
+
}
|
|
29712
|
+
if (full && (artifact?.type === "audio" || artifact?.type === "video" && texture)) drawPlayBadge(parts.previewArt, frame, context);
|
|
29713
|
+
if (surface) {
|
|
29714
|
+
const markY = frame.y + frame.height / 2 - (full && label ? 18 : 0);
|
|
29715
|
+
drawStateMark(parts.previewArt, surface, frame.x + frame.width / 2, markY, surface === "failed" ? color : context.colors.neutral.stroke);
|
|
29716
|
+
}
|
|
29717
|
+
if (showMeta) parts.previewArt.rect(frame.x, frame.y + frame.height - META_HEIGHT, frame.width, META_HEIGHT).fill({
|
|
29718
|
+
color: context.palette.bg,
|
|
29719
|
+
alpha: .68
|
|
29429
29720
|
});
|
|
29430
|
-
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
const hasPixels = Boolean(texture) && parts.sprite.width > 0;
|
|
29434
|
-
const ox = hasPixels ? parts.sprite.x : 0;
|
|
29435
|
-
const oy = hasPixels ? parts.sprite.y : 0;
|
|
29436
|
-
const ow = hasPixels ? parts.sprite.width : width;
|
|
29437
|
-
const oh = hasPixels ? parts.sprite.height : height;
|
|
29438
|
-
parts.placeholder.visible = true;
|
|
29439
|
-
parts.placeholder.roundRect(ox, oy, ow, oh, RADIUS$2).stroke({
|
|
29440
|
-
color: selected ? context.palette.brand : context.palette.muted,
|
|
29441
|
-
width: selected ? 2 : 1,
|
|
29442
|
-
alpha: selected ? .95 : .7
|
|
29721
|
+
if (showBadge) parts.previewArt.roundRect(width - badgeWidth - 8, 8, badgeWidth, 20, 10).fill({
|
|
29722
|
+
color: context.palette.bg,
|
|
29723
|
+
alpha: .72
|
|
29443
29724
|
});
|
|
29725
|
+
if (failedWithOutput) drawFailedBadge(parts.previewArt, width, color, context);
|
|
29444
29726
|
}
|
|
29727
|
+
const showPreview = kind === "texture" && Boolean(texture);
|
|
29728
|
+
const revealKey = showPreview ? `${artifact?.id}:${texture?.uid}` : null;
|
|
29729
|
+
const sameCard = parts.motion.itemId === item.id;
|
|
29730
|
+
parts.motion.itemId = item.id;
|
|
29731
|
+
if (revealKey !== parts.motion.revealKey || !sameCard) {
|
|
29732
|
+
const appearing = sameCard && parts.motion.revealKey === null && revealKey !== null;
|
|
29733
|
+
parts.motion.revealKey = revealKey;
|
|
29734
|
+
parts.motion.revealFrom = appearing && !context.reducedMotion ? performance.now() : null;
|
|
29735
|
+
parts.preview.alpha = parts.motion.revealFrom === null ? 1 : 0;
|
|
29736
|
+
}
|
|
29737
|
+
parts.preview.visible = showPreview;
|
|
29738
|
+
if (showPreview && texture) {
|
|
29739
|
+
if (parts.preview.texture !== texture) parts.preview.texture = texture;
|
|
29740
|
+
const fitted = containRect(frame.width, frame.height, texture.width, texture.height);
|
|
29741
|
+
parts.preview.position.set(frame.x + fitted.x, frame.y + fitted.y);
|
|
29742
|
+
parts.preview.width = fitted.width;
|
|
29743
|
+
parts.preview.height = fitted.height;
|
|
29744
|
+
}
|
|
29745
|
+
parts.body.visible = full && Boolean(bodyText);
|
|
29746
|
+
parts.detail.visible = full && Boolean(detailText);
|
|
29747
|
+
parts.meta.visible = showMeta;
|
|
29748
|
+
parts.badge.visible = showBadge;
|
|
29749
|
+
if (textArtifact) parts.body.position.set(PADDING, PADDING);
|
|
29750
|
+
else parts.body.position.set(width / 2, height / 2 + 2);
|
|
29751
|
+
parts.detail.position.set(width / 2, height / 2 + 2 + parts.body.height + 4);
|
|
29752
|
+
parts.meta.position.set(PADDING, height - META_HEIGHT + 7);
|
|
29753
|
+
parts.badge.position.set(width - 8 - badgeWidth / 2, 18);
|
|
29754
|
+
parts.motion.width = frame.width;
|
|
29755
|
+
parts.motion.shimmer = full && working && kind !== "texture" && !context.reducedMotion;
|
|
29756
|
+
const mosaic = parts.motion.shimmer && context.style.progress === "mosaic";
|
|
29757
|
+
parts.motion.mosaic = mosaic ? {
|
|
29758
|
+
color: context.palette.brand,
|
|
29759
|
+
height: frame.height,
|
|
29760
|
+
step: -1
|
|
29761
|
+
} : null;
|
|
29762
|
+
parts.shimmer.visible = parts.motion.shimmer;
|
|
29763
|
+
parts.motion.startedAt = counting ? startedAt : null;
|
|
29764
|
+
parts.motion.label = label;
|
|
29765
|
+
parts.motion.elapsed = elapsed;
|
|
29445
29766
|
}
|
|
29446
|
-
const
|
|
29447
|
-
id: "
|
|
29448
|
-
canRender: (item) => item.type === "
|
|
29767
|
+
const taskCardRenderer = {
|
|
29768
|
+
id: "task-card",
|
|
29769
|
+
canRender: (item) => item.type === "task",
|
|
29449
29770
|
create: (item, context) => {
|
|
29450
29771
|
const root = new Container();
|
|
29451
|
-
const
|
|
29452
|
-
const
|
|
29453
|
-
const
|
|
29454
|
-
const
|
|
29455
|
-
|
|
29456
|
-
|
|
29457
|
-
|
|
29458
|
-
|
|
29459
|
-
|
|
29460
|
-
|
|
29772
|
+
const plate = new Graphics();
|
|
29773
|
+
const clip = new Graphics();
|
|
29774
|
+
const previewBg = new Graphics();
|
|
29775
|
+
const preview = new Sprite();
|
|
29776
|
+
const previewMask = new Graphics();
|
|
29777
|
+
const shimmer = new Graphics();
|
|
29778
|
+
const previewArt = new Graphics();
|
|
29779
|
+
const resolution = textResolutionForZoom(context.zoom);
|
|
29780
|
+
const text = (fontFamily, fontSize, fontWeight) => new Text({
|
|
29781
|
+
text: "",
|
|
29782
|
+
style: {
|
|
29783
|
+
fontFamily,
|
|
29784
|
+
fontSize,
|
|
29785
|
+
fontWeight,
|
|
29786
|
+
wordWrap: true,
|
|
29787
|
+
breakWords: true
|
|
29788
|
+
},
|
|
29789
|
+
resolution,
|
|
29790
|
+
roundPixels: true
|
|
29791
|
+
});
|
|
29792
|
+
const body = text(BOARD_FONT_STACK, 11.5, "500");
|
|
29793
|
+
const detail = text(BOARD_FONT_STACK, 10.5, "400");
|
|
29794
|
+
const meta = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
29795
|
+
const badge = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
29796
|
+
badge.style.wordWrap = false;
|
|
29797
|
+
badge.anchor.set(.5);
|
|
29798
|
+
detail.anchor.set(.5, 0);
|
|
29799
|
+
detail.style.align = "center";
|
|
29800
|
+
preview.mask = previewMask;
|
|
29801
|
+
const content = new Container();
|
|
29802
|
+
content.mask = clip;
|
|
29803
|
+
content.addChild(previewBg, shimmer, preview, previewMask, previewArt, body, detail, meta, badge);
|
|
29804
|
+
const tag = createCardTag();
|
|
29805
|
+
root.addChild(plate, content, clip, tag.root);
|
|
29461
29806
|
partsByContainer$3.set(root, {
|
|
29462
29807
|
root,
|
|
29463
|
-
|
|
29464
|
-
|
|
29465
|
-
|
|
29466
|
-
|
|
29467
|
-
|
|
29468
|
-
|
|
29808
|
+
tag,
|
|
29809
|
+
plate,
|
|
29810
|
+
clip,
|
|
29811
|
+
previewBg,
|
|
29812
|
+
preview,
|
|
29813
|
+
previewMask,
|
|
29814
|
+
shimmer,
|
|
29815
|
+
previewArt,
|
|
29816
|
+
badge,
|
|
29817
|
+
body,
|
|
29818
|
+
detail,
|
|
29819
|
+
meta,
|
|
29820
|
+
assetKey: null,
|
|
29821
|
+
visualSig: "",
|
|
29822
|
+
textSig: "",
|
|
29823
|
+
resolution,
|
|
29824
|
+
motion: {
|
|
29825
|
+
itemId: "",
|
|
29826
|
+
width: 0,
|
|
29827
|
+
shimmer: false,
|
|
29828
|
+
mosaic: null,
|
|
29829
|
+
startedAt: null,
|
|
29830
|
+
label: "",
|
|
29831
|
+
elapsed: "",
|
|
29832
|
+
revealFrom: null,
|
|
29833
|
+
revealKey: null
|
|
29834
|
+
}
|
|
29469
29835
|
});
|
|
29470
|
-
if (item.type === "
|
|
29836
|
+
if (item.type === "task") sync$3(root, item, context);
|
|
29471
29837
|
return root;
|
|
29472
29838
|
},
|
|
29473
29839
|
update: (container, item, context) => {
|
|
29474
|
-
if (item.type
|
|
29840
|
+
if (item.type === "task") sync$3(container, item, context);
|
|
29841
|
+
},
|
|
29842
|
+
tick: (container, clock) => {
|
|
29475
29843
|
const parts = partsByContainer$3.get(container);
|
|
29476
|
-
|
|
29477
|
-
|
|
29478
|
-
|
|
29479
|
-
|
|
29844
|
+
return parts ? advance(parts, clock) : null;
|
|
29845
|
+
},
|
|
29846
|
+
zoom: (container, zoom) => {
|
|
29847
|
+
const tag = partsByContainer$3.get(container)?.tag;
|
|
29848
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
29480
29849
|
},
|
|
29481
29850
|
renderFar: (graphics, item, context) => {
|
|
29851
|
+
if (item.type !== "task") return;
|
|
29852
|
+
const { status } = liveStatus(item, context);
|
|
29853
|
+
const active = status === "failed" || status === "running" || status === "pending";
|
|
29482
29854
|
drawFarPlate(graphics, item.frame, {
|
|
29483
|
-
fill: context.palette.
|
|
29484
|
-
fillAlpha: .
|
|
29855
|
+
fill: context.palette.surface,
|
|
29856
|
+
fillAlpha: .82,
|
|
29857
|
+
...active ? {
|
|
29858
|
+
accent: statusColor(status, context),
|
|
29859
|
+
accentAlpha: .9
|
|
29860
|
+
} : {}
|
|
29485
29861
|
});
|
|
29486
29862
|
},
|
|
29487
|
-
destroy: (container) => {
|
|
29863
|
+
destroy: (container, context) => {
|
|
29488
29864
|
const parts = partsByContainer$3.get(container);
|
|
29865
|
+
if (parts?.assetKey) context.releaseTexture(parts.assetKey);
|
|
29489
29866
|
parts?.root.destroy({ children: true });
|
|
29490
|
-
parts?.cropped?.destroy(false);
|
|
29491
29867
|
partsByContainer$3.delete(container);
|
|
29492
29868
|
}
|
|
29493
29869
|
};
|
|
@@ -29591,37 +29967,37 @@ const textCardRenderer = {
|
|
|
29591
29967
|
};
|
|
29592
29968
|
//#endregion
|
|
29593
29969
|
//#region ../sdk/src/board/render/renderers/unknown-card-renderer.ts
|
|
29594
|
-
const RADIUS$1 = 10;
|
|
29595
29970
|
const partsByContainer$1 = /* @__PURE__ */ new WeakMap();
|
|
29596
29971
|
function sync$1(container, item, context) {
|
|
29597
29972
|
const parts = partsByContainer$1.get(container);
|
|
29598
29973
|
if (!parts) return;
|
|
29599
29974
|
positionShell(parts.root, item);
|
|
29600
29975
|
const { width, height } = item.frame;
|
|
29601
|
-
const selected = context.selectedIds.has(item.id);
|
|
29602
29976
|
const realType = item.type;
|
|
29603
29977
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
29978
|
+
const elevation = cardElevation(context, item.id);
|
|
29604
29979
|
const visualSig = [
|
|
29605
29980
|
width,
|
|
29606
29981
|
height,
|
|
29607
|
-
|
|
29608
|
-
context.
|
|
29609
|
-
context.palette.brand,
|
|
29610
|
-
context.palette.border,
|
|
29611
|
-
context.palette.muted
|
|
29982
|
+
elevation,
|
|
29983
|
+
context.themeKey
|
|
29612
29984
|
].join("|");
|
|
29613
29985
|
if (visualSig !== parts.visualSig) {
|
|
29614
29986
|
parts.visualSig = visualSig;
|
|
29615
|
-
|
|
29616
|
-
|
|
29617
|
-
|
|
29618
|
-
|
|
29619
|
-
|
|
29620
|
-
|
|
29621
|
-
|
|
29622
|
-
|
|
29987
|
+
const rect = {
|
|
29988
|
+
x: 0,
|
|
29989
|
+
y: 0,
|
|
29990
|
+
width,
|
|
29991
|
+
height
|
|
29992
|
+
};
|
|
29993
|
+
drawCardSurface(parts.box.clear(), rect, context.style, {
|
|
29994
|
+
fill: context.palette.surface,
|
|
29995
|
+
fillAlpha: .7,
|
|
29996
|
+
border: context.palette.border,
|
|
29997
|
+
borderAlpha: .8,
|
|
29998
|
+
elevation
|
|
29623
29999
|
});
|
|
29624
|
-
parts.box
|
|
30000
|
+
traceCardOutline(parts.box, rect, context.style, -6).stroke({
|
|
29625
30001
|
color: context.palette.muted,
|
|
29626
30002
|
width: 1,
|
|
29627
30003
|
alpha: .4
|
|
@@ -29683,86 +30059,87 @@ const unknownCardRenderer = {
|
|
|
29683
30059
|
//#endregion
|
|
29684
30060
|
//#region ../sdk/src/board/render/renderers/video-card-renderer.ts
|
|
29685
30061
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
29686
|
-
const
|
|
29687
|
-
|
|
29688
|
-
|
|
29689
|
-
|
|
29690
|
-
const scale = Math.min(width / texture.width, height / texture.height);
|
|
29691
|
-
sprite.width = texture.width * scale;
|
|
29692
|
-
sprite.height = texture.height * scale;
|
|
29693
|
-
sprite.x = (width - sprite.width) / 2;
|
|
29694
|
-
sprite.y = (height - sprite.height) / 2;
|
|
30062
|
+
const FILM_RAIL = 10;
|
|
30063
|
+
const FILM_HOLE = 4;
|
|
30064
|
+
function videoTitle(item) {
|
|
30065
|
+
return item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
29695
30066
|
}
|
|
29696
30067
|
function sync(container, item, context) {
|
|
29697
30068
|
const parts = partsByContainer.get(container);
|
|
29698
30069
|
if (!parts) return;
|
|
29699
30070
|
positionShell(parts.root, item);
|
|
29700
30071
|
const { width, height } = item.frame;
|
|
29701
|
-
const
|
|
29702
|
-
const
|
|
29703
|
-
const
|
|
29704
|
-
|
|
30072
|
+
const title = videoTitle(item);
|
|
30073
|
+
const durationMs = item.props.snapshot?.durationMs;
|
|
30074
|
+
const duration = durationMs ? formatBoardDuration(durationMs) : "";
|
|
30075
|
+
syncCardTag(parts.tag, {
|
|
30076
|
+
glyph: "video",
|
|
30077
|
+
text: duration ? `${title} · ${duration}` : title,
|
|
30078
|
+
width
|
|
30079
|
+
}, context);
|
|
29705
30080
|
const key = context.assetKey(item);
|
|
29706
30081
|
const texture = key ? context.getTexture(key) : null;
|
|
29707
|
-
const
|
|
29708
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
29709
|
-
if (parts.label.text !== title) parts.label.text = title;
|
|
29710
|
-
syncTextWrapWidth(parts.label, parts, Math.max(1, width - 16), resizing);
|
|
29711
|
-
parts.label.position.set(8, Math.max(8, height - parts.label.height - 8));
|
|
30082
|
+
const elevation = cardElevation(context, item.id);
|
|
29712
30083
|
const sig = [
|
|
29713
30084
|
key ?? "",
|
|
29714
30085
|
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29715
30086
|
width,
|
|
29716
30087
|
height,
|
|
29717
|
-
|
|
29718
|
-
|
|
29719
|
-
|
|
29720
|
-
title,
|
|
29721
|
-
item.props.time ?? 0,
|
|
29722
|
-
parts.label.height,
|
|
29723
|
-
context.palette.surface,
|
|
29724
|
-
context.palette.brand,
|
|
29725
|
-
context.palette.muted,
|
|
29726
|
-
context.palette.border,
|
|
29727
|
-
context.palette.hover,
|
|
29728
|
-
context.palette.text
|
|
30088
|
+
elevation,
|
|
30089
|
+
boardCardDetailed(context.zoom),
|
|
30090
|
+
context.themeKey
|
|
29729
30091
|
].join("|");
|
|
29730
30092
|
if (sig === parts.sig) return;
|
|
29731
30093
|
parts.sig = sig;
|
|
30094
|
+
const framed = context.style.media === "framed";
|
|
30095
|
+
const rect = {
|
|
30096
|
+
x: 0,
|
|
30097
|
+
y: 0,
|
|
30098
|
+
width,
|
|
30099
|
+
height
|
|
30100
|
+
};
|
|
30101
|
+
const rail = framed ? Math.min(FILM_RAIL, height / 6) : 0;
|
|
30102
|
+
const screen = {
|
|
30103
|
+
x: framed ? rail * .6 : 0,
|
|
30104
|
+
y: rail,
|
|
30105
|
+
width: width - (framed ? rail * 1.2 : 0),
|
|
30106
|
+
height: height - rail * 2
|
|
30107
|
+
};
|
|
30108
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
30109
|
+
fill: framed ? context.palette.text : context.palette.surface,
|
|
30110
|
+
border: framed ? null : context.palette.border,
|
|
30111
|
+
borderAlpha: .85,
|
|
30112
|
+
elevation
|
|
30113
|
+
});
|
|
30114
|
+
if (framed) drawFilmRails(parts.plate, width, height, rail, context.palette.bg);
|
|
30115
|
+
traceCardOutline(parts.mask.clear(), framed ? screen : rect, framed ? {
|
|
30116
|
+
corner: "round",
|
|
30117
|
+
radius: 1
|
|
30118
|
+
} : context.style).fill({ color: 16777215 });
|
|
29732
30119
|
if (texture && parts.sprite.texture !== texture) parts.sprite.texture = texture;
|
|
29733
30120
|
parts.sprite.visible = Boolean(texture);
|
|
29734
|
-
if (texture) layoutContain(parts.sprite, width, height);
|
|
29735
|
-
parts.mask.clear().roundRect(0, 0, width, height, RADIUS).fill({ color: 16777215 });
|
|
29736
|
-
parts.plate.clear().roundRect(0, 0, width, height, RADIUS).fill({
|
|
29737
|
-
color: context.palette.surface,
|
|
29738
|
-
alpha: .96
|
|
29739
|
-
});
|
|
29740
|
-
parts.chrome.clear();
|
|
29741
30121
|
if (texture) {
|
|
29742
|
-
const
|
|
29743
|
-
parts.
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
});
|
|
30122
|
+
const fitted = containRect(screen.width, screen.height, texture.width, texture.height);
|
|
30123
|
+
parts.sprite.position.set(screen.x + fitted.x, screen.y + fitted.y);
|
|
30124
|
+
parts.sprite.width = fitted.width;
|
|
30125
|
+
parts.sprite.height = fitted.height;
|
|
29747
30126
|
}
|
|
29748
|
-
|
|
29749
|
-
|
|
29750
|
-
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
const
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
}
|
|
29760
|
-
|
|
29761
|
-
color:
|
|
29762
|
-
|
|
29763
|
-
alpha: selected ? .95 : .85
|
|
30127
|
+
parts.chrome.clear();
|
|
30128
|
+
if (boardCardDetailed(context.zoom)) drawMediaPlayKey(parts.chrome, screen.x + screen.width / 2, screen.y + screen.height / 2, Math.min(18, Math.min(screen.width, screen.height) * .16), context);
|
|
30129
|
+
}
|
|
30130
|
+
function drawFilmRails(graphics, width, height, rail, hole) {
|
|
30131
|
+
const size = Math.min(FILM_HOLE, rail * .45);
|
|
30132
|
+
const step = size * 2.5;
|
|
30133
|
+
const count = Math.max(1, Math.floor((width - step) / step));
|
|
30134
|
+
const start = (width - (count - 1) * step - size) / 2;
|
|
30135
|
+
for (let index = 0; index < count; index += 1) {
|
|
30136
|
+
const x = start + index * step;
|
|
30137
|
+
graphics.rect(x, (rail - size) / 2, size, size).rect(x, height - rail + (rail - size) / 2, size, size);
|
|
30138
|
+
}
|
|
30139
|
+
graphics.fill({
|
|
30140
|
+
color: hole,
|
|
30141
|
+
alpha: .9
|
|
29764
30142
|
});
|
|
29765
|
-
parts.label.style.fill = texture ? context.palette.text : context.palette.muted;
|
|
29766
30143
|
}
|
|
29767
30144
|
const videoCardRenderer = {
|
|
29768
30145
|
id: "video-card",
|
|
@@ -29773,20 +30150,8 @@ const videoCardRenderer = {
|
|
|
29773
30150
|
const sprite = new Sprite(Texture.EMPTY);
|
|
29774
30151
|
const mask = new Graphics();
|
|
29775
30152
|
const chrome = new Graphics();
|
|
29776
|
-
const
|
|
29777
|
-
|
|
29778
|
-
text: "",
|
|
29779
|
-
style: {
|
|
29780
|
-
fill: context.palette.muted,
|
|
29781
|
-
fontFamily: BOARD_FONT_STACK,
|
|
29782
|
-
fontSize: 12,
|
|
29783
|
-
fontWeight: "500",
|
|
29784
|
-
wordWrap: true
|
|
29785
|
-
},
|
|
29786
|
-
resolution,
|
|
29787
|
-
roundPixels: true
|
|
29788
|
-
});
|
|
29789
|
-
root.addChild(plate, sprite, mask, chrome, label);
|
|
30153
|
+
const tag = createCardTag();
|
|
30154
|
+
root.addChild(plate, sprite, mask, chrome, tag.root);
|
|
29790
30155
|
sprite.mask = mask;
|
|
29791
30156
|
partsByContainer.set(root, {
|
|
29792
30157
|
root,
|
|
@@ -29794,10 +30159,8 @@ const videoCardRenderer = {
|
|
|
29794
30159
|
sprite,
|
|
29795
30160
|
mask,
|
|
29796
30161
|
chrome,
|
|
29797
|
-
|
|
29798
|
-
sig: ""
|
|
29799
|
-
wrapWidth: 0,
|
|
29800
|
-
resolution
|
|
30162
|
+
tag,
|
|
30163
|
+
sig: ""
|
|
29801
30164
|
});
|
|
29802
30165
|
if (item.type === "video") sync(root, item, context);
|
|
29803
30166
|
return root;
|
|
@@ -29805,6 +30168,10 @@ const videoCardRenderer = {
|
|
|
29805
30168
|
update: (container, item, context) => {
|
|
29806
30169
|
if (item.type === "video") sync(container, item, context);
|
|
29807
30170
|
},
|
|
30171
|
+
zoom: (container, zoom) => {
|
|
30172
|
+
const tag = partsByContainer.get(container)?.tag;
|
|
30173
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
30174
|
+
},
|
|
29808
30175
|
renderFar: (graphics, item, context) => {
|
|
29809
30176
|
drawFarPlate(graphics, item.frame, {
|
|
29810
30177
|
fill: context.palette.surface,
|
|
@@ -30729,6 +31096,58 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30729
31096
|
};
|
|
30730
31097
|
}
|
|
30731
31098
|
//#endregion
|
|
31099
|
+
//#region ../sdk/src/board/render/style.ts
|
|
31100
|
+
const BASE = {
|
|
31101
|
+
corner: "round",
|
|
31102
|
+
radius: 6,
|
|
31103
|
+
selection: {
|
|
31104
|
+
width: 1.5,
|
|
31105
|
+
outset: 3,
|
|
31106
|
+
dash: 0,
|
|
31107
|
+
handle: "square",
|
|
31108
|
+
handleSize: 8
|
|
31109
|
+
},
|
|
31110
|
+
media: "plain",
|
|
31111
|
+
progress: "shimmer",
|
|
31112
|
+
icons: "line",
|
|
31113
|
+
motion: "smooth",
|
|
31114
|
+
font: BOARD_FONT_STACK
|
|
31115
|
+
};
|
|
31116
|
+
const SHADOW = {
|
|
31117
|
+
light: {
|
|
31118
|
+
color: 1447704,
|
|
31119
|
+
alpha: .06,
|
|
31120
|
+
blur: 12,
|
|
31121
|
+
y: 2
|
|
31122
|
+
},
|
|
31123
|
+
dark: {
|
|
31124
|
+
color: 0,
|
|
31125
|
+
alpha: .24,
|
|
31126
|
+
blur: 12,
|
|
31127
|
+
y: 2
|
|
31128
|
+
}
|
|
31129
|
+
};
|
|
31130
|
+
function defaultBoardRenderStyle(mode) {
|
|
31131
|
+
return {
|
|
31132
|
+
...BASE,
|
|
31133
|
+
selection: { ...BASE.selection },
|
|
31134
|
+
shadow: { ...SHADOW[mode] }
|
|
31135
|
+
};
|
|
31136
|
+
}
|
|
31137
|
+
function resolveBoardRenderStyle(mode, style) {
|
|
31138
|
+
const base = defaultBoardRenderStyle(mode);
|
|
31139
|
+
if (!style) return base;
|
|
31140
|
+
return {
|
|
31141
|
+
...base,
|
|
31142
|
+
...style,
|
|
31143
|
+
selection: {
|
|
31144
|
+
...base.selection,
|
|
31145
|
+
...style.selection
|
|
31146
|
+
},
|
|
31147
|
+
shadow: style.shadow === void 0 ? base.shadow : style.shadow
|
|
31148
|
+
};
|
|
31149
|
+
}
|
|
31150
|
+
//#endregion
|
|
30732
31151
|
//#region ../sdk/src/board/export/scene.ts
|
|
30733
31152
|
function buildContext(input) {
|
|
30734
31153
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -30742,12 +31161,15 @@ function buildContext(input) {
|
|
|
30742
31161
|
selectedIds: /* @__PURE__ */ new Set(),
|
|
30743
31162
|
hoveredId: null,
|
|
30744
31163
|
resizingIds: /* @__PURE__ */ new Set(),
|
|
31164
|
+
liftedIds: /* @__PURE__ */ new Set(),
|
|
30745
31165
|
palette: {
|
|
30746
31166
|
...defaultBoardPalette(input.colorScheme),
|
|
30747
31167
|
...input.palette
|
|
30748
31168
|
},
|
|
30749
31169
|
colors: input.colors ?? buildFallbackShapeColors(input.colorScheme),
|
|
30750
31170
|
colorScheme: input.colorScheme,
|
|
31171
|
+
style: resolveBoardRenderStyle(input.colorScheme, input.style),
|
|
31172
|
+
themeKey: "export",
|
|
30751
31173
|
rendererType: "canvas",
|
|
30752
31174
|
zoom: input.scale,
|
|
30753
31175
|
reducedMotion: true,
|
|
@@ -30907,6 +31329,7 @@ function renderBoardExport(renderer, input, options = {}) {
|
|
|
30907
31329
|
colorScheme,
|
|
30908
31330
|
palette,
|
|
30909
31331
|
colors: options.colors,
|
|
31332
|
+
style: options.style,
|
|
30910
31333
|
textures: options.textures,
|
|
30911
31334
|
scripts: options.scripts,
|
|
30912
31335
|
assetKey: options.assetKey,
|