@formicoidea/labre-framework-uml 0.42.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.
Files changed (114) hide show
  1. package/LICENSE +384 -0
  2. package/dist/actions.d.ts +430 -0
  3. package/dist/actions.js +724 -0
  4. package/dist/background.d.ts +153 -0
  5. package/dist/background.js +557 -0
  6. package/dist/board-hit.d.ts +137 -0
  7. package/dist/board-hit.js +191 -0
  8. package/dist/commands-manifest.d.ts +19 -0
  9. package/dist/commands-manifest.js +571 -0
  10. package/dist/commands.d.ts +4 -0
  11. package/dist/commands.js +983 -0
  12. package/dist/component.d.ts +521 -0
  13. package/dist/component.js +708 -0
  14. package/dist/consts.d.ts +365 -0
  15. package/dist/consts.js +463 -0
  16. package/dist/descriptor.d.ts +12 -0
  17. package/dist/descriptor.js +10 -0
  18. package/dist/drawio-decode.d.ts +32 -0
  19. package/dist/drawio-decode.js +96 -0
  20. package/dist/drawio-import.d.ts +133 -0
  21. package/dist/drawio-import.js +885 -0
  22. package/dist/edge-morph.d.ts +154 -0
  23. package/dist/edge-morph.js +153 -0
  24. package/dist/edge-styles.d.ts +78 -0
  25. package/dist/edge-styles.js +210 -0
  26. package/dist/effects.d.ts +9 -0
  27. package/dist/effects.js +6 -0
  28. package/dist/element-renderer.d.ts +64 -0
  29. package/dist/element-renderer.js +114 -0
  30. package/dist/element-view.d.ts +234 -0
  31. package/dist/element-view.js +430 -0
  32. package/dist/export.d.ts +61 -0
  33. package/dist/export.js +41 -0
  34. package/dist/filename.d.ts +17 -0
  35. package/dist/filename.js +26 -0
  36. package/dist/frame-tag.d.ts +70 -0
  37. package/dist/frame-tag.js +78 -0
  38. package/dist/grammar.d.ts +695 -0
  39. package/dist/grammar.js +1436 -0
  40. package/dist/import.d.ts +306 -0
  41. package/dist/import.js +1270 -0
  42. package/dist/index.d.ts +47 -0
  43. package/dist/index.js +67 -0
  44. package/dist/interchange.d.ts +125 -0
  45. package/dist/interchange.js +372 -0
  46. package/dist/keywords.d.ts +204 -0
  47. package/dist/keywords.js +361 -0
  48. package/dist/kinds.d.ts +73 -0
  49. package/dist/kinds.js +91 -0
  50. package/dist/legend.d.ts +30 -0
  51. package/dist/legend.js +255 -0
  52. package/dist/model.d.ts +862 -0
  53. package/dist/model.js +1316 -0
  54. package/dist/morph.d.ts +178 -0
  55. package/dist/morph.js +496 -0
  56. package/dist/node/act-glyphs.d.ts +30 -0
  57. package/dist/node/act-glyphs.js +142 -0
  58. package/dist/node/compartment-watcher.d.ts +107 -0
  59. package/dist/node/compartment-watcher.js +163 -0
  60. package/dist/node/fit.d.ts +85 -0
  61. package/dist/node/fit.js +129 -0
  62. package/dist/node/node-renderer.d.ts +49 -0
  63. package/dist/node/node-renderer.js +611 -0
  64. package/dist/node/node-view.d.ts +51 -0
  65. package/dist/node/node-view.js +89 -0
  66. package/dist/node/paint.d.ts +84 -0
  67. package/dist/node/paint.js +143 -0
  68. package/dist/node/sd-glyphs.d.ts +36 -0
  69. package/dist/node/sd-glyphs.js +79 -0
  70. package/dist/node/stm-glyphs.d.ts +22 -0
  71. package/dist/node/stm-glyphs.js +111 -0
  72. package/dist/node/tier-metrics.d.ts +38 -0
  73. package/dist/node/tier-metrics.js +45 -0
  74. package/dist/operators.d.ts +45 -0
  75. package/dist/operators.js +75 -0
  76. package/dist/plantuml-import.d.ts +113 -0
  77. package/dist/plantuml-import.js +1723 -0
  78. package/dist/plantuml.d.ts +94 -0
  79. package/dist/plantuml.js +985 -0
  80. package/dist/presets.d.ts +149 -0
  81. package/dist/presets.js +302 -0
  82. package/dist/profiles.d.ts +2 -0
  83. package/dist/profiles.js +358 -0
  84. package/dist/reading.d.ts +160 -0
  85. package/dist/reading.js +648 -0
  86. package/dist/roles.d.ts +257 -0
  87. package/dist/roles.js +997 -0
  88. package/dist/rules.d.ts +267 -0
  89. package/dist/rules.js +3090 -0
  90. package/dist/templates.d.ts +2 -0
  91. package/dist/templates.js +197 -0
  92. package/dist/toolbar/config.d.ts +228 -0
  93. package/dist/toolbar/config.js +833 -0
  94. package/dist/toolbar/icons.d.ts +440 -0
  95. package/dist/toolbar/icons.js +711 -0
  96. package/dist/toolbar/senior-tool.d.ts +11 -0
  97. package/dist/toolbar/senior-tool.js +21 -0
  98. package/dist/toolbar/uml-menu.d.ts +17 -0
  99. package/dist/toolbar/uml-menu.js +20 -0
  100. package/dist/toolbar/uml-senior-button.d.ts +18 -0
  101. package/dist/toolbar/uml-senior-button.js +22 -0
  102. package/dist/translations.d.ts +27 -0
  103. package/dist/translations.js +117 -0
  104. package/dist/view.d.ts +33 -0
  105. package/dist/view.js +236 -0
  106. package/dist/xmi-import.d.ts +174 -0
  107. package/dist/xmi-import.js +2268 -0
  108. package/dist/xmi.d.ts +61 -0
  109. package/dist/xmi.js +1860 -0
  110. package/dist/xml-reader.d.ts +157 -0
  111. package/dist/xml-reader.js +430 -0
  112. package/dist/xml.d.ts +72 -0
  113. package/dist/xml.js +96 -0
  114. package/package.json +38 -0
