@swiftlysingh/excalidraw-cli 1.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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +152 -0
- package/dist/cli.js.map +1 -0
- package/dist/factory/connection-factory.d.ts +16 -0
- package/dist/factory/connection-factory.d.ts.map +1 -0
- package/dist/factory/connection-factory.js +91 -0
- package/dist/factory/connection-factory.js.map +1 -0
- package/dist/factory/element-factory.d.ts +16 -0
- package/dist/factory/element-factory.d.ts.map +1 -0
- package/dist/factory/element-factory.js +78 -0
- package/dist/factory/element-factory.js.map +1 -0
- package/dist/factory/index.d.ts +8 -0
- package/dist/factory/index.d.ts.map +1 -0
- package/dist/factory/index.js +8 -0
- package/dist/factory/index.js.map +1 -0
- package/dist/factory/node-factory.d.ts +24 -0
- package/dist/factory/node-factory.d.ts.map +1 -0
- package/dist/factory/node-factory.js +85 -0
- package/dist/factory/node-factory.js.map +1 -0
- package/dist/factory/text-factory.d.ts +42 -0
- package/dist/factory/text-factory.d.ts.map +1 -0
- package/dist/factory/text-factory.js +148 -0
- package/dist/factory/text-factory.js.map +1 -0
- package/dist/generator/excalidraw-generator.d.ts +17 -0
- package/dist/generator/excalidraw-generator.d.ts.map +1 -0
- package/dist/generator/excalidraw-generator.js +91 -0
- package/dist/generator/excalidraw-generator.js.map +1 -0
- package/dist/generator/index.d.ts +5 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +5 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/arrow-router.d.ts +48 -0
- package/dist/layout/arrow-router.d.ts.map +1 -0
- package/dist/layout/arrow-router.js +103 -0
- package/dist/layout/arrow-router.js.map +1 -0
- package/dist/layout/elk-layout.d.ts +11 -0
- package/dist/layout/elk-layout.d.ts.map +1 -0
- package/dist/layout/elk-layout.js +179 -0
- package/dist/layout/elk-layout.js.map +1 -0
- package/dist/layout/index.d.ts +6 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +6 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/parser/dsl-parser.d.ts +21 -0
- package/dist/parser/dsl-parser.d.ts.map +1 -0
- package/dist/parser/dsl-parser.js +249 -0
- package/dist/parser/dsl-parser.js.map +1 -0
- package/dist/parser/index.d.ts +6 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/json-parser.d.ts +16 -0
- package/dist/parser/json-parser.d.ts.map +1 -0
- package/dist/parser/json-parser.js +76 -0
- package/dist/parser/json-parser.js.map +1 -0
- package/dist/types/dsl.d.ts +127 -0
- package/dist/types/dsl.d.ts.map +1 -0
- package/dist/types/dsl.js +14 -0
- package/dist/types/dsl.js.map +1 -0
- package/dist/types/excalidraw.d.ts +171 -0
- package/dist/types/excalidraw.d.ts.map +1 -0
- package/dist/types/excalidraw.js +36 -0
- package/dist/types/excalidraw.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Excalidraw shape elements (rectangle, diamond, ellipse).
|
|
5
|
+
*/
|
|
6
|
+
import { createBaseElement } from './element-factory.js';
|
|
7
|
+
/**
|
|
8
|
+
* Map DSL style to Excalidraw properties
|
|
9
|
+
*/
|
|
10
|
+
function mapStyle(style) {
|
|
11
|
+
if (!style)
|
|
12
|
+
return {};
|
|
13
|
+
return {
|
|
14
|
+
strokeColor: style.strokeColor,
|
|
15
|
+
backgroundColor: style.backgroundColor,
|
|
16
|
+
strokeWidth: style.strokeWidth,
|
|
17
|
+
strokeStyle: style.strokeStyle,
|
|
18
|
+
fillStyle: style.fillStyle,
|
|
19
|
+
opacity: style.opacity,
|
|
20
|
+
roughness: style.roughness,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a rectangle element
|
|
25
|
+
*/
|
|
26
|
+
export function createRectangle(node, boundElements) {
|
|
27
|
+
const styleProps = mapStyle(node.style);
|
|
28
|
+
return {
|
|
29
|
+
...createBaseElement('rectangle', node.x, node.y, node.width, node.height, {
|
|
30
|
+
id: node.id,
|
|
31
|
+
roundness: { type: 3 }, // Adaptive roundness
|
|
32
|
+
boundElements: boundElements || null,
|
|
33
|
+
...styleProps,
|
|
34
|
+
}),
|
|
35
|
+
type: 'rectangle',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create a diamond element
|
|
40
|
+
*/
|
|
41
|
+
export function createDiamond(node, boundElements) {
|
|
42
|
+
const styleProps = mapStyle(node.style);
|
|
43
|
+
return {
|
|
44
|
+
...createBaseElement('diamond', node.x, node.y, node.width, node.height, {
|
|
45
|
+
id: node.id,
|
|
46
|
+
roundness: { type: 2 }, // Proportional roundness
|
|
47
|
+
boundElements: boundElements || null,
|
|
48
|
+
...styleProps,
|
|
49
|
+
}),
|
|
50
|
+
type: 'diamond',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create an ellipse element
|
|
55
|
+
*/
|
|
56
|
+
export function createEllipse(node, boundElements) {
|
|
57
|
+
const styleProps = mapStyle(node.style);
|
|
58
|
+
return {
|
|
59
|
+
...createBaseElement('ellipse', node.x, node.y, node.width, node.height, {
|
|
60
|
+
id: node.id,
|
|
61
|
+
roundness: null, // Ellipses don't use roundness
|
|
62
|
+
boundElements: boundElements || null,
|
|
63
|
+
...styleProps,
|
|
64
|
+
}),
|
|
65
|
+
type: 'ellipse',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a node element based on type
|
|
70
|
+
*/
|
|
71
|
+
export function createNode(node, boundElements) {
|
|
72
|
+
switch (node.type) {
|
|
73
|
+
case 'diamond':
|
|
74
|
+
return createDiamond(node, boundElements);
|
|
75
|
+
case 'ellipse':
|
|
76
|
+
return createEllipse(node, boundElements);
|
|
77
|
+
case 'database':
|
|
78
|
+
// Database is rendered as rectangle with special styling
|
|
79
|
+
return createRectangle(node, boundElements);
|
|
80
|
+
case 'rectangle':
|
|
81
|
+
default:
|
|
82
|
+
return createRectangle(node, boundElements);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=node-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-factory.js","sourceRoot":"","sources":["../../src/factory/node-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AASzD;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAiB;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAkB,EAClB,aAAwC;IAExC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO;QACL,GAAG,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;YACzE,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,qBAAqB;YAC7C,aAAa,EAAE,aAAa,IAAI,IAAI;YACpC,GAAG,UAAU;SACd,CAAC;QACF,IAAI,EAAE,WAAW;KACK,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAkB,EAClB,aAAwC;IAExC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO;QACL,GAAG,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;YACvE,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,yBAAyB;YACjD,aAAa,EAAE,aAAa,IAAI,IAAI;YACpC,GAAG,UAAU;SACd,CAAC;QACF,IAAI,EAAE,SAAS;KACK,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAkB,EAClB,aAAwC;IAExC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO;QACL,GAAG,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;YACvE,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,IAAI,EAAE,+BAA+B;YAChD,aAAa,EAAE,aAAa,IAAI,IAAI;YACpC,GAAG,UAAU;SACd,CAAC;QACF,IAAI,EAAE,SAAS;KACK,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,IAAkB,EAClB,aAAwC;IAExC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC5C,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC5C,KAAK,UAAU;YACb,yDAAyD;YACzD,OAAO,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC9C,KAAK,WAAW,CAAC;QACjB;YACE,OAAO,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Excalidraw text elements for labels.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExcalidrawText, ExcalidrawTextAlign, ExcalidrawVerticalAlign } from '../types/excalidraw.js';
|
|
7
|
+
import type { LayoutedNode } from '../types/dsl.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a standalone text element
|
|
10
|
+
*/
|
|
11
|
+
export declare function createText(text: string, x: number, y: number, options?: {
|
|
12
|
+
id?: string;
|
|
13
|
+
fontSize?: number;
|
|
14
|
+
fontFamily?: number;
|
|
15
|
+
textAlign?: ExcalidrawTextAlign;
|
|
16
|
+
verticalAlign?: ExcalidrawVerticalAlign;
|
|
17
|
+
strokeColor?: string;
|
|
18
|
+
}): ExcalidrawText;
|
|
19
|
+
/**
|
|
20
|
+
* Create a text element bound to a container (shape or arrow)
|
|
21
|
+
*/
|
|
22
|
+
export declare function createBoundText(text: string, containerId: string, centerX: number, centerY: number, options?: {
|
|
23
|
+
id?: string;
|
|
24
|
+
fontSize?: number;
|
|
25
|
+
fontFamily?: number;
|
|
26
|
+
textAlign?: ExcalidrawTextAlign;
|
|
27
|
+
verticalAlign?: ExcalidrawVerticalAlign;
|
|
28
|
+
strokeColor?: string;
|
|
29
|
+
}): ExcalidrawText;
|
|
30
|
+
/**
|
|
31
|
+
* Create a text label for a node (centered inside the shape)
|
|
32
|
+
*/
|
|
33
|
+
export declare function createNodeLabel(node: LayoutedNode, options?: {
|
|
34
|
+
fontSize?: number;
|
|
35
|
+
}): ExcalidrawText;
|
|
36
|
+
/**
|
|
37
|
+
* Create a text label for an edge (positioned at midpoint)
|
|
38
|
+
*/
|
|
39
|
+
export declare function createEdgeLabel(label: string, points: Array<[number, number]>, startX: number, startY: number, arrowId: string, options?: {
|
|
40
|
+
fontSize?: number;
|
|
41
|
+
}): ExcalidrawText;
|
|
42
|
+
//# sourceMappingURL=text-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-factory.d.ts","sourceRoot":"","sources":["../../src/factory/text-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,cAAc,EAEd,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA8BpD;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,cAAc,CAqBhB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,cAAc,CAyBhB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAuBnG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,cAAc,CAyChB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Excalidraw text elements for labels.
|
|
5
|
+
*/
|
|
6
|
+
import { nanoid } from 'nanoid';
|
|
7
|
+
import { createBaseElement } from './element-factory.js';
|
|
8
|
+
/**
|
|
9
|
+
* Default font settings
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_FONT_SIZE = 20;
|
|
12
|
+
const DEFAULT_FONT_FAMILY = 5; // Excalifont
|
|
13
|
+
const DEFAULT_LINE_HEIGHT = 1.25;
|
|
14
|
+
/**
|
|
15
|
+
* Calculate text dimensions
|
|
16
|
+
*/
|
|
17
|
+
function calculateTextDimensions(text, fontSize) {
|
|
18
|
+
const lines = text.split('\n');
|
|
19
|
+
const lineCount = lines.length;
|
|
20
|
+
const maxLineLength = Math.max(...lines.map((l) => l.length));
|
|
21
|
+
// Approximate character width (varies by font)
|
|
22
|
+
const charWidth = fontSize * 0.6;
|
|
23
|
+
const lineHeight = fontSize * DEFAULT_LINE_HEIGHT;
|
|
24
|
+
return {
|
|
25
|
+
width: maxLineLength * charWidth,
|
|
26
|
+
height: lineCount * lineHeight,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a standalone text element
|
|
31
|
+
*/
|
|
32
|
+
export function createText(text, x, y, options) {
|
|
33
|
+
const fontSize = options?.fontSize ?? DEFAULT_FONT_SIZE;
|
|
34
|
+
const dims = calculateTextDimensions(text, fontSize);
|
|
35
|
+
return {
|
|
36
|
+
...createBaseElement('text', x, y, dims.width, dims.height, {
|
|
37
|
+
id: options?.id || nanoid(21),
|
|
38
|
+
roundness: null,
|
|
39
|
+
strokeColor: options?.strokeColor,
|
|
40
|
+
}),
|
|
41
|
+
type: 'text',
|
|
42
|
+
text,
|
|
43
|
+
fontSize,
|
|
44
|
+
fontFamily: options?.fontFamily ?? DEFAULT_FONT_FAMILY,
|
|
45
|
+
textAlign: options?.textAlign ?? 'center',
|
|
46
|
+
verticalAlign: options?.verticalAlign ?? 'middle',
|
|
47
|
+
containerId: null,
|
|
48
|
+
originalText: text,
|
|
49
|
+
autoResize: true,
|
|
50
|
+
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a text element bound to a container (shape or arrow)
|
|
55
|
+
*/
|
|
56
|
+
export function createBoundText(text, containerId, centerX, centerY, options) {
|
|
57
|
+
const fontSize = options?.fontSize ?? DEFAULT_FONT_SIZE;
|
|
58
|
+
const dims = calculateTextDimensions(text, fontSize);
|
|
59
|
+
// Center text on the given coordinates
|
|
60
|
+
const x = centerX - dims.width / 2;
|
|
61
|
+
const y = centerY - dims.height / 2;
|
|
62
|
+
return {
|
|
63
|
+
...createBaseElement('text', x, y, dims.width, dims.height, {
|
|
64
|
+
id: options?.id || nanoid(21),
|
|
65
|
+
roundness: null,
|
|
66
|
+
strokeColor: options?.strokeColor,
|
|
67
|
+
}),
|
|
68
|
+
type: 'text',
|
|
69
|
+
text,
|
|
70
|
+
fontSize,
|
|
71
|
+
fontFamily: options?.fontFamily ?? DEFAULT_FONT_FAMILY,
|
|
72
|
+
textAlign: options?.textAlign ?? 'center',
|
|
73
|
+
verticalAlign: options?.verticalAlign ?? 'middle',
|
|
74
|
+
containerId,
|
|
75
|
+
originalText: text,
|
|
76
|
+
autoResize: true,
|
|
77
|
+
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a text label for a node (centered inside the shape)
|
|
82
|
+
*/
|
|
83
|
+
export function createNodeLabel(node, options) {
|
|
84
|
+
const fontSize = options?.fontSize ?? DEFAULT_FONT_SIZE;
|
|
85
|
+
const dims = calculateTextDimensions(node.label, fontSize);
|
|
86
|
+
// Center text inside the node
|
|
87
|
+
const x = node.x + (node.width - dims.width) / 2;
|
|
88
|
+
const y = node.y + (node.height - dims.height) / 2;
|
|
89
|
+
return {
|
|
90
|
+
...createBaseElement('text', x, y, dims.width, dims.height, {
|
|
91
|
+
roundness: null,
|
|
92
|
+
}),
|
|
93
|
+
type: 'text',
|
|
94
|
+
text: node.label,
|
|
95
|
+
fontSize,
|
|
96
|
+
fontFamily: DEFAULT_FONT_FAMILY,
|
|
97
|
+
textAlign: 'center',
|
|
98
|
+
verticalAlign: 'middle',
|
|
99
|
+
containerId: null, // Standalone text, positioned over the shape
|
|
100
|
+
originalText: node.label,
|
|
101
|
+
autoResize: true,
|
|
102
|
+
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a text label for an edge (positioned at midpoint)
|
|
107
|
+
*/
|
|
108
|
+
export function createEdgeLabel(label, points, startX, startY, arrowId, options) {
|
|
109
|
+
const fontSize = options?.fontSize ?? DEFAULT_FONT_SIZE;
|
|
110
|
+
const dims = calculateTextDimensions(label, fontSize);
|
|
111
|
+
// Find midpoint of the arrow path
|
|
112
|
+
let midX = 0;
|
|
113
|
+
let midY = 0;
|
|
114
|
+
if (points.length === 2) {
|
|
115
|
+
// Simple two-point arrow
|
|
116
|
+
midX = startX + (points[0][0] + points[1][0]) / 2;
|
|
117
|
+
midY = startY + (points[0][1] + points[1][1]) / 2;
|
|
118
|
+
}
|
|
119
|
+
else if (points.length > 2) {
|
|
120
|
+
// Multi-point arrow - use middle point or interpolate
|
|
121
|
+
const midIndex = Math.floor(points.length / 2);
|
|
122
|
+
midX = startX + points[midIndex][0];
|
|
123
|
+
midY = startY + points[midIndex][1];
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
midX = startX;
|
|
127
|
+
midY = startY;
|
|
128
|
+
}
|
|
129
|
+
// Position text centered at midpoint
|
|
130
|
+
const x = midX - dims.width / 2;
|
|
131
|
+
const y = midY - dims.height / 2;
|
|
132
|
+
return {
|
|
133
|
+
...createBaseElement('text', x, y, dims.width, dims.height, {
|
|
134
|
+
roundness: null,
|
|
135
|
+
}),
|
|
136
|
+
type: 'text',
|
|
137
|
+
text: label,
|
|
138
|
+
fontSize,
|
|
139
|
+
fontFamily: DEFAULT_FONT_FAMILY,
|
|
140
|
+
textAlign: 'center',
|
|
141
|
+
verticalAlign: 'middle',
|
|
142
|
+
containerId: arrowId, // Bound to the arrow
|
|
143
|
+
originalText: label,
|
|
144
|
+
autoResize: true,
|
|
145
|
+
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=text-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-factory.js","sourceRoot":"","sources":["../../src/factory/text-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excalidraw Generator
|
|
3
|
+
*
|
|
4
|
+
* Assembles a complete Excalidraw file from a layouted graph.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExcalidrawFile } from '../types/excalidraw.js';
|
|
7
|
+
import type { LayoutedGraph } from '../types/dsl.js';
|
|
8
|
+
/**
|
|
9
|
+
* Generate an Excalidraw file from a layouted graph
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateExcalidraw(graph: LayoutedGraph): ExcalidrawFile;
|
|
12
|
+
/**
|
|
13
|
+
* Serialize an Excalidraw file to JSON string
|
|
14
|
+
*/
|
|
15
|
+
export declare function serializeExcalidraw(file: ExcalidrawFile, pretty?: boolean): string;
|
|
16
|
+
export { DEFAULT_APP_STATE } from '../types/excalidraw.js';
|
|
17
|
+
//# sourceMappingURL=excalidraw-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excalidraw-generator.d.ts","sourceRoot":"","sources":["../../src/generator/excalidraw-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,iBAAiB,CAAC;AAIjF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CA0FvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,UAAO,GAAG,MAAM,CAE/E;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excalidraw Generator
|
|
3
|
+
*
|
|
4
|
+
* Assembles a complete Excalidraw file from a layouted graph.
|
|
5
|
+
*/
|
|
6
|
+
import { createNode, createArrow, createNodeLabel, createEdgeLabel, resetIndexCounter } from '../factory/index.js';
|
|
7
|
+
import { DEFAULT_APP_STATE } from '../types/excalidraw.js';
|
|
8
|
+
const SOURCE_URL = 'https://github.com/swiftlysingh/excalidraw-cli';
|
|
9
|
+
/**
|
|
10
|
+
* Generate an Excalidraw file from a layouted graph
|
|
11
|
+
*/
|
|
12
|
+
export function generateExcalidraw(graph) {
|
|
13
|
+
// Reset index counter for fresh ordering
|
|
14
|
+
resetIndexCounter();
|
|
15
|
+
const elements = [];
|
|
16
|
+
// Build a map of node IDs to nodes for quick lookup
|
|
17
|
+
const nodeMap = new Map();
|
|
18
|
+
for (const node of graph.nodes) {
|
|
19
|
+
nodeMap.set(node.id, node);
|
|
20
|
+
}
|
|
21
|
+
// Calculate bound elements for each node
|
|
22
|
+
const nodeBoundElements = new Map();
|
|
23
|
+
for (const edge of graph.edges) {
|
|
24
|
+
// Add arrow as bound element to source node
|
|
25
|
+
if (!nodeBoundElements.has(edge.source)) {
|
|
26
|
+
nodeBoundElements.set(edge.source, []);
|
|
27
|
+
}
|
|
28
|
+
nodeBoundElements.get(edge.source).push({ id: edge.id, type: 'arrow' });
|
|
29
|
+
// Add arrow as bound element to target node
|
|
30
|
+
if (!nodeBoundElements.has(edge.target)) {
|
|
31
|
+
nodeBoundElements.set(edge.target, []);
|
|
32
|
+
}
|
|
33
|
+
nodeBoundElements.get(edge.target).push({ id: edge.id, type: 'arrow' });
|
|
34
|
+
}
|
|
35
|
+
// Create shape elements for nodes
|
|
36
|
+
for (const node of graph.nodes) {
|
|
37
|
+
const boundElements = nodeBoundElements.get(node.id);
|
|
38
|
+
const shapeElement = createNode(node, boundElements);
|
|
39
|
+
elements.push(shapeElement);
|
|
40
|
+
// Create text label for the node
|
|
41
|
+
const textElement = createNodeLabel(node);
|
|
42
|
+
elements.push(textElement);
|
|
43
|
+
}
|
|
44
|
+
// Calculate bound elements for arrows (text labels)
|
|
45
|
+
const arrowBoundElements = new Map();
|
|
46
|
+
for (const edge of graph.edges) {
|
|
47
|
+
if (edge.label) {
|
|
48
|
+
if (!arrowBoundElements.has(edge.id)) {
|
|
49
|
+
arrowBoundElements.set(edge.id, []);
|
|
50
|
+
}
|
|
51
|
+
// Text element ID will be generated when we create it
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Create arrow elements for edges
|
|
55
|
+
for (const edge of graph.edges) {
|
|
56
|
+
const sourceNode = nodeMap.get(edge.source);
|
|
57
|
+
const targetNode = nodeMap.get(edge.target);
|
|
58
|
+
if (!sourceNode || !targetNode) {
|
|
59
|
+
console.warn(`Skipping edge ${edge.id}: missing source or target node`);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Create arrow with bound text if it has a label
|
|
63
|
+
const boundElements = edge.label ? [{ id: `text-${edge.id}`, type: 'text' }] : undefined;
|
|
64
|
+
const arrowElement = createArrow(edge, sourceNode, targetNode, boundElements);
|
|
65
|
+
elements.push(arrowElement);
|
|
66
|
+
// Create text label for the edge if it has one
|
|
67
|
+
if (edge.label) {
|
|
68
|
+
const textElement = createEdgeLabel(edge.label, edge.points, edge.sourcePoint.x, edge.sourcePoint.y, edge.id);
|
|
69
|
+
// Override the text element ID to match what we bound
|
|
70
|
+
textElement.id = `text-${edge.id}`;
|
|
71
|
+
elements.push(textElement);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
type: 'excalidraw',
|
|
76
|
+
version: 2,
|
|
77
|
+
source: SOURCE_URL,
|
|
78
|
+
elements,
|
|
79
|
+
appState: { ...DEFAULT_APP_STATE },
|
|
80
|
+
files: {},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Serialize an Excalidraw file to JSON string
|
|
85
|
+
*/
|
|
86
|
+
export function serializeExcalidraw(file, pretty = true) {
|
|
87
|
+
return JSON.stringify(file, null, pretty ? 2 : undefined);
|
|
88
|
+
}
|
|
89
|
+
// Re-export
|
|
90
|
+
export { DEFAULT_APP_STATE } from '../types/excalidraw.js';
|
|
91
|
+
//# sourceMappingURL=excalidraw-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excalidraw-generator.js","sourceRoot":"","sources":["../../src/generator/excalidraw-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excalidraw CLI - Programmatic API
|
|
3
|
+
*
|
|
4
|
+
* Create Excalidraw flowcharts programmatically.
|
|
5
|
+
*/
|
|
6
|
+
export type { FlowchartGraph, FlowchartInput, GraphNode, GraphEdge, LayoutOptions, LayoutedGraph, LayoutedNode, LayoutedEdge, NodeType, NodeStyle, EdgeStyle, FlowDirection, } from './types/dsl.js';
|
|
7
|
+
export type { ExcalidrawFile, ExcalidrawElement, ExcalidrawRectangle, ExcalidrawDiamond, ExcalidrawEllipse, ExcalidrawText, ExcalidrawArrow, ExcalidrawAppState, } from './types/excalidraw.js';
|
|
8
|
+
export { parseDSL } from './parser/dsl-parser.js';
|
|
9
|
+
export { parseJSON, parseJSONString } from './parser/json-parser.js';
|
|
10
|
+
export { layoutGraph } from './layout/elk-layout.js';
|
|
11
|
+
export { generateExcalidraw, serializeExcalidraw } from './generator/excalidraw-generator.js';
|
|
12
|
+
export { createNode, createArrow, createText } from './factory/index.js';
|
|
13
|
+
export { DEFAULT_LAYOUT_OPTIONS } from './types/dsl.js';
|
|
14
|
+
export { DEFAULT_APP_STATE, DEFAULT_ELEMENT_STYLE } from './types/excalidraw.js';
|
|
15
|
+
/**
|
|
16
|
+
* High-level API: Create an Excalidraw flowchart from DSL string
|
|
17
|
+
*/
|
|
18
|
+
export declare function createFlowchartFromDSL(dsl: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* High-level API: Create an Excalidraw flowchart from JSON input
|
|
21
|
+
*/
|
|
22
|
+
export declare function createFlowchartFromJSON(input: import('./types/dsl.js').FlowchartInput): Promise<string>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,cAAc,EACd,cAAc,EACd,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAG9F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEjF;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOzE;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,OAAO,gBAAgB,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7G"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excalidraw CLI - Programmatic API
|
|
3
|
+
*
|
|
4
|
+
* Create Excalidraw flowcharts programmatically.
|
|
5
|
+
*/
|
|
6
|
+
// Parser exports
|
|
7
|
+
export { parseDSL } from './parser/dsl-parser.js';
|
|
8
|
+
export { parseJSON, parseJSONString } from './parser/json-parser.js';
|
|
9
|
+
// Layout exports
|
|
10
|
+
export { layoutGraph } from './layout/elk-layout.js';
|
|
11
|
+
// Generator exports
|
|
12
|
+
export { generateExcalidraw, serializeExcalidraw } from './generator/excalidraw-generator.js';
|
|
13
|
+
// Factory exports (for advanced usage)
|
|
14
|
+
export { createNode, createArrow, createText } from './factory/index.js';
|
|
15
|
+
// Default options
|
|
16
|
+
export { DEFAULT_LAYOUT_OPTIONS } from './types/dsl.js';
|
|
17
|
+
export { DEFAULT_APP_STATE, DEFAULT_ELEMENT_STYLE } from './types/excalidraw.js';
|
|
18
|
+
/**
|
|
19
|
+
* High-level API: Create an Excalidraw flowchart from DSL string
|
|
20
|
+
*/
|
|
21
|
+
export async function createFlowchartFromDSL(dsl) {
|
|
22
|
+
const graph = (await import('./parser/dsl-parser.js')).parseDSL(dsl);
|
|
23
|
+
const layoutedGraph = await (await import('./layout/elk-layout.js')).layoutGraph(graph);
|
|
24
|
+
const excalidrawFile = (await import('./generator/excalidraw-generator.js')).generateExcalidraw(layoutedGraph);
|
|
25
|
+
return (await import('./generator/excalidraw-generator.js')).serializeExcalidraw(excalidrawFile);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* High-level API: Create an Excalidraw flowchart from JSON input
|
|
29
|
+
*/
|
|
30
|
+
export async function createFlowchartFromJSON(input) {
|
|
31
|
+
const graph = (await import('./parser/json-parser.js')).parseJSON(input);
|
|
32
|
+
const layoutedGraph = await (await import('./layout/elk-layout.js')).layoutGraph(graph);
|
|
33
|
+
const excalidrawFile = (await import('./generator/excalidraw-generator.js')).generateExcalidraw(layoutedGraph);
|
|
34
|
+
return (await import('./generator/excalidraw-generator.js')).serializeExcalidraw(excalidrawFile);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH,iBAAiB;AACjB,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAErE,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,oBAAoB;AACpB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE9F,uCAAuC;AACvC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzE,kBAAkB;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEjF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAW;IACtD,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrE,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACxF,MAAM,cAAc,GAAG,CAAC,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC,kBAAkB,CAC7F,aAAa,CACd,CAAC;IACF,OAAO,CAAC,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;AACnG,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAA8C;IAC1F,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACxF,MAAM,cAAc,GAAG,CAAC,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC,kBAAkB,CAC7F,aAAa,CACd,CAAC;IACF,OAAO,CAAC,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arrow Router
|
|
3
|
+
*
|
|
4
|
+
* Calculates binding points for arrows connecting to shapes.
|
|
5
|
+
*/
|
|
6
|
+
import type { LayoutedNode } from '../types/dsl.js';
|
|
7
|
+
import type { ExcalidrawArrowBinding } from '../types/excalidraw.js';
|
|
8
|
+
/**
|
|
9
|
+
* Calculate the binding point for an arrow endpoint on a node.
|
|
10
|
+
* Returns normalized coordinates [0-1] relative to the node.
|
|
11
|
+
*/
|
|
12
|
+
export declare function calculateBindingPoint(node: LayoutedNode, arrowPoint: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}): ExcalidrawArrowBinding;
|
|
16
|
+
/**
|
|
17
|
+
* Find the best connection point on a node's edge for an arrow
|
|
18
|
+
* coming from a given direction.
|
|
19
|
+
*/
|
|
20
|
+
export declare function findEdgeConnectionPoint(node: LayoutedNode, fromPoint: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
}): {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
binding: ExcalidrawArrowBinding;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Calculate arrow binding for a source node (where arrow starts)
|
|
30
|
+
*/
|
|
31
|
+
export declare function calculateStartBinding(sourceNode: LayoutedNode, targetNode: LayoutedNode): {
|
|
32
|
+
point: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
};
|
|
36
|
+
binding: ExcalidrawArrowBinding;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Calculate arrow binding for a target node (where arrow ends)
|
|
40
|
+
*/
|
|
41
|
+
export declare function calculateEndBinding(sourceNode: LayoutedNode, targetNode: LayoutedNode): {
|
|
42
|
+
point: {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
};
|
|
46
|
+
binding: ExcalidrawArrowBinding;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=arrow-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrow-router.d.ts","sourceRoot":"","sources":["../../src/layout/arrow-router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,sBAAsB,CAcxB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAuD3D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,YAAY,EACxB,UAAU,EAAE,YAAY,GACvB;IAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAQtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,YAAY,EACxB,UAAU,EAAE,YAAY,GACvB;IAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAQtE"}
|