@excalimate/mcp-server 0.1.0 → 0.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 +176 -16
- package/dist/checkpoint-store.d.ts +1 -0
- package/dist/checkpoint-store.d.ts.map +1 -1
- package/dist/checkpoint-store.js +23 -2
- package/dist/checkpoint-store.js.map +1 -1
- package/dist/httpServer.d.ts +4 -0
- package/dist/httpServer.d.ts.map +1 -0
- package/dist/httpServer.js +199 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -177
- package/dist/index.js.map +1 -1
- package/dist/server/animationTools.d.ts +9 -0
- package/dist/server/animationTools.d.ts.map +1 -0
- package/dist/server/animationTools.js +254 -0
- package/dist/server/animationTools.js.map +1 -0
- package/dist/server/checkpointTools.d.ts +5 -0
- package/dist/server/checkpointTools.d.ts.map +1 -0
- package/dist/server/checkpointTools.js +22 -0
- package/dist/server/checkpointTools.js.map +1 -0
- package/dist/server/elementNormalizer.d.ts +3 -0
- package/dist/server/elementNormalizer.d.ts.map +1 -0
- package/dist/server/elementNormalizer.js +52 -0
- package/dist/server/elementNormalizer.js.map +1 -0
- package/dist/server/geometry.d.ts +24 -0
- package/dist/server/geometry.d.ts.map +1 -0
- package/dist/server/geometry.js +102 -0
- package/dist/server/geometry.js.map +1 -0
- package/dist/server/queryTools.d.ts +28 -0
- package/dist/server/queryTools.d.ts.map +1 -0
- package/dist/server/queryTools.js +107 -0
- package/dist/server/queryTools.js.map +1 -0
- package/dist/server/referenceText.d.ts +3 -0
- package/dist/server/referenceText.d.ts.map +1 -0
- package/dist/server/referenceText.js +268 -0
- package/dist/server/referenceText.js.map +1 -0
- package/dist/server/sceneTools.d.ts +4 -0
- package/dist/server/sceneTools.d.ts.map +1 -0
- package/dist/server/sceneTools.js +86 -0
- package/dist/server/sceneTools.js.map +1 -0
- package/dist/server/shareTools.d.ts +11 -0
- package/dist/server/shareTools.d.ts.map +1 -0
- package/dist/server/shareTools.js +81 -0
- package/dist/server/shareTools.js.map +1 -0
- package/dist/server/stateContext.d.ts +21 -0
- package/dist/server/stateContext.d.ts.map +1 -0
- package/dist/server/stateContext.js +85 -0
- package/dist/server/stateContext.js.map +1 -0
- package/dist/server.d.ts +5 -10
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +24 -891
- package/dist/server.js.map +1 -1
- package/dist/shareRoutes.d.ts +4 -0
- package/dist/shareRoutes.d.ts.map +1 -0
- package/dist/shareRoutes.js +44 -0
- package/dist/shareRoutes.js.map +1 -0
- package/dist/stdioServer.d.ts +3 -0
- package/dist/stdioServer.d.ts.map +1 -0
- package/dist/stdioServer.js +5 -0
- package/dist/stdioServer.js.map +1 -0
- package/package.json +6 -2
- package/SKILL.md +0 -110
- package/references/REFERENCE.md +0 -192
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
let _elementIndexCounter = 0;
|
|
3
|
+
export function normalizeElement(el) {
|
|
4
|
+
const index = el.index ?? `a${_elementIndexCounter++}`;
|
|
5
|
+
return {
|
|
6
|
+
angle: 0,
|
|
7
|
+
strokeColor: '#1e1e1e',
|
|
8
|
+
backgroundColor: 'transparent',
|
|
9
|
+
fillStyle: 'solid',
|
|
10
|
+
strokeWidth: 2,
|
|
11
|
+
strokeStyle: 'solid',
|
|
12
|
+
roughness: 1,
|
|
13
|
+
groupIds: [],
|
|
14
|
+
frameId: null,
|
|
15
|
+
index,
|
|
16
|
+
roundness: null,
|
|
17
|
+
boundElements: null,
|
|
18
|
+
updated: Date.now(),
|
|
19
|
+
link: null,
|
|
20
|
+
locked: false,
|
|
21
|
+
isDeleted: false,
|
|
22
|
+
...(el.type === 'text' ? {
|
|
23
|
+
fontSize: 20,
|
|
24
|
+
fontFamily: 5,
|
|
25
|
+
textAlign: 'left',
|
|
26
|
+
verticalAlign: 'top',
|
|
27
|
+
lineHeight: 1.25,
|
|
28
|
+
baseline: 0,
|
|
29
|
+
containerId: null,
|
|
30
|
+
originalText: el.text ?? '',
|
|
31
|
+
autoResize: true,
|
|
32
|
+
} : {}),
|
|
33
|
+
...(el.type === 'arrow' || el.type === 'line' ? {
|
|
34
|
+
points: el.points ?? [[0, 0], [el.width ?? 100, el.height ?? 0]],
|
|
35
|
+
startBinding: null,
|
|
36
|
+
endBinding: null,
|
|
37
|
+
startArrowhead: null,
|
|
38
|
+
endArrowhead: el.type === 'arrow' ? 'arrow' : null,
|
|
39
|
+
lastCommittedPoint: null,
|
|
40
|
+
} : {}),
|
|
41
|
+
...el,
|
|
42
|
+
opacity: 100,
|
|
43
|
+
...(el.type === 'text' && !el.containerId ? { autoResize: true } : {}),
|
|
44
|
+
seed: el.seed ?? (Math.random() * 2147483647 | 0),
|
|
45
|
+
version: el.version ?? 1,
|
|
46
|
+
versionNonce: el.versionNonce ?? (Math.random() * 2147483647 | 0),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function normalizeElements(elements) {
|
|
50
|
+
return elements.map(normalizeElement);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=elementNormalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elementNormalizer.js","sourceRoot":"","sources":["../../src/server/elementNormalizer.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,IAAI,oBAAoB,GAAG,CAAC,CAAC;AAE7B,MAAM,UAAU,gBAAgB,CAAC,EAAO;IACtC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,IAAI,oBAAoB,EAAE,EAAE,CAAC;IAEvD,OAAO;QACL,KAAK,EAAE,CAAC;QACR,WAAW,EAAE,SAAS;QACtB,eAAe,EAAE,aAAa;QAC9B,SAAS,EAAE,OAAO;QAClB,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,CAAC;QACZ,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,IAAI;QACb,KAAK;QACL,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;QACnB,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,KAAK;QAChB,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC;YACvB,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,MAAM;YACjB,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE;YAC3B,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC;YAC9C,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;YAChE,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,IAAI;YAChB,cAAc,EAAE,IAAI;YACpB,YAAY,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAClD,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,EAAE;QACL,OAAO,EAAE,GAAG;QACZ,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,GAAG,CAAC,CAAC;QACjD,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC;QACxB,YAAY,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,GAAG,CAAC,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAe;IAC/C,OAAO,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AnimationTrack, ServerState } from '../types.js';
|
|
2
|
+
export declare const ORIGIN_MAP: Record<string, [number, number]>;
|
|
3
|
+
export declare function getElementBounds(el: any): {
|
|
4
|
+
minX: number;
|
|
5
|
+
minY: number;
|
|
6
|
+
maxX: number;
|
|
7
|
+
maxY: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function interpolateTrackAt(track: AnimationTrack, time: number): number;
|
|
10
|
+
export declare function getAnimatedBoundsAt(state: ServerState, elId: string, time: number): {
|
|
11
|
+
minX: number;
|
|
12
|
+
minY: number;
|
|
13
|
+
maxX: number;
|
|
14
|
+
maxY: number;
|
|
15
|
+
} | null;
|
|
16
|
+
export declare function getCameraRectAt(state: ServerState, time: number): {
|
|
17
|
+
left: number;
|
|
18
|
+
top: number;
|
|
19
|
+
right: number;
|
|
20
|
+
bottom: number;
|
|
21
|
+
cx: number;
|
|
22
|
+
cy: number;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/server/geometry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/D,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAUvD,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,GAAG,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAapG;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAY9E;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgBnE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAgBtF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ASPECT_RATIOS, PROPERTY_DEFAULTS } from '../types.js';
|
|
2
|
+
export const ORIGIN_MAP = {
|
|
3
|
+
'top-left': [0, 0],
|
|
4
|
+
'top': [0.5, 0],
|
|
5
|
+
'top-right': [1, 0],
|
|
6
|
+
'left': [0, 0.5],
|
|
7
|
+
'center': [0.5, 0.5],
|
|
8
|
+
'right': [1, 0.5],
|
|
9
|
+
'bottom-left': [0, 1],
|
|
10
|
+
'bottom': [0.5, 1],
|
|
11
|
+
'bottom-right': [1, 1],
|
|
12
|
+
};
|
|
13
|
+
export function getElementBounds(el) {
|
|
14
|
+
if (el.points?.length > 0) {
|
|
15
|
+
let minX = Infinity;
|
|
16
|
+
let minY = Infinity;
|
|
17
|
+
let maxX = -Infinity;
|
|
18
|
+
let maxY = -Infinity;
|
|
19
|
+
for (const [px, py] of el.points) {
|
|
20
|
+
const ax = el.x + px;
|
|
21
|
+
const ay = el.y + py;
|
|
22
|
+
if (ax < minX)
|
|
23
|
+
minX = ax;
|
|
24
|
+
if (ay < minY)
|
|
25
|
+
minY = ay;
|
|
26
|
+
if (ax > maxX)
|
|
27
|
+
maxX = ax;
|
|
28
|
+
if (ay > maxY)
|
|
29
|
+
maxY = ay;
|
|
30
|
+
}
|
|
31
|
+
return { minX, minY, maxX, maxY };
|
|
32
|
+
}
|
|
33
|
+
const x1 = Math.min(el.x, el.x + el.width);
|
|
34
|
+
const y1 = Math.min(el.y, el.y + el.height);
|
|
35
|
+
return { minX: x1, minY: y1, maxX: x1 + Math.abs(el.width), maxY: y1 + Math.abs(el.height) };
|
|
36
|
+
}
|
|
37
|
+
export function interpolateTrackAt(track, time) {
|
|
38
|
+
const kfs = track.keyframes;
|
|
39
|
+
if (kfs.length === 0)
|
|
40
|
+
return PROPERTY_DEFAULTS[track.property];
|
|
41
|
+
if (time <= kfs[0].time)
|
|
42
|
+
return kfs[0].value;
|
|
43
|
+
if (time >= kfs[kfs.length - 1].time)
|
|
44
|
+
return kfs[kfs.length - 1].value;
|
|
45
|
+
for (let i = 0; i < kfs.length - 1; i++) {
|
|
46
|
+
if (time >= kfs[i].time && time <= kfs[i + 1].time) {
|
|
47
|
+
const t = (time - kfs[i].time) / (kfs[i + 1].time - kfs[i].time);
|
|
48
|
+
return kfs[i].value + (kfs[i + 1].value - kfs[i].value) * t;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return kfs[kfs.length - 1].value;
|
|
52
|
+
}
|
|
53
|
+
export function getAnimatedBoundsAt(state, elId, time) {
|
|
54
|
+
const el = state.scene.elements.find((e) => e.id === elId);
|
|
55
|
+
if (!el)
|
|
56
|
+
return null;
|
|
57
|
+
const base = getElementBounds(el);
|
|
58
|
+
const tracks = state.timeline.tracks.filter((t) => t.targetId === elId);
|
|
59
|
+
let tx = 0;
|
|
60
|
+
let ty = 0;
|
|
61
|
+
let sx = 1;
|
|
62
|
+
let sy = 1;
|
|
63
|
+
for (const track of tracks) {
|
|
64
|
+
const v = interpolateTrackAt(track, time);
|
|
65
|
+
if (track.property === 'translateX')
|
|
66
|
+
tx = v;
|
|
67
|
+
if (track.property === 'translateY')
|
|
68
|
+
ty = v;
|
|
69
|
+
if (track.property === 'scaleX')
|
|
70
|
+
sx = v;
|
|
71
|
+
if (track.property === 'scaleY')
|
|
72
|
+
sy = v;
|
|
73
|
+
}
|
|
74
|
+
const w = (base.maxX - base.minX) * sx;
|
|
75
|
+
const h = (base.maxY - base.minY) * sy;
|
|
76
|
+
return { minX: base.minX + tx, minY: base.minY + ty, maxX: base.minX + tx + w, maxY: base.minY + ty + h };
|
|
77
|
+
}
|
|
78
|
+
export function getCameraRectAt(state, time) {
|
|
79
|
+
const cf = state.cameraFrame;
|
|
80
|
+
const camTracks = state.timeline.tracks.filter((t) => t.targetId === '__camera_frame__');
|
|
81
|
+
let tx = 0;
|
|
82
|
+
let ty = 0;
|
|
83
|
+
let sx = 1;
|
|
84
|
+
let sy = 1;
|
|
85
|
+
for (const track of camTracks) {
|
|
86
|
+
const v = interpolateTrackAt(track, time);
|
|
87
|
+
if (track.property === 'translateX')
|
|
88
|
+
tx = v;
|
|
89
|
+
if (track.property === 'translateY')
|
|
90
|
+
ty = v;
|
|
91
|
+
if (track.property === 'scaleX')
|
|
92
|
+
sx = v;
|
|
93
|
+
if (track.property === 'scaleY')
|
|
94
|
+
sy = v;
|
|
95
|
+
}
|
|
96
|
+
const w = cf.width * sx;
|
|
97
|
+
const h = (cf.width / (ASPECT_RATIOS[cf.aspectRatio] ?? 16 / 9)) * sy;
|
|
98
|
+
const cx = cf.x + tx;
|
|
99
|
+
const cy = cf.y + ty;
|
|
100
|
+
return { left: cx - w / 2, top: cy - h / 2, right: cx + w / 2, bottom: cy + h / 2, cx, cy };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../src/server/geometry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAqC;IAC1D,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAClB,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IACf,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACnB,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;IAChB,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;IACjB,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAO;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,IAAI,GAAG,QAAQ,CAAC;QAAC,IAAI,IAAI,GAAG,QAAQ,CAAC;QAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC;QAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC;QACrF,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3C,IAAI,EAAE,GAAG,IAAI;gBAAE,IAAI,GAAG,EAAE,CAAC;YAAC,IAAI,EAAE,GAAG,IAAI;gBAAE,IAAI,GAAG,EAAE,CAAC;YACnD,IAAI,EAAE,GAAG,IAAI;gBAAE,IAAI,GAAG,EAAE,CAAC;YAAC,IAAI,EAAE,GAAG,IAAI;gBAAE,IAAI,GAAG,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAqB,EAAE,IAAY;IACpE,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC;IAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,IAAY,EACZ,IAAY;IAEZ,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAChE,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;IAC7E,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY;YAAE,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY;YAAE,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAAE,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACvC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5G,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAkB,EAClB,IAAY;IAEZ,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,kBAAkB,CAAC,CAAC;IAC9F,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY;YAAE,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY;YAAE,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAAE,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACtE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACrB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAC9F,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { StateContext } from './stateContext.js';
|
|
3
|
+
interface Geometry {
|
|
4
|
+
getElementBounds: (el: any) => {
|
|
5
|
+
minX: number;
|
|
6
|
+
minY: number;
|
|
7
|
+
maxX: number;
|
|
8
|
+
maxY: number;
|
|
9
|
+
};
|
|
10
|
+
getAnimatedBoundsAt: (state: any, elId: string, time: number) => {
|
|
11
|
+
minX: number;
|
|
12
|
+
minY: number;
|
|
13
|
+
maxX: number;
|
|
14
|
+
maxY: number;
|
|
15
|
+
} | null;
|
|
16
|
+
getCameraRectAt: (state: any, time: number) => {
|
|
17
|
+
left: number;
|
|
18
|
+
top: number;
|
|
19
|
+
right: number;
|
|
20
|
+
bottom: number;
|
|
21
|
+
cx: number;
|
|
22
|
+
cy: number;
|
|
23
|
+
};
|
|
24
|
+
interpolateTrackAt: (track: any, time: number) => number;
|
|
25
|
+
}
|
|
26
|
+
export declare function registerQueryTools(server: McpServer, ctx: StateContext, geometry: Geometry): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=queryTools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryTools.d.ts","sourceRoot":"","sources":["../../src/server/queryTools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,UAAU,QAAQ;IAChB,gBAAgB,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,mBAAmB,EAAE,CACnB,KAAK,EAAE,GAAG,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,KACT;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,eAAe,EAAE,CACf,KAAK,EAAE,GAAG,EACV,IAAI,EAAE,MAAM,KACT;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,kBAAkB,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1D;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAiHN"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerQueryTools(server, ctx, geometry) {
|
|
3
|
+
server.tool('are_items_in_line', 'Check if the given items are aligned horizontally or vertically (within a tolerance).', {
|
|
4
|
+
ids: z.array(z.string()).describe('Element IDs to check'),
|
|
5
|
+
axis: z.enum(['horizontal', 'vertical']).describe('Alignment axis'),
|
|
6
|
+
tolerance: z.number().optional().describe('Max deviation in scene units (default 10)'),
|
|
7
|
+
}, async ({ ids, axis, tolerance = 10 }) => {
|
|
8
|
+
const state = ctx.getState();
|
|
9
|
+
const centers = [];
|
|
10
|
+
for (const id of ids) {
|
|
11
|
+
const el = state.scene.elements.find((e) => e.id === id);
|
|
12
|
+
if (!el)
|
|
13
|
+
return { content: [{ type: 'text', text: `Element "${id}" not found.` }] };
|
|
14
|
+
const b = geometry.getElementBounds(el);
|
|
15
|
+
centers.push({ id, cx: (b.minX + b.maxX) / 2, cy: (b.minY + b.maxY) / 2 });
|
|
16
|
+
}
|
|
17
|
+
const values = centers.map(c => axis === 'horizontal' ? c.cy : c.cx);
|
|
18
|
+
const avg = values.reduce((a, b) => a + b, 0) / values.length;
|
|
19
|
+
const maxDev = Math.max(...values.map(v => Math.abs(v - avg)));
|
|
20
|
+
const aligned = maxDev <= tolerance;
|
|
21
|
+
const details = centers.map(c => `${c.id}: (${Math.round(c.cx)}, ${Math.round(c.cy)})`).join(', ');
|
|
22
|
+
return { content: [{ type: 'text', text: `${aligned ? '✅ Aligned' : '❌ Not aligned'} (max deviation: ${Math.round(maxDev)}px, tolerance: ${tolerance}px). Centers: ${details}` }] };
|
|
23
|
+
});
|
|
24
|
+
server.tool('is_camera_centered', 'Check if the camera is centered on the scene content (horizontally, vertically, or both).', {
|
|
25
|
+
axis: z.enum(['horizontal', 'vertical', 'both']).describe('Which axis to check'),
|
|
26
|
+
time: z.number().min(0).default(0).describe('Time in ms to check at'),
|
|
27
|
+
tolerance: z.number().optional().describe('Max deviation (default 20)'),
|
|
28
|
+
}, async ({ axis, time, tolerance = 20 }) => {
|
|
29
|
+
const state = ctx.getState();
|
|
30
|
+
let sMinX = Infinity;
|
|
31
|
+
let sMinY = Infinity;
|
|
32
|
+
let sMaxX = -Infinity;
|
|
33
|
+
let sMaxY = -Infinity;
|
|
34
|
+
for (const el of state.scene.elements) {
|
|
35
|
+
const b = geometry.getElementBounds(el);
|
|
36
|
+
if (b.minX < sMinX)
|
|
37
|
+
sMinX = b.minX;
|
|
38
|
+
if (b.minY < sMinY)
|
|
39
|
+
sMinY = b.minY;
|
|
40
|
+
if (b.maxX > sMaxX)
|
|
41
|
+
sMaxX = b.maxX;
|
|
42
|
+
if (b.maxY > sMaxY)
|
|
43
|
+
sMaxY = b.maxY;
|
|
44
|
+
}
|
|
45
|
+
const sceneCX = (sMinX + sMaxX) / 2;
|
|
46
|
+
const sceneCY = (sMinY + sMaxY) / 2;
|
|
47
|
+
const cam = geometry.getCameraRectAt(state, time);
|
|
48
|
+
const dxOk = Math.abs(cam.cx - sceneCX) <= tolerance;
|
|
49
|
+
const dyOk = Math.abs(cam.cy - sceneCY) <= tolerance;
|
|
50
|
+
const ok = axis === 'horizontal' ? dxOk : axis === 'vertical' ? dyOk : dxOk && dyOk;
|
|
51
|
+
return { content: [{ type: 'text', text: `${ok ? '✅ Centered' : '❌ Not centered'} (scene center: ${Math.round(sceneCX)},${Math.round(sceneCY)}, camera center: ${Math.round(cam.cx)},${Math.round(cam.cy)}, offsets: dx=${Math.round(cam.cx - sceneCX)} dy=${Math.round(cam.cy - sceneCY)})` }] };
|
|
52
|
+
});
|
|
53
|
+
server.tool('items_visible_in_camera', 'Check what percentage of items are visible in the camera frame at a given time.', {
|
|
54
|
+
time: z.number().min(0).default(0).describe('Time in ms'),
|
|
55
|
+
}, async ({ time }) => {
|
|
56
|
+
const state = ctx.getState();
|
|
57
|
+
const cam = geometry.getCameraRectAt(state, time);
|
|
58
|
+
const elements = state.scene.elements.filter((e) => !e.isDeleted && e.id !== '__camera_frame__');
|
|
59
|
+
let visible = 0;
|
|
60
|
+
const details = [];
|
|
61
|
+
for (const el of elements) {
|
|
62
|
+
const b = geometry.getAnimatedBoundsAt(state, el.id, time);
|
|
63
|
+
if (!b)
|
|
64
|
+
continue;
|
|
65
|
+
const opTrack = state.timeline.tracks.find((t) => t.targetId === el.id && t.property === 'opacity');
|
|
66
|
+
const opacity = opTrack ? geometry.interpolateTrackAt(opTrack, time) : 1;
|
|
67
|
+
const inView = b.maxX > cam.left && b.minX < cam.right && b.maxY > cam.top && b.minY < cam.bottom;
|
|
68
|
+
const isVisible = inView && opacity > 0.01;
|
|
69
|
+
if (isVisible)
|
|
70
|
+
visible++;
|
|
71
|
+
details.push(`${el.id}: ${isVisible ? '✅' : '❌'} (opacity=${(opacity * 100).toFixed(0)}%, inView=${inView})`);
|
|
72
|
+
}
|
|
73
|
+
const pct = elements.length > 0 ? Math.round(visible / elements.length * 100) : 0;
|
|
74
|
+
return { content: [{ type: 'text', text: `${visible}/${elements.length} items visible (${pct}%) at ${time}ms.\n${details.join('\n')}` }] };
|
|
75
|
+
});
|
|
76
|
+
server.tool('animations_of_item', 'Returns a timeline description of all animations an item goes through.', {
|
|
77
|
+
targetId: z.string().describe('Element ID'),
|
|
78
|
+
}, async ({ targetId }) => {
|
|
79
|
+
const state = ctx.getState();
|
|
80
|
+
const tracks = state.timeline.tracks.filter((t) => t.targetId === targetId);
|
|
81
|
+
if (tracks.length === 0) {
|
|
82
|
+
return { content: [{ type: 'text', text: `No animations for "${targetId}".` }] };
|
|
83
|
+
}
|
|
84
|
+
const lines = [`Animations for "${targetId}":`];
|
|
85
|
+
for (const track of tracks) {
|
|
86
|
+
if (track.keyframes.length === 0)
|
|
87
|
+
continue;
|
|
88
|
+
lines.push(` ${track.property}:`);
|
|
89
|
+
for (let i = 0; i < track.keyframes.length; i++) {
|
|
90
|
+
const kf = track.keyframes[i];
|
|
91
|
+
const next = track.keyframes[i + 1];
|
|
92
|
+
if (next) {
|
|
93
|
+
const fromLabel = track.property === 'opacity' ? `${(kf.value * 100).toFixed(0)}%` : String(kf.value);
|
|
94
|
+
const toLabel = track.property === 'opacity' ? `${(next.value * 100).toFixed(0)}%` : String(next.value);
|
|
95
|
+
const direction = next.value > kf.value ? '↑' : next.value < kf.value ? '↓' : '→';
|
|
96
|
+
lines.push(` ${kf.time}ms ${fromLabel} ${direction} ${toLabel} ${next.time}ms (${kf.easing})`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
const label = track.property === 'opacity' ? `${(kf.value * 100).toFixed(0)}%` : String(kf.value);
|
|
100
|
+
lines.push(` ${kf.time}ms ${label} (hold)`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=queryTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryTools.js","sourceRoot":"","sources":["../../src/server/queryTools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,GAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,uFAAuF,EACvF;QACE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACzD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;KACvF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAA6C,EAAE,CAAC;QAC7D,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,EAAE;gBAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;YACpF,MAAM,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,IAAI,SAAS,CAAC;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnG,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,oBAAoB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,SAAS,iBAAiB,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IACtL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,2FAA2F,EAC3F;QACE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACrE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;KACxE,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAG,QAAQ,CAAC;QAAC,IAAI,KAAK,GAAG,QAAQ,CAAC;QAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAC;QAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAC;QACzF,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,CAAC,IAAI,GAAG,KAAK;gBAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC;YAAC,IAAI,CAAC,CAAC,IAAI,GAAG,KAAK;gBAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC;YACvE,IAAI,CAAC,CAAC,IAAI,GAAG,KAAK;gBAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC;YAAC,IAAI,CAAC,CAAC,IAAI,GAAG,KAAK;gBAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC;QACzE,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,SAAS,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,SAAS,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;QACpF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,mBAAmB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;IACpS,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,iFAAiF,EACjF;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;KAC1D,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC;QACtG,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;YACzG,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;YAClG,MAAM,SAAS,GAAG,MAAM,IAAI,OAAO,GAAG,IAAI,CAAC;YAC3C,IAAI,SAAS;gBAAE,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,MAAM,GAAG,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,IAAI,QAAQ,CAAC,MAAM,mBAAmB,GAAG,SAAS,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC7I,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,wEAAwE,EACxE;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;KAC5C,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QACnF,CAAC;QACD,MAAM,KAAK,GAAa,CAAC,mBAAmB,QAAQ,IAAI,CAAC,CAAC;QAC1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC3C,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;YACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpC,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;oBACtG,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACxG,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBAClF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,SAAS,IAAI,SAAS,IAAI,OAAO,IAAI,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;gBACpG,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;oBAClG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const REFERENCE_TEXT = "# Excalimate MCP Reference\n\n## Excalidraw Element Format\n\nEvery element has these base properties:\n```json\n{\n \"id\": \"unique-id\",\n \"type\": \"rectangle|ellipse|diamond|arrow|line|text|freedraw|image\",\n \"x\": 100, \"y\": 200,\n \"width\": 300, \"height\": 150,\n \"angle\": 0,\n \"strokeColor\": \"#1e1e1e\",\n \"backgroundColor\": \"transparent\",\n \"fillStyle\": \"solid\",\n \"strokeWidth\": 2,\n \"roughness\": 1,\n \"opacity\": 100,\n \"groupIds\": [],\n \"isDeleted\": false\n}\n```\n\n### Text Elements\n```json\n{\n \"type\": \"text\",\n \"text\": \"Hello World\",\n \"fontSize\": 20,\n \"fontFamily\": 5,\n \"textAlign\": \"center\",\n \"verticalAlign\": \"middle\"\n}\n```\n\n### Arrow/Line Elements\n```json\n{\n \"type\": \"arrow\",\n \"points\": [[0, 0], [200, 100]],\n \"startArrowhead\": null,\n \"endArrowhead\": \"arrow\",\n \"startBinding\": null,\n \"endBinding\": null\n}\n```\n\n### Bound Text (Label on Shape)\nCreate a text element with `containerId` pointing to the shape:\n```json\n{ \"type\": \"text\", \"containerId\": \"shape-id\", ... }\n```\nAnd add to the shape: `\"boundElements\": [{\"id\": \"text-id\", \"type\": \"text\"}]`\n\n## Color Palettes\n\n**Stroke**: #1e1e1e, #e03131, #2f9e44, #1971c2, #f08c00, #6741d9, #0c8599, #e8590c\n**Background**: transparent, #ffc9c9, #b2f2bb, #a5d8ff, #ffec99, #d0bfff, #99e9f2, #ffd8a8\n\n## Animatable Properties\n\n| Property | Range | Description |\n|----------|-------|-------------|\n| opacity | 0\u20131 | Element visibility (0=hidden, 1=visible) |\n| translateX | px | Horizontal position offset |\n| translateY | px | Vertical position offset |\n| scaleX | 0.1+ | Horizontal scale (1=normal) |\n| scaleY | 0.1+ | Vertical scale (1=normal) |\n| rotation | degrees | Rotation angle |\n| drawProgress | 0\u20131 | Stroke draw-on progress (for lines/arrows) |\n\n## Easing Types\n\nlinear, easeIn, easeOut, easeInOut, easeInQuad, easeOutQuad, easeInOutQuad,\neaseInCubic, easeOutCubic, easeInOutCubic, easeInBack, easeOutBack, easeInOutBack,\neaseInElastic, easeOutElastic, easeInBounce, easeOutBounce, step\n\n## Workflow\n\n1. Call `read_me` (this tool) to get the reference\n2. Call `create_scene` with Excalidraw elements JSON (or `clear_scene` to start fresh)\n3. Call `add_keyframe` or `add_keyframes_batch` to animate elements\n4. Use `create_sequence` for reveal animations\n5. Call `set_clip_range` to set export bounds\n6. Call `save_checkpoint` to persist\n7. User opens the checkpoint in the Excalimate web app for preview/export\n\nUse `clear_scene` to reset everything (elements + animations) or `clear_animation` to keep elements but remove all keyframes.\n\n## Example: Fade-in Rectangle\n\n```\n1. create_scene: [{\"id\":\"rect1\",\"type\":\"rectangle\",\"x\":100,\"y\":100,\"width\":200,\"height\":100,...}]\n2. add_keyframe: {targetId:\"rect1\", property:\"opacity\", time:0, value:0}\n3. add_keyframe: {targetId:\"rect1\", property:\"opacity\", time:1000, value:1, easing:\"easeOut\"}\n```\n";
|
|
2
|
+
export declare const EXAMPLES_TEXT = "# Excalimate \u2014 Few-Shot Examples\n\n## Example 1: Single Rectangle\n```\ncreate_scene({ elements: '[{\"id\":\"box1\",\"type\":\"rectangle\",\"x\":200,\"y\":150,\"width\":250,\"height\":120,\"strokeColor\":\"#1971c2\",\"backgroundColor\":\"#a5d8ff\",\"fillStyle\":\"solid\"}]' })\n```\n\n## Example 2: Rectangle with Bound Text Label\n```\ncreate_scene({ elements: '[{\"id\":\"server\",\"type\":\"rectangle\",\"x\":100,\"y\":100,\"width\":200,\"height\":80,\"strokeColor\":\"#1e1e1e\",\"backgroundColor\":\"#a5d8ff\",\"fillStyle\":\"solid\",\"boundElements\":[{\"id\":\"server-label\",\"type\":\"text\"}]},{\"id\":\"server-label\",\"type\":\"text\",\"x\":140,\"y\":125,\"width\":120,\"height\":30,\"text\":\"API Server\",\"fontSize\":20,\"fontFamily\":5,\"textAlign\":\"center\",\"verticalAlign\":\"middle\",\"containerId\":\"server\"}]' })\n```\n\n## Example 3: Two Shapes Connected by Arrow\n```\ncreate_scene({ elements: '[{\"id\":\"A\",\"type\":\"rectangle\",\"x\":100,\"y\":200,\"width\":150,\"height\":80,\"strokeColor\":\"#1e1e1e\",\"backgroundColor\":\"#b2f2bb\",\"fillStyle\":\"solid\"},{\"id\":\"B\",\"type\":\"rectangle\",\"x\":500,\"y\":200,\"width\":150,\"height\":80,\"strokeColor\":\"#1e1e1e\",\"backgroundColor\":\"#a5d8ff\",\"fillStyle\":\"solid\"},{\"id\":\"arrow1\",\"type\":\"arrow\",\"x\":250,\"y\":240,\"width\":250,\"height\":0,\"points\":[[0,0],[250,0]],\"endArrowhead\":\"arrow\",\"startBinding\":{\"elementId\":\"A\",\"focus\":0,\"gap\":1},\"endBinding\":{\"elementId\":\"B\",\"focus\":0,\"gap\":1}}]' })\n```\n\n## Example 4: Ellipse and Diamond\n```\nadd_elements({ elements: '[{\"id\":\"circle1\",\"type\":\"ellipse\",\"x\":300,\"y\":100,\"width\":120,\"height\":120,\"strokeColor\":\"#e03131\",\"backgroundColor\":\"#ffc9c9\",\"fillStyle\":\"solid\"},{\"id\":\"diamond1\",\"type\":\"diamond\",\"x\":500,\"y\":90,\"width\":140,\"height\":140,\"strokeColor\":\"#6741d9\",\"backgroundColor\":\"#d0bfff\",\"fillStyle\":\"solid\"}]' })\n```\n\n## Example 5: Multi-Point Line\n```\nadd_elements({ elements: '[{\"id\":\"line1\",\"type\":\"line\",\"x\":100,\"y\":300,\"width\":400,\"height\":80,\"points\":[[0,0],[200,-80],[400,0]],\"strokeColor\":\"#e03131\",\"strokeWidth\":3}]' })\n```\n\n## Example 6: Standalone Text\n```\nadd_elements({ elements: '[{\"id\":\"title\",\"type\":\"text\",\"x\":200,\"y\":50,\"width\":300,\"height\":50,\"text\":\"Architecture Overview\",\"fontSize\":36,\"fontFamily\":5,\"textAlign\":\"center\",\"strokeColor\":\"#1e1e1e\"}]' })\n```\n\n---\n\n# Animation Examples\n\n## Example 7: Fade In\n```\nadd_keyframe({ targetId: \"box1\", property: \"opacity\", time: 0, value: 0 })\nadd_keyframe({ targetId: \"box1\", property: \"opacity\", time: 800, value: 1, easing: \"easeOut\" })\n```\n\n## Example 8: Slide In from Left\n```\nadd_keyframes_batch({ keyframes: '[{\"targetId\":\"box1\",\"property\":\"translateX\",\"time\":0,\"value\":-300},{\"targetId\":\"box1\",\"property\":\"translateX\",\"time\":1000,\"value\":0,\"easing\":\"easeOutCubic\"},{\"targetId\":\"box1\",\"property\":\"opacity\",\"time\":0,\"value\":0},{\"targetId\":\"box1\",\"property\":\"opacity\",\"time\":500,\"value\":1,\"easing\":\"easeOut\"}]' })\n```\n\n## Example 9: Pop In from Center (Scale Up with Bounce)\n```\nadd_keyframes_batch({ keyframes: '[{\"targetId\":\"box1\",\"property\":\"scaleX\",\"time\":0,\"value\":0.3,\"scaleOrigin\":\"center\"},{\"targetId\":\"box1\",\"property\":\"scaleY\",\"time\":0,\"value\":0.3,\"scaleOrigin\":\"center\"},{\"targetId\":\"box1\",\"property\":\"scaleX\",\"time\":600,\"value\":1,\"easing\":\"easeOutBack\",\"scaleOrigin\":\"center\"},{\"targetId\":\"box1\",\"property\":\"scaleY\",\"time\":600,\"value\":1,\"easing\":\"easeOutBack\",\"scaleOrigin\":\"center\"},{\"targetId\":\"box1\",\"property\":\"opacity\",\"time\":0,\"value\":0},{\"targetId\":\"box1\",\"property\":\"opacity\",\"time\":300,\"value\":1}]' })\n```\n\n## Example 9b: Scale from Bottom Edge\n```\nadd_scale_animation({ targetId: \"box1\", origin: \"bottom\", keyframes: '[{\"time\":0,\"scaleX\":1,\"scaleY\":0},{\"time\":800,\"scaleX\":1,\"scaleY\":1,\"easing\":\"easeOutCubic\"}]' })\n```\nScale origins: center, top-left, top-right, bottom-left, bottom-right, top, bottom, left, right.\nAdd \"scaleOrigin\" per scaleX/scaleY keyframe in add_keyframes_batch, or use add_scale_animation for a single element.\n\n## Example 10: Draw In an Arrow (Stroke Animation)\n```\nadd_keyframe({ targetId: \"arrow1\", property: \"drawProgress\", time: 0, value: 0 })\nadd_keyframe({ targetId: \"arrow1\", property: \"drawProgress\", time: 1200, value: 1, easing: \"easeInOut\" })\n```\n\n## Example 11: Sequential Reveal \u2014 A \u2192 Arrow \u2192 B (Most Common Pattern)\n```\nadd_keyframes_batch({ keyframes: '[\n {\"targetId\":\"A\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"A\",\"property\":\"opacity\",\"time\":600,\"value\":1,\"easing\":\"easeOut\"},\n {\"targetId\":\"arrow1\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"arrow1\",\"property\":\"opacity\",\"time\":600,\"value\":0},\n {\"targetId\":\"arrow1\",\"property\":\"opacity\",\"time\":700,\"value\":1},\n {\"targetId\":\"arrow1\",\"property\":\"drawProgress\",\"time\":600,\"value\":0},\n {\"targetId\":\"arrow1\",\"property\":\"drawProgress\",\"time\":1800,\"value\":1,\"easing\":\"easeInOut\"},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":1800,\"value\":0},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":2400,\"value\":1,\"easing\":\"easeOut\"}\n]' })\n```\n\n## Example 12: Bidirectional Flow \u2014 A \u2194 B\n```\nadd_keyframes_batch({ keyframes: '[\n {\"targetId\":\"A\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"A\",\"property\":\"opacity\",\"time\":500,\"value\":1,\"easing\":\"easeOut\"},\n {\"targetId\":\"arrowAB\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"arrowAB\",\"property\":\"opacity\",\"time\":500,\"value\":1},\n {\"targetId\":\"arrowAB\",\"property\":\"drawProgress\",\"time\":500,\"value\":0},\n {\"targetId\":\"arrowAB\",\"property\":\"drawProgress\",\"time\":1500,\"value\":1,\"easing\":\"easeInOut\"},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":1500,\"value\":0},\n {\"targetId\":\"B\",\"property\":\"opacity\",\"time\":2000,\"value\":1,\"easing\":\"easeOut\"},\n {\"targetId\":\"arrowBA\",\"property\":\"opacity\",\"time\":0,\"value\":0},\n {\"targetId\":\"arrowBA\",\"property\":\"opacity\",\"time\":2000,\"value\":1},\n {\"targetId\":\"arrowBA\",\"property\":\"drawProgress\",\"time\":2000,\"value\":0},\n {\"targetId\":\"arrowBA\",\"property\":\"drawProgress\",\"time\":3000,\"value\":1,\"easing\":\"easeInOut\"}\n]' })\n```\n\n## Example 13: Staggered Reveal via create_sequence\n```\ncreate_sequence({ elementIds: [\"title\",\"box1\",\"arrow1\",\"box2\",\"arrow2\",\"box3\"], property: \"opacity\", startTime: 0, delay: 400, duration: 600 })\n```\nResult: title at 0ms, box1 at 400ms, arrow1 at 800ms, box2 at 1200ms, arrow2 at 1600ms, box3 at 2000ms.\n\n## Example 14: Camera Pan\n```\nset_camera_frame({ x: 300, y: 200, width: 800, aspectRatio: \"16:9\" })\nadd_camera_keyframe({ property: \"translateX\", time: 0, value: -200 })\nadd_camera_keyframe({ property: \"translateX\", time: 3000, value: 200, easing: \"easeInOut\" })\n```\n\n## Example 15: Camera Zoom In\n```\nadd_camera_keyframe({ property: \"scaleX\", time: 0, value: 2 })\nadd_camera_keyframe({ property: \"scaleY\", time: 0, value: 2 })\nadd_camera_keyframe({ property: \"scaleX\", time: 2000, value: 1, easing: \"easeInOutCubic\" })\nadd_camera_keyframe({ property: \"scaleY\", time: 2000, value: 1, easing: \"easeInOutCubic\" })\n```\n\n## Example 16: Clip Range + Save\n```\nset_clip_range({ start: 0, end: 5000 })\nsave_checkpoint({ id: \"my-animation\" })\n```\n\n---\n\n# Tips\n\n1. Always call create_scene first (or clear_scene to start fresh), then animate.\n2. Use add_keyframes_batch for efficiency \u2014 one call for many keyframes.\n3. Use create_sequence for simple staggered reveals.\n4. Bound text inherits container animation \u2014 animating arrow opacity also hides its label.\n5. drawProgress only works on arrows and lines.\n6. easeOutBack gives a nice bounce for pop-in effects.\n7. easeInOutCubic is the best general-purpose easing.\n8. Set elements to opacity 0 at time 0 if they should appear later.\n9. Set clip range before saving \u2014 it defines what gets exported.\n10. Camera scale > 1 = zoomed out, < 1 = zoomed in.\n11. Use delete_items to remove elements AND their animation tracks in one call.\n12. Verify your work with animations_of_item, items_visible_in_camera, are_items_in_line, is_camera_centered.\n\n## Example 17: Verify Animation\n```\nanimations_of_item({ targetId: \"box1\" })\n// Returns:\n// opacity:\n// 0ms 0% \u2191 100% 600ms (easeOut)\n\nitems_visible_in_camera({ time: 1000 })\n// Returns: 5/8 items visible (62%) at 1000ms\n\nare_items_in_line({ ids: [\"box1\",\"box2\",\"box3\"], axis: \"horizontal\" })\n// Returns: \u2705 Aligned (max deviation: 3px)\n\nis_camera_centered({ axis: \"both\", time: 0 })\n// Returns: \u2705 Centered (offsets: dx=5 dy=2)\n```\n\n## Example 18: Delete and Rebuild\n```\ndelete_items({ ids: [\"old_box\", \"old_arrow\"] })\n// Removes elements + all their animation tracks\n\nclear_scene()\n// Nuclear option: removes everything\n```\n";
|
|
3
|
+
//# sourceMappingURL=referenceText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referenceText.d.ts","sourceRoot":"","sources":["../../src/server/referenceText.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,w9FAgG1B,CAAC;AAEF,eAAO,MAAM,aAAa,m0SAyKzB,CAAC"}
|