@stealthscale/component-graphs 0.2.1 → 0.2.2

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.
@@ -0,0 +1,1619 @@
1
+ import { t as __exportAll } from "../../rolldown-runtime-D7D4PA-g.js";
2
+ import { a as ZoomLevel, c as Controls, f as Root, g as layoutGraph, h as Canvas, l as Control, m as Summary, o as PaletteItem, p as Caption, s as MiniMap$1, x as diffGraphs } from "../../shared-DOF4V8-Q.js";
3
+ import { t as recipe } from "../../recipes-lWPA4IJC.js";
4
+ import { useRef, useState } from "react";
5
+ import { c } from "react/compiler-runtime";
6
+ import { Button } from "@stealthscale/component-actions";
7
+ import { Badge } from "@stealthscale/component-data";
8
+ import { addEdge, useEdgesState, useNodesState } from "@xyflow/react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { Room, scenesOf, specimen, useWords } from "@stealthscale/specimen";
11
+ import { MaximizeIcon, MinusIcon, PlusIcon, XIcon } from "lucide-react";
12
+ import { Grid, Stack } from "@stealthscale/component-layout";
13
+ import { DataList } from "@stealthscale/component-collections";
14
+ import { Heading, Text } from "@stealthscale/component-typography";
15
+ //#region src/graph/examples/changes.example.tsx
16
+ var changes_example_exports = /* @__PURE__ */ __exportAll({
17
+ Changes: () => Changes,
18
+ source: () => source$7
19
+ });
20
+ const ORIGIN$1 = {
21
+ x: 0,
22
+ y: 0
23
+ };
24
+ const BEFORE$1 = {
25
+ links: [
26
+ ["screen", "draft"],
27
+ ["draft", "publish"],
28
+ ["publish", "notify"]
29
+ ],
30
+ steps: [
31
+ ["screen", "screening"],
32
+ ["draft", "small"],
33
+ ["publish", "helpCentre"],
34
+ ["notify", "email"]
35
+ ]
36
+ };
37
+ const AFTER$1 = {
38
+ links: [
39
+ ["screen", "draft"],
40
+ ["draft", "score"],
41
+ ["score", "publish"]
42
+ ],
43
+ steps: [
44
+ ["screen", "screening"],
45
+ ["draft", "large"],
46
+ ["score", "three"],
47
+ ["publish", "helpCentre"]
48
+ ]
49
+ };
50
+ const LOOKS = {
51
+ added: {
52
+ mark: "+",
53
+ palette: "success"
54
+ },
55
+ changed: {
56
+ mark: "~",
57
+ palette: "warning"
58
+ },
59
+ removed: {
60
+ mark: "−",
61
+ palette: "error"
62
+ },
63
+ unchanged: {
64
+ mark: "",
65
+ palette: "neutral"
66
+ }
67
+ };
68
+ function edgesOf$1(links) {
69
+ return links.map(([source, target]) => ({
70
+ id: `${source}-${target}`,
71
+ source,
72
+ target
73
+ }));
74
+ }
75
+ function changed({ change }) {
76
+ return change !== "unchanged";
77
+ }
78
+ function Changes() {
79
+ const $ = c(5);
80
+ const { t } = useWords("graph");
81
+ let t0;
82
+ if ($[0] !== t) {
83
+ t0 = (steps) => steps.map((t1) => {
84
+ const [id, detail] = t1;
85
+ return {
86
+ data: {
87
+ label: t(`versions.steps.${id}`),
88
+ subtitle: t(`versions.details.${detail}`)
89
+ },
90
+ id,
91
+ position: ORIGIN$1
92
+ };
93
+ });
94
+ $[0] = t;
95
+ $[1] = t0;
96
+ } else t0 = $[1];
97
+ const nodesOf = t0;
98
+ let t1;
99
+ if ($[2] !== nodesOf || $[3] !== t) {
100
+ const diff = diffGraphs({
101
+ edges: edgesOf$1(BEFORE$1.links),
102
+ nodes: nodesOf(BEFORE$1.steps)
103
+ }, {
104
+ edges: edgesOf$1(AFTER$1.links),
105
+ nodes: nodesOf(AFTER$1.steps)
106
+ });
107
+ const fields = { subtitle: t("versions.list.subtitle") };
108
+ const groups = [{
109
+ entries: diff.nodes.filter(changed),
110
+ title: t("versions.list.steps")
111
+ }, {
112
+ entries: diff.edges.filter(changed),
113
+ title: t("versions.list.links")
114
+ }];
115
+ const count = groups.reduce(_temp$1, 0);
116
+ t1 = /* @__PURE__ */ jsxs(Stack, {
117
+ gap: "md",
118
+ children: [/* @__PURE__ */ jsx(Text, {
119
+ as: "output",
120
+ children: t("versions.list.summary", { count })
121
+ }), groups.map((t2) => {
122
+ const { entries: entries_0, title } = t2;
123
+ return /* @__PURE__ */ jsxs(Stack, {
124
+ gap: "sm",
125
+ children: [/* @__PURE__ */ jsx(Heading, {
126
+ as: "h3",
127
+ size: "sm",
128
+ children: title
129
+ }), /* @__PURE__ */ jsx(DataList.Root, {
130
+ orientation: "horizontal",
131
+ children: entries_0.map((entry) => /* @__PURE__ */ jsxs(DataList.Item, { children: [/* @__PURE__ */ jsx(DataList.ItemLabel, { children: /* @__PURE__ */ jsx(Badge, {
132
+ palette: LOOKS[entry.change].palette,
133
+ size: "sm",
134
+ variant: "surface",
135
+ children: `${LOOKS[entry.change].mark} ${t(`versions.${entry.change}`)}`
136
+ }) }), /* @__PURE__ */ jsx(DataList.ItemValue, { children: entry.fields.length === 0 ? entry.label : t("versions.list.fields", {
137
+ fields: entry.fields.map((field) => fields[field] ?? field).join(", "),
138
+ label: entry.label
139
+ }) })] }, entry.id))
140
+ })]
141
+ }, title);
142
+ })]
143
+ });
144
+ $[2] = nodesOf;
145
+ $[3] = t;
146
+ $[4] = t1;
147
+ } else t1 = $[4];
148
+ return t1;
149
+ }
150
+ function _temp$1(sum, t0) {
151
+ const { entries } = t0;
152
+ return sum + entries.length;
153
+ }
154
+ const source$7 = "import { type ReactElement } from \"react\";\n\nimport { type Edge, type Node } from \"@xyflow/react\";\n\nimport { DataList } from \"@stealthscale/component-collections\";\nimport { Badge } from \"@stealthscale/component-data\";\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { Heading, Text } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { GraphChange, diffGraphs } from \"@stealthscale/component-graphs\";\n\nconst ORIGIN = { x: 0, y: 0 };\n\nconst BEFORE = {\n links: [\n [\"screen\", \"draft\"],\n [\"draft\", \"publish\"],\n [\"publish\", \"notify\"],\n ],\n steps: [\n [\"screen\", \"screening\"],\n [\"draft\", \"small\"],\n [\"publish\", \"helpCentre\"],\n [\"notify\", \"email\"],\n ],\n} as const;\n\nconst AFTER = {\n links: [\n [\"screen\", \"draft\"],\n [\"draft\", \"score\"],\n [\"score\", \"publish\"],\n ],\n steps: [\n [\"screen\", \"screening\"],\n [\"draft\", \"large\"],\n [\"score\", \"three\"],\n [\"publish\", \"helpCentre\"],\n ],\n} as const;\n\nconst LOOKS = {\n added: { mark: \"+\", palette: \"success\" },\n changed: { mark: \"~\", palette: \"warning\" },\n removed: { mark: \"−\", palette: \"error\" },\n unchanged: { mark: \"\", palette: \"neutral\" },\n} as const;\n\nfunction edgesOf(links: typeof AFTER.links | typeof BEFORE.links): Edge[] {\n return links.map(([source, target]) => ({ id: `${source}-${target}`, source, target }));\n}\n\nfunction changed({ change }: GraphChange): boolean {\n return change !== \"unchanged\";\n}\n\nexport function Changes(): ReactElement {\n const { t } = useWords(\"graph\");\n const nodesOf = (steps: typeof AFTER.steps | typeof BEFORE.steps): Node[] =>\n steps.map(([id, detail]) => ({\n data: { label: t(`versions.steps.${id}`), subtitle: t(`versions.details.${detail}`) },\n id,\n position: ORIGIN,\n }));\n const diff = diffGraphs(\n { edges: edgesOf(BEFORE.links), nodes: nodesOf(BEFORE.steps) },\n { edges: edgesOf(AFTER.links), nodes: nodesOf(AFTER.steps) },\n );\n const fields: Record<string, string> = { subtitle: t(\"versions.list.subtitle\") };\n const groups = [\n { entries: diff.nodes.filter(changed), title: t(\"versions.list.steps\") },\n { entries: diff.edges.filter(changed), title: t(\"versions.list.links\") },\n ];\n const count = groups.reduce((sum, { entries }) => sum + entries.length, 0);\n\n return (\n <Stack gap=\"md\">\n <Text as=\"output\">{t(\"versions.list.summary\", { count })}</Text>\n {groups.map(({ entries, title }) => (\n <Stack gap=\"sm\" key={title}>\n <Heading as=\"h3\" size=\"sm\">\n {title}\n </Heading>\n <DataList.Root orientation=\"horizontal\">\n {entries.map((entry) => (\n <DataList.Item key={entry.id}>\n <DataList.ItemLabel>\n <Badge palette={LOOKS[entry.change].palette} size=\"sm\" variant=\"surface\">\n {`${LOOKS[entry.change].mark} ${t(`versions.${entry.change}`)}`}\n </Badge>\n </DataList.ItemLabel>\n <DataList.ItemValue>\n {entry.fields.length === 0\n ? entry.label\n : t(\"versions.list.fields\", {\n fields: entry.fields.map((field) => fields[field] ?? field).join(\", \"),\n label: entry.label,\n })}\n </DataList.ItemValue>\n </DataList.Item>\n ))}\n </DataList.Root>\n </Stack>\n ))}\n </Stack>\n );\n}\n";
155
+ //#endregion
156
+ //#region src/graph/examples/editor.example.tsx
157
+ var editor_example_exports = /* @__PURE__ */ __exportAll({
158
+ Editor: () => Editor,
159
+ source: () => source$6
160
+ });
161
+ const IDS$1 = [
162
+ "webhook",
163
+ "enrich",
164
+ "route",
165
+ "slack",
166
+ "email"
167
+ ];
168
+ const LINKS = [
169
+ ["webhook", "enrich"],
170
+ ["enrich", "route"],
171
+ ["route", "slack"]
172
+ ];
173
+ function Editor() {
174
+ const $ = c(51);
175
+ const { t } = useWords("graph");
176
+ let t0;
177
+ if ($[0] !== t) {
178
+ t0 = layoutGraph(IDS$1.map((id) => ({
179
+ data: { label: t(`editor.${id}`) },
180
+ id,
181
+ position: {
182
+ x: 0,
183
+ y: 0
184
+ },
185
+ type: id === "webhook" ? "input" : id === "slack" || id === "email" ? "output" : "default"
186
+ })), LINKS.map(_temp), { ranksep: 64 });
187
+ $[0] = t;
188
+ $[1] = t0;
189
+ } else t0 = $[1];
190
+ const [nodes, , onNodesChange] = useNodesState(t0);
191
+ let t1;
192
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
193
+ t1 = LINKS.map(_temp2);
194
+ $[2] = t1;
195
+ } else t1 = $[2];
196
+ const [edges, setEdges, onEdgesChange] = useEdgesState(t1);
197
+ let t2;
198
+ if ($[3] !== t) {
199
+ t2 = t("controls");
200
+ $[3] = t;
201
+ $[4] = t2;
202
+ } else t2 = $[4];
203
+ let t3;
204
+ if ($[5] !== t) {
205
+ t3 = t("zoomIn");
206
+ $[5] = t;
207
+ $[6] = t3;
208
+ } else t3 = $[6];
209
+ let t4;
210
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
211
+ t4 = /* @__PURE__ */ jsx(PlusIcon, {});
212
+ $[7] = t4;
213
+ } else t4 = $[7];
214
+ let t5;
215
+ if ($[8] !== t3) {
216
+ t5 = /* @__PURE__ */ jsx(Control, {
217
+ action: "zoomIn",
218
+ label: t3,
219
+ children: t4
220
+ });
221
+ $[8] = t3;
222
+ $[9] = t5;
223
+ } else t5 = $[9];
224
+ let t6;
225
+ if ($[10] !== t) {
226
+ t6 = t("zoomOut");
227
+ $[10] = t;
228
+ $[11] = t6;
229
+ } else t6 = $[11];
230
+ let t7;
231
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
232
+ t7 = /* @__PURE__ */ jsx(MinusIcon, {});
233
+ $[12] = t7;
234
+ } else t7 = $[12];
235
+ let t8;
236
+ if ($[13] !== t6) {
237
+ t8 = /* @__PURE__ */ jsx(Control, {
238
+ action: "zoomOut",
239
+ label: t6,
240
+ children: t7
241
+ });
242
+ $[13] = t6;
243
+ $[14] = t8;
244
+ } else t8 = $[14];
245
+ let t9;
246
+ if ($[15] !== t) {
247
+ t9 = t("fit");
248
+ $[15] = t;
249
+ $[16] = t9;
250
+ } else t9 = $[16];
251
+ let t10;
252
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
253
+ t10 = /* @__PURE__ */ jsx(MaximizeIcon, {});
254
+ $[17] = t10;
255
+ } else t10 = $[17];
256
+ let t11;
257
+ if ($[18] !== t9) {
258
+ t11 = /* @__PURE__ */ jsx(Control, {
259
+ action: "fit",
260
+ label: t9,
261
+ children: t10
262
+ });
263
+ $[18] = t9;
264
+ $[19] = t11;
265
+ } else t11 = $[19];
266
+ let t12;
267
+ if ($[20] !== t11 || $[21] !== t2 || $[22] !== t5 || $[23] !== t8) {
268
+ t12 = /* @__PURE__ */ jsxs(Controls, {
269
+ label: t2,
270
+ children: [
271
+ t5,
272
+ t8,
273
+ t11
274
+ ]
275
+ });
276
+ $[20] = t11;
277
+ $[21] = t2;
278
+ $[22] = t5;
279
+ $[23] = t8;
280
+ $[24] = t12;
281
+ } else t12 = $[24];
282
+ let t13;
283
+ if ($[25] !== t) {
284
+ t13 = t("editor.label");
285
+ $[25] = t;
286
+ $[26] = t13;
287
+ } else t13 = $[26];
288
+ let t14;
289
+ if ($[27] !== setEdges) {
290
+ t14 = (connection) => {
291
+ setEdges((current) => addEdge(connection, current));
292
+ };
293
+ $[27] = setEdges;
294
+ $[28] = t14;
295
+ } else t14 = $[28];
296
+ let t15;
297
+ if ($[29] === Symbol.for("react.memo_cache_sentinel")) {
298
+ t15 = /* @__PURE__ */ jsx(XIcon, {});
299
+ $[29] = t15;
300
+ } else t15 = $[29];
301
+ let t16;
302
+ if ($[30] !== t) {
303
+ t16 = (t17) => {
304
+ const { source: source_1, target: target_1 } = t17;
305
+ return t("editor.remove", {
306
+ source: source_1,
307
+ target: target_1
308
+ });
309
+ };
310
+ $[30] = t;
311
+ $[31] = t16;
312
+ } else t16 = $[31];
313
+ let t17;
314
+ if ($[32] !== edges || $[33] !== nodes || $[34] !== onEdgesChange || $[35] !== onNodesChange || $[36] !== t13 || $[37] !== t14 || $[38] !== t16) {
315
+ t17 = /* @__PURE__ */ jsx(Canvas, {
316
+ edges,
317
+ label: t13,
318
+ nodes,
319
+ onConnect: t14,
320
+ onEdgesChange,
321
+ onNodesChange,
322
+ removeGlyph: t15,
323
+ removeName: t16
324
+ });
325
+ $[32] = edges;
326
+ $[33] = nodes;
327
+ $[34] = onEdgesChange;
328
+ $[35] = onNodesChange;
329
+ $[36] = t13;
330
+ $[37] = t14;
331
+ $[38] = t16;
332
+ $[39] = t17;
333
+ } else t17 = $[39];
334
+ let t18;
335
+ if ($[40] !== t12 || $[41] !== t17) {
336
+ t18 = /* @__PURE__ */ jsxs(Root, { children: [t12, t17] });
337
+ $[40] = t12;
338
+ $[41] = t17;
339
+ $[42] = t18;
340
+ } else t18 = $[42];
341
+ let t19;
342
+ if ($[43] !== edges.length || $[44] !== t) {
343
+ t19 = t("editor.count", { count: edges.length });
344
+ $[43] = edges.length;
345
+ $[44] = t;
346
+ $[45] = t19;
347
+ } else t19 = $[45];
348
+ let t20;
349
+ if ($[46] !== t19) {
350
+ t20 = /* @__PURE__ */ jsx(Text, {
351
+ as: "output",
352
+ size: "sm",
353
+ tone: "muted",
354
+ children: t19
355
+ });
356
+ $[46] = t19;
357
+ $[47] = t20;
358
+ } else t20 = $[47];
359
+ let t21;
360
+ if ($[48] !== t18 || $[49] !== t20) {
361
+ t21 = /* @__PURE__ */ jsxs(Stack, { children: [t18, t20] });
362
+ $[48] = t18;
363
+ $[49] = t20;
364
+ $[50] = t21;
365
+ } else t21 = $[50];
366
+ return t21;
367
+ }
368
+ function _temp2(t0) {
369
+ const [source_0, target_0] = t0;
370
+ return {
371
+ id: `${source_0}-${target_0}`,
372
+ source: source_0,
373
+ target: target_0
374
+ };
375
+ }
376
+ function _temp(t0) {
377
+ const [source, target] = t0;
378
+ return {
379
+ id: `${source}-${target}`,
380
+ source,
381
+ target
382
+ };
383
+ }
384
+ const source$6 = "import { type ReactElement } from \"react\";\n\nimport { addEdge, useEdgesState, useNodesState } from \"@xyflow/react\";\nimport { MaximizeIcon, MinusIcon, PlusIcon, XIcon } from \"lucide-react\";\n\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { Text } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst IDS = [\"webhook\", \"enrich\", \"route\", \"slack\", \"email\"] as const;\n\nconst LINKS = [\n [\"webhook\", \"enrich\"],\n [\"enrich\", \"route\"],\n [\"route\", \"slack\"],\n] as const;\n\nexport function Editor(): ReactElement {\n const { t } = useWords(\"graph\");\n const [nodes, , onNodesChange] = useNodesState(\n layoutGraph(\n IDS.map((id) => ({\n data: { label: t(`editor.${id}`) },\n id,\n position: { x: 0, y: 0 },\n type: id === \"webhook\" ? \"input\" : id === \"slack\" || id === \"email\" ? \"output\" : \"default\",\n })),\n LINKS.map(([source, target]) => ({ id: `${source}-${target}`, source, target })),\n { ranksep: 64 },\n ),\n );\n const [edges, setEdges, onEdgesChange] = useEdgesState(\n LINKS.map(([source, target]) => ({ id: `${source}-${target}`, source, target })),\n );\n\n return (\n <Stack>\n <Graph.Root>\n <Graph.Controls label={t(\"controls\")}>\n <Graph.Control action=\"zoomIn\" label={t(\"zoomIn\")}>\n <PlusIcon />\n </Graph.Control>\n <Graph.Control action=\"zoomOut\" label={t(\"zoomOut\")}>\n <MinusIcon />\n </Graph.Control>\n <Graph.Control action=\"fit\" label={t(\"fit\")}>\n <MaximizeIcon />\n </Graph.Control>\n </Graph.Controls>\n <Graph.Canvas\n edges={edges}\n label={t(\"editor.label\")}\n nodes={nodes}\n onConnect={(connection) => {\n setEdges((current) => addEdge(connection, current));\n }}\n onEdgesChange={onEdgesChange}\n onNodesChange={onNodesChange}\n removeGlyph={<XIcon />}\n removeName={({ source, target }) => t(\"editor.remove\", { source, target })}\n />\n </Graph.Root>\n <Text as=\"output\" size=\"sm\" tone=\"muted\">\n {t(\"editor.count\", { count: edges.length })}\n </Text>\n </Stack>\n );\n}\n";
385
+ //#endregion
386
+ //#region src/graph/examples/judge.example.tsx
387
+ var judge_example_exports = /* @__PURE__ */ __exportAll({
388
+ Judge: () => Judge,
389
+ source: () => source$5
390
+ });
391
+ const EDGES$3 = [
392
+ {
393
+ id: "draft-judge",
394
+ source: "draft",
395
+ target: "judge"
396
+ },
397
+ {
398
+ id: "judge-publish",
399
+ source: "judge",
400
+ sourceHandle: "pass",
401
+ target: "publish"
402
+ },
403
+ {
404
+ id: "judge-revise",
405
+ source: "judge",
406
+ sourceHandle: "fail",
407
+ target: "revise"
408
+ }
409
+ ];
410
+ function Judge() {
411
+ const $ = c(14);
412
+ const { t } = useWords("graph");
413
+ let t0;
414
+ if ($[0] !== t) {
415
+ t0 = layoutGraph([
416
+ {
417
+ data: {
418
+ label: t("judge.draft"),
419
+ subtitle: t("judge.model")
420
+ },
421
+ id: "draft",
422
+ position: {
423
+ x: 0,
424
+ y: 0
425
+ }
426
+ },
427
+ {
428
+ data: {
429
+ invalid: true,
430
+ label: t("judge.judge"),
431
+ outputs: [{
432
+ id: "pass",
433
+ label: t("judge.pass")
434
+ }, {
435
+ id: "fail",
436
+ label: t("judge.fail")
437
+ }],
438
+ problem: t("judge.problem"),
439
+ subtitle: t("judge.rubric")
440
+ },
441
+ id: "judge",
442
+ position: {
443
+ x: 0,
444
+ y: 0
445
+ }
446
+ },
447
+ {
448
+ data: { label: t("judge.publish") },
449
+ id: "publish",
450
+ position: {
451
+ x: 0,
452
+ y: 0
453
+ },
454
+ type: "output"
455
+ },
456
+ {
457
+ data: { label: t("judge.revise") },
458
+ id: "revise",
459
+ position: {
460
+ x: 0,
461
+ y: 0
462
+ },
463
+ type: "output"
464
+ }
465
+ ], EDGES$3, { ranksep: 96 });
466
+ $[0] = t;
467
+ $[1] = t0;
468
+ } else t0 = $[1];
469
+ const nodes = t0;
470
+ let t1;
471
+ if ($[2] !== t) {
472
+ t1 = t("judge.label");
473
+ $[2] = t;
474
+ $[3] = t1;
475
+ } else t1 = $[3];
476
+ let t2;
477
+ if ($[4] !== nodes || $[5] !== t1) {
478
+ t2 = /* @__PURE__ */ jsx(Canvas, {
479
+ edges: EDGES$3,
480
+ label: t1,
481
+ nodes,
482
+ readOnly: true
483
+ });
484
+ $[4] = nodes;
485
+ $[5] = t1;
486
+ $[6] = t2;
487
+ } else t2 = $[6];
488
+ let t3;
489
+ if ($[7] !== t) {
490
+ t3 = t("judge.caption");
491
+ $[7] = t;
492
+ $[8] = t3;
493
+ } else t3 = $[8];
494
+ let t4;
495
+ if ($[9] !== t3) {
496
+ t4 = /* @__PURE__ */ jsx(Caption, { children: t3 });
497
+ $[9] = t3;
498
+ $[10] = t4;
499
+ } else t4 = $[10];
500
+ let t5;
501
+ if ($[11] !== t2 || $[12] !== t4) {
502
+ t5 = /* @__PURE__ */ jsxs(Root, { children: [t2, t4] });
503
+ $[11] = t2;
504
+ $[12] = t4;
505
+ $[13] = t5;
506
+ } else t5 = $[13];
507
+ return t5;
508
+ }
509
+ const source$5 = "import { type ReactElement } from \"react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst EDGES = [\n { id: \"draft-judge\", source: \"draft\", target: \"judge\" },\n { id: \"judge-publish\", source: \"judge\", sourceHandle: \"pass\", target: \"publish\" },\n { id: \"judge-revise\", source: \"judge\", sourceHandle: \"fail\", target: \"revise\" },\n];\n\nexport function Judge(): ReactElement {\n const { t } = useWords(\"graph\");\n const nodes = layoutGraph(\n [\n {\n data: { label: t(\"judge.draft\"), subtitle: t(\"judge.model\") },\n id: \"draft\",\n position: { x: 0, y: 0 },\n },\n {\n data: {\n invalid: true,\n label: t(\"judge.judge\"),\n outputs: [\n { id: \"pass\", label: t(\"judge.pass\") },\n { id: \"fail\", label: t(\"judge.fail\") },\n ],\n problem: t(\"judge.problem\"),\n subtitle: t(\"judge.rubric\"),\n },\n id: \"judge\",\n position: { x: 0, y: 0 },\n },\n {\n data: { label: t(\"judge.publish\") },\n id: \"publish\",\n position: { x: 0, y: 0 },\n type: \"output\",\n },\n {\n data: { label: t(\"judge.revise\") },\n id: \"revise\",\n position: { x: 0, y: 0 },\n type: \"output\",\n },\n ],\n EDGES,\n { ranksep: 96 },\n );\n\n return (\n <Graph.Root>\n <Graph.Canvas edges={EDGES} label={t(\"judge.label\")} nodes={nodes} readOnly />\n <Graph.Caption>{t(\"judge.caption\")}</Graph.Caption>\n </Graph.Root>\n );\n}\n";
510
+ //#endregion
511
+ //#region src/graph/examples/pipeline.example.tsx
512
+ var pipeline_example_exports = /* @__PURE__ */ __exportAll({
513
+ Pipeline: () => Pipeline,
514
+ source: () => source$4
515
+ });
516
+ const STEPS$1 = [
517
+ {
518
+ id: "orders",
519
+ type: "input"
520
+ },
521
+ {
522
+ id: "customers",
523
+ type: "input"
524
+ },
525
+ {
526
+ id: "clean",
527
+ status: {
528
+ key: "succeeded",
529
+ palette: "success"
530
+ },
531
+ type: "default"
532
+ },
533
+ {
534
+ id: "join",
535
+ status: {
536
+ key: "running",
537
+ palette: "info"
538
+ },
539
+ type: "default"
540
+ },
541
+ {
542
+ id: "revenue",
543
+ type: "output"
544
+ },
545
+ {
546
+ id: "churn",
547
+ status: {
548
+ key: "failed",
549
+ palette: "error"
550
+ },
551
+ type: "output"
552
+ }
553
+ ];
554
+ const EDGES$2 = [
555
+ {
556
+ id: "orders-clean",
557
+ source: "orders",
558
+ target: "clean"
559
+ },
560
+ {
561
+ id: "clean-join",
562
+ source: "clean",
563
+ target: "join"
564
+ },
565
+ {
566
+ id: "customers-join",
567
+ source: "customers",
568
+ target: "join"
569
+ },
570
+ {
571
+ id: "join-revenue",
572
+ source: "join",
573
+ target: "revenue"
574
+ },
575
+ {
576
+ id: "join-churn",
577
+ source: "join",
578
+ target: "churn"
579
+ }
580
+ ];
581
+ function Pipeline() {
582
+ const $ = c(38);
583
+ const { t } = useWords("graph");
584
+ let t0;
585
+ if ($[0] !== t) {
586
+ t0 = layoutGraph(STEPS$1.map((step) => ({
587
+ data: {
588
+ label: t(`pipeline.${step.id}.label`),
589
+ subtitle: t(`pipeline.${step.id}.kind`),
590
+ ..."status" in step ? { status: {
591
+ label: t(`status.${step.status.key}`),
592
+ palette: step.status.palette
593
+ } } : {}
594
+ },
595
+ id: step.id,
596
+ position: {
597
+ x: 0,
598
+ y: 0
599
+ },
600
+ type: step.type
601
+ })), EDGES$2, { ranksep: 64 });
602
+ $[0] = t;
603
+ $[1] = t0;
604
+ } else t0 = $[1];
605
+ const nodes = t0;
606
+ let t1;
607
+ if ($[2] !== t) {
608
+ t1 = t("controls");
609
+ $[2] = t;
610
+ $[3] = t1;
611
+ } else t1 = $[3];
612
+ let t2;
613
+ if ($[4] !== t) {
614
+ t2 = t("zoomIn");
615
+ $[4] = t;
616
+ $[5] = t2;
617
+ } else t2 = $[5];
618
+ let t3;
619
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
620
+ t3 = /* @__PURE__ */ jsx(PlusIcon, {});
621
+ $[6] = t3;
622
+ } else t3 = $[6];
623
+ let t4;
624
+ if ($[7] !== t2) {
625
+ t4 = /* @__PURE__ */ jsx(Control, {
626
+ action: "zoomIn",
627
+ label: t2,
628
+ children: t3
629
+ });
630
+ $[7] = t2;
631
+ $[8] = t4;
632
+ } else t4 = $[8];
633
+ let t5;
634
+ if ($[9] !== t) {
635
+ t5 = t("zoomOut");
636
+ $[9] = t;
637
+ $[10] = t5;
638
+ } else t5 = $[10];
639
+ let t6;
640
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
641
+ t6 = /* @__PURE__ */ jsx(MinusIcon, {});
642
+ $[11] = t6;
643
+ } else t6 = $[11];
644
+ let t7;
645
+ if ($[12] !== t5) {
646
+ t7 = /* @__PURE__ */ jsx(Control, {
647
+ action: "zoomOut",
648
+ label: t5,
649
+ children: t6
650
+ });
651
+ $[12] = t5;
652
+ $[13] = t7;
653
+ } else t7 = $[13];
654
+ let t8;
655
+ if ($[14] !== t) {
656
+ t8 = t("fit");
657
+ $[14] = t;
658
+ $[15] = t8;
659
+ } else t8 = $[15];
660
+ let t9;
661
+ if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
662
+ t9 = /* @__PURE__ */ jsx(MaximizeIcon, {});
663
+ $[16] = t9;
664
+ } else t9 = $[16];
665
+ let t10;
666
+ if ($[17] !== t8) {
667
+ t10 = /* @__PURE__ */ jsx(Control, {
668
+ action: "fit",
669
+ label: t8,
670
+ children: t9
671
+ });
672
+ $[17] = t8;
673
+ $[18] = t10;
674
+ } else t10 = $[18];
675
+ let t11;
676
+ if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
677
+ t11 = /* @__PURE__ */ jsx(ZoomLevel, {});
678
+ $[19] = t11;
679
+ } else t11 = $[19];
680
+ let t12;
681
+ if ($[20] !== t1 || $[21] !== t10 || $[22] !== t4 || $[23] !== t7) {
682
+ t12 = /* @__PURE__ */ jsxs(Controls, {
683
+ label: t1,
684
+ children: [
685
+ t4,
686
+ t7,
687
+ t10,
688
+ t11
689
+ ]
690
+ });
691
+ $[20] = t1;
692
+ $[21] = t10;
693
+ $[22] = t4;
694
+ $[23] = t7;
695
+ $[24] = t12;
696
+ } else t12 = $[24];
697
+ let t13;
698
+ if ($[25] !== t) {
699
+ t13 = t("pipeline.label");
700
+ $[25] = t;
701
+ $[26] = t13;
702
+ } else t13 = $[26];
703
+ let t14;
704
+ if ($[27] !== nodes || $[28] !== t13) {
705
+ t14 = /* @__PURE__ */ jsx(Canvas, {
706
+ edges: EDGES$2,
707
+ label: t13,
708
+ nodes,
709
+ readOnly: true
710
+ });
711
+ $[27] = nodes;
712
+ $[28] = t13;
713
+ $[29] = t14;
714
+ } else t14 = $[29];
715
+ let t15;
716
+ if ($[30] !== t) {
717
+ t15 = t("pipeline.caption");
718
+ $[30] = t;
719
+ $[31] = t15;
720
+ } else t15 = $[31];
721
+ let t16;
722
+ if ($[32] !== t15) {
723
+ t16 = /* @__PURE__ */ jsx(Caption, { children: t15 });
724
+ $[32] = t15;
725
+ $[33] = t16;
726
+ } else t16 = $[33];
727
+ let t17;
728
+ if ($[34] !== t12 || $[35] !== t14 || $[36] !== t16) {
729
+ t17 = /* @__PURE__ */ jsxs(Root, { children: [
730
+ t12,
731
+ t14,
732
+ t16
733
+ ] });
734
+ $[34] = t12;
735
+ $[35] = t14;
736
+ $[36] = t16;
737
+ $[37] = t17;
738
+ } else t17 = $[37];
739
+ return t17;
740
+ }
741
+ const source$4 = "import { type ReactElement } from \"react\";\n\nimport { MaximizeIcon, MinusIcon, PlusIcon } from \"lucide-react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst STEPS = [\n { id: \"orders\", type: \"input\" },\n { id: \"customers\", type: \"input\" },\n { id: \"clean\", status: { key: \"succeeded\", palette: \"success\" }, type: \"default\" },\n { id: \"join\", status: { key: \"running\", palette: \"info\" }, type: \"default\" },\n { id: \"revenue\", type: \"output\" },\n { id: \"churn\", status: { key: \"failed\", palette: \"error\" }, type: \"output\" },\n] as const;\n\nconst EDGES = [\n { id: \"orders-clean\", source: \"orders\", target: \"clean\" },\n { id: \"clean-join\", source: \"clean\", target: \"join\" },\n { id: \"customers-join\", source: \"customers\", target: \"join\" },\n { id: \"join-revenue\", source: \"join\", target: \"revenue\" },\n { id: \"join-churn\", source: \"join\", target: \"churn\" },\n];\n\nexport function Pipeline(): ReactElement {\n const { t } = useWords(\"graph\");\n const nodes = layoutGraph(\n STEPS.map((step) => ({\n data: {\n label: t(`pipeline.${step.id}.label`),\n subtitle: t(`pipeline.${step.id}.kind`),\n ...(\"status\" in step\n ? { status: { label: t(`status.${step.status.key}`), palette: step.status.palette } }\n : {}),\n },\n id: step.id,\n position: { x: 0, y: 0 },\n type: step.type,\n })),\n EDGES,\n { ranksep: 64 },\n );\n\n return (\n <Graph.Root>\n <Graph.Controls label={t(\"controls\")}>\n <Graph.Control action=\"zoomIn\" label={t(\"zoomIn\")}>\n <PlusIcon />\n </Graph.Control>\n <Graph.Control action=\"zoomOut\" label={t(\"zoomOut\")}>\n <MinusIcon />\n </Graph.Control>\n <Graph.Control action=\"fit\" label={t(\"fit\")}>\n <MaximizeIcon />\n </Graph.Control>\n <Graph.ZoomLevel />\n </Graph.Controls>\n <Graph.Canvas edges={EDGES} label={t(\"pipeline.label\")} nodes={nodes} readOnly />\n <Graph.Caption>{t(\"pipeline.caption\")}</Graph.Caption>\n </Graph.Root>\n );\n}\n";
742
+ //#endregion
743
+ //#region src/graph/examples/services.example.tsx
744
+ var services_example_exports = /* @__PURE__ */ __exportAll({
745
+ Services: () => Services,
746
+ source: () => source$3
747
+ });
748
+ const CALLS = [
749
+ ["gateway", "auth"],
750
+ ["gateway", "catalog"],
751
+ ["gateway", "cart"],
752
+ ["gateway", "search"],
753
+ ["cart", "pricing"],
754
+ ["cart", "inventory"],
755
+ ["catalog", "inventory"],
756
+ ["catalog", "media"],
757
+ ["search", "catalog"],
758
+ ["checkout", "cart"],
759
+ ["checkout", "payments"],
760
+ ["checkout", "shipping"],
761
+ ["payments", "fraud"],
762
+ ["payments", "ledger"],
763
+ ["shipping", "inventory"],
764
+ ["gateway", "checkout"]
765
+ ];
766
+ const IDS = [...new Set(CALLS.flat())];
767
+ const EDGES$1 = CALLS.map(([source, target]) => ({
768
+ id: `${source}-${target}`,
769
+ source,
770
+ target
771
+ }));
772
+ function Services() {
773
+ const $ = c(19);
774
+ const { t } = useWords("graph");
775
+ let t0;
776
+ if ($[0] !== t) {
777
+ t0 = layoutGraph(IDS.map((id) => ({
778
+ data: { label: t(`services.${id}`) },
779
+ id,
780
+ position: {
781
+ x: 0,
782
+ y: 0
783
+ }
784
+ })), EDGES$1, { direction: "right" });
785
+ $[0] = t;
786
+ $[1] = t0;
787
+ } else t0 = $[1];
788
+ const nodes = t0;
789
+ let t1;
790
+ if ($[2] !== t) {
791
+ t1 = t("services.label");
792
+ $[2] = t;
793
+ $[3] = t1;
794
+ } else t1 = $[3];
795
+ let t2;
796
+ if ($[4] !== nodes || $[5] !== t1) {
797
+ t2 = /* @__PURE__ */ jsx(Canvas, {
798
+ edges: EDGES$1,
799
+ label: t1,
800
+ nodes,
801
+ readOnly: true
802
+ });
803
+ $[4] = nodes;
804
+ $[5] = t1;
805
+ $[6] = t2;
806
+ } else t2 = $[6];
807
+ let t3;
808
+ if ($[7] !== t) {
809
+ t3 = t("services.overview");
810
+ $[7] = t;
811
+ $[8] = t3;
812
+ } else t3 = $[8];
813
+ let t4;
814
+ if ($[9] !== t3) {
815
+ t4 = /* @__PURE__ */ jsx(MiniMap$1, { label: t3 });
816
+ $[9] = t3;
817
+ $[10] = t4;
818
+ } else t4 = $[10];
819
+ let t5;
820
+ if ($[11] !== t) {
821
+ t5 = t("services.caption");
822
+ $[11] = t;
823
+ $[12] = t5;
824
+ } else t5 = $[12];
825
+ let t6;
826
+ if ($[13] !== t5) {
827
+ t6 = /* @__PURE__ */ jsx(Caption, { children: t5 });
828
+ $[13] = t5;
829
+ $[14] = t6;
830
+ } else t6 = $[14];
831
+ let t7;
832
+ if ($[15] !== t2 || $[16] !== t4 || $[17] !== t6) {
833
+ t7 = /* @__PURE__ */ jsxs(Root, {
834
+ direction: "right",
835
+ ratio: "wide",
836
+ children: [
837
+ t2,
838
+ t4,
839
+ t6
840
+ ]
841
+ });
842
+ $[15] = t2;
843
+ $[16] = t4;
844
+ $[17] = t6;
845
+ $[18] = t7;
846
+ } else t7 = $[18];
847
+ return t7;
848
+ }
849
+ const source$3 = "import { type ReactElement } from \"react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst CALLS = [\n [\"gateway\", \"auth\"],\n [\"gateway\", \"catalog\"],\n [\"gateway\", \"cart\"],\n [\"gateway\", \"search\"],\n [\"cart\", \"pricing\"],\n [\"cart\", \"inventory\"],\n [\"catalog\", \"inventory\"],\n [\"catalog\", \"media\"],\n [\"search\", \"catalog\"],\n [\"checkout\", \"cart\"],\n [\"checkout\", \"payments\"],\n [\"checkout\", \"shipping\"],\n [\"payments\", \"fraud\"],\n [\"payments\", \"ledger\"],\n [\"shipping\", \"inventory\"],\n [\"gateway\", \"checkout\"],\n] as const;\n\nconst IDS = [...new Set(CALLS.flat())];\n\nconst EDGES = CALLS.map(([source, target]) => ({ id: `${source}-${target}`, source, target }));\n\nexport function Services(): ReactElement {\n const { t } = useWords(\"graph\");\n const nodes = layoutGraph(\n IDS.map((id) => ({ data: { label: t(`services.${id}`) }, id, position: { x: 0, y: 0 } })),\n EDGES,\n { direction: \"right\" },\n );\n\n return (\n <Graph.Root direction=\"right\" ratio=\"wide\">\n <Graph.Canvas edges={EDGES} label={t(\"services.label\")} nodes={nodes} readOnly />\n <Graph.MiniMap label={t(\"services.overview\")} />\n <Graph.Caption>{t(\"services.caption\")}</Graph.Caption>\n </Graph.Root>\n );\n}\n";
850
+ //#endregion
851
+ //#region src/graph/examples/versions.example.tsx
852
+ var versions_example_exports = /* @__PURE__ */ __exportAll({
853
+ Versions: () => Versions,
854
+ source: () => source$2
855
+ });
856
+ const ORIGIN = {
857
+ x: 0,
858
+ y: 0
859
+ };
860
+ const BEFORE = {
861
+ links: [
862
+ ["screen", "draft"],
863
+ ["draft", "publish"],
864
+ ["publish", "notify"]
865
+ ],
866
+ steps: [
867
+ ["screen", "screening"],
868
+ ["draft", "small"],
869
+ ["publish", "helpCentre"],
870
+ ["notify", "email"]
871
+ ]
872
+ };
873
+ const AFTER = {
874
+ links: [
875
+ ["screen", "draft"],
876
+ ["draft", "score"],
877
+ ["score", "publish"]
878
+ ],
879
+ steps: [
880
+ ["screen", "screening"],
881
+ ["draft", "large"],
882
+ ["score", "three"],
883
+ ["publish", "helpCentre"]
884
+ ]
885
+ };
886
+ function edgesOf(links) {
887
+ return links.map(([source, target]) => ({
888
+ id: `${source}-${target}`,
889
+ source,
890
+ target
891
+ }));
892
+ }
893
+ function Versions() {
894
+ const $ = c(62);
895
+ const { t } = useWords("graph");
896
+ let t0;
897
+ if ($[0] !== t) {
898
+ t0 = (steps) => steps.map((t1) => {
899
+ const [id, detail] = t1;
900
+ return {
901
+ data: {
902
+ label: t(`versions.steps.${id}`),
903
+ subtitle: t(`versions.details.${detail}`)
904
+ },
905
+ id,
906
+ position: ORIGIN
907
+ };
908
+ });
909
+ $[0] = t;
910
+ $[1] = t0;
911
+ } else t0 = $[1];
912
+ const nodesOf = t0;
913
+ let T0;
914
+ let T1;
915
+ let T2;
916
+ let T3;
917
+ let t1;
918
+ let t2;
919
+ let t3;
920
+ let t4;
921
+ let t5;
922
+ let t6;
923
+ let t7;
924
+ let t8;
925
+ let words;
926
+ if ($[2] !== nodesOf || $[3] !== t) {
927
+ const before = {
928
+ edges: edgesOf(BEFORE.links),
929
+ nodes: nodesOf(BEFORE.steps)
930
+ };
931
+ const after = {
932
+ edges: edgesOf(AFTER.links),
933
+ nodes: nodesOf(AFTER.steps)
934
+ };
935
+ const diff = diffGraphs(before, after);
936
+ let t9;
937
+ if ($[17] !== t) {
938
+ t9 = t("versions.added");
939
+ $[17] = t;
940
+ $[18] = t9;
941
+ } else t9 = $[18];
942
+ let t10;
943
+ if ($[19] !== t) {
944
+ t10 = t("versions.changed");
945
+ $[19] = t;
946
+ $[20] = t10;
947
+ } else t10 = $[20];
948
+ let t11;
949
+ if ($[21] !== t) {
950
+ t11 = t("versions.removed");
951
+ $[21] = t;
952
+ $[22] = t11;
953
+ } else t11 = $[22];
954
+ let t12;
955
+ if ($[23] !== t10 || $[24] !== t11 || $[25] !== t9) {
956
+ t12 = {
957
+ addedLabel: t9,
958
+ changedLabel: t10,
959
+ removedLabel: t11
960
+ };
961
+ $[23] = t10;
962
+ $[24] = t11;
963
+ $[25] = t9;
964
+ $[26] = t12;
965
+ } else t12 = $[26];
966
+ words = t12;
967
+ T3 = Grid.Root;
968
+ t6 = "fit-xs";
969
+ t7 = "md";
970
+ const t13 = before.edges;
971
+ let t14;
972
+ if ($[27] !== t) {
973
+ t14 = t("versions.before.label");
974
+ $[27] = t;
975
+ $[28] = t14;
976
+ } else t14 = $[28];
977
+ let t15;
978
+ if ($[29] !== t) {
979
+ t15 = t("versions.before.caption");
980
+ $[29] = t;
981
+ $[30] = t15;
982
+ } else t15 = $[30];
983
+ let t16;
984
+ if ($[31] !== t15) {
985
+ t16 = /* @__PURE__ */ jsx(Caption, { children: t15 });
986
+ $[31] = t15;
987
+ $[32] = t16;
988
+ } else t16 = $[32];
989
+ const t17 = /* @__PURE__ */ jsxs(Root, {
990
+ ratio: "portrait",
991
+ children: [/* @__PURE__ */ jsx(Canvas, {
992
+ changes: diff,
993
+ edges: t13,
994
+ label: t14,
995
+ nodes: layoutGraph(before.nodes, before.edges),
996
+ readOnly: true,
997
+ ...words
998
+ }), t16]
999
+ });
1000
+ if ($[33] !== t17) {
1001
+ t8 = /* @__PURE__ */ jsx(Grid.Item, { children: t17 });
1002
+ $[33] = t17;
1003
+ $[34] = t8;
1004
+ } else t8 = $[34];
1005
+ T2 = Grid.Item;
1006
+ T1 = Root;
1007
+ t5 = "portrait";
1008
+ T0 = Canvas;
1009
+ t1 = diff;
1010
+ t2 = after.edges;
1011
+ if ($[35] !== t) {
1012
+ t3 = t("versions.after.label");
1013
+ $[35] = t;
1014
+ $[36] = t3;
1015
+ } else t3 = $[36];
1016
+ t4 = layoutGraph(after.nodes, after.edges);
1017
+ $[2] = nodesOf;
1018
+ $[3] = t;
1019
+ $[4] = T0;
1020
+ $[5] = T1;
1021
+ $[6] = T2;
1022
+ $[7] = T3;
1023
+ $[8] = t1;
1024
+ $[9] = t2;
1025
+ $[10] = t3;
1026
+ $[11] = t4;
1027
+ $[12] = t5;
1028
+ $[13] = t6;
1029
+ $[14] = t7;
1030
+ $[15] = t8;
1031
+ $[16] = words;
1032
+ } else {
1033
+ T0 = $[4];
1034
+ T1 = $[5];
1035
+ T2 = $[6];
1036
+ T3 = $[7];
1037
+ t1 = $[8];
1038
+ t2 = $[9];
1039
+ t3 = $[10];
1040
+ t4 = $[11];
1041
+ t5 = $[12];
1042
+ t6 = $[13];
1043
+ t7 = $[14];
1044
+ t8 = $[15];
1045
+ words = $[16];
1046
+ }
1047
+ let t9;
1048
+ if ($[37] !== T0 || $[38] !== t1 || $[39] !== t2 || $[40] !== t3 || $[41] !== t4 || $[42] !== words) {
1049
+ t9 = /* @__PURE__ */ jsx(T0, {
1050
+ changes: t1,
1051
+ edges: t2,
1052
+ label: t3,
1053
+ nodes: t4,
1054
+ readOnly: true,
1055
+ ...words
1056
+ });
1057
+ $[37] = T0;
1058
+ $[38] = t1;
1059
+ $[39] = t2;
1060
+ $[40] = t3;
1061
+ $[41] = t4;
1062
+ $[42] = words;
1063
+ $[43] = t9;
1064
+ } else t9 = $[43];
1065
+ let t10;
1066
+ if ($[44] !== t) {
1067
+ t10 = t("versions.after.caption");
1068
+ $[44] = t;
1069
+ $[45] = t10;
1070
+ } else t10 = $[45];
1071
+ let t11;
1072
+ if ($[46] !== t10) {
1073
+ t11 = /* @__PURE__ */ jsx(Caption, { children: t10 });
1074
+ $[46] = t10;
1075
+ $[47] = t11;
1076
+ } else t11 = $[47];
1077
+ let t12;
1078
+ if ($[48] !== T1 || $[49] !== t11 || $[50] !== t5 || $[51] !== t9) {
1079
+ t12 = /* @__PURE__ */ jsxs(T1, {
1080
+ ratio: t5,
1081
+ children: [t9, t11]
1082
+ });
1083
+ $[48] = T1;
1084
+ $[49] = t11;
1085
+ $[50] = t5;
1086
+ $[51] = t9;
1087
+ $[52] = t12;
1088
+ } else t12 = $[52];
1089
+ let t13;
1090
+ if ($[53] !== T2 || $[54] !== t12) {
1091
+ t13 = /* @__PURE__ */ jsx(T2, { children: t12 });
1092
+ $[53] = T2;
1093
+ $[54] = t12;
1094
+ $[55] = t13;
1095
+ } else t13 = $[55];
1096
+ let t14;
1097
+ if ($[56] !== T3 || $[57] !== t13 || $[58] !== t6 || $[59] !== t7 || $[60] !== t8) {
1098
+ t14 = /* @__PURE__ */ jsxs(T3, {
1099
+ columns: t6,
1100
+ gap: t7,
1101
+ children: [t8, t13]
1102
+ });
1103
+ $[56] = T3;
1104
+ $[57] = t13;
1105
+ $[58] = t6;
1106
+ $[59] = t7;
1107
+ $[60] = t8;
1108
+ $[61] = t14;
1109
+ } else t14 = $[61];
1110
+ return t14;
1111
+ }
1112
+ const source$2 = "import { type ReactElement } from \"react\";\n\nimport { type Edge, type Node } from \"@xyflow/react\";\n\nimport { Grid } from \"@stealthscale/component-layout\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, diffGraphs, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst ORIGIN = { x: 0, y: 0 };\n\nconst BEFORE = {\n links: [\n [\"screen\", \"draft\"],\n [\"draft\", \"publish\"],\n [\"publish\", \"notify\"],\n ],\n steps: [\n [\"screen\", \"screening\"],\n [\"draft\", \"small\"],\n [\"publish\", \"helpCentre\"],\n [\"notify\", \"email\"],\n ],\n} as const;\n\nconst AFTER = {\n links: [\n [\"screen\", \"draft\"],\n [\"draft\", \"score\"],\n [\"score\", \"publish\"],\n ],\n steps: [\n [\"screen\", \"screening\"],\n [\"draft\", \"large\"],\n [\"score\", \"three\"],\n [\"publish\", \"helpCentre\"],\n ],\n} as const;\n\nfunction edgesOf(links: typeof AFTER.links | typeof BEFORE.links): Edge[] {\n return links.map(([source, target]) => ({ id: `${source}-${target}`, source, target }));\n}\n\nexport function Versions(): ReactElement {\n const { t } = useWords(\"graph\");\n const nodesOf = (steps: typeof AFTER.steps | typeof BEFORE.steps): Node[] =>\n steps.map(([id, detail]) => ({\n data: { label: t(`versions.steps.${id}`), subtitle: t(`versions.details.${detail}`) },\n id,\n position: ORIGIN,\n }));\n const before = { edges: edgesOf(BEFORE.links), nodes: nodesOf(BEFORE.steps) };\n const after = { edges: edgesOf(AFTER.links), nodes: nodesOf(AFTER.steps) };\n const diff = diffGraphs(before, after);\n const words = {\n addedLabel: t(\"versions.added\"),\n changedLabel: t(\"versions.changed\"),\n removedLabel: t(\"versions.removed\"),\n };\n\n return (\n <Grid.Root columns=\"fit-xs\" gap=\"md\">\n <Grid.Item>\n <Graph.Root ratio=\"portrait\">\n <Graph.Canvas\n changes={diff}\n edges={before.edges}\n label={t(\"versions.before.label\")}\n nodes={layoutGraph(before.nodes, before.edges)}\n readOnly\n {...words}\n />\n <Graph.Caption>{t(\"versions.before.caption\")}</Graph.Caption>\n </Graph.Root>\n </Grid.Item>\n <Grid.Item>\n <Graph.Root ratio=\"portrait\">\n <Graph.Canvas\n changes={diff}\n edges={after.edges}\n label={t(\"versions.after.label\")}\n nodes={layoutGraph(after.nodes, after.edges)}\n readOnly\n {...words}\n />\n <Graph.Caption>{t(\"versions.after.caption\")}</Graph.Caption>\n </Graph.Root>\n </Grid.Item>\n </Grid.Root>\n );\n}\n";
1113
+ //#endregion
1114
+ //#region src/graph/examples/workflow.example.tsx
1115
+ var workflow_example_exports = /* @__PURE__ */ __exportAll({
1116
+ Workflow: () => Workflow,
1117
+ source: () => source$1
1118
+ });
1119
+ const KINDS = [
1120
+ "fraud",
1121
+ "stock",
1122
+ "notice"
1123
+ ];
1124
+ function Workflow() {
1125
+ const $ = c(78);
1126
+ const { t } = useWords("graph");
1127
+ let t0;
1128
+ if ($[0] !== t) {
1129
+ t0 = t("workflow.placed");
1130
+ $[0] = t;
1131
+ $[1] = t0;
1132
+ } else t0 = $[1];
1133
+ let t1;
1134
+ if ($[2] !== t0) {
1135
+ t1 = { label: t0 };
1136
+ $[2] = t0;
1137
+ $[3] = t1;
1138
+ } else t1 = $[3];
1139
+ let t2;
1140
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
1141
+ t2 = {
1142
+ x: 0,
1143
+ y: 0
1144
+ };
1145
+ $[4] = t2;
1146
+ } else t2 = $[4];
1147
+ let t3;
1148
+ if ($[5] !== t1) {
1149
+ t3 = {
1150
+ data: t1,
1151
+ id: "placed",
1152
+ position: t2,
1153
+ type: "input"
1154
+ };
1155
+ $[5] = t1;
1156
+ $[6] = t3;
1157
+ } else t3 = $[6];
1158
+ let t4;
1159
+ if ($[7] !== t) {
1160
+ t4 = t("workflow.receipt");
1161
+ $[7] = t;
1162
+ $[8] = t4;
1163
+ } else t4 = $[8];
1164
+ let t5;
1165
+ if ($[9] !== t4) {
1166
+ t5 = { label: t4 };
1167
+ $[9] = t4;
1168
+ $[10] = t5;
1169
+ } else t5 = $[10];
1170
+ let t6;
1171
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
1172
+ t6 = {
1173
+ x: 0,
1174
+ y: 240
1175
+ };
1176
+ $[11] = t6;
1177
+ } else t6 = $[11];
1178
+ let t7;
1179
+ if ($[12] !== t5) {
1180
+ t7 = {
1181
+ data: t5,
1182
+ id: "receipt",
1183
+ position: t6,
1184
+ type: "output"
1185
+ };
1186
+ $[12] = t5;
1187
+ $[13] = t7;
1188
+ } else t7 = $[13];
1189
+ let t8;
1190
+ if ($[14] !== t3 || $[15] !== t7) {
1191
+ t8 = [t3, t7];
1192
+ $[14] = t3;
1193
+ $[15] = t7;
1194
+ $[16] = t8;
1195
+ } else t8 = $[16];
1196
+ const [nodes, setNodes, onNodesChange] = useNodesState(t8);
1197
+ let t9;
1198
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
1199
+ t9 = [{
1200
+ id: "placed-receipt",
1201
+ source: "placed",
1202
+ target: "receipt"
1203
+ }];
1204
+ $[17] = t9;
1205
+ } else t9 = $[17];
1206
+ const [edges, setEdges, onEdgesChange] = useEdgesState(t9);
1207
+ let t10;
1208
+ if ($[18] !== edges || $[19] !== nodes) {
1209
+ t10 = {
1210
+ edges,
1211
+ nodes
1212
+ };
1213
+ $[18] = edges;
1214
+ $[19] = nodes;
1215
+ $[20] = t10;
1216
+ } else t10 = $[20];
1217
+ const start = useRef(t10);
1218
+ let t11;
1219
+ if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
1220
+ t11 = [];
1221
+ $[21] = t11;
1222
+ } else t11 = $[21];
1223
+ const [versions, setVersions] = useState(t11);
1224
+ const [note, setNote] = useState();
1225
+ let t12;
1226
+ if ($[22] !== t) {
1227
+ t12 = new Map(KINDS.map((kind) => [kind, t(`workflow.kinds.${kind}`)]));
1228
+ $[22] = t;
1229
+ $[23] = t12;
1230
+ } else t12 = $[23];
1231
+ const names = t12;
1232
+ let t13;
1233
+ if ($[24] !== setEdges || $[25] !== setNodes) {
1234
+ t13 = (version) => {
1235
+ setVersions((known) => [version, ...known]);
1236
+ setNote(version.note);
1237
+ setNodes(version.nodes);
1238
+ setEdges(version.edges);
1239
+ };
1240
+ $[24] = setEdges;
1241
+ $[25] = setNodes;
1242
+ $[26] = t13;
1243
+ } else t13 = $[26];
1244
+ const commit = t13;
1245
+ let t14;
1246
+ if ($[27] !== commit || $[28] !== edges || $[29] !== names || $[30] !== nodes || $[31] !== t) {
1247
+ t14 = (kind_0, position) => {
1248
+ const label = names.get(kind_0) ?? kind_0;
1249
+ const id = `${kind_0}-${crypto.randomUUID()}`;
1250
+ commit({
1251
+ edges,
1252
+ nodes: [...nodes, {
1253
+ data: { label },
1254
+ id,
1255
+ origin: [.5, .5],
1256
+ position
1257
+ }],
1258
+ note: t("workflow.edits.add", { name: label })
1259
+ });
1260
+ };
1261
+ $[27] = commit;
1262
+ $[28] = edges;
1263
+ $[29] = names;
1264
+ $[30] = nodes;
1265
+ $[31] = t;
1266
+ $[32] = t14;
1267
+ } else t14 = $[32];
1268
+ const add = t14;
1269
+ let t15;
1270
+ if ($[33] !== add || $[34] !== t) {
1271
+ t15 = KINDS.map((kind_1) => /* @__PURE__ */ jsx(PaletteItem, {
1272
+ item: kind_1,
1273
+ onAdd: add,
1274
+ size: "sm",
1275
+ children: t(`workflow.add.${kind_1}`)
1276
+ }, kind_1));
1277
+ $[33] = add;
1278
+ $[34] = t;
1279
+ $[35] = t15;
1280
+ } else t15 = $[35];
1281
+ let t16;
1282
+ if ($[36] !== t15) {
1283
+ t16 = /* @__PURE__ */ jsx(Stack, {
1284
+ direction: "row",
1285
+ gap: "sm",
1286
+ wrap: true,
1287
+ children: t15
1288
+ });
1289
+ $[36] = t15;
1290
+ $[37] = t16;
1291
+ } else t16 = $[37];
1292
+ let t17;
1293
+ if ($[38] !== t) {
1294
+ t17 = t("workflow.label");
1295
+ $[38] = t;
1296
+ $[39] = t17;
1297
+ } else t17 = $[39];
1298
+ let t18;
1299
+ if ($[40] !== commit || $[41] !== t) {
1300
+ t18 = (graph, step) => {
1301
+ const touched = step.nodes.length > 0 ? step.nodes : step.edges;
1302
+ const kind_2 = step.type === "remove" && step.nodes.length === 0 ? "unlink" : step.type;
1303
+ commit({
1304
+ ...graph,
1305
+ note: t(`workflow.edits.${kind_2}`, { count: touched.length })
1306
+ });
1307
+ };
1308
+ $[40] = commit;
1309
+ $[41] = t;
1310
+ $[42] = t18;
1311
+ } else t18 = $[42];
1312
+ let t19;
1313
+ if ($[43] === Symbol.for("react.memo_cache_sentinel")) {
1314
+ t19 = /* @__PURE__ */ jsx(XIcon, {});
1315
+ $[43] = t19;
1316
+ } else t19 = $[43];
1317
+ let t20;
1318
+ if ($[44] !== t) {
1319
+ t20 = (t21) => {
1320
+ const { source, target } = t21;
1321
+ return t("workflow.remove", {
1322
+ source,
1323
+ target
1324
+ });
1325
+ };
1326
+ $[44] = t;
1327
+ $[45] = t20;
1328
+ } else t20 = $[45];
1329
+ let t21;
1330
+ if ($[46] !== add || $[47] !== edges || $[48] !== nodes || $[49] !== onEdgesChange || $[50] !== onNodesChange || $[51] !== t17 || $[52] !== t18 || $[53] !== t20) {
1331
+ t21 = /* @__PURE__ */ jsx(Canvas, {
1332
+ edges,
1333
+ label: t17,
1334
+ nodes,
1335
+ onDropItem: add,
1336
+ onEdgesChange,
1337
+ onGraphChange: t18,
1338
+ onNodesChange,
1339
+ removeGlyph: t19,
1340
+ removeName: t20
1341
+ });
1342
+ $[46] = add;
1343
+ $[47] = edges;
1344
+ $[48] = nodes;
1345
+ $[49] = onEdgesChange;
1346
+ $[50] = onNodesChange;
1347
+ $[51] = t17;
1348
+ $[52] = t18;
1349
+ $[53] = t20;
1350
+ $[54] = t21;
1351
+ } else t21 = $[54];
1352
+ let t22;
1353
+ if ($[55] !== note || $[56] !== t) {
1354
+ t22 = note ?? t("workflow.none");
1355
+ $[55] = note;
1356
+ $[56] = t;
1357
+ $[57] = t22;
1358
+ } else t22 = $[57];
1359
+ let t23;
1360
+ if ($[58] !== t22) {
1361
+ t23 = /* @__PURE__ */ jsx("output", { children: t22 });
1362
+ $[58] = t22;
1363
+ $[59] = t23;
1364
+ } else t23 = $[59];
1365
+ const t24 = versions.length === 0 ? true : void 0;
1366
+ let t25;
1367
+ if ($[60] !== setEdges || $[61] !== setNodes || $[62] !== t || $[63] !== versions) {
1368
+ t25 = () => {
1369
+ const [last, ...rest] = versions;
1370
+ if (last === void 0) return;
1371
+ const graph_0 = rest[0] ?? start.current;
1372
+ setNodes(graph_0.nodes);
1373
+ setEdges(graph_0.edges);
1374
+ setVersions(rest);
1375
+ setNote(t("workflow.undone", { edit: last.note }));
1376
+ };
1377
+ $[60] = setEdges;
1378
+ $[61] = setNodes;
1379
+ $[62] = t;
1380
+ $[63] = versions;
1381
+ $[64] = t25;
1382
+ } else t25 = $[64];
1383
+ let t26;
1384
+ if ($[65] !== t) {
1385
+ t26 = t("workflow.undo");
1386
+ $[65] = t;
1387
+ $[66] = t26;
1388
+ } else t26 = $[66];
1389
+ let t27;
1390
+ if ($[67] !== t24 || $[68] !== t25 || $[69] !== t26) {
1391
+ t27 = /* @__PURE__ */ jsx(Button, {
1392
+ "aria-disabled": t24,
1393
+ onClick: t25,
1394
+ size: "sm",
1395
+ variant: "outline",
1396
+ children: t26
1397
+ });
1398
+ $[67] = t24;
1399
+ $[68] = t25;
1400
+ $[69] = t26;
1401
+ $[70] = t27;
1402
+ } else t27 = $[70];
1403
+ let t28;
1404
+ if ($[71] !== t23 || $[72] !== t27) {
1405
+ t28 = /* @__PURE__ */ jsxs(Summary, { children: [t23, t27] });
1406
+ $[71] = t23;
1407
+ $[72] = t27;
1408
+ $[73] = t28;
1409
+ } else t28 = $[73];
1410
+ let t29;
1411
+ if ($[74] !== t16 || $[75] !== t21 || $[76] !== t28) {
1412
+ t29 = /* @__PURE__ */ jsxs(Root, { children: [
1413
+ t16,
1414
+ t21,
1415
+ t28
1416
+ ] });
1417
+ $[74] = t16;
1418
+ $[75] = t21;
1419
+ $[76] = t28;
1420
+ $[77] = t29;
1421
+ } else t29 = $[77];
1422
+ return t29;
1423
+ }
1424
+ const source$1 = "import { type ReactElement, useRef, useState } from \"react\";\n\nimport { type Edge, type Node, useEdgesState, useNodesState, type XYPosition } from \"@xyflow/react\";\nimport { XIcon } from \"lucide-react\";\n\nimport { Button } from \"@stealthscale/component-actions\";\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph } from \"@stealthscale/component-graphs\";\n\nconst KINDS = [\"fraud\", \"stock\", \"notice\"] as const;\n\ninterface Version {\n readonly edges: Edge[];\n readonly nodes: Node[];\n readonly note: string;\n}\n\nexport function Workflow(): ReactElement {\n const { t } = useWords(\"graph\");\n const [nodes, setNodes, onNodesChange] = useNodesState<Node>([\n {\n data: { label: t(\"workflow.placed\") },\n id: \"placed\",\n position: { x: 0, y: 0 },\n type: \"input\",\n },\n {\n data: { label: t(\"workflow.receipt\") },\n id: \"receipt\",\n position: { x: 0, y: 240 },\n type: \"output\",\n },\n ]);\n const [edges, setEdges, onEdgesChange] = useEdgesState([\n { id: \"placed-receipt\", source: \"placed\", target: \"receipt\" },\n ]);\n const start = useRef({ edges, nodes });\n const [versions, setVersions] = useState<Version[]>([]);\n const [note, setNote] = useState<string>();\n const names = new Map<string, string>(KINDS.map((kind) => [kind, t(`workflow.kinds.${kind}`)]));\n const commit = (version: Version): void => {\n setVersions((known) => [version, ...known]);\n setNote(version.note);\n setNodes(version.nodes);\n setEdges(version.edges);\n };\n const add = (kind: string, position: XYPosition): void => {\n const label = names.get(kind) ?? kind;\n const id = `${kind}-${crypto.randomUUID()}`;\n\n commit({\n edges,\n nodes: [...nodes, { data: { label }, id, origin: [0.5, 0.5], position }],\n note: t(\"workflow.edits.add\", { name: label }),\n });\n };\n\n return (\n <Graph.Root>\n <Stack direction=\"row\" gap=\"sm\" wrap>\n {KINDS.map((kind) => (\n <Graph.PaletteItem item={kind} key={kind} onAdd={add} size=\"sm\">\n {t(`workflow.add.${kind}`)}\n </Graph.PaletteItem>\n ))}\n </Stack>\n <Graph.Canvas\n edges={edges}\n label={t(\"workflow.label\")}\n nodes={nodes}\n onDropItem={add}\n onEdgesChange={onEdgesChange}\n onGraphChange={(graph, step) => {\n const touched = step.nodes.length > 0 ? step.nodes : step.edges;\n const kind = step.type === \"remove\" && step.nodes.length === 0 ? \"unlink\" : step.type;\n\n commit({ ...graph, note: t(`workflow.edits.${kind}`, { count: touched.length }) });\n }}\n onNodesChange={onNodesChange}\n removeGlyph={<XIcon />}\n removeName={({ source, target }) => t(\"workflow.remove\", { source, target })}\n />\n <Graph.Summary>\n <output>{note ?? t(\"workflow.none\")}</output>\n <Button\n aria-disabled={versions.length === 0 ? true : undefined}\n onClick={() => {\n const [last, ...rest] = versions;\n\n if (last === undefined) return;\n\n const graph = rest[0] ?? start.current;\n\n setNodes(graph.nodes);\n setEdges(graph.edges);\n setVersions(rest);\n setNote(t(\"workflow.undone\", { edit: last.note }));\n }}\n size=\"sm\"\n variant=\"outline\"\n >\n {t(\"workflow.undo\")}\n </Button>\n </Graph.Summary>\n </Graph.Root>\n );\n}\n";
1425
+ //#endregion
1426
+ //#region src/graph/examples/review.example.tsx
1427
+ var review_example_exports = /* @__PURE__ */ __exportAll({
1428
+ Review: () => Review,
1429
+ source: () => source
1430
+ });
1431
+ const STEPS = [
1432
+ "draft",
1433
+ "review",
1434
+ "publish"
1435
+ ];
1436
+ const EDGES = [{
1437
+ id: "draft-review",
1438
+ source: "draft",
1439
+ target: "review"
1440
+ }, {
1441
+ id: "review-publish",
1442
+ source: "review",
1443
+ target: "publish"
1444
+ }];
1445
+ function Review(props) {
1446
+ const $ = c(10);
1447
+ const { t } = useWords("graph");
1448
+ let t0;
1449
+ if ($[0] !== t) {
1450
+ t0 = layoutGraph(STEPS.map((step) => ({
1451
+ data: { label: t(`review.${step}`) },
1452
+ id: step,
1453
+ position: {
1454
+ x: 0,
1455
+ y: 0
1456
+ },
1457
+ type: step === "draft" ? "input" : step === "publish" ? "output" : "default"
1458
+ })), EDGES, { ranksep: 48 });
1459
+ $[0] = t;
1460
+ $[1] = t0;
1461
+ } else t0 = $[1];
1462
+ const nodes = t0;
1463
+ let t1;
1464
+ if ($[2] !== t) {
1465
+ t1 = t("review.label");
1466
+ $[2] = t;
1467
+ $[3] = t1;
1468
+ } else t1 = $[3];
1469
+ let t2;
1470
+ if ($[4] !== nodes || $[5] !== t1) {
1471
+ t2 = /* @__PURE__ */ jsx(Canvas, {
1472
+ edges: EDGES,
1473
+ label: t1,
1474
+ nodes,
1475
+ readOnly: true
1476
+ });
1477
+ $[4] = nodes;
1478
+ $[5] = t1;
1479
+ $[6] = t2;
1480
+ } else t2 = $[6];
1481
+ let t3;
1482
+ if ($[7] !== props || $[8] !== t2) {
1483
+ t3 = /* @__PURE__ */ jsx(Root, {
1484
+ ...props,
1485
+ children: t2
1486
+ });
1487
+ $[7] = props;
1488
+ $[8] = t2;
1489
+ $[9] = t3;
1490
+ } else t3 = $[9];
1491
+ return t3;
1492
+ }
1493
+ const source = "import { type ReactElement } from \"react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { Graph, layoutGraph } from \"@stealthscale/component-graphs\";\n\nconst STEPS = [\"draft\", \"review\", \"publish\"] as const;\n\nconst EDGES = [\n { id: \"draft-review\", source: \"draft\", target: \"review\" },\n { id: \"review-publish\", source: \"review\", target: \"publish\" },\n];\n\nexport function Review(props: Graph.RootProps): ReactElement {\n const { t } = useWords(\"graph\");\n const nodes = layoutGraph(\n STEPS.map((step) => ({\n data: { label: t(`review.${step}`) },\n id: step,\n position: { x: 0, y: 0 },\n type: step === \"draft\" ? \"input\" : step === \"publish\" ? \"output\" : \"default\",\n })),\n EDGES,\n { ranksep: 48 },\n );\n\n return (\n <Graph.Root {...props}>\n <Graph.Canvas edges={EDGES} label={t(\"review.label\")} nodes={nodes} readOnly />\n </Graph.Root>\n );\n}\n";
1494
+ //#endregion
1495
+ //#region src/graph/graph.specimen.tsx
1496
+ /**
1497
+ * Catalogue page for the graph kit.
1498
+ *
1499
+ * @remarks
1500
+ * `scenesOf` generates the `ratio` scene from a three-step review flow, one canvas per ratio in
1501
+ * an `md` room. The other scenes are hand-written: a read-only data pipeline laid out by rank, an
1502
+ * editable canvas whose connections a person makes and removes, a palette that adds steps with a
1503
+ * history that undoes each edit, a judge whose two ports fan out with a problem on the card, a
1504
+ * map of services with the overview map, two versions of a flow marked with their changes, and
1505
+ * the list of those changes. Every scene renders a component from `examples/` and shows that file
1506
+ * as its source. The words are keys under `graph` in `locales/en/specimen/graph.json`. The page
1507
+ * imports the review example directly, because the props reader follows a specimen's own imports
1508
+ * and the example files they name, not an examples barrel.
1509
+ */
1510
+ /**
1511
+ * Hand-written scene for a read-only pipeline laid out by rank.
1512
+ */
1513
+ const read = {
1514
+ about: "graph.pipeline.about",
1515
+ draw: () => /* @__PURE__ */ jsx(Room, {
1516
+ size: "2xl",
1517
+ children: /* @__PURE__ */ jsx(Pipeline, {})
1518
+ }),
1519
+ example: pipeline_example_exports,
1520
+ title: "graph.pipeline.title"
1521
+ };
1522
+ /**
1523
+ * Hand-written scene for a canvas whose connections a person makes and removes.
1524
+ */
1525
+ const edit = {
1526
+ about: "graph.editor.about",
1527
+ draw: () => /* @__PURE__ */ jsx(Room, {
1528
+ size: "2xl",
1529
+ children: /* @__PURE__ */ jsx(Editor, {})
1530
+ }),
1531
+ example: editor_example_exports,
1532
+ title: "graph.editor.title"
1533
+ };
1534
+ /**
1535
+ * Hand-written scene for a palette that adds steps and a history that undoes each edit.
1536
+ */
1537
+ const palette = {
1538
+ about: "graph.workflow.about",
1539
+ draw: () => /* @__PURE__ */ jsx(Room, {
1540
+ size: "2xl",
1541
+ children: /* @__PURE__ */ jsx(Workflow, {})
1542
+ }),
1543
+ example: workflow_example_exports,
1544
+ title: "graph.workflow.title"
1545
+ };
1546
+ /**
1547
+ * Hand-written scene for named ports that fan out and a problem on the card.
1548
+ */
1549
+ const ports = {
1550
+ about: "graph.judge.about",
1551
+ draw: () => /* @__PURE__ */ jsx(Room, {
1552
+ size: "2xl",
1553
+ children: /* @__PURE__ */ jsx(Judge, {})
1554
+ }),
1555
+ example: judge_example_exports,
1556
+ title: "graph.judge.title"
1557
+ };
1558
+ /**
1559
+ * Hand-written scene for a graph larger than its canvas, with the overview map.
1560
+ */
1561
+ const overview = {
1562
+ about: "graph.services.about",
1563
+ draw: () => /* @__PURE__ */ jsx(Room, {
1564
+ size: "4xl",
1565
+ children: /* @__PURE__ */ jsx(Services, {})
1566
+ }),
1567
+ example: services_example_exports,
1568
+ title: "graph.services.title"
1569
+ };
1570
+ /**
1571
+ * Hand-written scene for two versions of a flow side by side, each marked with the changes.
1572
+ */
1573
+ const compared = {
1574
+ about: "graph.versions.about",
1575
+ draw: () => /* @__PURE__ */ jsx(Room, {
1576
+ size: "4xl",
1577
+ children: /* @__PURE__ */ jsx(Versions, {})
1578
+ }),
1579
+ example: versions_example_exports,
1580
+ title: "graph.versions.title"
1581
+ };
1582
+ /**
1583
+ * Hand-written scene for the list of changes between two versions.
1584
+ */
1585
+ const listed = {
1586
+ about: "graph.versions.list.about",
1587
+ draw: () => /* @__PURE__ */ jsx(Room, {
1588
+ size: "md",
1589
+ children: /* @__PURE__ */ jsx(Changes, {})
1590
+ }),
1591
+ example: changes_example_exports,
1592
+ title: "graph.versions.list.title"
1593
+ };
1594
+ var graph_specimen_default = specimen({
1595
+ about: "graph.about",
1596
+ id: "components/graphs/graph",
1597
+ imports: "import { diffGraphs, Graph, layoutGraph } from \"@stealthscale/component-graphs\";",
1598
+ scenes: [
1599
+ read,
1600
+ edit,
1601
+ palette,
1602
+ ports,
1603
+ overview,
1604
+ compared,
1605
+ listed,
1606
+ ...scenesOf(recipe, {
1607
+ axes: { ratio: { direction: "column" } },
1608
+ draw: (props) => /* @__PURE__ */ jsx(Room, {
1609
+ size: "md",
1610
+ children: /* @__PURE__ */ jsx(Review, { ...props })
1611
+ }),
1612
+ example: review_example_exports,
1613
+ namespace: "graph"
1614
+ })
1615
+ ],
1616
+ title: "graph.title"
1617
+ });
1618
+ //#endregion
1619
+ export { compared, graph_specimen_default as default, edit, listed, overview, palette, ports, read };