@neta-art/cohub-cli 10.1.0 → 10.3.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 +12 -4
- package/dist/board-kernel.js +2128 -1705
- 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/boards.js +17 -12
- package/dist/commands/decision.d.ts +4 -0
- package/dist/commands/decision.js +113 -0
- package/dist/commands/rooms-connect.d.ts +17 -0
- package/dist/commands/rooms-connect.js +140 -0
- package/dist/commands/rooms-rtc-binary.d.ts +2 -0
- package/dist/commands/rooms-rtc-binary.js +107 -0
- package/dist/commands/rooms-rtc.d.ts +21 -0
- package/dist/commands/rooms-rtc.js +171 -0
- package/dist/commands/rooms.js +45 -0
- package/dist/commands/sandboxd-binary.d.ts +1 -1
- package/dist/commands/sandboxd-binary.js +1 -1
- package/dist/commands/spaces.js +4 -15
- package/dist/index.js +2 -1
- package/package.json +4 -3
package/dist/board-kernel.js
CHANGED
|
@@ -5772,10 +5772,10 @@ const colorString$1 = string().max(120).refine(isBoardColorString$1, "expected a
|
|
|
5772
5772
|
const BoardColorSchema$1 = union([colorString$1, object({
|
|
5773
5773
|
light: colorString$1,
|
|
5774
5774
|
dark: colorString$1
|
|
5775
|
-
}).strict()]);
|
|
5775
|
+
}).strict()]).describe("Palette token (follows the theme), CSS color, or { light, dark }.");
|
|
5776
5776
|
const BoardStyleSchema$1 = object({
|
|
5777
5777
|
fill: BoardColorSchema$1.optional(),
|
|
5778
|
-
fillOpacity: ratio$1.optional(),
|
|
5778
|
+
fillOpacity: ratio$1.optional().describe("Fill opacity, independent of the item's opacity."),
|
|
5779
5779
|
stroke: BoardColorSchema$1.optional(),
|
|
5780
5780
|
strokeWidth: finite$1.min(0).max(64).optional(),
|
|
5781
5781
|
dash: _enum([
|
|
@@ -5783,8 +5783,8 @@ const BoardStyleSchema$1 = object({
|
|
|
5783
5783
|
"dashed",
|
|
5784
5784
|
"dotted"
|
|
5785
5785
|
]).optional(),
|
|
5786
|
-
radius: nonNegative$1.optional(),
|
|
5787
|
-
trim: ratio$1.optional()
|
|
5786
|
+
radius: nonNegative$1.optional().describe("Corner radius in board units."),
|
|
5787
|
+
trim: ratio$1.optional().describe("Fraction of the outline drawn; animate 0 → 1 to draw it in.")
|
|
5788
5788
|
}).strict();
|
|
5789
5789
|
function isSafeBoardSourcePath$1(value) {
|
|
5790
5790
|
return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !/^[a-z][a-z\d+.-]*:/i.test(value.trimStart()) && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
@@ -5800,18 +5800,18 @@ function parseBoardMediaSource$1(src) {
|
|
|
5800
5800
|
value: src
|
|
5801
5801
|
} : null;
|
|
5802
5802
|
}
|
|
5803
|
-
const BoardMediaSourceSchema$1 = string().max(4096).refine((src) => parseBoardMediaSource$1(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a
|
|
5803
|
+
const BoardMediaSourceSchema$1 = string().max(4096).refine((src) => parseBoardMediaSource$1(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a public HTTP(S) URL; a Space path relative to the workspace root also works.");
|
|
5804
5804
|
const BoardScriptSchema$1 = object({
|
|
5805
|
-
src: srcSchema$1.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module"),
|
|
5806
|
-
params: record(string(), json()).default({}),
|
|
5807
|
-
targets: record(string().min(1).max(80), BoardIdSchema$1).default({}),
|
|
5808
|
-
seed: string().min(1).max(160).optional(),
|
|
5805
|
+
src: srcSchema$1.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module").describe("A .js or .mjs Space file."),
|
|
5806
|
+
params: record(string(), json()).default({}).describe("Values the module reads as params."),
|
|
5807
|
+
targets: record(string().min(1).max(80), BoardIdSchema$1).default({}).describe("Named items the module can reach, as ctx.targets."),
|
|
5808
|
+
seed: string().min(1).max(160).optional().describe("Seed for ctx.random(); defaults to the item id."),
|
|
5809
5809
|
enabled: boolean().default(true)
|
|
5810
|
-
}).strict();
|
|
5810
|
+
}).strict().describe("A JavaScript module attached to the item; `cohub boards schema script` lists its API.");
|
|
5811
5811
|
const itemEnvelope$1 = {
|
|
5812
5812
|
script: BoardScriptSchema$1.optional(),
|
|
5813
|
-
parent: BoardIdSchema$1.optional(),
|
|
5814
|
-
z: finite$1.optional(),
|
|
5813
|
+
parent: BoardIdSchema$1.optional().describe("A frame id; position becomes relative to the frame, and the item moves with it."),
|
|
5814
|
+
z: finite$1.optional().describe("Order among siblings; new items go on top."),
|
|
5815
5815
|
position: BoardVec2Schema$1.default({
|
|
5816
5816
|
x: 0,
|
|
5817
5817
|
y: 0
|
|
@@ -5821,7 +5821,7 @@ const itemEnvelope$1 = {
|
|
|
5821
5821
|
origin: BoardVec2Schema$1.default({
|
|
5822
5822
|
x: .5,
|
|
5823
5823
|
y: .5
|
|
5824
|
-
}),
|
|
5824
|
+
}).describe("Rotation and scale origin as fractions of the size."),
|
|
5825
5825
|
opacity: ratio$1.default(1),
|
|
5826
5826
|
style: BoardStyleSchema$1.default({}),
|
|
5827
5827
|
locked: boolean().optional(),
|
|
@@ -5854,8 +5854,8 @@ const BoardFrameItemSchema$1 = object({
|
|
|
5854
5854
|
type: literal("frame"),
|
|
5855
5855
|
props: object({
|
|
5856
5856
|
label: string().max(280).default(""),
|
|
5857
|
-
decoration: _enum(["frame", "none"]).optional(),
|
|
5858
|
-
clip: boolean().default(true)
|
|
5857
|
+
decoration: _enum(["frame", "none"]).optional().describe("none hides the title, border and background: an invisible group whose tracks move every child."),
|
|
5858
|
+
clip: boolean().default(true).describe("Hide children outside the frame.")
|
|
5859
5859
|
}).strict().prefault({})
|
|
5860
5860
|
}).strict();
|
|
5861
5861
|
const BoardTextItemSchema$1 = object({
|
|
@@ -5865,12 +5865,12 @@ const BoardTextItemSchema$1 = object({
|
|
|
5865
5865
|
text: string().default(""),
|
|
5866
5866
|
fontSize: fontSize$1.default(24),
|
|
5867
5867
|
fontWeight: finite$1.min(100).max(900).default(500),
|
|
5868
|
-
font: string().min(1).max(120).default("sans"),
|
|
5868
|
+
font: string().min(1).max(120).default("sans").describe("sans, serif, mono, or a font family name."),
|
|
5869
5869
|
align: _enum(BOARD_TEXT_ALIGNS$1).default("left"),
|
|
5870
5870
|
lineHeight: finite$1.min(.5).max(4).default(4 / 3),
|
|
5871
|
-
width: finite$1.positive().optional(),
|
|
5872
|
-
reveal: ratio$1.default(1),
|
|
5873
|
-
caret: boolean().default(false)
|
|
5871
|
+
width: finite$1.positive().optional().describe("Wrap width; the height follows the text."),
|
|
5872
|
+
reveal: ratio$1.default(1).describe("Fraction of the text shown; animate 0 → 1 to type it."),
|
|
5873
|
+
caret: boolean().default(false).describe("Blink a caret while the text is being revealed.")
|
|
5874
5874
|
}).strict().prefault({})
|
|
5875
5875
|
}).strict();
|
|
5876
5876
|
const BoardShapeItemSchema$1 = object({
|
|
@@ -5878,7 +5878,7 @@ const BoardShapeItemSchema$1 = object({
|
|
|
5878
5878
|
type: literal("shape"),
|
|
5879
5879
|
props: object({
|
|
5880
5880
|
geometry: _enum(BOARD_SHAPE_GEOMETRIES$1).default("rectangle"),
|
|
5881
|
-
path: string().min(1).max(2e5).optional(),
|
|
5881
|
+
path: string().min(1).max(2e5).optional().describe("SVG path data for path geometry, fitted to the item size."),
|
|
5882
5882
|
text: string().default(""),
|
|
5883
5883
|
fontSize: fontSize$1.default(20),
|
|
5884
5884
|
align: _enum(BOARD_TEXT_ALIGNS$1).default("center")
|
|
@@ -5890,12 +5890,12 @@ const BoardShapeItemSchema$1 = object({
|
|
|
5890
5890
|
const BoardDrawPointSchema$1 = object({
|
|
5891
5891
|
x: finite$1,
|
|
5892
5892
|
y: finite$1,
|
|
5893
|
-
p: ratio$1.default(.5)
|
|
5893
|
+
p: ratio$1.default(.5).describe("Pen pressure.")
|
|
5894
5894
|
}).strict();
|
|
5895
5895
|
const BoardDrawItemSchema$1 = object({
|
|
5896
5896
|
...unsized$1,
|
|
5897
5897
|
type: literal("draw"),
|
|
5898
|
-
props: object({ points: array(BoardDrawPointSchema$1).min(1).max(1e5) }).strict()
|
|
5898
|
+
props: object({ points: array(BoardDrawPointSchema$1).min(1).max(1e5).describe("Stroke points relative to position; the size follows them.") }).strict()
|
|
5899
5899
|
}).strict();
|
|
5900
5900
|
const BoardArrowEndSchema$1 = union([BoardVec2Schema$1, object({
|
|
5901
5901
|
item: BoardIdSchema$1,
|
|
@@ -5914,9 +5914,9 @@ const BoardArrowEndSchema$1 = union([BoardVec2Schema$1, object({
|
|
|
5914
5914
|
x: ratio$1,
|
|
5915
5915
|
y: ratio$1
|
|
5916
5916
|
}).strict()
|
|
5917
|
-
]).default("auto"),
|
|
5917
|
+
]).default("auto").describe("auto uses the side facing the other end; or a side with an offset, or a point as fractions of the item."),
|
|
5918
5918
|
port: string().min(1).max(120).optional()
|
|
5919
|
-
}).strict()]);
|
|
5919
|
+
}).strict()]).describe("A point relative to position, or { item } to follow that item.");
|
|
5920
5920
|
const BOARD_ARROW_ROUTES$1 = [
|
|
5921
5921
|
"straight",
|
|
5922
5922
|
"curve",
|
|
@@ -5929,13 +5929,13 @@ const BoardArrowItemSchema$1 = object({
|
|
|
5929
5929
|
start: BoardArrowEndSchema$1,
|
|
5930
5930
|
end: BoardArrowEndSchema$1,
|
|
5931
5931
|
route: _enum(BOARD_ARROW_ROUTES$1).default("straight"),
|
|
5932
|
-
bend: finite$1.min(-.85).max(.85).default(0),
|
|
5933
|
-
waypoints: array(BoardVec2Schema$1).max(64).default([]),
|
|
5932
|
+
bend: finite$1.min(-.85).max(.85).default(0).describe("Sideways curve as a fraction of the length; the sign picks the side."),
|
|
5933
|
+
waypoints: array(BoardVec2Schema$1).max(64).default([]).describe("Points the route passes through."),
|
|
5934
5934
|
arrowStart: boolean().default(false),
|
|
5935
5935
|
arrowEnd: boolean().default(true),
|
|
5936
5936
|
label: string().max(280).default(""),
|
|
5937
5937
|
fontSize: fontSize$1.default(14),
|
|
5938
|
-
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional()
|
|
5938
|
+
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional().describe("What the arrow means, as a slug such as triggers or depends-on.")
|
|
5939
5939
|
}).strict()
|
|
5940
5940
|
}).strict();
|
|
5941
5941
|
const fileProps$1 = {
|
|
@@ -5951,26 +5951,26 @@ const fileProps$1 = {
|
|
|
5951
5951
|
excerpt: string().optional(),
|
|
5952
5952
|
coverPath: string().optional(),
|
|
5953
5953
|
coverUrl: string().optional()
|
|
5954
|
-
}).strict().optional()
|
|
5954
|
+
}).strict().describe("Cached facts for an instant preview; filled in when the media loads.").optional()
|
|
5955
5955
|
};
|
|
5956
5956
|
const BoardMediaOriginSchema$1 = object({
|
|
5957
5957
|
taskRunId: string().min(1).max(160),
|
|
5958
5958
|
artifactId: string().min(1).max(240)
|
|
5959
|
-
}).strict();
|
|
5959
|
+
}).strict().describe("The generation run and result this media came from.");
|
|
5960
5960
|
const mediaProps$1 = {
|
|
5961
5961
|
...fileProps$1,
|
|
5962
5962
|
origin: BoardMediaOriginSchema$1.optional()
|
|
5963
5963
|
};
|
|
5964
5964
|
const timedFileProps$1 = {
|
|
5965
5965
|
...mediaProps$1,
|
|
5966
|
-
time: nonNegative$1.optional()
|
|
5966
|
+
time: nonNegative$1.optional().describe("Playback position in milliseconds; animate props.time to play it on a timeline.")
|
|
5967
5967
|
};
|
|
5968
5968
|
const BoardCropSchema$1 = object({
|
|
5969
5969
|
x: ratio$1,
|
|
5970
5970
|
y: ratio$1,
|
|
5971
5971
|
w: ratio$1,
|
|
5972
5972
|
h: ratio$1
|
|
5973
|
-
}).strict();
|
|
5973
|
+
}).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
|
|
5974
5974
|
const BoardImageItemSchema$1 = object({
|
|
5975
5975
|
...boxed$1(640, 360),
|
|
5976
5976
|
type: literal("image"),
|
|
@@ -6050,8 +6050,8 @@ const BoardTaskItemSchema$1 = object({
|
|
|
6050
6050
|
...boxed$1(420, 240),
|
|
6051
6051
|
type: literal("task"),
|
|
6052
6052
|
props: object({
|
|
6053
|
-
taskRunId: string().min(1).max(160),
|
|
6054
|
-
snapshot: BoardTaskSnapshotSchema$1.describe("Maintained by the server
|
|
6053
|
+
taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
|
|
6054
|
+
snapshot: BoardTaskSnapshotSchema$1.describe("Maintained by the server; omit it.")
|
|
6055
6055
|
}).strict()
|
|
6056
6056
|
}).strict();
|
|
6057
6057
|
const BOARD_EFFECT_KINDS$1 = [
|
|
@@ -6074,8 +6074,8 @@ const BoardEffectItemSchema$1 = object({
|
|
|
6074
6074
|
spread: finite$1.min(0).max(360).default(360),
|
|
6075
6075
|
gravity: finite$1.default(0),
|
|
6076
6076
|
intensity: nonNegative$1.max(10).default(1),
|
|
6077
|
-
follow: BoardIdSchema$1.optional(),
|
|
6078
|
-
seed: string().min(1).max(160).optional()
|
|
6077
|
+
follow: BoardIdSchema$1.optional().describe("trail: the item to follow."),
|
|
6078
|
+
seed: string().min(1).max(160).optional().describe("Makes procedural motion repeatable.")
|
|
6079
6079
|
}).strict()
|
|
6080
6080
|
}).strict();
|
|
6081
6081
|
const BoardCustomItemSchema$1 = object({
|
|
@@ -6177,21 +6177,21 @@ function isBoardEase$1(value) {
|
|
|
6177
6177
|
}
|
|
6178
6178
|
const BoardEaseSchema$1 = string().max(120).refine(isBoardEase$1, "expected a CSS easing: linear, ease-in-out, cubic-bezier(…) or steps(…)");
|
|
6179
6179
|
const BoardKeyframeSchema$1 = object({
|
|
6180
|
-
at: nonNegative$1,
|
|
6180
|
+
at: nonNegative$1.describe("Time in milliseconds."),
|
|
6181
6181
|
value: unknown(),
|
|
6182
|
-
ease: BoardEaseSchema$1.optional()
|
|
6182
|
+
ease: BoardEaseSchema$1.optional().describe("Easing into this keyframe: a CSS keyword, cubic-bezier() or steps(); defaults to linear.")
|
|
6183
6183
|
}).strict();
|
|
6184
6184
|
const BoardTrackSchema$1 = object({
|
|
6185
|
-
target: string().min(1).max(160),
|
|
6186
|
-
property: string().min(1).max(200),
|
|
6187
|
-
keyframes: array(BoardKeyframeSchema$1).min(1).max(1e5),
|
|
6188
|
-
composite: _enum(["replace", "add"]).default("replace"),
|
|
6185
|
+
target: string().min(1).max(160).describe("An item id, camera, or another animation id (its time property nests that timeline)."),
|
|
6186
|
+
property: string().min(1).max(200).describe("JSON path in the target, e.g. position, opacity, style.fill, props.text."),
|
|
6187
|
+
keyframes: array(BoardKeyframeSchema$1).min(1).max(1e5).describe("Ordered by at. The value holds before the first and after the last keyframe."),
|
|
6188
|
+
composite: _enum(["replace", "add"]).default("replace").describe("replace: the latest-started track wins. add: positions and rotations add; scale and opacity multiply."),
|
|
6189
6189
|
interpolation: _enum([
|
|
6190
6190
|
"auto",
|
|
6191
6191
|
"step",
|
|
6192
6192
|
"spline"
|
|
6193
|
-
]).default("auto"),
|
|
6194
|
-
orient: boolean().optional()
|
|
6193
|
+
]).default("auto").describe("auto blends numbers, vectors and colors and steps other values; spline smooths position paths."),
|
|
6194
|
+
orient: boolean().optional().describe("Rotate the item along its path.")
|
|
6195
6195
|
}).strict().superRefine((track, context) => {
|
|
6196
6196
|
for (let index = 1; index < track.keyframes.length; index += 1) if ((track.keyframes[index]?.at ?? 0) < (track.keyframes[index - 1]?.at ?? 0)) context.addIssue({
|
|
6197
6197
|
code: "custom",
|
|
@@ -6206,20 +6206,20 @@ const BoardTrackSchema$1 = object({
|
|
|
6206
6206
|
const BoardMarkerSchema$1 = object({
|
|
6207
6207
|
at: nonNegative$1,
|
|
6208
6208
|
label: string().max(280).optional(),
|
|
6209
|
-
pause: boolean().optional()
|
|
6209
|
+
pause: boolean().optional().describe("Hold shared playback here until next.")
|
|
6210
6210
|
}).strict();
|
|
6211
6211
|
const BoardAnimationHeaderSchema$1 = object({
|
|
6212
6212
|
name: string().max(280).optional(),
|
|
6213
|
-
duration: finite$1.positive().max(864e5),
|
|
6213
|
+
duration: finite$1.positive().max(864e5).describe("Milliseconds; a new animation without it ends at its last keyframe."),
|
|
6214
6214
|
play: _enum([
|
|
6215
6215
|
"manual",
|
|
6216
6216
|
"auto",
|
|
6217
6217
|
"always"
|
|
6218
|
-
]).default("manual"),
|
|
6218
|
+
]).default("manual").describe("manual: only shared playback starts it. auto: plays when the Board opens. always: loops continuously."),
|
|
6219
6219
|
delay: nonNegative$1.default(0),
|
|
6220
6220
|
loop: boolean().default(false),
|
|
6221
|
-
end: _enum(["hold", "reset"]).default("hold"),
|
|
6222
|
-
markers: array(BoardMarkerSchema$1).max(1e4).default([])
|
|
6221
|
+
end: _enum(["hold", "reset"]).default("hold").describe("hold keeps the last frame; reset returns to the start."),
|
|
6222
|
+
markers: array(BoardMarkerSchema$1).max(1e4).default([]).describe("Labeled points on this timeline; a nested animation's markers do not carry over.")
|
|
6223
6223
|
}).strict();
|
|
6224
6224
|
BoardAnimationHeaderSchema$1.extend({ tracks: record(BoardKeySchema$1, BoardTrackSchema$1).default({}) }).strict();
|
|
6225
6225
|
const BOARD_ENTER_PRESETS$1 = [
|
|
@@ -6237,7 +6237,7 @@ const BoardBackgroundSchema$1 = object({
|
|
|
6237
6237
|
"image"
|
|
6238
6238
|
]).default("dots"),
|
|
6239
6239
|
color: BoardColorSchema$1.optional(),
|
|
6240
|
-
imageUrl: string().url().max(4096).optional(),
|
|
6240
|
+
imageUrl: string().url().max(4096).optional().describe("Background image for kind image."),
|
|
6241
6241
|
fit: _enum([
|
|
6242
6242
|
"cover",
|
|
6243
6243
|
"contain",
|
|
@@ -6249,13 +6249,13 @@ const BoardSettingsSchema$1 = object({
|
|
|
6249
6249
|
title: string().min(1).max(255).optional(),
|
|
6250
6250
|
background: BoardBackgroundSchema$1.default({ kind: "dots" }),
|
|
6251
6251
|
grid: object({
|
|
6252
|
-
visible: boolean().default(false),
|
|
6252
|
+
visible: boolean().default(false).describe("Show the grid overlay."),
|
|
6253
6253
|
size: finite$1.min(4).max(512).default(24)
|
|
6254
6254
|
}).strict().optional(),
|
|
6255
6255
|
enter: object({
|
|
6256
6256
|
preset: _enum(BOARD_ENTER_PRESETS$1),
|
|
6257
6257
|
duration: finite$1.positive().max(1e4).optional()
|
|
6258
|
-
}).strict().optional()
|
|
6258
|
+
}).strict().optional().describe("Motion for items as they are added.")
|
|
6259
6259
|
}).strict();
|
|
6260
6260
|
const patchObject$1 = record(string(), unknown());
|
|
6261
6261
|
const BoardPatchSchema$1 = object({
|
|
@@ -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,1197 +27908,306 @@ 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
|
-
|
|
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
|
|
27608
28080
|
].join("|");
|
|
27609
|
-
if (
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
|
|
27613
|
-
|
|
27614
|
-
|
|
27615
|
-
|
|
27616
|
-
|
|
27617
|
-
|
|
27618
|
-
|
|
27619
|
-
|
|
27620
|
-
parts.
|
|
27621
|
-
parts.
|
|
27622
|
-
|
|
27623
|
-
|
|
27624
|
-
|
|
27625
|
-
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27629
|
-
|
|
27630
|
-
|
|
27631
|
-
|
|
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 "";
|
|
27784
|
-
}
|
|
27785
|
-
}
|
|
27786
|
-
function statusColor(status, context) {
|
|
27787
|
-
if (status === "failed") return context.colors.rose.stroke;
|
|
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();
|
|
28207
|
+
function replaceStroke(parts, next) {
|
|
28208
|
+
if (parts.stroke) {
|
|
28209
|
+
parts.root.removeChild(parts.stroke);
|
|
28210
|
+
parts.stroke.destroy();
|
|
28601
28211
|
}
|
|
28602
28212
|
parts.stroke = next;
|
|
28603
28213
|
parts.root.addChild(next);
|
|
@@ -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);
|
|
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;
|
|
29444
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,
|
|
@@ -29974,10 +30341,10 @@ const colorString = string().max(120).refine(isBoardColorString, "expected a pal
|
|
|
29974
30341
|
const BoardColorSchema = union([colorString, object({
|
|
29975
30342
|
light: colorString,
|
|
29976
30343
|
dark: colorString
|
|
29977
|
-
}).strict()]);
|
|
30344
|
+
}).strict()]).describe("Palette token (follows the theme), CSS color, or { light, dark }.");
|
|
29978
30345
|
const BoardStyleSchema = object({
|
|
29979
30346
|
fill: BoardColorSchema.optional(),
|
|
29980
|
-
fillOpacity: ratio.optional(),
|
|
30347
|
+
fillOpacity: ratio.optional().describe("Fill opacity, independent of the item's opacity."),
|
|
29981
30348
|
stroke: BoardColorSchema.optional(),
|
|
29982
30349
|
strokeWidth: finite.min(0).max(64).optional(),
|
|
29983
30350
|
dash: _enum([
|
|
@@ -29985,8 +30352,8 @@ const BoardStyleSchema = object({
|
|
|
29985
30352
|
"dashed",
|
|
29986
30353
|
"dotted"
|
|
29987
30354
|
]).optional(),
|
|
29988
|
-
radius: nonNegative.optional(),
|
|
29989
|
-
trim: ratio.optional()
|
|
30355
|
+
radius: nonNegative.optional().describe("Corner radius in board units."),
|
|
30356
|
+
trim: ratio.optional().describe("Fraction of the outline drawn; animate 0 → 1 to draw it in.")
|
|
29990
30357
|
}).strict();
|
|
29991
30358
|
function isSafeBoardSourcePath(value) {
|
|
29992
30359
|
return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !/^[a-z][a-z\d+.-]*:/i.test(value.trimStart()) && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
@@ -30002,18 +30369,18 @@ function parseBoardMediaSource(src) {
|
|
|
30002
30369
|
value: src
|
|
30003
30370
|
} : null;
|
|
30004
30371
|
}
|
|
30005
|
-
const BoardMediaSourceSchema = string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a
|
|
30372
|
+
const BoardMediaSourceSchema = string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a public HTTP(S) URL; a Space path relative to the workspace root also works.");
|
|
30006
30373
|
const BoardScriptSchema = object({
|
|
30007
|
-
src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module"),
|
|
30008
|
-
params: record(string(), json()).default({}),
|
|
30009
|
-
targets: record(string().min(1).max(80), BoardIdSchema).default({}),
|
|
30010
|
-
seed: string().min(1).max(160).optional(),
|
|
30374
|
+
src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module").describe("A .js or .mjs Space file."),
|
|
30375
|
+
params: record(string(), json()).default({}).describe("Values the module reads as params."),
|
|
30376
|
+
targets: record(string().min(1).max(80), BoardIdSchema).default({}).describe("Named items the module can reach, as ctx.targets."),
|
|
30377
|
+
seed: string().min(1).max(160).optional().describe("Seed for ctx.random(); defaults to the item id."),
|
|
30011
30378
|
enabled: boolean().default(true)
|
|
30012
|
-
}).strict();
|
|
30379
|
+
}).strict().describe("A JavaScript module attached to the item; `cohub boards schema script` lists its API.");
|
|
30013
30380
|
const itemEnvelope = {
|
|
30014
30381
|
script: BoardScriptSchema.optional(),
|
|
30015
|
-
parent: BoardIdSchema.optional(),
|
|
30016
|
-
z: finite.optional(),
|
|
30382
|
+
parent: BoardIdSchema.optional().describe("A frame id; position becomes relative to the frame, and the item moves with it."),
|
|
30383
|
+
z: finite.optional().describe("Order among siblings; new items go on top."),
|
|
30017
30384
|
position: BoardVec2Schema.default({
|
|
30018
30385
|
x: 0,
|
|
30019
30386
|
y: 0
|
|
@@ -30023,7 +30390,7 @@ const itemEnvelope = {
|
|
|
30023
30390
|
origin: BoardVec2Schema.default({
|
|
30024
30391
|
x: .5,
|
|
30025
30392
|
y: .5
|
|
30026
|
-
}),
|
|
30393
|
+
}).describe("Rotation and scale origin as fractions of the size."),
|
|
30027
30394
|
opacity: ratio.default(1),
|
|
30028
30395
|
style: BoardStyleSchema.default({}),
|
|
30029
30396
|
locked: boolean().optional(),
|
|
@@ -30056,8 +30423,8 @@ object({
|
|
|
30056
30423
|
type: literal("frame"),
|
|
30057
30424
|
props: object({
|
|
30058
30425
|
label: string().max(280).default(""),
|
|
30059
|
-
decoration: _enum(["frame", "none"]).optional(),
|
|
30060
|
-
clip: boolean().default(true)
|
|
30426
|
+
decoration: _enum(["frame", "none"]).optional().describe("none hides the title, border and background: an invisible group whose tracks move every child."),
|
|
30427
|
+
clip: boolean().default(true).describe("Hide children outside the frame.")
|
|
30061
30428
|
}).strict().prefault({})
|
|
30062
30429
|
}).strict();
|
|
30063
30430
|
object({
|
|
@@ -30067,12 +30434,12 @@ object({
|
|
|
30067
30434
|
text: string().default(""),
|
|
30068
30435
|
fontSize: fontSize.default(24),
|
|
30069
30436
|
fontWeight: finite.min(100).max(900).default(500),
|
|
30070
|
-
font: string().min(1).max(120).default("sans"),
|
|
30437
|
+
font: string().min(1).max(120).default("sans").describe("sans, serif, mono, or a font family name."),
|
|
30071
30438
|
align: _enum(BOARD_TEXT_ALIGNS).default("left"),
|
|
30072
30439
|
lineHeight: finite.min(.5).max(4).default(4 / 3),
|
|
30073
|
-
width: finite.positive().optional(),
|
|
30074
|
-
reveal: ratio.default(1),
|
|
30075
|
-
caret: boolean().default(false)
|
|
30440
|
+
width: finite.positive().optional().describe("Wrap width; the height follows the text."),
|
|
30441
|
+
reveal: ratio.default(1).describe("Fraction of the text shown; animate 0 → 1 to type it."),
|
|
30442
|
+
caret: boolean().default(false).describe("Blink a caret while the text is being revealed.")
|
|
30076
30443
|
}).strict().prefault({})
|
|
30077
30444
|
}).strict();
|
|
30078
30445
|
object({
|
|
@@ -30080,7 +30447,7 @@ object({
|
|
|
30080
30447
|
type: literal("shape"),
|
|
30081
30448
|
props: object({
|
|
30082
30449
|
geometry: _enum(BOARD_SHAPE_GEOMETRIES).default("rectangle"),
|
|
30083
|
-
path: string().min(1).max(2e5).optional(),
|
|
30450
|
+
path: string().min(1).max(2e5).optional().describe("SVG path data for path geometry, fitted to the item size."),
|
|
30084
30451
|
text: string().default(""),
|
|
30085
30452
|
fontSize: fontSize.default(20),
|
|
30086
30453
|
align: _enum(BOARD_TEXT_ALIGNS).default("center")
|
|
@@ -30092,12 +30459,12 @@ object({
|
|
|
30092
30459
|
const BoardDrawPointSchema = object({
|
|
30093
30460
|
x: finite,
|
|
30094
30461
|
y: finite,
|
|
30095
|
-
p: ratio.default(.5)
|
|
30462
|
+
p: ratio.default(.5).describe("Pen pressure.")
|
|
30096
30463
|
}).strict();
|
|
30097
30464
|
object({
|
|
30098
30465
|
...unsized,
|
|
30099
30466
|
type: literal("draw"),
|
|
30100
|
-
props: object({ points: array(BoardDrawPointSchema).min(1).max(1e5) }).strict()
|
|
30467
|
+
props: object({ points: array(BoardDrawPointSchema).min(1).max(1e5).describe("Stroke points relative to position; the size follows them.") }).strict()
|
|
30101
30468
|
}).strict();
|
|
30102
30469
|
const BoardArrowEndSchema = union([BoardVec2Schema, object({
|
|
30103
30470
|
item: BoardIdSchema,
|
|
@@ -30116,9 +30483,9 @@ const BoardArrowEndSchema = union([BoardVec2Schema, object({
|
|
|
30116
30483
|
x: ratio,
|
|
30117
30484
|
y: ratio
|
|
30118
30485
|
}).strict()
|
|
30119
|
-
]).default("auto"),
|
|
30486
|
+
]).default("auto").describe("auto uses the side facing the other end; or a side with an offset, or a point as fractions of the item."),
|
|
30120
30487
|
port: string().min(1).max(120).optional()
|
|
30121
|
-
}).strict()]);
|
|
30488
|
+
}).strict()]).describe("A point relative to position, or { item } to follow that item.");
|
|
30122
30489
|
const BOARD_ARROW_ROUTES = [
|
|
30123
30490
|
"straight",
|
|
30124
30491
|
"curve",
|
|
@@ -30131,13 +30498,13 @@ object({
|
|
|
30131
30498
|
start: BoardArrowEndSchema,
|
|
30132
30499
|
end: BoardArrowEndSchema,
|
|
30133
30500
|
route: _enum(BOARD_ARROW_ROUTES).default("straight"),
|
|
30134
|
-
bend: finite.min(-.85).max(.85).default(0),
|
|
30135
|
-
waypoints: array(BoardVec2Schema).max(64).default([]),
|
|
30501
|
+
bend: finite.min(-.85).max(.85).default(0).describe("Sideways curve as a fraction of the length; the sign picks the side."),
|
|
30502
|
+
waypoints: array(BoardVec2Schema).max(64).default([]).describe("Points the route passes through."),
|
|
30136
30503
|
arrowStart: boolean().default(false),
|
|
30137
30504
|
arrowEnd: boolean().default(true),
|
|
30138
30505
|
label: string().max(280).default(""),
|
|
30139
30506
|
fontSize: fontSize.default(14),
|
|
30140
|
-
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional()
|
|
30507
|
+
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional().describe("What the arrow means, as a slug such as triggers or depends-on.")
|
|
30141
30508
|
}).strict()
|
|
30142
30509
|
}).strict();
|
|
30143
30510
|
const fileProps = {
|
|
@@ -30153,26 +30520,26 @@ const fileProps = {
|
|
|
30153
30520
|
excerpt: string().optional(),
|
|
30154
30521
|
coverPath: string().optional(),
|
|
30155
30522
|
coverUrl: string().optional()
|
|
30156
|
-
}).strict().optional()
|
|
30523
|
+
}).strict().describe("Cached facts for an instant preview; filled in when the media loads.").optional()
|
|
30157
30524
|
};
|
|
30158
30525
|
const BoardMediaOriginSchema = object({
|
|
30159
30526
|
taskRunId: string().min(1).max(160),
|
|
30160
30527
|
artifactId: string().min(1).max(240)
|
|
30161
|
-
}).strict();
|
|
30528
|
+
}).strict().describe("The generation run and result this media came from.");
|
|
30162
30529
|
const mediaProps = {
|
|
30163
30530
|
...fileProps,
|
|
30164
30531
|
origin: BoardMediaOriginSchema.optional()
|
|
30165
30532
|
};
|
|
30166
30533
|
const timedFileProps = {
|
|
30167
30534
|
...mediaProps,
|
|
30168
|
-
time: nonNegative.optional()
|
|
30535
|
+
time: nonNegative.optional().describe("Playback position in milliseconds; animate props.time to play it on a timeline.")
|
|
30169
30536
|
};
|
|
30170
30537
|
const BoardCropSchema = object({
|
|
30171
30538
|
x: ratio,
|
|
30172
30539
|
y: ratio,
|
|
30173
30540
|
w: ratio,
|
|
30174
30541
|
h: ratio
|
|
30175
|
-
}).strict();
|
|
30542
|
+
}).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
|
|
30176
30543
|
object({
|
|
30177
30544
|
...boxed(640, 360),
|
|
30178
30545
|
type: literal("image"),
|
|
@@ -30252,8 +30619,8 @@ object({
|
|
|
30252
30619
|
...boxed(420, 240),
|
|
30253
30620
|
type: literal("task"),
|
|
30254
30621
|
props: object({
|
|
30255
|
-
taskRunId: string().min(1).max(160),
|
|
30256
|
-
snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server
|
|
30622
|
+
taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
|
|
30623
|
+
snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server; omit it.")
|
|
30257
30624
|
}).strict()
|
|
30258
30625
|
}).strict();
|
|
30259
30626
|
const BOARD_EFFECT_KINDS = [
|
|
@@ -30276,8 +30643,8 @@ object({
|
|
|
30276
30643
|
spread: finite.min(0).max(360).default(360),
|
|
30277
30644
|
gravity: finite.default(0),
|
|
30278
30645
|
intensity: nonNegative.max(10).default(1),
|
|
30279
|
-
follow: BoardIdSchema.optional(),
|
|
30280
|
-
seed: string().min(1).max(160).optional()
|
|
30646
|
+
follow: BoardIdSchema.optional().describe("trail: the item to follow."),
|
|
30647
|
+
seed: string().min(1).max(160).optional().describe("Makes procedural motion repeatable.")
|
|
30281
30648
|
}).strict()
|
|
30282
30649
|
}).strict();
|
|
30283
30650
|
object({
|
|
@@ -30317,21 +30684,21 @@ function isBoardEase(value) {
|
|
|
30317
30684
|
}
|
|
30318
30685
|
const BoardEaseSchema = string().max(120).refine(isBoardEase, "expected a CSS easing: linear, ease-in-out, cubic-bezier(…) or steps(…)");
|
|
30319
30686
|
const BoardKeyframeSchema = object({
|
|
30320
|
-
at: nonNegative,
|
|
30687
|
+
at: nonNegative.describe("Time in milliseconds."),
|
|
30321
30688
|
value: unknown(),
|
|
30322
|
-
ease: BoardEaseSchema.optional()
|
|
30689
|
+
ease: BoardEaseSchema.optional().describe("Easing into this keyframe: a CSS keyword, cubic-bezier() or steps(); defaults to linear.")
|
|
30323
30690
|
}).strict();
|
|
30324
30691
|
const BoardTrackSchema = object({
|
|
30325
|
-
target: string().min(1).max(160),
|
|
30326
|
-
property: string().min(1).max(200),
|
|
30327
|
-
keyframes: array(BoardKeyframeSchema).min(1).max(1e5),
|
|
30328
|
-
composite: _enum(["replace", "add"]).default("replace"),
|
|
30692
|
+
target: string().min(1).max(160).describe("An item id, camera, or another animation id (its time property nests that timeline)."),
|
|
30693
|
+
property: string().min(1).max(200).describe("JSON path in the target, e.g. position, opacity, style.fill, props.text."),
|
|
30694
|
+
keyframes: array(BoardKeyframeSchema).min(1).max(1e5).describe("Ordered by at. The value holds before the first and after the last keyframe."),
|
|
30695
|
+
composite: _enum(["replace", "add"]).default("replace").describe("replace: the latest-started track wins. add: positions and rotations add; scale and opacity multiply."),
|
|
30329
30696
|
interpolation: _enum([
|
|
30330
30697
|
"auto",
|
|
30331
30698
|
"step",
|
|
30332
30699
|
"spline"
|
|
30333
|
-
]).default("auto"),
|
|
30334
|
-
orient: boolean().optional()
|
|
30700
|
+
]).default("auto").describe("auto blends numbers, vectors and colors and steps other values; spline smooths position paths."),
|
|
30701
|
+
orient: boolean().optional().describe("Rotate the item along its path.")
|
|
30335
30702
|
}).strict().superRefine((track, context) => {
|
|
30336
30703
|
for (let index = 1; index < track.keyframes.length; index += 1) if ((track.keyframes[index]?.at ?? 0) < (track.keyframes[index - 1]?.at ?? 0)) context.addIssue({
|
|
30337
30704
|
code: "custom",
|
|
@@ -30346,20 +30713,20 @@ const BoardTrackSchema = object({
|
|
|
30346
30713
|
const BoardMarkerSchema = object({
|
|
30347
30714
|
at: nonNegative,
|
|
30348
30715
|
label: string().max(280).optional(),
|
|
30349
|
-
pause: boolean().optional()
|
|
30716
|
+
pause: boolean().optional().describe("Hold shared playback here until next.")
|
|
30350
30717
|
}).strict();
|
|
30351
30718
|
object({
|
|
30352
30719
|
name: string().max(280).optional(),
|
|
30353
|
-
duration: finite.positive().max(864e5),
|
|
30720
|
+
duration: finite.positive().max(864e5).describe("Milliseconds; a new animation without it ends at its last keyframe."),
|
|
30354
30721
|
play: _enum([
|
|
30355
30722
|
"manual",
|
|
30356
30723
|
"auto",
|
|
30357
30724
|
"always"
|
|
30358
|
-
]).default("manual"),
|
|
30725
|
+
]).default("manual").describe("manual: only shared playback starts it. auto: plays when the Board opens. always: loops continuously."),
|
|
30359
30726
|
delay: nonNegative.default(0),
|
|
30360
30727
|
loop: boolean().default(false),
|
|
30361
|
-
end: _enum(["hold", "reset"]).default("hold"),
|
|
30362
|
-
markers: array(BoardMarkerSchema).max(1e4).default([])
|
|
30728
|
+
end: _enum(["hold", "reset"]).default("hold").describe("hold keeps the last frame; reset returns to the start."),
|
|
30729
|
+
markers: array(BoardMarkerSchema).max(1e4).default([]).describe("Labeled points on this timeline; a nested animation's markers do not carry over.")
|
|
30363
30730
|
}).strict().extend({ tracks: record(BoardKeySchema, BoardTrackSchema).default({}) }).strict();
|
|
30364
30731
|
const BOARD_ENTER_PRESETS = [
|
|
30365
30732
|
"fade-in",
|
|
@@ -30376,7 +30743,7 @@ const BoardBackgroundSchema = object({
|
|
|
30376
30743
|
"image"
|
|
30377
30744
|
]).default("dots"),
|
|
30378
30745
|
color: BoardColorSchema.optional(),
|
|
30379
|
-
imageUrl: string().url().max(4096).optional(),
|
|
30746
|
+
imageUrl: string().url().max(4096).optional().describe("Background image for kind image."),
|
|
30380
30747
|
fit: _enum([
|
|
30381
30748
|
"cover",
|
|
30382
30749
|
"contain",
|
|
@@ -30388,13 +30755,13 @@ object({
|
|
|
30388
30755
|
title: string().min(1).max(255).optional(),
|
|
30389
30756
|
background: BoardBackgroundSchema.default({ kind: "dots" }),
|
|
30390
30757
|
grid: object({
|
|
30391
|
-
visible: boolean().default(false),
|
|
30758
|
+
visible: boolean().default(false).describe("Show the grid overlay."),
|
|
30392
30759
|
size: finite.min(4).max(512).default(24)
|
|
30393
30760
|
}).strict().optional(),
|
|
30394
30761
|
enter: object({
|
|
30395
30762
|
preset: _enum(BOARD_ENTER_PRESETS),
|
|
30396
30763
|
duration: finite.positive().max(1e4).optional()
|
|
30397
|
-
}).strict().optional()
|
|
30764
|
+
}).strict().optional().describe("Motion for items as they are added.")
|
|
30398
30765
|
}).strict();
|
|
30399
30766
|
const patchObject = record(string(), unknown());
|
|
30400
30767
|
object({
|
|
@@ -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,
|