package/dist/kinds.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The combined fragment's OPERATOR picker, re-exported.
3
+ *
4
+ * It lives in `operators.ts` — a fragment's operator is a different field on a
5
+ * different element, and thirteen entries beside the diagram kinds would make
6
+ * this file two tables under one name. It is re-exported here all the same,
7
+ * because a reader looking for "the pickers this framework declares" looks
8
+ * first at the file named after one of them, and because both spellings were
9
+ * already in use by the time the second picker landed.
10
+ */
11
+ export { UML_FRAGMENT_OPERATOR_MENU, } from './operators.js';
12
+ /** i18n key stem: `class` → `com.labre.uml.kind.class`. */
13
+ const kindKey = (name) => `com.labre.uml.kind.${name}`;
14
+ /**
15
+ * The picker, whole: its own heading and its entries, in the order UML itself
16
+ * teaches them — the classifiers first, then what groups them, then their
17
+ * instances, then what the system is for, then what it is built of and where it
18
+ * runs.
19
+ *
20
+ * One object rather than a loose array plus a stray heading constant, because
21
+ * the manifest walks DECLARATIONS: `umlTranslationEntries` hands this value to
22
+ * `collectTranslationKeys` and every key below reaches a host's catalogue with
23
+ * nothing restated anywhere.
24
+ */
25
+ export const UML_DIAGRAM_KIND_MENU = {
26
+ labelKey: kindKey('section'),
27
+ labelFallback: 'Diagram',
28
+ options: [
29
+ {
30
+ kind: 'class',
31
+ labelKey: kindKey('class'),
32
+ labelFallback: 'Class diagram',
33
+ },
34
+ {
35
+ kind: 'pkg',
36
+ labelKey: kindKey('pkg'),
37
+ labelFallback: 'Package diagram',
38
+ },
39
+ {
40
+ // Not an Annex A frame kind: the standard treats an object diagram as a
41
+ // class diagram showing instances. `obj` is the TOOL CONVENTION every
42
+ // drawing tool uses and every architect expects — recorded as a choice in
43
+ // `UmlDiagramKind`, and offered here for the same reason.
44
+ kind: 'obj',
45
+ labelKey: kindKey('obj'),
46
+ labelFallback: 'Object diagram',
47
+ },
48
+ {
49
+ kind: 'uc',
50
+ labelKey: kindKey('uc'),
51
+ labelFallback: 'Use case diagram',
52
+ },
53
+ // Phase 2. Both are Annex A frame kinds with Annex A's own abbreviations,
54
+ // and they come after the phase-1 four rather than in alphabetical order:
55
+ // the list teaches the notation in the sequence an architect meets it, and
56
+ // what a system is BUILT of comes after what it is made of.
57
+ {
58
+ kind: 'cmp',
59
+ labelKey: kindKey('cmp'),
60
+ labelFallback: 'Component diagram',
61
+ },
62
+ {
63
+ kind: 'dep',
64
+ labelKey: kindKey('dep'),
65
+ labelFallback: 'Deployment diagram',
66
+ },
67
+ // Phase 2, the behaviour frames. Last in the list because they are what a
68
+ // system DOES, and the list teaches the notation in the order an architect
69
+ // meets it: what the system is made of, what it is built of, where it runs,
70
+ // and only then how it behaves.
71
+ {
72
+ kind: 'act',
73
+ labelKey: kindKey('act'),
74
+ labelFallback: 'Activity diagram',
75
+ },
76
+ {
77
+ kind: 'stm',
78
+ labelKey: kindKey('stm'),
79
+ labelFallback: 'State machine diagram',
80
+ },
81
+ // Phase 3, the interaction frame (§17.2.4). Last, and last for the reason
82
+ // the behaviour frames came after the structural ones: a sequence diagram
83
+ // is what the parts a reader has already met SAY to each other, so it only
84
+ // means anything once they have been drawn.
85
+ {
86
+ kind: 'sd',
87
+ labelKey: kindKey('sd'),
88
+ labelFallback: 'Sequence diagram',
89
+ },
90
+ ],
91
+ };
@@ -0,0 +1,30 @@
1
+ import type { ChromeWording } from '@formicoidea/labre-core/shared/services';
2
+ import type { CommandLegendEntry } from '@formicoidea/labre-core/std';
3
+ /** Every section `titleKey` above, for `translations.ts`'s manifest. */
4
+ export declare const UML_LEGEND_SECTION_WORDINGS: readonly ChromeWording[];
5
+ /**
6
+ * The legend row a toolbox entry subscribes, read off the `element` value it
7
+ * already declares for telemetry (`node:class`, `connector:association`,
8
+ * `boundary:region`) — so the row and the gesture cannot drift, and a kind
9
+ * added to the pack gets its row on the day its command lands.
10
+ *
11
+ * `undefined` for an entry that owes none: the frame itself, and the
12
+ * interaction use whose role another row already covers.
13
+ *
14
+ * The box's layout is the board command's to declare, not this function's: see
15
+ * {@link UML_LEGEND_BOX}.
16
+ */
17
+ export declare function umlLegendEntry(element: string): CommandLegendEntry | undefined;
18
+ /**
19
+ * The BOX, declared once on the command that puts the frame down.
20
+ *
21
+ * A picture needs room a colour chip does not: 34 × 24 is enough for a class to
22
+ * show its two compartment rules and for an actor to show a head, arms and legs,
23
+ * and 34 is the pitch that leaves them breathing space between rows.
24
+ */
25
+ export declare const UML_LEGEND_BOX: {
26
+ readonly width: 300;
27
+ readonly rowHeight: 34;
28
+ readonly swatchWidth: 34;
29
+ readonly swatchHeight: 24;
30
+ };
package/dist/legend.js ADDED
@@ -0,0 +1,255 @@
1
+ import { StrokeStyle } from '@formicoidea/labre-core/model';
2
+ import { UML_CARD, UML_FRAME_INK, UML_INK, UML_NODE_BOX, UML_NODE_STROKE_WIDTH, } from './consts.js';
3
+ import { UML_EDGE_STYLE } from './edge-styles.js';
4
+ import { umlNodeProps } from './presets.js';
5
+ import { UML_ROLE, UML_ROLE_OF_KIND } from './roles.js';
6
+ /**
7
+ * What the UML diagram frame's automatic legend can say — not a table, but the
8
+ * ROW each of the toolbox's own commands subscribes (`docs/adr/0026`).
9
+ * `commands.ts` calls {@link umlLegendEntry} once per entry and the surface
10
+ * block's engine does the rest: the scan, the order, the sections, the
11
+ * placement and the box.
12
+ *
13
+ * Every row's WORDING is the role vocabulary's own and is nowhere in here, so
14
+ * renaming a role renames its legend row — which is what keeps a legend a
15
+ * description of the board rather than a second opinion about it.
16
+ *
17
+ * ## A monochrome legend, and what carries the meaning instead
18
+ *
19
+ * The other packs' legends are colour keys: a C4 row is a blue square, an EDGY
20
+ * row a facet's hue. UML defines no palette — every figure in the specification
21
+ * is black on white — so no swatch below can carry meaning in its colour, and
22
+ * every one of them is the same card white with the same ink round it.
23
+ *
24
+ * What carries the meaning is the SILHOUETTE, and the PO's recette of
25
+ * 2026-09-15 is what made that non-negotiable: « les pictogrammes de la légende
26
+ * ne sont pas correctement importés, il n'y a que des rectangles pour class et
27
+ * actors alors qu'ils ont des pictos bien particuliers ». A key of identical
28
+ * white chips documents nothing at all in a notation whose whole vocabulary is
29
+ * pictures — a class is a divided box, an actor a stick figure, a use case an
30
+ * ellipse, a package a tabbed folder, an aggregation a hollow diamond.
31
+ *
32
+ * ## So every row draws the artefact itself
33
+ *
34
+ * A node row is a `glyph` swatch carrying {@link umlNodeProps} — the SAME preset
35
+ * the toolbox creates the artefact with, minus its role and its box — so the
36
+ * picture in the legend is painted by `UmlNodeRendererExtension` from the same
37
+ * declaration as the picture on the sheet. Nothing here draws a second copy of
38
+ * the notation, which is the rule this pack has followed since `background.ts`:
39
+ * a legend that redrew its own classes would be a second opinion about them, and
40
+ * it would drift the first time somebody touched a glyph.
41
+ *
42
+ * A relation row is an `edge` swatch carrying its own line from
43
+ * {@link UML_EDGE_STYLE} — the one table the toolbox and the morph already
44
+ * share — so a hollow diamond, a hollow triangle, a filled head and a broken
45
+ * line are drawn by the connector renderer at swatch size rather than
46
+ * approximated by a bar.
47
+ *
48
+ * The aspect of each glyph is the artefact's own footprint
49
+ * ({@link UML_NODE_BOX}), fitted inside the swatch box: an actor is drawn
50
+ * portrait, a class landscape, a fork as the bar §15.3.4 draws.
51
+ *
52
+ * ## The one thing a swatch must NOT carry
53
+ *
54
+ * A role. The legend is drawn ON the frame it documents and the scan is by role
55
+ * (`rolesInBound`), so a swatch stamped with one would list ITSELF the next time
56
+ * a legend was generated — a class row conjured by the class row before it.
57
+ * {@link nodeRow} strips it, deliberately and in one place, and the drawing side
58
+ * strips it again for anything that slipped through.
59
+ *
60
+ * ## `exact` on the association and on the node, and nowhere else
61
+ *
62
+ * `uml:aggregation` and `uml:composition` specialise `uml:association`
63
+ * (`roles.ts`), so an inclusive entry on the parent would put an "Association"
64
+ * row — a plain undecorated line — on a board carrying nothing but diamonds. The
65
+ * row would name a line that is nowhere on the diagram. `exact` makes the base
66
+ * and its two specialisations three separate statements, each listed when it is
67
+ * the thing the author actually drew.
68
+ *
69
+ * `uml:node` is the second and last, for the same sentence one clause later:
70
+ * §19.4.4 makes a Device and an ExecutionEnvironment kinds of Node, and a
71
+ * deployment sheet of keyworded cubes would otherwise carry a bare "Node" row
72
+ * naming a box nobody drew.
73
+ *
74
+ * The other chains need no such care, because none of their parents gets a row
75
+ * at all: `uml:classifier`, `uml:control-node`, `uml:pseudostate` and
76
+ * `uml:message` are ancestors nothing is ever drawn as, and a "Classifier" or a
77
+ * "Message" row would name a shape that exists only in the vocabulary.
78
+ *
79
+ * ## What subscribes nothing, and why
80
+ *
81
+ * `uml.addDiagram` — `uml:diagram` is the sheet the legend is drawn ON, and
82
+ * listing it would be listing the paper. It declares the BOX instead
83
+ * (`CommandDescriptor.legendBox`).
84
+ *
85
+ * `uml.addInteractionUse` — it draws the very same combined fragment with `ref`
86
+ * in its tag (§17.7.4) and therefore stamps `uml:fragment`, which the fragment's
87
+ * own row already covers. A second row would name one frame twice.
88
+ */
89
+ /* ── The three kinds of row ────────────────────────────────────────────── */
90
+ /**
91
+ * A node row: the artefact itself, drawn at swatch size by its own renderer.
92
+ *
93
+ * `role` and `xywh` are dropped from the preset and for two different reasons.
94
+ * The BOX is the legend's to decide — the layout fits the aspect below inside
95
+ * the swatch column — and the ROLE must not be on a swatch at all, or the
96
+ * legend starts documenting itself (see the note above).
97
+ */
98
+ function nodeRow(kind) {
99
+ const { role: _role, xywh: _xywh, ...props } = umlNodeProps(kind, {
100
+ xywh: '[0,0,0,0]',
101
+ });
102
+ const box = UML_NODE_BOX[kind];
103
+ return {
104
+ swatch: 'glyph',
105
+ // Read by nothing for a glyph row — the element carries its own fill and
106
+ // stroke — and written all the same, because `CommandLegendRow` asks for a
107
+ // colour and a row that lied about which one it uses would be worse than
108
+ // one that repeats the paper.
109
+ color: UML_CARD,
110
+ props,
111
+ aspect: box.h > 0 ? box.w / box.h : 1,
112
+ };
113
+ }
114
+ /**
115
+ * A relation row: the line the toolbox actually arms, endpoints and all.
116
+ *
117
+ * `dashed` is kept beside the props although the connector already carries its
118
+ * own `strokeStyle`: it is the one fact about a relation row a pure test can
119
+ * read without a renderer, and it is DERIVED from the same table rather than
120
+ * restated, so the two can never disagree.
121
+ */
122
+ function edgeRow(role) {
123
+ const style = UML_EDGE_STYLE[role];
124
+ return {
125
+ swatch: 'edge',
126
+ color: UML_INK,
127
+ dashed: style.strokeStyle === StrokeStyle.Dash,
128
+ props: { ...style },
129
+ };
130
+ }
131
+ /**
132
+ * A frame row: a hollow rectangle in the frame ink.
133
+ *
134
+ * None of the four has a body — a subject, a swimlane, a composite state and a
135
+ * combined fragment are each a rectangle drawn ROUND part of the drawing — so
136
+ * the swatch is an OUTLINE and never a filled chip, which is the same statement
137
+ * the `line` swatch used to make and a better picture of it.
138
+ */
139
+ function frameRow(radius) {
140
+ return {
141
+ swatch: 'glyph',
142
+ color: UML_FRAME_INK,
143
+ props: {
144
+ type: 'shape',
145
+ shapeType: 'rect',
146
+ filled: false,
147
+ fillColor: UML_CARD,
148
+ strokeColor: UML_FRAME_INK,
149
+ strokeWidth: UML_NODE_STROKE_WIDTH,
150
+ strokeStyle: StrokeStyle.Solid,
151
+ roughness: 0,
152
+ radius,
153
+ },
154
+ // The sheets are drawn wider than they are tall, and the swatch says so.
155
+ aspect: 1.5,
156
+ };
157
+ }
158
+ /* ── The three sections ────────────────────────────────────────────────── */
159
+ /**
160
+ * This legend's own three section titles.
161
+ *
162
+ * Declared here beside the rows they head, and keyed per FRAMEWORK rather than
163
+ * shared with C4's identical three: a framework never imports another's wording
164
+ * (`translation-service/README.md`), so "Elements" is UML's own word about UML's
165
+ * own vocabulary, and a host is free to word it differently on a class diagram
166
+ * than on a context diagram.
167
+ *
168
+ * They are DECLARED rather than left to the commands' `category`, which since
169
+ * 2026-09-16 files the catalogue by DIAGRAM KIND: nine headers from "Class
170
+ * diagram" to "Sequence diagram" would tell a reader which toolbox drawer a
171
+ * gesture lives in, not whether the thing on the sheet is a shape, a frame or a
172
+ * line. The box's own title is the one exception — every board that has a legend
173
+ * says the same generic "Legend", and reuses `BOARD_LEGEND_TITLE` for it.
174
+ */
175
+ const SECTION_ELEMENTS = [
176
+ 'com.labre.uml.legend.section.elements',
177
+ 'Elements',
178
+ ];
179
+ const SECTION_FRAMES = [
180
+ 'com.labre.uml.legend.section.frames',
181
+ 'Frames',
182
+ ];
183
+ const SECTION_RELATIONS = [
184
+ 'com.labre.uml.legend.section.relations',
185
+ 'Relations',
186
+ ];
187
+ /** Every section `titleKey` above, for `translations.ts`'s manifest. */
188
+ export const UML_LEGEND_SECTION_WORDINGS = [
189
+ SECTION_ELEMENTS,
190
+ SECTION_FRAMES,
191
+ SECTION_RELATIONS,
192
+ ];
193
+ /**
194
+ * The four frames that get a row, with the corner §14.2.4 draws them with: a
195
+ * composite state is rounded like the state it is one of, and it is the one
196
+ * frame whose outline is not square.
197
+ *
198
+ * `interaction-use` is deliberately absent — see the header.
199
+ */
200
+ const FRAME_ROWS = {
201
+ subject: { role: UML_ROLE.subject, radius: 0 },
202
+ partition: { role: UML_ROLE.partition, radius: 0 },
203
+ region: { role: UML_ROLE.region, radius: 4 },
204
+ fragment: { role: UML_ROLE.fragment, radius: 0 },
205
+ };
206
+ /**
207
+ * The legend row a toolbox entry subscribes, read off the `element` value it
208
+ * already declares for telemetry (`node:class`, `connector:association`,
209
+ * `boundary:region`) — so the row and the gesture cannot drift, and a kind
210
+ * added to the pack gets its row on the day its command lands.
211
+ *
212
+ * `undefined` for an entry that owes none: the frame itself, and the
213
+ * interaction use whose role another row already covers.
214
+ *
215
+ * The box's layout is the board command's to declare, not this function's: see
216
+ * {@link UML_LEGEND_BOX}.
217
+ */
218
+ export function umlLegendEntry(element) {
219
+ const [type, name] = element.split(':');
220
+ if (type === 'node' && name in UML_ROLE_OF_KIND) {
221
+ const kind = name;
222
+ return {
223
+ role: UML_ROLE_OF_KIND[kind],
224
+ row: nodeRow(kind),
225
+ ...(kind === 'node' ? { exact: true } : {}),
226
+ section: SECTION_ELEMENTS,
227
+ };
228
+ }
229
+ if (type === 'connector' && name in UML_EDGE_STYLE) {
230
+ const role = name;
231
+ return {
232
+ role: UML_ROLE[role],
233
+ row: edgeRow(role),
234
+ ...(role === 'association' ? { exact: true } : {}),
235
+ section: SECTION_RELATIONS,
236
+ };
237
+ }
238
+ const frame = type === 'boundary' ? FRAME_ROWS[name] : undefined;
239
+ return frame
240
+ ? { role: frame.role, row: frameRow(frame.radius), section: SECTION_FRAMES }
241
+ : undefined;
242
+ }
243
+ /**
244
+ * The BOX, declared once on the command that puts the frame down.
245
+ *
246
+ * A picture needs room a colour chip does not: 34 × 24 is enough for a class to
247
+ * show its two compartment rules and for an actor to show a head, arms and legs,
248
+ * and 34 is the pitch that leaves them breathing space between rows.
249
+ */
250
+ export const UML_LEGEND_BOX = {
251
+ width: 300,
252
+ rowHeight: 34,
253
+ swatchWidth: 34,
254
+ swatchHeight: 24,
255
+ };