@diagrammo/dgmo 0.8.23 → 0.8.26
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/.claude/commands/dgmo.md +43 -431
- package/.cursorrules +2 -2
- package/.windsurfrules +2 -2
- package/AGENTS.md +8 -5
- package/dist/cli.cjs +119 -114
- package/dist/editor.cjs +0 -2
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +0 -2
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +0 -2
- package/dist/highlight.cjs.map +1 -1
- package/dist/highlight.js +0 -2
- package/dist/highlight.js.map +1 -1
- package/dist/index.cjs +719 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -18
- package/dist/index.d.ts +105 -18
- package/dist/index.js +709 -280
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +348 -51
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +93 -5
- package/dist/internal.d.ts +93 -5
- package/dist/internal.js +334 -38
- package/dist/internal.js.map +1 -1
- package/docs/guide/chart-area.md +17 -17
- package/docs/guide/chart-bar-stacked.md +12 -12
- package/docs/guide/chart-doughnut.md +10 -10
- package/docs/guide/chart-funnel.md +9 -9
- package/docs/guide/chart-heatmap.md +10 -10
- package/docs/guide/chart-kanban.md +2 -0
- package/docs/guide/chart-line.md +19 -19
- package/docs/guide/chart-multi-line.md +16 -16
- package/docs/guide/chart-pie.md +11 -11
- package/docs/guide/chart-polar-area.md +10 -10
- package/docs/guide/chart-radar.md +9 -9
- package/docs/guide/chart-scatter.md +24 -27
- package/docs/guide/index.md +3 -3
- package/docs/language-reference.md +46 -25
- package/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/LICENSE-Inter.txt +92 -0
- package/gallery/fixtures/bar-stacked.dgmo +12 -6
- package/gallery/fixtures/heatmap.dgmo +12 -6
- package/gallery/fixtures/multi-line.dgmo +11 -7
- package/gallery/fixtures/quadrant.dgmo +8 -8
- package/gallery/fixtures/scatter.dgmo +12 -12
- package/package.json +10 -3
- package/src/boxes-and-lines/parser.ts +13 -2
- package/src/boxes-and-lines/renderer.ts +22 -13
- package/src/chart-type-scoring.ts +162 -0
- package/src/chart-types.ts +437 -0
- package/src/cli.ts +147 -66
- package/src/completion.ts +0 -4
- package/src/d3.ts +40 -2
- package/src/dgmo-router.ts +85 -130
- package/src/editor/keywords.ts +0 -2
- package/src/fonts.ts +3 -2
- package/src/gantt/parser.ts +5 -1
- package/src/index.ts +24 -1
- package/src/infra/parser.ts +1 -1
- package/src/internal.ts +6 -2
- package/src/journey-map/layout.ts +8 -6
- package/src/journey-map/parser.ts +5 -1
- package/src/kanban/parser.ts +5 -1
- package/src/org/collapse.ts +1 -4
- package/src/org/parser.ts +1 -1
- package/src/org/renderer.ts +26 -17
- package/src/sequence/parser.ts +2 -2
- package/src/sequence/participant-inference.ts +0 -1
- package/src/sequence/renderer.ts +95 -263
- package/src/sharing.ts +0 -1
- package/src/sitemap/parser.ts +1 -1
- package/src/tech-radar/layout.ts +1 -2
- package/src/tech-radar/shared.ts +1 -37
- package/src/utils/tag-groups.ts +35 -5
- package/src/wireframe/parser.ts +3 -1
- package/src/tech-radar/index.ts +0 -14
package/dist/internal.d.cts
CHANGED
|
@@ -103,6 +103,27 @@ declare function computeCardArchive(content: string, parsed: ParsedKanban, cardI
|
|
|
103
103
|
/** Check if a column name is the archive column (case-insensitive). */
|
|
104
104
|
declare function isArchiveColumn(name: string): boolean;
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Participant types that can be declared via "Name is a type" syntax.
|
|
108
|
+
*/
|
|
109
|
+
type ParticipantType = 'default' | 'service' | 'database' | 'actor' | 'queue' | 'cache' | 'gateway' | 'external' | 'networking' | 'frontend';
|
|
110
|
+
/**
|
|
111
|
+
* A declared or inferred participant in the sequence diagram.
|
|
112
|
+
*/
|
|
113
|
+
interface SequenceParticipant {
|
|
114
|
+
/** Internal identifier (e.g. "AuthService") */
|
|
115
|
+
id: string;
|
|
116
|
+
/** Display label — uses aka alias if provided, otherwise id */
|
|
117
|
+
label: string;
|
|
118
|
+
/** Participant shape type */
|
|
119
|
+
type: ParticipantType;
|
|
120
|
+
/** Source line number (1-based) */
|
|
121
|
+
lineNumber: number;
|
|
122
|
+
/** Explicit layout position override (0-based from left, negative from right) */
|
|
123
|
+
position?: number;
|
|
124
|
+
/** Pipe-delimited tag metadata (e.g. `| role: Gateway`) */
|
|
125
|
+
metadata?: Record<string, string>;
|
|
126
|
+
}
|
|
106
127
|
/**
|
|
107
128
|
* A message between two participants.
|
|
108
129
|
*/
|
|
@@ -153,6 +174,18 @@ interface SequenceNote {
|
|
|
153
174
|
endLineNumber: number;
|
|
154
175
|
}
|
|
155
176
|
type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
|
|
177
|
+
/**
|
|
178
|
+
* A named group of participants rendered as a labeled box.
|
|
179
|
+
*/
|
|
180
|
+
interface SequenceGroup {
|
|
181
|
+
name: string;
|
|
182
|
+
participantIds: string[];
|
|
183
|
+
lineNumber: number;
|
|
184
|
+
/** Pipe-delimited tag metadata (e.g. `[Backend | t: Product]`) */
|
|
185
|
+
metadata?: Record<string, string>;
|
|
186
|
+
/** Whether this group is collapsed by default */
|
|
187
|
+
collapsed?: boolean;
|
|
188
|
+
}
|
|
156
189
|
|
|
157
190
|
interface SectionMessageGroup {
|
|
158
191
|
section: SequenceSection;
|
|
@@ -164,16 +197,71 @@ interface SectionMessageGroup {
|
|
|
164
197
|
* Only top-level sections are collapsible — sections inside blocks are excluded.
|
|
165
198
|
*/
|
|
166
199
|
declare function groupMessagesBySection(elements: SequenceElement[], messages: SequenceMessage[]): SectionMessageGroup[];
|
|
200
|
+
interface RenderStep {
|
|
201
|
+
type: 'call' | 'return';
|
|
202
|
+
from: string;
|
|
203
|
+
to: string;
|
|
204
|
+
label: string;
|
|
205
|
+
messageIndex: number;
|
|
206
|
+
async?: boolean;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Build an ordered render sequence from flat messages.
|
|
210
|
+
* Uses a call stack to infer where returns should be placed:
|
|
211
|
+
* returns appear after all nested sub-calls complete.
|
|
212
|
+
*/
|
|
213
|
+
declare function buildRenderSequence(messages: SequenceMessage[]): RenderStep[];
|
|
214
|
+
interface Activation {
|
|
215
|
+
participantId: string;
|
|
216
|
+
startStep: number;
|
|
217
|
+
endStep: number;
|
|
218
|
+
depth: number;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Compute activation rectangles from render steps.
|
|
222
|
+
* Each call pushes onto the callee's stack; each return pops it.
|
|
223
|
+
*/
|
|
224
|
+
declare function computeActivations(steps: RenderStep[]): Activation[];
|
|
225
|
+
/**
|
|
226
|
+
* Reorder participants based on explicit `position` overrides.
|
|
227
|
+
* Positive positions are 0-based from the left; negative positions count from the right (-1 = last).
|
|
228
|
+
* Unpositioned participants maintain their relative order, filling remaining slots.
|
|
229
|
+
*/
|
|
230
|
+
declare function applyPositionOverrides(participants: SequenceParticipant[]): SequenceParticipant[];
|
|
231
|
+
/**
|
|
232
|
+
* Reorder participants so that members of the same group are adjacent.
|
|
233
|
+
* Groups are positioned at the point where their first member would naturally
|
|
234
|
+
* appear based on message order (first-occurrence positioning). This prevents
|
|
235
|
+
* groups declared at the top of the file from being placed before participants
|
|
236
|
+
* that appear in messages earlier.
|
|
237
|
+
*
|
|
238
|
+
* Explicit `position` overrides are handled separately by `applyPositionOverrides`.
|
|
239
|
+
*/
|
|
240
|
+
declare function applyGroupOrdering(participants: SequenceParticipant[], groups: SequenceGroup[], messages?: SequenceMessage[]): SequenceParticipant[];
|
|
167
241
|
/**
|
|
168
242
|
* Build a mapping from each note's lineNumber to the lineNumber of its
|
|
169
243
|
* associated message (the last message before the note in document order).
|
|
170
|
-
* Used by the app to
|
|
244
|
+
* Used by the app to highlight the associated message when cursor is on a note.
|
|
171
245
|
*/
|
|
172
246
|
declare function buildNoteMessageMap(elements: SequenceElement[]): Map<number, number>;
|
|
247
|
+
|
|
248
|
+
interface ArcLink {
|
|
249
|
+
source: string;
|
|
250
|
+
target: string;
|
|
251
|
+
value: number;
|
|
252
|
+
color: string | null;
|
|
253
|
+
lineNumber: number;
|
|
254
|
+
}
|
|
255
|
+
type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';
|
|
256
|
+
interface ArcNodeGroup {
|
|
257
|
+
name: string;
|
|
258
|
+
nodes: string[];
|
|
259
|
+
color: string | null;
|
|
260
|
+
lineNumber: number;
|
|
261
|
+
}
|
|
173
262
|
/**
|
|
174
|
-
*
|
|
175
|
-
* Used by the app to compute the "expand all" set.
|
|
263
|
+
* Orders arc diagram nodes based on the selected ordering strategy.
|
|
176
264
|
*/
|
|
177
|
-
declare function
|
|
265
|
+
declare function orderArcNodes(links: ArcLink[], order: ArcOrder, groups: ArcNodeGroup[]): string[];
|
|
178
266
|
|
|
179
|
-
export { buildNoteMessageMap,
|
|
267
|
+
export { applyGroupOrdering, applyPositionOverrides, buildNoteMessageMap, buildRenderSequence, computeActivations, computeCardArchive, computeCardMove, groupMessagesBySection, isArchiveColumn, orderArcNodes, parseDataRowValues };
|
package/dist/internal.d.ts
CHANGED
|
@@ -103,6 +103,27 @@ declare function computeCardArchive(content: string, parsed: ParsedKanban, cardI
|
|
|
103
103
|
/** Check if a column name is the archive column (case-insensitive). */
|
|
104
104
|
declare function isArchiveColumn(name: string): boolean;
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Participant types that can be declared via "Name is a type" syntax.
|
|
108
|
+
*/
|
|
109
|
+
type ParticipantType = 'default' | 'service' | 'database' | 'actor' | 'queue' | 'cache' | 'gateway' | 'external' | 'networking' | 'frontend';
|
|
110
|
+
/**
|
|
111
|
+
* A declared or inferred participant in the sequence diagram.
|
|
112
|
+
*/
|
|
113
|
+
interface SequenceParticipant {
|
|
114
|
+
/** Internal identifier (e.g. "AuthService") */
|
|
115
|
+
id: string;
|
|
116
|
+
/** Display label — uses aka alias if provided, otherwise id */
|
|
117
|
+
label: string;
|
|
118
|
+
/** Participant shape type */
|
|
119
|
+
type: ParticipantType;
|
|
120
|
+
/** Source line number (1-based) */
|
|
121
|
+
lineNumber: number;
|
|
122
|
+
/** Explicit layout position override (0-based from left, negative from right) */
|
|
123
|
+
position?: number;
|
|
124
|
+
/** Pipe-delimited tag metadata (e.g. `| role: Gateway`) */
|
|
125
|
+
metadata?: Record<string, string>;
|
|
126
|
+
}
|
|
106
127
|
/**
|
|
107
128
|
* A message between two participants.
|
|
108
129
|
*/
|
|
@@ -153,6 +174,18 @@ interface SequenceNote {
|
|
|
153
174
|
endLineNumber: number;
|
|
154
175
|
}
|
|
155
176
|
type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
|
|
177
|
+
/**
|
|
178
|
+
* A named group of participants rendered as a labeled box.
|
|
179
|
+
*/
|
|
180
|
+
interface SequenceGroup {
|
|
181
|
+
name: string;
|
|
182
|
+
participantIds: string[];
|
|
183
|
+
lineNumber: number;
|
|
184
|
+
/** Pipe-delimited tag metadata (e.g. `[Backend | t: Product]`) */
|
|
185
|
+
metadata?: Record<string, string>;
|
|
186
|
+
/** Whether this group is collapsed by default */
|
|
187
|
+
collapsed?: boolean;
|
|
188
|
+
}
|
|
156
189
|
|
|
157
190
|
interface SectionMessageGroup {
|
|
158
191
|
section: SequenceSection;
|
|
@@ -164,16 +197,71 @@ interface SectionMessageGroup {
|
|
|
164
197
|
* Only top-level sections are collapsible — sections inside blocks are excluded.
|
|
165
198
|
*/
|
|
166
199
|
declare function groupMessagesBySection(elements: SequenceElement[], messages: SequenceMessage[]): SectionMessageGroup[];
|
|
200
|
+
interface RenderStep {
|
|
201
|
+
type: 'call' | 'return';
|
|
202
|
+
from: string;
|
|
203
|
+
to: string;
|
|
204
|
+
label: string;
|
|
205
|
+
messageIndex: number;
|
|
206
|
+
async?: boolean;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Build an ordered render sequence from flat messages.
|
|
210
|
+
* Uses a call stack to infer where returns should be placed:
|
|
211
|
+
* returns appear after all nested sub-calls complete.
|
|
212
|
+
*/
|
|
213
|
+
declare function buildRenderSequence(messages: SequenceMessage[]): RenderStep[];
|
|
214
|
+
interface Activation {
|
|
215
|
+
participantId: string;
|
|
216
|
+
startStep: number;
|
|
217
|
+
endStep: number;
|
|
218
|
+
depth: number;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Compute activation rectangles from render steps.
|
|
222
|
+
* Each call pushes onto the callee's stack; each return pops it.
|
|
223
|
+
*/
|
|
224
|
+
declare function computeActivations(steps: RenderStep[]): Activation[];
|
|
225
|
+
/**
|
|
226
|
+
* Reorder participants based on explicit `position` overrides.
|
|
227
|
+
* Positive positions are 0-based from the left; negative positions count from the right (-1 = last).
|
|
228
|
+
* Unpositioned participants maintain their relative order, filling remaining slots.
|
|
229
|
+
*/
|
|
230
|
+
declare function applyPositionOverrides(participants: SequenceParticipant[]): SequenceParticipant[];
|
|
231
|
+
/**
|
|
232
|
+
* Reorder participants so that members of the same group are adjacent.
|
|
233
|
+
* Groups are positioned at the point where their first member would naturally
|
|
234
|
+
* appear based on message order (first-occurrence positioning). This prevents
|
|
235
|
+
* groups declared at the top of the file from being placed before participants
|
|
236
|
+
* that appear in messages earlier.
|
|
237
|
+
*
|
|
238
|
+
* Explicit `position` overrides are handled separately by `applyPositionOverrides`.
|
|
239
|
+
*/
|
|
240
|
+
declare function applyGroupOrdering(participants: SequenceParticipant[], groups: SequenceGroup[], messages?: SequenceMessage[]): SequenceParticipant[];
|
|
167
241
|
/**
|
|
168
242
|
* Build a mapping from each note's lineNumber to the lineNumber of its
|
|
169
243
|
* associated message (the last message before the note in document order).
|
|
170
|
-
* Used by the app to
|
|
244
|
+
* Used by the app to highlight the associated message when cursor is on a note.
|
|
171
245
|
*/
|
|
172
246
|
declare function buildNoteMessageMap(elements: SequenceElement[]): Map<number, number>;
|
|
247
|
+
|
|
248
|
+
interface ArcLink {
|
|
249
|
+
source: string;
|
|
250
|
+
target: string;
|
|
251
|
+
value: number;
|
|
252
|
+
color: string | null;
|
|
253
|
+
lineNumber: number;
|
|
254
|
+
}
|
|
255
|
+
type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';
|
|
256
|
+
interface ArcNodeGroup {
|
|
257
|
+
name: string;
|
|
258
|
+
nodes: string[];
|
|
259
|
+
color: string | null;
|
|
260
|
+
lineNumber: number;
|
|
261
|
+
}
|
|
173
262
|
/**
|
|
174
|
-
*
|
|
175
|
-
* Used by the app to compute the "expand all" set.
|
|
263
|
+
* Orders arc diagram nodes based on the selected ordering strategy.
|
|
176
264
|
*/
|
|
177
|
-
declare function
|
|
265
|
+
declare function orderArcNodes(links: ArcLink[], order: ArcOrder, groups: ArcNodeGroup[]): string[];
|
|
178
266
|
|
|
179
|
-
export { buildNoteMessageMap,
|
|
267
|
+
export { applyGroupOrdering, applyPositionOverrides, buildNoteMessageMap, buildRenderSequence, computeActivations, computeCardArchive, computeCardMove, groupMessagesBySection, isArchiveColumn, orderArcNodes, parseDataRowValues };
|
package/dist/internal.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
+
var __esm = (fn, res) => function __init() {
|
|
3
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
|
+
};
|
|
5
|
+
|
|
1
6
|
// src/utils/parsing.ts
|
|
2
7
|
function normalizeNumericToken(token) {
|
|
3
8
|
if (!token.includes(",") && !token.includes("_")) return null;
|
|
@@ -21,10 +26,15 @@ function normalizeNumericToken(token) {
|
|
|
21
26
|
return sign + unsigned.replace(/_/g, "");
|
|
22
27
|
return null;
|
|
23
28
|
}
|
|
29
|
+
var init_parsing = __esm({
|
|
30
|
+
"src/utils/parsing.ts"() {
|
|
31
|
+
"use strict";
|
|
32
|
+
}
|
|
33
|
+
});
|
|
24
34
|
|
|
25
35
|
// src/chart.ts
|
|
26
|
-
function parseDataRowValues(
|
|
27
|
-
const segments =
|
|
36
|
+
function parseDataRowValues(line2, options) {
|
|
37
|
+
const segments = line2.split(",");
|
|
28
38
|
const normalized = [];
|
|
29
39
|
for (let i = 0; i < segments.length; i++) {
|
|
30
40
|
const seg = segments[i].trim();
|
|
@@ -101,9 +111,14 @@ function parseDataRowValues(line, options) {
|
|
|
101
111
|
if (!label) return null;
|
|
102
112
|
return { label, values: [num] };
|
|
103
113
|
}
|
|
114
|
+
var init_chart = __esm({
|
|
115
|
+
"src/chart.ts"() {
|
|
116
|
+
"use strict";
|
|
117
|
+
init_parsing();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
104
120
|
|
|
105
121
|
// src/kanban/mutations.ts
|
|
106
|
-
var ARCHIVE_COLUMN_NAME = "archive";
|
|
107
122
|
function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
|
|
108
123
|
let sourceCard = null;
|
|
109
124
|
let sourceColumn = null;
|
|
@@ -207,9 +222,13 @@ function computeCardArchive(content, parsed, cardId) {
|
|
|
207
222
|
function isArchiveColumn(name) {
|
|
208
223
|
return name.toLowerCase() === ARCHIVE_COLUMN_NAME;
|
|
209
224
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
225
|
+
var ARCHIVE_COLUMN_NAME;
|
|
226
|
+
var init_mutations = __esm({
|
|
227
|
+
"src/kanban/mutations.ts"() {
|
|
228
|
+
"use strict";
|
|
229
|
+
ARCHIVE_COLUMN_NAME = "archive";
|
|
230
|
+
}
|
|
231
|
+
});
|
|
213
232
|
|
|
214
233
|
// src/sequence/parser.ts
|
|
215
234
|
function isSequenceBlock(el) {
|
|
@@ -221,24 +240,14 @@ function isSequenceSection(el) {
|
|
|
221
240
|
function isSequenceNote(el) {
|
|
222
241
|
return "kind" in el && el.kind === "note";
|
|
223
242
|
}
|
|
243
|
+
var init_parser = __esm({
|
|
244
|
+
"src/sequence/parser.ts"() {
|
|
245
|
+
"use strict";
|
|
246
|
+
}
|
|
247
|
+
});
|
|
224
248
|
|
|
225
249
|
// src/sequence/renderer.ts
|
|
226
|
-
|
|
227
|
-
var PARTICIPANT_BOX_WIDTH = 120;
|
|
228
|
-
var NOTE_MAX_W = 200;
|
|
229
|
-
var NOTE_FOLD = 10;
|
|
230
|
-
var NOTE_PAD_H = 8;
|
|
231
|
-
var NOTE_GAP = 15;
|
|
232
|
-
var NOTE_CHAR_W = 6;
|
|
233
|
-
var NOTE_CHARS_PER_LINE = Math.floor(
|
|
234
|
-
(NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W
|
|
235
|
-
);
|
|
236
|
-
var ACTIVATION_WIDTH = 10;
|
|
237
|
-
var NOTE_LANE_MAX = PARTICIPANT_GAP - ACTIVATION_WIDTH - NOTE_GAP;
|
|
238
|
-
var LABEL_CHAR_WIDTH = 7.5;
|
|
239
|
-
var LABEL_MAX_CHARS = Math.floor(
|
|
240
|
-
(PARTICIPANT_BOX_WIDTH - 10) / LABEL_CHAR_WIDTH
|
|
241
|
-
);
|
|
250
|
+
import * as d3Selection from "d3-selection";
|
|
242
251
|
function groupMessagesBySection(elements, messages) {
|
|
243
252
|
const groups = [];
|
|
244
253
|
let currentGroup = null;
|
|
@@ -279,6 +288,180 @@ function groupMessagesBySection(elements, messages) {
|
|
|
279
288
|
}
|
|
280
289
|
return groups;
|
|
281
290
|
}
|
|
291
|
+
function buildRenderSequence(messages) {
|
|
292
|
+
const steps = [];
|
|
293
|
+
const stack = [];
|
|
294
|
+
for (let mi = 0; mi < messages.length; mi++) {
|
|
295
|
+
const msg = messages[mi];
|
|
296
|
+
while (stack.length > 0) {
|
|
297
|
+
const top = stack[stack.length - 1];
|
|
298
|
+
if (top.to === msg.from) break;
|
|
299
|
+
stack.pop();
|
|
300
|
+
steps.push({
|
|
301
|
+
type: "return",
|
|
302
|
+
from: top.to,
|
|
303
|
+
to: top.from,
|
|
304
|
+
label: "",
|
|
305
|
+
messageIndex: top.messageIndex
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
steps.push({
|
|
309
|
+
type: "call",
|
|
310
|
+
from: msg.from,
|
|
311
|
+
to: msg.to,
|
|
312
|
+
label: msg.label,
|
|
313
|
+
messageIndex: mi,
|
|
314
|
+
...msg.async ? { async: true } : {}
|
|
315
|
+
});
|
|
316
|
+
if (msg.async) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (msg.from === msg.to) {
|
|
320
|
+
steps.push({
|
|
321
|
+
type: "return",
|
|
322
|
+
from: msg.to,
|
|
323
|
+
to: msg.from,
|
|
324
|
+
label: "",
|
|
325
|
+
messageIndex: mi
|
|
326
|
+
});
|
|
327
|
+
} else {
|
|
328
|
+
stack.push({
|
|
329
|
+
from: msg.from,
|
|
330
|
+
to: msg.to,
|
|
331
|
+
messageIndex: mi
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
while (stack.length > 0) {
|
|
336
|
+
const top = stack.pop();
|
|
337
|
+
steps.push({
|
|
338
|
+
type: "return",
|
|
339
|
+
from: top.to,
|
|
340
|
+
to: top.from,
|
|
341
|
+
label: "",
|
|
342
|
+
messageIndex: top.messageIndex
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
return steps;
|
|
346
|
+
}
|
|
347
|
+
function computeActivations(steps) {
|
|
348
|
+
const activations = [];
|
|
349
|
+
const stacks = /* @__PURE__ */ new Map();
|
|
350
|
+
const getStack = (id) => {
|
|
351
|
+
if (!stacks.has(id)) stacks.set(id, []);
|
|
352
|
+
return stacks.get(id);
|
|
353
|
+
};
|
|
354
|
+
for (let i = 0; i < steps.length; i++) {
|
|
355
|
+
const step = steps[i];
|
|
356
|
+
if (step.type === "call") {
|
|
357
|
+
const s = getStack(step.to);
|
|
358
|
+
s.push(i);
|
|
359
|
+
} else {
|
|
360
|
+
const s = getStack(step.from);
|
|
361
|
+
if (s.length > 0) {
|
|
362
|
+
const startIdx = s.pop();
|
|
363
|
+
activations.push({
|
|
364
|
+
participantId: step.from,
|
|
365
|
+
startStep: startIdx,
|
|
366
|
+
endStep: i,
|
|
367
|
+
depth: s.length
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return activations;
|
|
373
|
+
}
|
|
374
|
+
function applyPositionOverrides(participants) {
|
|
375
|
+
if (!participants.some((p) => p.position !== void 0)) return participants;
|
|
376
|
+
const total = participants.length;
|
|
377
|
+
const positioned = [];
|
|
378
|
+
const unpositioned = [];
|
|
379
|
+
for (const p of participants) {
|
|
380
|
+
if (p.position !== void 0) {
|
|
381
|
+
let idx = p.position < 0 ? total + p.position : p.position;
|
|
382
|
+
idx = Math.max(0, Math.min(total - 1, idx));
|
|
383
|
+
positioned.push({ participant: p, index: idx });
|
|
384
|
+
} else {
|
|
385
|
+
unpositioned.push(p);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
positioned.sort((a, b) => a.index - b.index);
|
|
389
|
+
const result = new Array(total).fill(null);
|
|
390
|
+
const usedIndices = /* @__PURE__ */ new Set();
|
|
391
|
+
for (const { participant, index } of positioned) {
|
|
392
|
+
let idx = index;
|
|
393
|
+
if (usedIndices.has(idx)) {
|
|
394
|
+
for (let offset = 1; offset < total; offset++) {
|
|
395
|
+
if (idx + offset < total && !usedIndices.has(idx + offset)) {
|
|
396
|
+
idx = idx + offset;
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
if (idx - offset >= 0 && !usedIndices.has(idx - offset)) {
|
|
400
|
+
idx = idx - offset;
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
result[idx] = participant;
|
|
406
|
+
usedIndices.add(idx);
|
|
407
|
+
}
|
|
408
|
+
let uIdx = 0;
|
|
409
|
+
for (let i = 0; i < total; i++) {
|
|
410
|
+
if (result[i] === null) {
|
|
411
|
+
result[i] = unpositioned[uIdx++];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return result;
|
|
415
|
+
}
|
|
416
|
+
function applyGroupOrdering(participants, groups, messages = []) {
|
|
417
|
+
if (groups.length === 0) return participants;
|
|
418
|
+
const idToGroup = /* @__PURE__ */ new Map();
|
|
419
|
+
for (const group of groups) {
|
|
420
|
+
for (const id of group.participantIds) {
|
|
421
|
+
idToGroup.set(id, group);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
const appearanceOrder = [];
|
|
425
|
+
const seen = /* @__PURE__ */ new Set();
|
|
426
|
+
for (const msg of messages) {
|
|
427
|
+
for (const id of [msg.from, msg.to]) {
|
|
428
|
+
if (!seen.has(id)) {
|
|
429
|
+
seen.add(id);
|
|
430
|
+
appearanceOrder.push(id);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
for (const p of participants) {
|
|
435
|
+
if (!seen.has(p.id)) {
|
|
436
|
+
seen.add(p.id);
|
|
437
|
+
appearanceOrder.push(p.id);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const result = [];
|
|
441
|
+
const placed = /* @__PURE__ */ new Set();
|
|
442
|
+
const placedGroups = /* @__PURE__ */ new Set();
|
|
443
|
+
for (const id of appearanceOrder) {
|
|
444
|
+
if (placed.has(id)) continue;
|
|
445
|
+
const group = idToGroup.get(id);
|
|
446
|
+
if (group && !placedGroups.has(group)) {
|
|
447
|
+
placedGroups.add(group);
|
|
448
|
+
for (const gid of group.participantIds) {
|
|
449
|
+
const p = participants.find((pp) => pp.id === gid);
|
|
450
|
+
if (p && !placed.has(gid)) {
|
|
451
|
+
result.push(p);
|
|
452
|
+
placed.add(gid);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
} else if (!group) {
|
|
456
|
+
const p = participants.find((pp) => pp.id === id);
|
|
457
|
+
if (p) {
|
|
458
|
+
result.push(p);
|
|
459
|
+
placed.add(id);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
282
465
|
function buildNoteMessageMap(elements) {
|
|
283
466
|
const map = /* @__PURE__ */ new Map();
|
|
284
467
|
let lastMessageLine = -1;
|
|
@@ -305,33 +488,146 @@ function buildNoteMessageMap(elements) {
|
|
|
305
488
|
walk(elements);
|
|
306
489
|
return map;
|
|
307
490
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
491
|
+
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS;
|
|
492
|
+
var init_renderer = __esm({
|
|
493
|
+
"src/sequence/renderer.ts"() {
|
|
494
|
+
"use strict";
|
|
495
|
+
init_parser();
|
|
496
|
+
PARTICIPANT_GAP = 160;
|
|
497
|
+
PARTICIPANT_BOX_WIDTH = 120;
|
|
498
|
+
NOTE_MAX_W = 200;
|
|
499
|
+
NOTE_FOLD = 10;
|
|
500
|
+
NOTE_PAD_H = 8;
|
|
501
|
+
NOTE_GAP = 15;
|
|
502
|
+
NOTE_CHAR_W = 6;
|
|
503
|
+
NOTE_CHARS_PER_LINE = Math.floor(
|
|
504
|
+
(NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W
|
|
505
|
+
);
|
|
506
|
+
ACTIVATION_WIDTH = 10;
|
|
507
|
+
NOTE_LANE_MAX = PARTICIPANT_GAP - ACTIVATION_WIDTH - NOTE_GAP;
|
|
508
|
+
LABEL_CHAR_WIDTH = 7.5;
|
|
509
|
+
LABEL_MAX_CHARS = Math.floor(
|
|
510
|
+
(PARTICIPANT_BOX_WIDTH - 10) / LABEL_CHAR_WIDTH
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// src/d3.ts
|
|
516
|
+
import * as d3Scale from "d3-scale";
|
|
517
|
+
import * as d3Selection2 from "d3-selection";
|
|
518
|
+
import * as d3Shape from "d3-shape";
|
|
519
|
+
import * as d3Array from "d3-array";
|
|
520
|
+
import cloud from "d3-cloud";
|
|
521
|
+
function orderArcNodes(links, order, groups) {
|
|
522
|
+
const nodeSet = /* @__PURE__ */ new Set();
|
|
523
|
+
for (const link of links) {
|
|
524
|
+
nodeSet.add(link.source);
|
|
525
|
+
nodeSet.add(link.target);
|
|
526
|
+
}
|
|
527
|
+
const allNodes = Array.from(nodeSet);
|
|
528
|
+
if (order === "name") {
|
|
529
|
+
return allNodes.slice().sort((a, b) => a.localeCompare(b));
|
|
530
|
+
}
|
|
531
|
+
if (order === "degree") {
|
|
532
|
+
const degree = /* @__PURE__ */ new Map();
|
|
533
|
+
for (const node of allNodes) degree.set(node, 0);
|
|
534
|
+
for (const link of links) {
|
|
535
|
+
degree.set(link.source, degree.get(link.source) + link.value);
|
|
536
|
+
degree.set(link.target, degree.get(link.target) + link.value);
|
|
537
|
+
}
|
|
538
|
+
return allNodes.slice().sort((a, b) => {
|
|
539
|
+
const diff = degree.get(b) - degree.get(a);
|
|
540
|
+
return diff !== 0 ? diff : a.localeCompare(b);
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
if (order === "group") {
|
|
544
|
+
if (groups.length > 0) {
|
|
545
|
+
const ordered = [];
|
|
546
|
+
const placed = /* @__PURE__ */ new Set();
|
|
547
|
+
for (const group of groups) {
|
|
548
|
+
for (const node of group.nodes) {
|
|
549
|
+
if (!placed.has(node)) {
|
|
550
|
+
ordered.push(node);
|
|
551
|
+
placed.add(node);
|
|
319
552
|
}
|
|
320
553
|
}
|
|
321
|
-
walk(el.elseChildren);
|
|
322
554
|
}
|
|
555
|
+
for (const node of allNodes) {
|
|
556
|
+
if (!placed.has(node)) {
|
|
557
|
+
ordered.push(node);
|
|
558
|
+
placed.add(node);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return ordered;
|
|
323
562
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
563
|
+
const adj = /* @__PURE__ */ new Map();
|
|
564
|
+
for (const node of allNodes) adj.set(node, /* @__PURE__ */ new Set());
|
|
565
|
+
for (const link of links) {
|
|
566
|
+
adj.get(link.source).add(link.target);
|
|
567
|
+
adj.get(link.target).add(link.source);
|
|
568
|
+
}
|
|
569
|
+
const degree = /* @__PURE__ */ new Map();
|
|
570
|
+
for (const node of allNodes) degree.set(node, 0);
|
|
571
|
+
for (const link of links) {
|
|
572
|
+
degree.set(link.source, degree.get(link.source) + link.value);
|
|
573
|
+
degree.set(link.target, degree.get(link.target) + link.value);
|
|
574
|
+
}
|
|
575
|
+
const visited = /* @__PURE__ */ new Set();
|
|
576
|
+
const components = [];
|
|
577
|
+
const remaining = new Set(allNodes);
|
|
578
|
+
while (remaining.size > 0) {
|
|
579
|
+
let root = "";
|
|
580
|
+
let maxDeg = -1;
|
|
581
|
+
for (const node of remaining) {
|
|
582
|
+
if (degree.get(node) > maxDeg) {
|
|
583
|
+
maxDeg = degree.get(node);
|
|
584
|
+
root = node;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
const component = [];
|
|
588
|
+
const queue = [root];
|
|
589
|
+
visited.add(root);
|
|
590
|
+
remaining.delete(root);
|
|
591
|
+
while (queue.length > 0) {
|
|
592
|
+
const curr = queue.shift();
|
|
593
|
+
component.push(curr);
|
|
594
|
+
for (const neighbor of adj.get(curr)) {
|
|
595
|
+
if (!visited.has(neighbor)) {
|
|
596
|
+
visited.add(neighbor);
|
|
597
|
+
remaining.delete(neighbor);
|
|
598
|
+
queue.push(neighbor);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
components.push(component);
|
|
603
|
+
}
|
|
604
|
+
components.sort((a, b) => b.length - a.length);
|
|
605
|
+
return components.flat();
|
|
606
|
+
}
|
|
607
|
+
return allNodes;
|
|
327
608
|
}
|
|
609
|
+
var init_d3 = __esm({
|
|
610
|
+
"src/d3.ts"() {
|
|
611
|
+
"use strict";
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
// src/internal.ts
|
|
616
|
+
init_chart();
|
|
617
|
+
init_mutations();
|
|
618
|
+
init_renderer();
|
|
619
|
+
init_d3();
|
|
328
620
|
export {
|
|
621
|
+
applyGroupOrdering,
|
|
622
|
+
applyPositionOverrides,
|
|
329
623
|
buildNoteMessageMap,
|
|
330
|
-
|
|
624
|
+
buildRenderSequence,
|
|
625
|
+
computeActivations,
|
|
331
626
|
computeCardArchive,
|
|
332
627
|
computeCardMove,
|
|
333
628
|
groupMessagesBySection,
|
|
334
629
|
isArchiveColumn,
|
|
630
|
+
orderArcNodes,
|
|
335
631
|
parseDataRowValues
|
|
336
632
|
};
|
|
337
633
|
//# sourceMappingURL=internal.js.map
|