@neta-art/cohub 5.10.0 → 6.0.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 +42 -46
- package/dist/board/animation.d.ts +156 -67
- package/dist/board/animation.js +161 -305
- package/dist/board/geometry.js +4 -4
- package/dist/board/index.d.ts +4 -4
- package/dist/board/index.js +3 -4
- package/dist/board/mutation.d.ts +5 -11
- package/dist/board/mutation.js +9 -46
- package/dist/chunks/http.d.ts +23 -12
- package/dist/chunks/http.js +674 -316
- package/dist/chunks/websocket.d.ts +2623 -201
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +158 -299
- package/dist/index.js +164 -306
- package/dist/protocol/dist/board-authoring.d.ts +1 -0
- package/dist/protocol/dist/board-authoring.js +217 -0
- package/dist/protocol/dist/board-capability-registry.d.ts +2 -0
- package/dist/protocol/dist/board-capability-registry.js +74 -0
- package/dist/protocol/dist/board-codec.d.ts +2 -0
- package/dist/protocol/dist/board-codec.js +4 -0
- package/dist/protocol/dist/board-composition.d.ts +258 -0
- package/dist/protocol/dist/board-composition.js +318 -0
- package/dist/protocol/dist/board-constants.js +0 -25
- package/dist/protocol/dist/board-node.d.ts +1 -12
- package/dist/protocol/dist/board-node.js +1 -81
- package/dist/protocol/dist/board-upgrade.d.ts +1 -0
- package/dist/protocol/dist/board-upgrade.js +2 -0
- package/dist/protocol/dist/board.d.ts +19 -92
- package/dist/protocol/dist/board.js +18 -78
- package/dist/protocol/dist/index.d.ts +8 -3
- package/dist/protocol/dist/index.js +9 -4
- package/dist/types.d.ts +2 -1
- package/docs/work-runtime-guide.md +19 -3
- package/package.json +3 -2
- package/dist/board/nodes.d.ts +0 -113
- package/dist/board/nodes.js +0 -154
package/dist/board/animation.js
CHANGED
|
@@ -1,282 +1,148 @@
|
|
|
1
1
|
import { BOARD_BUILTIN_CAPABILITIES, DEFAULT_BOARD_RENDER_LIMITS } from "../protocol/dist/board-constants.js";
|
|
2
|
-
import {
|
|
2
|
+
import { BOARD_ANIMATION_CHANNELS, BoardCompositionSchema, BoardProceduralClipSchema, BoardTrackSchema } from "../protocol/dist/board-composition.js";
|
|
3
|
+
import { estimateBuiltinBoardClipCost, validateBuiltinBoardClip } from "../protocol/dist/board-capability-registry.js";
|
|
3
4
|
import "../protocol/dist/index.js";
|
|
4
5
|
//#region src/board/animation.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
vertices: 0,
|
|
8
|
-
dynamicVertices: 0,
|
|
9
|
-
drawCalls: 0,
|
|
10
|
-
filterPasses: 0,
|
|
11
|
-
renderTexturePixels: 0,
|
|
12
|
-
textureBytes: 0,
|
|
13
|
-
bufferBytes: 0,
|
|
14
|
-
simulationSteps: 0
|
|
15
|
-
};
|
|
16
|
-
const DEFAULT_BOARD_LIMITS = DEFAULT_BOARD_RENDER_LIMITS;
|
|
17
|
-
const BUILTIN_CAPABILITIES = BOARD_BUILTIN_CAPABILITIES;
|
|
18
|
-
function numericParam(params, key, fallback) {
|
|
19
|
-
const value = params[key];
|
|
20
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
6
|
+
function track(input) {
|
|
7
|
+
return BoardTrackSchema.parse(input);
|
|
21
8
|
}
|
|
22
|
-
function
|
|
23
|
-
return {
|
|
24
|
-
...
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
path: "params.bounds",
|
|
41
|
-
coordinateSpace: "world"
|
|
42
|
-
});
|
|
43
|
-
else {
|
|
44
|
-
const value = bounds;
|
|
45
|
-
if (![
|
|
46
|
-
value.x,
|
|
47
|
-
value.y,
|
|
48
|
-
value.width,
|
|
49
|
-
value.height
|
|
50
|
-
].every((item) => typeof item === "number" && Number.isFinite(item)) || value.width <= 0 || value.height <= 0) diagnostics.push({
|
|
51
|
-
severity: "error",
|
|
52
|
-
code: "INVALID_PARTICLE_BOUNDS",
|
|
53
|
-
message: "particle bounds must have a positive finite size",
|
|
54
|
-
path: "params.bounds",
|
|
55
|
-
coordinateSpace: "world"
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (capability.id === "motion.path") {
|
|
60
|
-
const points = params.points;
|
|
61
|
-
if (!Array.isArray(points) || points.length < 2 || points.length > 1e4) diagnostics.push({
|
|
62
|
-
severity: "error",
|
|
63
|
-
code: "INVALID_MOTION_PATH",
|
|
64
|
-
message: "motion path must contain 2 to 10000 world-offset points",
|
|
65
|
-
path: "params.points",
|
|
66
|
-
coordinateSpace: "world-offset"
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
if (capability.id === "camera.focus") {
|
|
70
|
-
const parsed = BoardCameraFocusParamsSchema.safeParse(params);
|
|
71
|
-
if (!parsed.success) diagnostics.push({
|
|
72
|
-
severity: "error",
|
|
73
|
-
code: "INVALID_CAMERA_FOCUS",
|
|
74
|
-
message: parsed.error.issues[0]?.message ?? "invalid camera focus",
|
|
75
|
-
path: "params",
|
|
76
|
-
coordinateSpace: "world"
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
return diagnostics;
|
|
9
|
+
function proceduralClip(input) {
|
|
10
|
+
return BoardProceduralClipSchema.parse({
|
|
11
|
+
...input,
|
|
12
|
+
kindVersion: input.kindVersion ?? 1
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function composition(input) {
|
|
16
|
+
return BoardCompositionSchema.parse(input);
|
|
17
|
+
}
|
|
18
|
+
function compileComposition(input) {
|
|
19
|
+
return composition({
|
|
20
|
+
id: input.id,
|
|
21
|
+
name: input.name,
|
|
22
|
+
timeline: {
|
|
23
|
+
duration: input.duration,
|
|
24
|
+
tracks: (input.tracks ?? []).map(track),
|
|
25
|
+
clips: (input.clips ?? []).map(proceduralClip),
|
|
26
|
+
markers: input.markers ?? []
|
|
80
27
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return [
|
|
86
|
-
value.x,
|
|
87
|
-
value.y,
|
|
88
|
-
value.width,
|
|
89
|
-
value.height
|
|
90
|
-
].every((item) => typeof item === "number" && Number.isFinite(item)) ? value : null;
|
|
28
|
+
playback: input.playback ?? {
|
|
29
|
+
loop: false,
|
|
30
|
+
endBehavior: "hold",
|
|
31
|
+
reducedMotion: { mode: "base" }
|
|
91
32
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const particles = Math.max(0, Math.floor(numericParam(params, "count", 0)));
|
|
96
|
-
return {
|
|
97
|
-
particles,
|
|
98
|
-
vertices: particles * 4,
|
|
99
|
-
dynamicVertices: particles * 4,
|
|
100
|
-
drawCalls: 1,
|
|
101
|
-
bufferBytes: particles * 48,
|
|
102
|
-
simulationSteps: particles
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
case "effects.trail": return {
|
|
106
|
-
vertices: 32,
|
|
107
|
-
dynamicVertices: 32,
|
|
108
|
-
drawCalls: 1,
|
|
109
|
-
bufferBytes: 1024,
|
|
110
|
-
simulationSteps: 16
|
|
111
|
-
};
|
|
112
|
-
case "effects.impact":
|
|
113
|
-
case "effects.flash": return {
|
|
114
|
-
vertices: 64,
|
|
115
|
-
drawCalls: 1
|
|
116
|
-
};
|
|
117
|
-
case "effects.color": return {
|
|
118
|
-
drawCalls: 1,
|
|
119
|
-
filterPasses: 1
|
|
120
|
-
};
|
|
121
|
-
case "draw.reveal":
|
|
122
|
-
case "draw.handwrite": return {
|
|
123
|
-
drawCalls: 1,
|
|
124
|
-
dynamicVertices: 1
|
|
125
|
-
};
|
|
126
|
-
default: return {};
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
33
|
+
metadata: input.metadata ?? {},
|
|
34
|
+
revision: 0
|
|
35
|
+
});
|
|
130
36
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
37
|
+
const clamp01 = (value) => Math.max(0, Math.min(1, value));
|
|
38
|
+
function sampleEasing(easing, value) {
|
|
39
|
+
const t = clamp01(value);
|
|
40
|
+
switch (easing) {
|
|
41
|
+
case "ease-in-quad": return t * t;
|
|
42
|
+
case "ease-out-quad": return 1 - (1 - t) ** 2;
|
|
43
|
+
case "ease-in-out-quad": return t < .5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2;
|
|
44
|
+
case "ease-in-cubic": return t ** 3;
|
|
45
|
+
case "ease-out-cubic": return 1 - (1 - t) ** 3;
|
|
46
|
+
case "ease-in-out-cubic": return t < .5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
|
|
47
|
+
case "ease-out-quart": return 1 - (1 - t) ** 4;
|
|
48
|
+
case "ease-out-expo": return t === 1 ? 1 : 1 - 2 ** (-10 * t);
|
|
49
|
+
default: return t;
|
|
136
50
|
}
|
|
137
|
-
return (hash >>> 0).toString(36).padStart(7, "0");
|
|
138
|
-
}
|
|
139
|
-
function stableId(prefix, seed, path) {
|
|
140
|
-
return `${prefix}_${stableHash(`${seed}:${path}`)}`;
|
|
141
|
-
}
|
|
142
|
-
function assertDuration(value, field) {
|
|
143
|
-
if (!Number.isFinite(value) || value < 0) throw new TypeError(`${field} must be a finite non-negative number`);
|
|
144
51
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
type: "parallel",
|
|
155
|
-
children
|
|
156
|
-
};
|
|
157
|
-
},
|
|
158
|
-
sequence(...children) {
|
|
159
|
-
return {
|
|
160
|
-
type: "sequence",
|
|
161
|
-
children
|
|
162
|
-
};
|
|
163
|
-
},
|
|
164
|
-
stagger(each, ...children) {
|
|
165
|
-
assertDuration(each, "stagger each");
|
|
166
|
-
return {
|
|
167
|
-
type: "stagger",
|
|
168
|
-
each,
|
|
169
|
-
children
|
|
170
|
-
};
|
|
171
|
-
},
|
|
172
|
-
delay(duration, child) {
|
|
173
|
-
assertDuration(duration, "delay duration");
|
|
174
|
-
return {
|
|
175
|
-
type: "delay",
|
|
176
|
-
duration,
|
|
177
|
-
child
|
|
178
|
-
};
|
|
179
|
-
},
|
|
180
|
-
repeat(count, child) {
|
|
181
|
-
if (!Number.isSafeInteger(count) || count < 1 || count > 1e3) throw new TypeError("repeat count must be an integer between 1 and 1000");
|
|
182
|
-
return {
|
|
183
|
-
type: "repeat",
|
|
184
|
-
count,
|
|
185
|
-
child
|
|
186
|
-
};
|
|
52
|
+
function interpolate(left, right, progress) {
|
|
53
|
+
if (typeof left === "number" && typeof right === "number") return left + (right - left) * progress;
|
|
54
|
+
if (left && right && typeof left === "object" && typeof right === "object" && !Array.isArray(left) && !Array.isArray(right)) {
|
|
55
|
+
const a = left;
|
|
56
|
+
const b = right;
|
|
57
|
+
const result = {};
|
|
58
|
+
for (const key of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])) result[key] = interpolate(a[key], b[key], progress);
|
|
59
|
+
return result;
|
|
187
60
|
}
|
|
188
|
-
|
|
189
|
-
function clip(input) {
|
|
190
|
-
assertDuration(input.duration, "clip duration");
|
|
191
|
-
if (input.duration === 0) throw new TypeError("clip duration must be greater than zero");
|
|
192
|
-
return timeline.clip({
|
|
193
|
-
id: input.id,
|
|
194
|
-
kind: input.kind,
|
|
195
|
-
kindVersion: input.kindVersion ?? 1,
|
|
196
|
-
target: input.target,
|
|
197
|
-
duration: input.duration,
|
|
198
|
-
layer: input.layer ?? "content",
|
|
199
|
-
fill: input.fill ?? "none",
|
|
200
|
-
easing: input.easing ?? "linear",
|
|
201
|
-
params: input.params ?? {},
|
|
202
|
-
keyframes: input.keyframes ?? [],
|
|
203
|
-
assetRefs: input.assetRefs ?? [],
|
|
204
|
-
seed: input.seed,
|
|
205
|
-
metadata: input.metadata ?? {}
|
|
206
|
-
});
|
|
61
|
+
return progress < 1 ? left : right;
|
|
207
62
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
63
|
+
/** Deterministically sample one validated Track without touching scene state. */
|
|
64
|
+
function sampleTrack(trackValue, time) {
|
|
65
|
+
const frames = trackValue.keyframes;
|
|
66
|
+
const first = frames[0];
|
|
67
|
+
const last = frames.at(-1);
|
|
68
|
+
if (!first || !last) return null;
|
|
69
|
+
if (time < first.time) {
|
|
70
|
+
if (trackValue.fill !== "backwards" && trackValue.fill !== "both") return null;
|
|
211
71
|
return {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
id: input.clip.id ?? stableId("clip", sequenceSeed, path),
|
|
216
|
-
start: offset,
|
|
217
|
-
seed: clipSeed
|
|
218
|
-
}]
|
|
72
|
+
target: trackValue.target,
|
|
73
|
+
channel: trackValue.channel,
|
|
74
|
+
value: first.value
|
|
219
75
|
};
|
|
220
76
|
}
|
|
221
|
-
if (
|
|
222
|
-
|
|
77
|
+
if (time > last.time) {
|
|
78
|
+
if (trackValue.fill !== "forwards" && trackValue.fill !== "both") return null;
|
|
223
79
|
return {
|
|
224
|
-
|
|
225
|
-
|
|
80
|
+
target: trackValue.target,
|
|
81
|
+
channel: trackValue.channel,
|
|
82
|
+
value: last.value
|
|
226
83
|
};
|
|
227
84
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
clips.push(...nested.clips);
|
|
235
|
-
cursor += nested.duration;
|
|
236
|
-
total += nested.duration;
|
|
237
|
-
}
|
|
238
|
-
return {
|
|
239
|
-
duration: total,
|
|
240
|
-
clips
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
const clips = [];
|
|
244
|
-
let duration = 0;
|
|
245
|
-
for (const [index, child] of input.children.entries()) {
|
|
246
|
-
const childOffset = input.type === "sequence" ? duration : input.type === "stagger" ? input.each * index : 0;
|
|
247
|
-
const nested = flatten(child, offset + childOffset, sequenceSeed, `${path}.${index}`);
|
|
248
|
-
clips.push(...nested.clips);
|
|
249
|
-
duration = input.type === "sequence" ? duration + nested.duration : Math.max(duration, childOffset + nested.duration);
|
|
85
|
+
let low = 0;
|
|
86
|
+
let high = frames.length;
|
|
87
|
+
while (low < high) {
|
|
88
|
+
const middle = low + high >>> 1;
|
|
89
|
+
if ((frames[middle]?.time ?? Number.POSITIVE_INFINITY) <= time) low = middle + 1;
|
|
90
|
+
else high = middle;
|
|
250
91
|
}
|
|
92
|
+
const left = frames[Math.max(0, low - 1)] ?? first;
|
|
93
|
+
const right = frames[Math.min(frames.length - 1, low)] ?? last;
|
|
94
|
+
if (left === right || trackValue.interpolation === "step") return {
|
|
95
|
+
target: trackValue.target,
|
|
96
|
+
channel: trackValue.channel,
|
|
97
|
+
value: left.value
|
|
98
|
+
};
|
|
99
|
+
const span = Math.max(Number.EPSILON, right.time - left.time);
|
|
100
|
+
const progress = sampleEasing(right.easing ?? "linear", (time - left.time) / span);
|
|
251
101
|
return {
|
|
252
|
-
|
|
253
|
-
|
|
102
|
+
target: trackValue.target,
|
|
103
|
+
channel: trackValue.channel,
|
|
104
|
+
value: interpolate(left.value, right.value, progress)
|
|
254
105
|
};
|
|
255
106
|
}
|
|
256
|
-
function
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
107
|
+
function sampleCompositionTracks(value, time) {
|
|
108
|
+
const position = Math.max(0, Math.min(value.timeline.duration, time));
|
|
109
|
+
return value.timeline.tracks.flatMap((item) => {
|
|
110
|
+
const sampled = sampleTrack(item, position);
|
|
111
|
+
return sampled ? [sampled] : [];
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const ZERO_COST = {
|
|
115
|
+
particles: 0,
|
|
116
|
+
vertices: 0,
|
|
117
|
+
dynamicVertices: 0,
|
|
118
|
+
drawCalls: 0,
|
|
119
|
+
filterPasses: 0,
|
|
120
|
+
renderTexturePixels: 0,
|
|
121
|
+
textureBytes: 0,
|
|
122
|
+
bufferBytes: 0,
|
|
123
|
+
simulationSteps: 0
|
|
124
|
+
};
|
|
125
|
+
const DEFAULT_BOARD_LIMITS = DEFAULT_BOARD_RENDER_LIMITS;
|
|
126
|
+
function builtinDefinition(capability) {
|
|
261
127
|
return {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
duration: flattened.duration,
|
|
266
|
-
seed: input.seed,
|
|
267
|
-
restPose: input.restPose ?? {},
|
|
268
|
-
metadata: input.metadata ?? {}
|
|
128
|
+
...capability,
|
|
129
|
+
validate() {
|
|
130
|
+
return [];
|
|
269
131
|
},
|
|
270
|
-
|
|
271
|
-
|
|
132
|
+
estimateCost(params) {
|
|
133
|
+
return estimateBuiltinBoardClipCost({
|
|
134
|
+
kind: capability.id,
|
|
135
|
+
params
|
|
136
|
+
});
|
|
137
|
+
}
|
|
272
138
|
};
|
|
273
139
|
}
|
|
274
|
-
function addCost(target, source) {
|
|
275
|
-
for (const key of Object.keys(target)) target[key] += source[key] ?? 0;
|
|
276
|
-
}
|
|
277
140
|
var BoardExtensionRegistry = class {
|
|
278
141
|
#extensions = /* @__PURE__ */ new Map();
|
|
279
142
|
#presets = /* @__PURE__ */ new Map();
|
|
143
|
+
constructor() {
|
|
144
|
+
for (const capability of BOARD_BUILTIN_CAPABILITIES) this.register(builtinDefinition(capability));
|
|
145
|
+
}
|
|
280
146
|
register(definition) {
|
|
281
147
|
const key = `${definition.kind}:${definition.id}@${definition.version}`;
|
|
282
148
|
const target = definition.kind === "preset" ? this.#presets : this.#extensions;
|
|
@@ -285,9 +151,15 @@ var BoardExtensionRegistry = class {
|
|
|
285
151
|
return this;
|
|
286
152
|
}
|
|
287
153
|
capabilities() {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
154
|
+
return [...this.#extensions.values(), ...this.#presets.values()].map((definition) => ({
|
|
155
|
+
kind: definition.kind,
|
|
156
|
+
id: definition.id,
|
|
157
|
+
version: definition.version,
|
|
158
|
+
...definition.digest ? { digest: definition.digest } : {},
|
|
159
|
+
...definition.renderers ? { renderers: definition.renderers } : {},
|
|
160
|
+
...definition.fallbackId ? { fallbackId: definition.fallbackId } : {},
|
|
161
|
+
...definition.schema ? { schema: definition.schema } : {}
|
|
162
|
+
}));
|
|
291
163
|
}
|
|
292
164
|
compilePreset(id, version, params) {
|
|
293
165
|
const preset = this.#presets.get(`preset:${id}@${version}`);
|
|
@@ -295,88 +167,72 @@ var BoardExtensionRegistry = class {
|
|
|
295
167
|
return preset.compile(params);
|
|
296
168
|
}
|
|
297
169
|
validate(input) {
|
|
170
|
+
const parsed = BoardCompositionSchema.safeParse(input.composition);
|
|
171
|
+
if (!parsed.success) return {
|
|
172
|
+
valid: false,
|
|
173
|
+
diagnostics: parsed.error.issues.map((issue) => ({
|
|
174
|
+
severity: "error",
|
|
175
|
+
code: "INVALID_COMPOSITION",
|
|
176
|
+
message: issue.message,
|
|
177
|
+
path: issue.path.join(".")
|
|
178
|
+
})),
|
|
179
|
+
peakCost: { ...ZERO_COST }
|
|
180
|
+
};
|
|
298
181
|
const diagnostics = [];
|
|
182
|
+
const composition = parsed.data;
|
|
183
|
+
const cost = { ...ZERO_COST };
|
|
299
184
|
const events = [];
|
|
300
|
-
const
|
|
301
|
-
const persistentCost = { ...ZERO_COST };
|
|
302
|
-
for (const [index, effect] of (input.effects ?? []).entries()) {
|
|
303
|
-
const definition = this.#extensions.get(`effect:${effect.kind}@${effect.kindVersion}`);
|
|
304
|
-
if (!definition) {
|
|
305
|
-
diagnostics.push({
|
|
306
|
-
severity: "warning",
|
|
307
|
-
code: "UNKNOWN_EFFECT",
|
|
308
|
-
message: `No renderer is registered for ${effect.kind}@${effect.kindVersion}`,
|
|
309
|
-
path: `effects.${index}`
|
|
310
|
-
});
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
diagnostics.push(...definition.validate?.(effect.params) ?? []);
|
|
314
|
-
addCost(persistentCost, definition.estimateCost(effect.params, profile));
|
|
315
|
-
}
|
|
316
|
-
for (const [index, clip] of input.clips.entries()) {
|
|
185
|
+
for (const clip of composition.timeline.clips) {
|
|
317
186
|
const definition = this.#extensions.get(`clip:${clip.kind}@${clip.kindVersion}`);
|
|
318
187
|
if (!definition) {
|
|
319
188
|
diagnostics.push({
|
|
320
189
|
severity: "warning",
|
|
321
190
|
code: "UNKNOWN_CLIP",
|
|
322
|
-
message: `No renderer is registered for ${clip.kind}@${clip.kindVersion}
|
|
323
|
-
path: `clips.${index}`
|
|
191
|
+
message: `No renderer is registered for ${clip.kind}@${clip.kindVersion}`
|
|
324
192
|
});
|
|
325
193
|
continue;
|
|
326
194
|
}
|
|
195
|
+
diagnostics.push(...validateBuiltinBoardClip(clip, `composition.timeline.clips.${clip.id}`));
|
|
327
196
|
diagnostics.push(...definition.validate?.(clip.params) ?? []);
|
|
328
|
-
const
|
|
329
|
-
|
|
197
|
+
const estimate = definition.estimateCost(clip.params, input.profile ?? "high");
|
|
198
|
+
const clipCost = { ...ZERO_COST };
|
|
199
|
+
for (const key of Object.keys(clipCost)) clipCost[key] = estimate[key] ?? 0;
|
|
330
200
|
events.push({
|
|
331
201
|
at: clip.start,
|
|
332
202
|
direction: 1,
|
|
333
|
-
cost
|
|
334
|
-
}
|
|
203
|
+
cost: clipCost
|
|
204
|
+
});
|
|
205
|
+
events.push({
|
|
335
206
|
at: clip.start + clip.duration,
|
|
336
207
|
direction: -1,
|
|
337
|
-
cost
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
const cameraFocusClips = input.clips.map((clip, index) => ({
|
|
341
|
-
clip,
|
|
342
|
-
index
|
|
343
|
-
})).filter(({ clip }) => clip.kind === "camera.focus").sort((left, right) => left.clip.start - right.clip.start);
|
|
344
|
-
for (let index = 1; index < cameraFocusClips.length; index += 1) {
|
|
345
|
-
const previous = cameraFocusClips[index - 1];
|
|
346
|
-
const currentFocus = cameraFocusClips[index];
|
|
347
|
-
if (previous && currentFocus && currentFocus.clip.start < previous.clip.start + previous.clip.duration) diagnostics.push({
|
|
348
|
-
severity: "error",
|
|
349
|
-
code: "OVERLAPPING_CAMERA_FOCUS",
|
|
350
|
-
message: "camera.focus clips must not overlap",
|
|
351
|
-
path: `clips.${currentFocus.index}.start`
|
|
208
|
+
cost: clipCost
|
|
352
209
|
});
|
|
353
210
|
}
|
|
354
211
|
events.sort((left, right) => left.at - right.at || left.direction - right.direction);
|
|
355
|
-
const
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
peak[key] = Math.max(peak[key], current[key]);
|
|
212
|
+
const active = { ...ZERO_COST };
|
|
213
|
+
for (const event of events) for (const key of Object.keys(active)) {
|
|
214
|
+
active[key] += event.cost[key] * event.direction;
|
|
215
|
+
cost[key] = Math.max(cost[key], active[key]);
|
|
360
216
|
}
|
|
217
|
+
for (const effect of input.effects ?? []) if (effect.kind === "effects.pulse" || effect.kind === "effects.float") cost.drawCalls += 1;
|
|
361
218
|
const limits = input.limits ?? DEFAULT_BOARD_LIMITS;
|
|
362
|
-
for (const key of Object.keys(
|
|
219
|
+
for (const key of Object.keys(cost)) if (cost[key] > limits[key]) diagnostics.push({
|
|
363
220
|
severity: "warning",
|
|
364
221
|
code: "RENDER_BUDGET_EXCEEDED",
|
|
365
|
-
message: `${key} peaks at ${
|
|
222
|
+
message: `${key} peaks at ${cost[key]}, above ${limits[key]}`,
|
|
366
223
|
path: key,
|
|
367
224
|
adaptation: { quality: "lower" }
|
|
368
225
|
});
|
|
369
226
|
return {
|
|
370
227
|
valid: !diagnostics.some((item) => item.severity === "error"),
|
|
371
228
|
diagnostics,
|
|
372
|
-
peakCost:
|
|
229
|
+
peakCost: cost
|
|
373
230
|
};
|
|
374
231
|
}
|
|
375
232
|
};
|
|
376
|
-
function createBoardExtensionRegistry(
|
|
377
|
-
|
|
378
|
-
if (input.builtins !== false) for (const capability of BUILTIN_CAPABILITIES) registry.register(builtinDefinition(capability));
|
|
379
|
-
return registry;
|
|
233
|
+
function createBoardExtensionRegistry() {
|
|
234
|
+
return new BoardExtensionRegistry();
|
|
380
235
|
}
|
|
236
|
+
const BOARD_CHANNELS = BOARD_ANIMATION_CHANNELS;
|
|
381
237
|
//#endregion
|
|
382
|
-
export { BoardExtensionRegistry, DEFAULT_BOARD_LIMITS,
|
|
238
|
+
export { BOARD_CHANNELS, BoardExtensionRegistry, DEFAULT_BOARD_LIMITS, compileComposition, composition, createBoardExtensionRegistry, proceduralClip, sampleCompositionTracks, sampleEasing, sampleTrack, track };
|
package/dist/board/geometry.js
CHANGED
|
@@ -538,19 +538,19 @@ function cameraForRect(content, surface, options = {
|
|
|
538
538
|
}
|
|
539
539
|
function rectForCameraFocus(focus, getFrame) {
|
|
540
540
|
if (focus.type === "rect") return focus.rect;
|
|
541
|
-
if (focus.type === "
|
|
542
|
-
const frame = getFrame(focus.
|
|
541
|
+
if (focus.type === "item") {
|
|
542
|
+
const frame = getFrame(focus.itemId);
|
|
543
543
|
return frame ? itemBounds(frame) : null;
|
|
544
544
|
}
|
|
545
545
|
if (focus.type === "frame") {
|
|
546
546
|
const frame = getFrame(focus.frameId);
|
|
547
547
|
return frame ? itemBounds(frame) : null;
|
|
548
548
|
}
|
|
549
|
-
const frames = focus.
|
|
549
|
+
const frames = focus.itemIds.flatMap((id) => {
|
|
550
550
|
const frame = getFrame(id);
|
|
551
551
|
return frame ? [frame] : [];
|
|
552
552
|
});
|
|
553
|
-
return frames.length === focus.
|
|
553
|
+
return frames.length === focus.itemIds.length ? selectionBounds(frames) : null;
|
|
554
554
|
}
|
|
555
555
|
function cameraForFocus(params, getFrame, surface) {
|
|
556
556
|
const rect = rectForCameraFocus(params.focus, getFrame);
|
package/dist/board/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../protocol/dist/board-constants.js";
|
|
2
2
|
import { AUTO_BOARD_CONNECTION_ANCHOR, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardRelationSchema, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_RELATION, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, flipBoardConnection, normalizeBoardConnectionStyle } from "../protocol/dist/board-connection.js";
|
|
3
|
+
import { BoardTrackInterpolation } from "../protocol/dist/board-composition.js";
|
|
3
4
|
import { BoardColorId } from "../protocol/dist/board-node.js";
|
|
4
5
|
import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardCameraFocus, BoardCameraFocusParams, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, BoardCameraState, BoardCameraStateSchema, BoardManifest, BoardNodeRecord, BoardRecord, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
|
|
5
6
|
import "../protocol/dist/index.js";
|
|
6
|
-
import { BoardExtensionDefinition, BoardExtensionRegistry, BoardPresetDefinition,
|
|
7
|
+
import { BOARD_CHANNELS, BoardExtensionDefinition, BoardExtensionRegistry, BoardPresetDefinition, CompositionInput, DEFAULT_BOARD_LIMITS, ProceduralClipInput, QualityProfile, RenderBounds, SampledTrack, TrackInput, compileComposition, composition, createBoardExtensionRegistry, proceduralClip, sampleCompositionTracks, sampleEasing, sampleTrack, track } from "./animation.js";
|
|
7
8
|
import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
|
|
8
9
|
import { BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAudioItem, BoardAudioItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardPoint, BoardPointSchema, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, DrawPoint, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, SpaceFileRef, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections } from "../protocol/dist/board-document.js";
|
|
9
10
|
import { BOARD_NODE_SOURCE, DEFAULT_BOARD_APPEARANCE, ITEM_BASE_KEYS, WireBackedBoardItem, boardBootstrapToDocument, boardNodeToItem, isRecord, nodeInputFromRecord, sourceForItem } from "./codec.js";
|
|
@@ -22,7 +23,6 @@ import { BoardStyledToolId, BoardToolStyleMap, BoardToolStylePatch, DEFAULT_BOAR
|
|
|
22
23
|
import { boardImageKeySource, imageAssetKey } from "./image-key.js";
|
|
23
24
|
import { BoardMediaKind, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind } from "./media.js";
|
|
24
25
|
import { BoardAssetSource, BoardPlayableMedia, playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache } from "./media-playback.js";
|
|
25
|
-
import { boardAppearanceOperation,
|
|
26
|
-
import { BoardInputError, BoardNodeFrameInput, BoardNodeSpec, assertBoardNodes, assertBoardTransactionNodeCreates, createBoardNode, validateBoardNodes } from "./nodes.js";
|
|
26
|
+
import { boardAppearanceOperation, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardPlaybackPolicyOperation, boardTitleOperation, patchBoardAppearance } from "./mutation.js";
|
|
27
27
|
import { featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot } from "./task.js";
|
|
28
|
-
export { AUTO_BOARD_CONNECTION_ANCHOR, type ArrowShapeProps, type AudioShapeProps, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAssetSource, BoardAudioItem, BoardAudioItemSchema, type BoardCameraFocus, type BoardCameraFocusParams, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, type BoardCameraState, BoardCameraStateSchema, BoardColorEntry, type BoardColorId, BoardColorValue, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema,
|
|
28
|
+
export { AUTO_BOARD_CONNECTION_ANCHOR, type ArrowShapeProps, type AudioShapeProps, BOARD_CHANNELS, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAssetSource, BoardAudioItem, BoardAudioItemSchema, type BoardCameraFocus, type BoardCameraFocusParams, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, type BoardCameraState, BoardCameraStateSchema, BoardColorEntry, type BoardColorId, BoardColorValue, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, type BoardManifest, BoardMediaKind, BoardMediaSnapshot, BoardMediaSnapshotSchema, type BoardNodeRecord, BoardNormalizedPoint, BoardPlayableMedia, BoardPoint, BoardPointSchema, BoardPresetDefinition, type BoardRecord, BoardRelationSchema, BoardRemoteUrlSchema, BoardScreenOffset, BoardScreenPoint, BoardShapeColors, BoardStyledToolId, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardToolStyleMap, BoardToolStylePatch, type BoardTrackInterpolation, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, BoardWorldOffset, BoardWorldPoint, BoardWorldRect, BuildSnapshotInput, CONNECTION_ENDPOINT_GAP, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CompositionInput, ConnectionIndex, CornerResizeHandle, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_RELATION, DEFAULT_BOARD_TOOL_STYLES, DrawPoint, DrawPointSchema, type DrawShapeProps, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, FileAvailability, FilePreviewKind, FrameLookup, GEO_KINDS, type GeoKind, type GeoShapeProps, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, type HandleDragResult, ITEM_BASE_KEYS, type ImageShapeProps, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, ProceduralClipInput, QualityProfile, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, RenderBounds, ResizeHandle, ResolvedArrow, ResolvedConnection, ResolvedConnectionEndpoint, ResolvedCover, SampledTrack, ScreenPoint, type ShapeCapabilities, ShapeDefinition, type ShapeGeometry, type ShapeHandle, type ShapeHandleId, type ShapeResizeMode, Size, SpaceFileRef, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, type TextShapeProps, TrackInput, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, type VideoShapeProps, WireBackedBoardItem, WorldPoint, anchorPointOnFrame, anchorToWorld, angleFromCenter, arrowBounds, arrowFrame, autoConnectionSide, availabilityFromError, boardAppearanceOperation, boardBootstrapToDocument, boardColorCssVar, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardPlaybackPolicyOperation, boardTextLineHeight, boardTitleOperation, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, cameraForFocus, cameraForRect, cameraForState, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, compileComposition, composition, computeDrawBounds, connectionArrowheads, connectionBounds, connectionHitTest, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, createBoardExtensionRegistry, createBoardToolStyles, createConnectionIndex, definitionForItem, degToRad, distanceToArrow, distanceToConnection, distanceToStroke, expandRect, exportConnectionBounds, exportItemBounds, featuredTaskArtifact, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, flipBoardConnection, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, getShapeDefinition, handlePosition, imageAssetKey, inferBoardMediaKind, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isPublicBoardRemoteAddress, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardConnectionStyle, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, normalizedPoint, panBy, parseBoardDocument, parseBoardItemLoose, parseBoardManifest, patchBoardAppearance, pathMidpoint, pickBoardColor, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, pointsBounds, proceduralClip, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, registerShapeDefinition, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveConnection, resolveCoverRef, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleArrow, sampleCompositionTracks, sampleEasing, sampleRadius, sampleTrack, scaleFrames, screenOffset, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, track, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, visibleWorldRect, withResolvedConnections, worldOffset, worldPoint, worldRect, worldToAnchor, worldToScreen, zoomAround };
|