@coldtea/pr-lens-renderer 0.1.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 (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/bounds.d.ts +23 -0
  4. package/dist/bounds.d.ts.map +1 -0
  5. package/dist/bounds.js +39 -0
  6. package/dist/bounds.js.map +1 -0
  7. package/dist/corrections.d.ts +12 -0
  8. package/dist/corrections.d.ts.map +1 -0
  9. package/dist/corrections.js +122 -0
  10. package/dist/corrections.js.map +1 -0
  11. package/dist/design.d.ts +112 -0
  12. package/dist/design.d.ts.map +1 -0
  13. package/dist/design.js +112 -0
  14. package/dist/design.js.map +1 -0
  15. package/dist/errors.d.ts +11 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +9 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/geometry.d.ts +20 -0
  20. package/dist/geometry.d.ts.map +1 -0
  21. package/dist/geometry.js +15 -0
  22. package/dist/geometry.js.map +1 -0
  23. package/dist/glob.d.ts +7 -0
  24. package/dist/glob.d.ts.map +1 -0
  25. package/dist/glob.js +17 -0
  26. package/dist/glob.js.map +1 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +8 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/layout/architecture.d.ts +78 -0
  32. package/dist/layout/architecture.d.ts.map +1 -0
  33. package/dist/layout/architecture.js +207 -0
  34. package/dist/layout/architecture.js.map +1 -0
  35. package/dist/layout/congestion.d.ts +18 -0
  36. package/dist/layout/congestion.d.ts.map +1 -0
  37. package/dist/layout/congestion.js +50 -0
  38. package/dist/layout/congestion.js.map +1 -0
  39. package/dist/layout/dataflow.d.ts +85 -0
  40. package/dist/layout/dataflow.d.ts.map +1 -0
  41. package/dist/layout/dataflow.js +184 -0
  42. package/dist/layout/dataflow.js.map +1 -0
  43. package/dist/layout/edges.d.ts +48 -0
  44. package/dist/layout/edges.d.ts.map +1 -0
  45. package/dist/layout/edges.js +843 -0
  46. package/dist/layout/edges.js.map +1 -0
  47. package/dist/layout/labels.d.ts +9 -0
  48. package/dist/layout/labels.d.ts.map +1 -0
  49. package/dist/layout/labels.js +149 -0
  50. package/dist/layout/labels.js.map +1 -0
  51. package/dist/layout/rank.d.ts +16 -0
  52. package/dist/layout/rank.d.ts.map +1 -0
  53. package/dist/layout/rank.js +80 -0
  54. package/dist/layout/rank.js.map +1 -0
  55. package/dist/layout/seating.d.ts +29 -0
  56. package/dist/layout/seating.d.ts.map +1 -0
  57. package/dist/layout/seating.js +131 -0
  58. package/dist/layout/seating.js.map +1 -0
  59. package/dist/manifest.d.ts +39 -0
  60. package/dist/manifest.d.ts.map +1 -0
  61. package/dist/manifest.js +99 -0
  62. package/dist/manifest.js.map +1 -0
  63. package/dist/render.d.ts +49 -0
  64. package/dist/render.d.ts.map +1 -0
  65. package/dist/render.js +125 -0
  66. package/dist/render.js.map +1 -0
  67. package/dist/scope.d.ts +21 -0
  68. package/dist/scope.d.ts.map +1 -0
  69. package/dist/scope.js +57 -0
  70. package/dist/scope.js.map +1 -0
  71. package/dist/svg/architecture.d.ts +15 -0
  72. package/dist/svg/architecture.d.ts.map +1 -0
  73. package/dist/svg/architecture.js +197 -0
  74. package/dist/svg/architecture.js.map +1 -0
  75. package/dist/svg/dataflow.d.ts +9 -0
  76. package/dist/svg/dataflow.d.ts.map +1 -0
  77. package/dist/svg/dataflow.js +284 -0
  78. package/dist/svg/dataflow.js.map +1 -0
  79. package/dist/svg/document.d.ts +37 -0
  80. package/dist/svg/document.d.ts.map +1 -0
  81. package/dist/svg/document.js +148 -0
  82. package/dist/svg/document.js.map +1 -0
  83. package/dist/svg/icons.d.ts +3 -0
  84. package/dist/svg/icons.d.ts.map +1 -0
  85. package/dist/svg/icons.js +106 -0
  86. package/dist/svg/icons.js.map +1 -0
  87. package/dist/svg/primitives.d.ts +13 -0
  88. package/dist/svg/primitives.d.ts.map +1 -0
  89. package/dist/svg/primitives.js +34 -0
  90. package/dist/svg/primitives.js.map +1 -0
  91. package/dist/svg/pulse.d.ts +24 -0
  92. package/dist/svg/pulse.d.ts.map +1 -0
  93. package/dist/svg/pulse.js +33 -0
  94. package/dist/svg/pulse.js.map +1 -0
  95. package/dist/text.d.ts +18 -0
  96. package/dist/text.d.ts.map +1 -0
  97. package/dist/text.js +70 -0
  98. package/dist/text.js.map +1 -0
  99. package/dist/theme.d.ts +44 -0
  100. package/dist/theme.d.ts.map +1 -0
  101. package/dist/theme.js +72 -0
  102. package/dist/theme.js.map +1 -0
  103. package/dist/version.d.ts +9 -0
  104. package/dist/version.d.ts.map +1 -0
  105. package/dist/version.js +9 -0
  106. package/dist/version.js.map +1 -0
  107. package/package.json +56 -0
  108. package/src/bounds.ts +50 -0
  109. package/src/corrections.ts +166 -0
  110. package/src/design.ts +124 -0
  111. package/src/errors.ts +21 -0
  112. package/src/geometry.ts +22 -0
  113. package/src/glob.ts +20 -0
  114. package/src/index.ts +30 -0
  115. package/src/layout/architecture.ts +324 -0
  116. package/src/layout/congestion.ts +76 -0
  117. package/src/layout/dataflow.ts +307 -0
  118. package/src/layout/edges.ts +1061 -0
  119. package/src/layout/labels.ts +192 -0
  120. package/src/layout/rank.ts +95 -0
  121. package/src/layout/seating.ts +189 -0
  122. package/src/manifest.ts +118 -0
  123. package/src/render.ts +190 -0
  124. package/src/scope.ts +67 -0
  125. package/src/svg/architecture.ts +293 -0
  126. package/src/svg/dataflow.ts +408 -0
  127. package/src/svg/document.ts +198 -0
  128. package/src/svg/icons.ts +121 -0
  129. package/src/svg/primitives.ts +50 -0
  130. package/src/svg/pulse.ts +48 -0
  131. package/src/text.ts +92 -0
  132. package/src/theme.ts +107 -0
  133. package/src/version.ts +9 -0
@@ -0,0 +1,284 @@
1
+ import { assertNever } from "@coldtea/pr-lens-schema";
2
+ import { DIAGRAM_MARGIN, FLOW_CYCLE_MAX, FLOW_MAX_PULSES_PER_MESSAGE, FLOW_PULSE_RAMP, FLOW_STEP_TRAVEL, LANE_RADIUS, PILL_HEIGHT, PILL_PADDING_X, PILL_TEXT_SIZE, TITLE_SIZE, } from "../design.js";
3
+ import { canvasFor, union } from "../bounds.js";
4
+ import { measure } from "../text.js";
5
+ import { coord } from "../geometry.js";
6
+ import { ACTIVATION_HALF_WIDTH, FLOW_BAND_PAD_X, FLOW_BAND_PAD_Y, layoutDataFlow, MARKER_INSET, PARTICIPANT_TOP, SELF_LOOP_CORNER, SELF_LOOP_DROP, SELF_LOOP_EXTENT, SELF_LOOP_REACH, } from "../layout/dataflow.js";
7
+ import { paintCard, paintLabelPill } from "./architecture.js";
8
+ import { markerFor, openMarkerFor, shifted, toneColour, toneFor } from "./document.js";
9
+ import { lines, tag, wrap } from "./primitives.js";
10
+ import { PULSE_RADIUS, TRAIN_RADIUS } from "./pulse.js";
11
+ /** A ratio inside the animation cycle, written to a fixed number of places. */
12
+ const ratio = (value) => String(Math.round(value * 10000) / 10000);
13
+ /**
14
+ * How long the whole sequence takes. Every step would rather have a full
15
+ * crossing to itself; a flow long enough to overrun the ceiling shares it
16
+ * instead, and its steps go by faster.
17
+ */
18
+ const cycleFor = (slotCount) => Math.min(FLOW_CYCLE_MAX, slotCount * FLOW_STEP_TRAVEL);
19
+ /** Whether a message crosses to another column, and which way. */
20
+ const travelDirection = (kind, fromX, toX) => {
21
+ switch (kind) {
22
+ case "self":
23
+ return 0;
24
+ case "sync":
25
+ case "async":
26
+ case "return":
27
+ return toX >= fromX ? 1 : -1;
28
+ default:
29
+ return assertNever(kind, "Unhandled message kind");
30
+ }
31
+ };
32
+ const messageClasses = (message, tone) => {
33
+ const classes = ["msg", `edge-${tone}`];
34
+ if (message.kind === "return")
35
+ classes.push("msg-return");
36
+ if (message.delta === "added")
37
+ classes.push("msg-strong");
38
+ return classes.join(" ");
39
+ };
40
+ /**
41
+ * Fire-and-forget gets the open head; everything else keeps the filled one.
42
+ *
43
+ * Deliberate deviation from strict UML 2, which draws replies with an open
44
+ * head as well: here each signal carries exactly one meaning, so a reader
45
+ * needs no legend. The dashed stroke is already the whole mark of "this is
46
+ * an answer", and the open head stays the exclusive mark of "nobody waits on
47
+ * this". Open-headed returns would put the async signature on every reply
48
+ * and dilute the one distinction the head shape exists to draw.
49
+ */
50
+ const headFor = (kind, tone) => {
51
+ switch (kind) {
52
+ case "async":
53
+ return openMarkerFor(tone);
54
+ case "sync":
55
+ case "return":
56
+ case "self":
57
+ return markerFor(tone);
58
+ default:
59
+ return assertNever(kind, "Unhandled message kind");
60
+ }
61
+ };
62
+ const activationLookup = (layout) => {
63
+ const byNode = new Map(layout.participants.map((participant) => [participant.node.id, participant.activations]));
64
+ return (node, y) => (byNode.get(node) ?? []).some((bar) => bar.top <= y && y <= bar.bottom);
65
+ };
66
+ /**
67
+ * Where an arrow starts and stops horizontally. An activated column is a bar,
68
+ * not a line, so an arrow that touches one has to stop at its edge, and the
69
+ * arrowhead needs room of its own on top of that.
70
+ */
71
+ const endsFor = (placed, activeAt, direction) => ({
72
+ start: placed.fromX +
73
+ direction * (activeAt(placed.message.from, placed.y) ? ACTIVATION_HALF_WIDTH : 0),
74
+ end: placed.toX -
75
+ direction *
76
+ ((activeAt(placed.message.to, placed.y) ? ACTIVATION_HALF_WIDTH : 0) + MARKER_INSET),
77
+ });
78
+ const selfPath = (x, y, activated) => {
79
+ const start = x + (activated ? ACTIVATION_HALF_WIDTH : 0);
80
+ return (`M${coord(start)},${coord(y)} h${coord(SELF_LOOP_REACH)} ` +
81
+ `a${SELF_LOOP_CORNER},${SELF_LOOP_CORNER} 0 0 1 ${SELF_LOOP_CORNER},${SELF_LOOP_CORNER} ` +
82
+ `v${coord(SELF_LOOP_DROP)} ` +
83
+ `a${SELF_LOOP_CORNER},${SELF_LOOP_CORNER} 0 0 1 -${SELF_LOOP_CORNER},${SELF_LOOP_CORNER} ` +
84
+ `h-${coord(SELF_LOOP_REACH - MARKER_INSET)}`);
85
+ };
86
+ /** How far a self message's pill stands off the loop it names. */
87
+ const SELF_PILL_GAP = 8;
88
+ const pillWidth = (label) => measure(label, "sans-bold", PILL_TEXT_SIZE) + PILL_PADDING_X * 2;
89
+ /** The pill of a straight message, settled onto the middle of its arrow. */
90
+ const pillBox = (placed, ends) => {
91
+ const width = pillWidth(placed.label);
92
+ return {
93
+ x: (ends.start + ends.end) / 2 - width / 2,
94
+ y: placed.y - PILL_HEIGHT / 2,
95
+ width,
96
+ height: PILL_HEIGHT,
97
+ };
98
+ };
99
+ /** A self message's pill, beside the loop and centred on its height. */
100
+ const selfPillBox = (placed, activated) => ({
101
+ x: placed.fromX +
102
+ (activated ? ACTIVATION_HALF_WIDTH : 0) +
103
+ SELF_LOOP_REACH +
104
+ SELF_LOOP_CORNER +
105
+ SELF_PILL_GAP,
106
+ y: placed.y + SELF_LOOP_EXTENT / 2 - PILL_HEIGHT / 2,
107
+ width: pillWidth(placed.label),
108
+ height: PILL_HEIGHT,
109
+ });
110
+ /**
111
+ * Pulses for one message: the architecture lens's dot, on a sequence's own
112
+ * clock. Every pulse in the drawing shares one cycle and owns a slot of it
113
+ * outright, so the steps light in the order they happen, one at a time.
114
+ *
115
+ * A slot is spent entirely on the crossing — the dot enters as the previous
116
+ * one lands and leaves as the next departs. Nothing waits in the dark for its
117
+ * turn, which is the whole difference between a sequence that reads as a
118
+ * relay and one that reads as a still picture with an occasional blink.
119
+ */
120
+ const pulsesFor = (placed, path, slotCount, palette) => {
121
+ if (slotCount === 0)
122
+ return "";
123
+ const colour = toneColour(palette, toneFor(placed.message.delta));
124
+ // A repeated step keeps the heavier mark it has always carried; only when
125
+ // its crossings happen changed here, not what they look like.
126
+ const radius = placed.slot.count > 1 ? TRAIN_RADIUS : PULSE_RADIUS;
127
+ const width = 1 / slotCount;
128
+ const ramp = width * FLOW_PULSE_RAMP;
129
+ const duration = `${coord(cycleFor(slotCount))}s`;
130
+ return lines(Array.from({ length: placed.slot.count }, (_, index) => {
131
+ const start = (placed.slot.start + index) * width;
132
+ const finish = start + width;
133
+ return wrap("circle", { r: radius, fill: colour, opacity: 0 }, tag("animateMotion", {
134
+ dur: duration,
135
+ repeatCount: "indefinite",
136
+ keyPoints: "0;0;1;1",
137
+ keyTimes: `0;${ratio(start)};${ratio(finish)};1`,
138
+ calcMode: "linear",
139
+ path,
140
+ }) +
141
+ tag("animate", {
142
+ attributeName: "opacity",
143
+ dur: duration,
144
+ repeatCount: "indefinite",
145
+ values: "0;0;1;1;0;0",
146
+ keyTimes: `0;${ratio(start)};${ratio(start + ramp)};` +
147
+ `${ratio(finish - ramp)};${ratio(finish)};1`,
148
+ }));
149
+ }));
150
+ };
151
+ /**
152
+ * Paints one message and the pill that names it. Like an architecture edge
153
+ * and its label, the two come back separately because they belong to
154
+ * different layers: the pill is opaque precisely so it can be read wherever
155
+ * it lands, so it passes in front of everything the arrows drew.
156
+ */
157
+ const paintMessage = (placed, activeAt, slotCount, palette) => {
158
+ const tone = toneFor(placed.message.delta);
159
+ const direction = travelDirection(placed.message.kind, placed.fromX, placed.toX);
160
+ const head = headFor(placed.message.kind, tone);
161
+ if (direction === 0) {
162
+ const activated = activeAt(placed.message.from, placed.y);
163
+ const path = selfPath(placed.fromX, placed.y, activated);
164
+ return {
165
+ line: lines([
166
+ tag("path", { class: messageClasses(placed.message, tone), d: path, "marker-end": head }),
167
+ pulsesFor(placed, path, slotCount, palette),
168
+ ]),
169
+ pill: paintLabelPill(placed.label, selfPillBox(placed, activated), tone),
170
+ };
171
+ }
172
+ const ends = endsFor(placed, activeAt, direction);
173
+ const path = `M${coord(ends.start)},${coord(placed.y)} L${coord(ends.end)},${coord(placed.y)}`;
174
+ return {
175
+ line: lines([
176
+ tag("path", { class: messageClasses(placed.message, tone), d: path, "marker-end": head }),
177
+ pulsesFor(placed, path, slotCount, palette),
178
+ ]),
179
+ pill: paintLabelPill(placed.label, pillBox(placed, ends), tone),
180
+ };
181
+ };
182
+ /**
183
+ * The ground under one column: a band in the lane language, holding the
184
+ * card, its lifeline and its activation bars with the same breathing room a
185
+ * lane keeps around its cards.
186
+ */
187
+ const bandBox = (centreX, columnWidth, layout) => {
188
+ const top = layout.top + PARTICIPANT_TOP - FLOW_BAND_PAD_Y;
189
+ return {
190
+ x: centreX - columnWidth / 2 - FLOW_BAND_PAD_X,
191
+ y: top,
192
+ width: columnWidth + FLOW_BAND_PAD_X * 2,
193
+ height: layout.top + layout.height + FLOW_BAND_PAD_Y - top,
194
+ };
195
+ };
196
+ const paintFlow = (layout, columnWidth, slotCount, palette) => {
197
+ const activeAt = activationLookup(layout);
198
+ const lifelineBottom = layout.top + layout.height;
199
+ const bands = layout.participants.map((participant) => {
200
+ const box = bandBox(participant.centreX, columnWidth, layout);
201
+ return tag("rect", {
202
+ class: "lanebox",
203
+ x: coord(box.x),
204
+ y: coord(box.y),
205
+ width: coord(box.width),
206
+ height: coord(box.height),
207
+ rx: LANE_RADIUS,
208
+ });
209
+ });
210
+ const columns = layout.participants.map((participant) => lines([
211
+ tag("line", {
212
+ class: "lifeline",
213
+ x1: coord(participant.centreX),
214
+ y1: coord(layout.lifelineTop),
215
+ x2: coord(participant.centreX),
216
+ y2: coord(lifelineBottom),
217
+ }),
218
+ ...participant.activations.map((bar) => tag("rect", {
219
+ class: "actbar",
220
+ x: coord(participant.centreX - ACTIVATION_HALF_WIDTH),
221
+ y: coord(bar.top),
222
+ width: ACTIVATION_HALF_WIDTH * 2,
223
+ height: coord(bar.bottom - bar.top),
224
+ rx: 4,
225
+ })),
226
+ ]));
227
+ const cards = layout.participants.map((participant, index) => paintCard({
228
+ node: participant.node,
229
+ box: participant.card,
230
+ showIcon: true,
231
+ titleSize: TITLE_SIZE,
232
+ row: 0,
233
+ laneIndex: index,
234
+ }));
235
+ const lineMarkup = [];
236
+ const pillMarkup = [];
237
+ for (const message of layout.messages) {
238
+ const { line, pill } = paintMessage(message, activeAt, slotCount, palette);
239
+ lineMarkup.push(line);
240
+ pillMarkup.push(pill);
241
+ }
242
+ return lines([
243
+ wrap("g", {}, lines(bands)),
244
+ wrap("g", {}, lines(columns)),
245
+ wrap("g", {}, lines(cards)),
246
+ wrap("g", {}, lines(lineMarkup)),
247
+ wrap("g", {}, lines(pillMarkup)),
248
+ ]);
249
+ };
250
+ /**
251
+ * The room a flow's own drawing takes. The bands already hold the cards and
252
+ * columns, but a pill is centred on its arrow and a self message's sits off
253
+ * to the right of one, so either can reach past what the layout sized the
254
+ * canvas from.
255
+ */
256
+ const flowBounds = (layout, columnWidth) => {
257
+ const activeAt = activationLookup(layout);
258
+ const bands = layout.participants.map((participant) => bandBox(participant.centreX, columnWidth, layout));
259
+ const pills = layout.messages.map((placed) => {
260
+ const direction = travelDirection(placed.message.kind, placed.fromX, placed.toX);
261
+ if (direction === 0)
262
+ return selfPillBox(placed, activeAt(placed.message.from, placed.y));
263
+ return pillBox(placed, endsFor(placed, activeAt, direction));
264
+ });
265
+ const loops = layout.messages
266
+ .filter((placed) => placed.message.kind === "self")
267
+ .map((placed) => ({
268
+ x: placed.fromX,
269
+ y: placed.y,
270
+ width: SELF_LOOP_REACH + SELF_LOOP_CORNER + ACTIVATION_HALF_WIDTH,
271
+ height: SELF_LOOP_DROP + SELF_LOOP_CORNER * 2,
272
+ }));
273
+ return [...bands, ...pills, ...loops];
274
+ };
275
+ export const paintDataFlow = (flows, nodes, palette) => {
276
+ const layout = layoutDataFlow(flows, nodes, FLOW_MAX_PULSES_PER_MESSAGE);
277
+ const canvas = canvasFor(layout, union(layout.flows.flatMap((flow) => flowBounds(flow, layout.columnWidth))), DIAGRAM_MARGIN);
278
+ return {
279
+ width: canvas.width,
280
+ height: canvas.height,
281
+ body: shifted(canvas, lines(layout.flows.map((flow) => paintFlow(flow, layout.columnWidth, layout.slotCount, palette)))),
282
+ };
283
+ };
284
+ //# sourceMappingURL=dataflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataflow.js","sourceRoot":"","sources":["../../src/svg/dataflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,cAAc,EACd,cAAc,EACd,2BAA2B,EAC3B,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,cAAc,EACd,cAAc,EACd,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,eAAe,GAGhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAa,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAExD,+EAA+E;AAC/E,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAEnF;;;;GAIG;AACH,MAAM,QAAQ,GAAG,CAAC,SAAiB,EAAU,EAAE,CAC7C,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,GAAG,gBAAgB,CAAC,CAAC;AAEzD,kEAAkE;AAClE,MAAM,eAAe,GAAG,CAAC,IAAiB,EAAE,KAAa,EAAE,GAAW,EAAc,EAAE;IACpF,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,CAAC,CAAC;QACX,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B;YACE,OAAO,WAAW,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,OAAoB,EAAE,IAAU,EAAU,EAAE;IAClE,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;IACxC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,KAAK,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,OAAO,GAAG,CAAC,IAAiB,EAAE,IAAU,EAAU,EAAE;IACxD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB;YACE,OAAO,WAAW,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC,CAAC;AAKF,MAAM,gBAAgB,GAAG,CAAC,MAAkB,EAAY,EAAE;IACxD,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CACzF,CAAC;IACF,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACjB,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC,CAAC;AAIF;;;;GAIG;AACH,MAAM,OAAO,GAAG,CACd,MAAqB,EACrB,QAAkB,EAClB,SAAiB,EACX,EAAE,CAAC,CAAC;IACV,KAAK,EACH,MAAM,CAAC,KAAK;QACZ,SAAS,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,GAAG,EACD,MAAM,CAAC,GAAG;QACV,SAAS;YACP,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;CACzF,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,SAAkB,EAAU,EAAE;IACpE,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CACL,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,eAAe,CAAC,GAAG;QAC1D,IAAI,gBAAgB,IAAI,gBAAgB,UAAU,gBAAgB,IAAI,gBAAgB,GAAG;QACzF,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG;QAC5B,IAAI,gBAAgB,IAAI,gBAAgB,WAAW,gBAAgB,IAAI,gBAAgB,GAAG;QAC1F,KAAK,KAAK,CAAC,eAAe,GAAG,YAAY,CAAC,EAAE,CAC7C,CAAC;AACJ,CAAC,CAAC;AAEF,kEAAkE;AAClE,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,KAAa,EAAU,EAAE,CAC1C,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC;AAEnE,4EAA4E;AAC5E,MAAM,OAAO,GAAG,CAAC,MAAqB,EAAE,IAAU,EAAO,EAAE;IACzD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO;QACL,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC;QAC1C,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC;QAC7B,KAAK;QACL,MAAM,EAAE,WAAW;KACpB,CAAC;AACJ,CAAC,CAAC;AAEF,wEAAwE;AACxE,MAAM,WAAW,GAAG,CAAC,MAAqB,EAAE,SAAkB,EAAO,EAAE,CAAC,CAAC;IACvE,CAAC,EACC,MAAM,CAAC,KAAK;QACZ,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,eAAe;QACf,gBAAgB;QAChB,aAAa;IACf,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC;IACpD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;IAC9B,MAAM,EAAE,WAAW;CACpB,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,SAAS,GAAG,CAChB,MAAqB,EACrB,IAAY,EACZ,SAAiB,EACjB,OAAgB,EACR,EAAE;IACV,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IACnE,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;IAC5B,MAAM,IAAI,GAAG,KAAK,GAAG,eAAe,CAAC;IACrC,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC;IAElD,OAAO,KAAK,CACV,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QACrD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;QAClD,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QAE7B,OAAO,IAAI,CACT,QAAQ,EACR,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,EACvC,GAAG,CAAC,eAAe,EAAE;YACnB,GAAG,EAAE,QAAQ;YACb,WAAW,EAAE,YAAY;YACzB,SAAS,EAAE,SAAS;YACpB,QAAQ,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI;YAChD,QAAQ,EAAE,QAAQ;YAClB,IAAI;SACL,CAAC;YACA,GAAG,CAAC,SAAS,EAAE;gBACb,aAAa,EAAE,SAAS;gBACxB,GAAG,EAAE,QAAQ;gBACb,WAAW,EAAE,YAAY;gBACzB,MAAM,EAAE,aAAa;gBACrB,QAAQ,EACN,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG;oBAC3C,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI;aAC/C,CAAC,CACL,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,YAAY,GAAG,CACnB,MAAqB,EACrB,QAAkB,EAClB,SAAiB,EACjB,OAAgB,EACgB,EAAE;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAEhD,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO;YACL,IAAI,EAAE,KAAK,CAAC;gBACV,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;gBACzF,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;aAC5C,CAAC;YACF,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC;SACzE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/F,OAAO;QACL,IAAI,EAAE,KAAK,CAAC;YACV,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;YACzF,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;SAC5C,CAAC;QACF,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;KAChE,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAE,MAAkB,EAAO,EAAE;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,eAAe,GAAG,eAAe,CAAC;IAC3D,OAAO;QACL,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,CAAC,GAAG,eAAe;QAC9C,CAAC,EAAE,GAAG;QACN,KAAK,EAAE,WAAW,GAAG,eAAe,GAAG,CAAC;QACxC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,eAAe,GAAG,GAAG;KAC3D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAChB,MAAkB,EAClB,WAAmB,EACnB,SAAiB,EACjB,OAAgB,EACR,EAAE;IACV,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;IAElD,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9D,OAAO,GAAG,CAAC,MAAM,EAAE;YACjB,KAAK,EAAE,SAAS;YAChB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YACf,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YACvB,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;YACzB,EAAE,EAAE,WAAW;SAChB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CACtD,KAAK,CAAC;QACJ,GAAG,CAAC,MAAM,EAAE;YACV,KAAK,EAAE,UAAU;YACjB,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC;YAC9B,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;YAC7B,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC;YAC9B,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC;SAC1B,CAAC;QACF,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACrC,GAAG,CAAC,MAAM,EAAE;YACV,KAAK,EAAE,QAAQ;YACf,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,GAAG,qBAAqB,CAAC;YACrD,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YACjB,KAAK,EAAE,qBAAqB,GAAG,CAAC;YAChC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC;YACnC,EAAE,EAAE,CAAC;SACN,CAAC,CACH;KACF,CAAC,CACH,CAAC;IAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAC3D,SAAS,CAAC;QACR,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,GAAG,EAAE,WAAW,CAAC,IAAI;QACrB,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,UAAU;QACrB,GAAG,EAAE,CAAC;QACN,SAAS,EAAE,KAAK;KACjB,CAAC,CACH,CAAC;IAEF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3E,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,KAAK,CAAC;QACX,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;KACjC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,MAAkB,EAAE,WAAmB,EAAS,EAAE;IACpE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CACpD,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAClD,CAAC;IAEF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjF,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACzF,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ;SAC1B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC;SAClD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChB,CAAC,EAAE,MAAM,CAAC,KAAK;QACf,CAAC,EAAE,MAAM,CAAC,CAAC;QACX,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,qBAAqB;QACjE,MAAM,EAAE,cAAc,GAAG,gBAAgB,GAAG,CAAC;KAC9C,CAAC,CAAC,CAAC;IAEN,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC;AACxC,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,KAAsB,EACtB,KAA2B,EAC3B,OAAgB,EACE,EAAE;IACpB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,2BAA2B,CAAC,CAAC;IAEzE,MAAM,MAAM,GAAG,SAAS,CACtB,MAAM,EACN,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAC3E,cAAc,CACf,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE,OAAO,CACX,MAAM,EACN,KAAK,CACH,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAC/D,CACF,CACF;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { Delta } from "@coldtea/pr-lens-schema";
2
+ import type { Canvas } from "../bounds.js";
3
+ import type { Palette } from "../theme.js";
4
+ /**
5
+ * The colour family an element is drawn in. It follows the delta rather than
6
+ * the element type, because the one question a reviewer asks of a diagram is
7
+ * what changed.
8
+ */
9
+ export type Tone = "added" | "modified" | "removed" | "neutral";
10
+ export declare const toneFor: (delta: Delta) => Tone;
11
+ export declare const toneColour: (palette: Palette, tone: Tone) => string;
12
+ export declare const markerFor: (tone: Tone) => string;
13
+ export declare const openMarkerFor: (tone: Tone) => string;
14
+ /**
15
+ * Wraps painted content in a standalone SVG file.
16
+ *
17
+ * Nothing outside the file is referenced: it is served through an image proxy
18
+ * where the page it lands in does not exist, and it is served as an image, so
19
+ * script would not run even if it were there. Colours are literal for the
20
+ * same reason — the theme is chosen by picking a file, not by asking the page.
21
+ */
22
+ export declare const svgDocument: (input: {
23
+ width: number;
24
+ height: number;
25
+ palette: Palette;
26
+ title: string;
27
+ description?: string;
28
+ body: string;
29
+ }) => string;
30
+ /**
31
+ * Moves painted content clear of the canvas edge when something was drawn
32
+ * above or to the left of the origin. Wrapping rather than re-deriving every
33
+ * coordinate keeps the geometry — and so the bytes — unchanged whenever the
34
+ * shift is zero, which is the ordinary case.
35
+ */
36
+ export declare const shifted: (canvas: Canvas, body: string) => string;
37
+ //# sourceMappingURL=document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/svg/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhE,eAAO,MAAM,OAAO,UAAW,KAAK,KAAG,IAatC,CAAC;AAEF,eAAO,MAAM,UAAU,YAAa,OAAO,QAAQ,IAAI,KAAG,MAazD,CAAC;AAiGF,eAAO,MAAM,SAAS,SAAU,IAAI,KAAG,MAA4B,CAAC;AAEpE,eAAO,MAAM,aAAa,SAAU,IAAI,KAAG,MAA6B,CAAC;AAIzE;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,UAAW;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,KAAG,MAyBH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,WAAY,MAAM,QAAQ,MAAM,KAAG,MAG2C,CAAC"}
@@ -0,0 +1,148 @@
1
+ import { assertNever } from "@coldtea/pr-lens-schema";
2
+ import { coord } from "../geometry.js";
3
+ import { MONO_STACK, SANS_STACK } from "../text.js";
4
+ import { escapeXml, lines, tag, wrap } from "./primitives.js";
5
+ export const toneFor = (delta) => {
6
+ switch (delta) {
7
+ case "added":
8
+ return "added";
9
+ case "modified":
10
+ return "modified";
11
+ case "removed":
12
+ return "removed";
13
+ case "unchanged":
14
+ return "neutral";
15
+ default:
16
+ return assertNever(delta, "Unhandled delta");
17
+ }
18
+ };
19
+ export const toneColour = (palette, tone) => {
20
+ switch (tone) {
21
+ case "added":
22
+ return palette.added;
23
+ case "modified":
24
+ return palette.modified;
25
+ case "removed":
26
+ return palette.removed;
27
+ case "neutral":
28
+ return palette.edge;
29
+ default:
30
+ return assertNever(tone, "Unhandled tone");
31
+ }
32
+ };
33
+ const TONES = ["added", "modified", "removed", "neutral"];
34
+ const stylesheet = (palette) => [
35
+ `text{font-family:${SANS_STACK}}`,
36
+ `.lanebox{fill:${palette.lane}}`,
37
+ `.lanelabel{font-size:10px;font-weight:700;letter-spacing:.12em;fill:${palette.muted}}`,
38
+ `.card{fill:${palette.card};stroke:${palette.cardBorder};stroke-width:1}`,
39
+ `.card-added{stroke:${palette.added};stroke-opacity:.55}`,
40
+ `.card-modified{stroke:${palette.modified};stroke-opacity:.5}`,
41
+ `.ghost{opacity:.55}`,
42
+ `.ghost .card{stroke:${palette.removed};stroke-dasharray:4 3;stroke-opacity:.6}`,
43
+ `.context{opacity:.82}`,
44
+ `.ntitle{font-weight:600;fill:${palette.foreground}}`,
45
+ `.strike{text-decoration:line-through}`,
46
+ `.nsub{font-size:9.5px;fill:${palette.muted};font-family:${MONO_STACK}}`,
47
+ `.chip{fill:${palette.chip}}`,
48
+ `.glyph{fill:${palette.muted}}`,
49
+ `.glyph-stroke{stroke:${palette.muted};stroke-width:1.4;fill:none}`,
50
+ `.bdg text{font-size:8.5px;font-weight:700;letter-spacing:.06em}`,
51
+ `.bdg rect{stroke-width:1}`,
52
+ `.bdg-added rect{fill:${palette.addedFill};stroke:${palette.addedBorder}}`,
53
+ `.bdg-added text{fill:${palette.added}}`,
54
+ `.bdg-modified rect{fill:${palette.modifiedFill};stroke:${palette.modifiedBorder}}`,
55
+ `.bdg-modified text{fill:${palette.modified}}`,
56
+ `.bdg-removed rect{fill:${palette.removedFill};stroke:${palette.removedBorder}}`,
57
+ `.bdg-removed text{fill:${palette.removed}}`,
58
+ `.bdg-neutral rect{fill:${palette.neutralFill};stroke:${palette.cardBorder}}`,
59
+ `.bdg-neutral text{fill:${palette.muted}}`,
60
+ `.edge{fill:none;stroke-width:1.5}`,
61
+ `.edge-added{stroke:${palette.added}}`,
62
+ `.edge-modified{stroke:${palette.modified}}`,
63
+ `.edge-removed{stroke:${palette.removed};stroke-dasharray:5 4;opacity:.7}`,
64
+ `.edge-neutral{stroke:${palette.edge}}`,
65
+ `.hero{stroke-width:2.25}`,
66
+ `.faded{opacity:.45}`,
67
+ `.glow{fill:none;stroke-width:7;opacity:.14}`,
68
+ `.msg-self{font-size:11px;fill:${palette.foreground}}`,
69
+ `.lpill{fill:${palette.pill};stroke:${palette.pillBorder};stroke-width:1}`,
70
+ `.ltext{font-size:9.5px;font-weight:600;fill:${palette.muted}}`,
71
+ `.ltext-added{fill:${palette.added}}`,
72
+ `.ltext-modified{fill:${palette.modified}}`,
73
+ `.ltext-removed{fill:${palette.removed}}`,
74
+ `.cardsh{filter:drop-shadow(0 1px 2px ${palette.shadow})}`,
75
+ `.lifeline{stroke:${palette.lifeline};stroke-width:1;stroke-dasharray:3 4}`,
76
+ `.actbar{fill:${palette.addedFill};stroke:${palette.addedBorder}}`,
77
+ `.msg{fill:none;stroke-width:1.5}`,
78
+ `.msg-return{stroke-dasharray:4 3;opacity:.8}`,
79
+ `.msg-strong{stroke-width:2.25}`,
80
+ ].join("");
81
+ /**
82
+ * Two arrowhead forms per tone, the classic sequence-diagram pair: a filled
83
+ * head for a message the sender waits on, an open line-form head for one it
84
+ * fires and forgets. The open head anchors at its tip so the line runs all
85
+ * the way into the point, where a filled head covers its own line end.
86
+ */
87
+ const markers = (palette) => TONES.map((tone) => wrap("marker", {
88
+ id: `mk-${tone}`,
89
+ viewBox: "0 0 10 10",
90
+ refX: 8,
91
+ refY: 5,
92
+ markerWidth: 6.5,
93
+ markerHeight: 6.5,
94
+ orient: "auto-start-reverse",
95
+ }, tag("path", { d: "M0,0 L10,5 L0,10 z", fill: toneColour(palette, tone) })) +
96
+ wrap("marker", {
97
+ id: `mko-${tone}`,
98
+ viewBox: "0 0 10 10",
99
+ refX: 10,
100
+ refY: 5,
101
+ markerWidth: 6.5,
102
+ markerHeight: 6.5,
103
+ orient: "auto-start-reverse",
104
+ }, tag("path", {
105
+ d: "M2,1 L10,5 L2,9",
106
+ fill: "none",
107
+ stroke: toneColour(palette, tone),
108
+ "stroke-width": 1.6,
109
+ "stroke-linecap": "round",
110
+ "stroke-linejoin": "round",
111
+ }))).join("");
112
+ export const markerFor = (tone) => `url(#mk-${tone})`;
113
+ export const openMarkerFor = (tone) => `url(#mko-${tone})`;
114
+ const DOT_PITCH = 18;
115
+ /**
116
+ * Wraps painted content in a standalone SVG file.
117
+ *
118
+ * Nothing outside the file is referenced: it is served through an image proxy
119
+ * where the page it lands in does not exist, and it is served as an image, so
120
+ * script would not run even if it were there. Colours are literal for the
121
+ * same reason — the theme is chosen by picking a file, not by asking the page.
122
+ */
123
+ export const svgDocument = (input) => {
124
+ const { width, height, palette, title, description, body } = input;
125
+ const defs = wrap("defs", {}, wrap("pattern", { id: "dots", width: DOT_PITCH, height: DOT_PITCH, patternUnits: "userSpaceOnUse" }, tag("circle", { cx: 1.5, cy: 1.5, r: 1, fill: palette.dot })) + markers(palette));
126
+ return lines([
127
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${coord(width)} ${coord(height)}" ` +
128
+ `width="${coord(width)}" height="${coord(height)}" role="img" aria-label="${escapeXml(title)}">`,
129
+ wrap("title", {}, escapeXml(title)),
130
+ description === undefined ? "" : wrap("desc", {}, escapeXml(description)),
131
+ wrap("style", {}, stylesheet(palette)),
132
+ defs,
133
+ tag("rect", { x: 0, y: 0, width: coord(width), height: coord(height), rx: 12, fill: palette.background }),
134
+ tag("rect", { x: 0, y: 0, width: coord(width), height: coord(height), rx: 12, fill: "url(#dots)" }),
135
+ body,
136
+ "</svg>",
137
+ ]);
138
+ };
139
+ /**
140
+ * Moves painted content clear of the canvas edge when something was drawn
141
+ * above or to the left of the origin. Wrapping rather than re-deriving every
142
+ * coordinate keeps the geometry — and so the bytes — unchanged whenever the
143
+ * shift is zero, which is the ordinary case.
144
+ */
145
+ export const shifted = (canvas, body) => canvas.shiftX === 0 && canvas.shiftY === 0
146
+ ? body
147
+ : wrap("g", { transform: `translate(${coord(canvas.shiftX)},${coord(canvas.shiftY)})` }, body);
148
+ //# sourceMappingURL=document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/svg/document.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { NodeKind } from "@coldtea/pr-lens-schema";
2
+ export declare const glyphGroup: (kind: NodeKind, cx: number, cy: number) => string;
3
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/svg/icons.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAuHxD,eAAO,MAAM,UAAU,SAAU,QAAQ,MAAM,MAAM,MAAM,MAAM,KAAG,MAC5B,CAAC"}
@@ -0,0 +1,106 @@
1
+ import { assertNever } from "@coldtea/pr-lens-schema";
2
+ import { coord } from "../geometry.js";
3
+ import { MONO_STACK } from "../text.js";
4
+ import { lines, tag, textNode, wrap } from "./primitives.js";
5
+ const stroked = (path) => tag("path", { class: "glyph-stroke", d: path });
6
+ const glyphText = (cx, cy, content, style) => textNode({
7
+ class: "glyph",
8
+ x: coord(cx),
9
+ y: coord(cy + 4.5),
10
+ "text-anchor": "middle",
11
+ style,
12
+ }, content);
13
+ const box = (cx, cy, width, height, radius) => tag("rect", {
14
+ class: "glyph-stroke",
15
+ x: coord(cx - width / 2),
16
+ y: coord(cy - height / 2),
17
+ width: coord(width),
18
+ height: coord(height),
19
+ rx: radius === undefined ? undefined : coord(radius),
20
+ });
21
+ /**
22
+ * The chip glyph for a node's kind, centred on a point.
23
+ *
24
+ * These say "what sort of thing is this" at a glance and nothing more, which
25
+ * is why the kind enum is coarse. Every kind draws something: a card with an
26
+ * empty chip reads as a rendering fault rather than as an unknown kind.
27
+ */
28
+ const kindGlyph = (kind, cx, cy) => {
29
+ switch (kind) {
30
+ case "service":
31
+ return lines([
32
+ box(cx, cy, 13, 13, 3),
33
+ tag("circle", { class: "glyph", cx: coord(cx), cy: coord(cy), r: 2 }),
34
+ ]);
35
+ case "app":
36
+ return lines([
37
+ box(cx, cy, 14, 12, 2),
38
+ stroked(`M${coord(cx - 7)},${coord(cy - 2)} h14`),
39
+ ]);
40
+ case "module":
41
+ return glyphText(cx, cy, "{ }", `font-size:11px;font-family:${MONO_STACK}`);
42
+ case "function":
43
+ return glyphText(cx, cy, "ƒ", "font-size:14px;font-style:italic;font-family:Georgia,serif");
44
+ case "route":
45
+ return tag("path", {
46
+ class: "glyph",
47
+ d: `M${coord(cx - 7)},${coord(cy - 6)} L${coord(cx + 7)},${coord(cy)} L${coord(cx - 7)},${coord(cy + 6)} Z`,
48
+ });
49
+ case "job":
50
+ return lines([
51
+ tag("circle", { class: "glyph-stroke", cx: coord(cx), cy: coord(cy), r: 6.5 }),
52
+ stroked(`M${coord(cx)},${coord(cy - 3.5)} V${coord(cy)} H${coord(cx + 3)}`),
53
+ ]);
54
+ case "queue":
55
+ return lines([
56
+ stroked(`M${coord(cx - 6.5)},${coord(cy - 4.5)} h13`),
57
+ stroked(`M${coord(cx - 6.5)},${coord(cy)} h13`),
58
+ stroked(`M${coord(cx - 6.5)},${coord(cy + 4.5)} h13`),
59
+ ]);
60
+ case "datastore":
61
+ return lines([
62
+ tag("ellipse", { class: "glyph-stroke", cx: coord(cx), cy: coord(cy - 4.5), rx: 6.5, ry: 2.6 }),
63
+ stroked(`M${coord(cx - 6.5)},${coord(cy - 4.5)} v9 a6.5,2.6 0 0 0 13 0 v-9`),
64
+ ]);
65
+ case "cache":
66
+ return tag("path", {
67
+ class: "glyph",
68
+ d: `M${coord(cx + 1)},${coord(cy - 7)} L${coord(cx - 6)},${coord(cy + 1)} H${coord(cx - 1)} L${coord(cx - 1)},${coord(cy + 7)} L${coord(cx + 6)},${coord(cy - 1)} H${coord(cx + 1)} Z`,
69
+ });
70
+ case "external":
71
+ return lines([
72
+ box(cx, cy, 16, 12, 2),
73
+ stroked(`M${coord(cx - 8)},${coord(cy - 4)} l8,6 8,-6`),
74
+ ]);
75
+ case "ui":
76
+ return lines([
77
+ box(cx, cy, 14, 12, 2),
78
+ stroked(`M${coord(cx - 2.5)},${coord(cy - 6)} v12`),
79
+ ]);
80
+ case "config":
81
+ return lines([
82
+ stroked(`M${coord(cx - 7)},${coord(cy - 4)} h14`),
83
+ stroked(`M${coord(cx - 7)},${coord(cy + 4)} h14`),
84
+ tag("circle", { class: "glyph", cx: coord(cx - 2), cy: coord(cy - 4), r: 2.2 }),
85
+ tag("circle", { class: "glyph", cx: coord(cx + 3), cy: coord(cy + 4), r: 2.2 }),
86
+ ]);
87
+ case "test":
88
+ return stroked(`M${coord(cx - 6)},${coord(cy)} l4,4 l8,-8`);
89
+ case "package":
90
+ return lines([
91
+ stroked(`M${coord(cx)},${coord(cy - 7)} l6.5,3.5 v7 l-6.5,3.5 l-6.5,-3.5 v-7 Z`),
92
+ stroked(`M${coord(cx - 6.5)},${coord(cy - 3.5)} l6.5,3.5 l6.5,-3.5`),
93
+ stroked(`M${coord(cx)},${coord(cy)} v7`),
94
+ ]);
95
+ case "other":
96
+ return lines([
97
+ tag("circle", { class: "glyph", cx: coord(cx - 5), cy: coord(cy), r: 1.8 }),
98
+ tag("circle", { class: "glyph", cx: coord(cx), cy: coord(cy), r: 1.8 }),
99
+ tag("circle", { class: "glyph", cx: coord(cx + 5), cy: coord(cy), r: 1.8 }),
100
+ ]);
101
+ default:
102
+ return assertNever(kind, "Unhandled node kind");
103
+ }
104
+ };
105
+ export const glyphGroup = (kind, cx, cy) => wrap("g", {}, kindGlyph(kind, cx, cy));
106
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/svg/icons.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * XML escaping for text nodes and attribute values alike. Attributes are
3
+ * always written in double quotes, so the single quote does not need an
4
+ * entity, but `<` and `&` do in both positions.
5
+ */
6
+ export declare const escapeXml: (value: string) => string;
7
+ export type Attributes = Readonly<Record<string, string | number | undefined>>;
8
+ export declare const tag: (name: string, attributes: Attributes) => string;
9
+ export declare const wrap: (name: string, attributes: Attributes, children: string) => string;
10
+ export declare const textNode: (attributes: Attributes, content: string) => string;
11
+ /** Joins emitted fragments with newlines, dropping the ones that produced nothing. */
12
+ export declare const lines: (fragments: readonly string[]) => string;
13
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/svg/primitives.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAMd,CAAC;AAE7B,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAQ/E,eAAO,MAAM,GAAG,SAAU,MAAM,cAAc,UAAU,KAAG,MACX,CAAC;AAEjD,eAAO,MAAM,IAAI,SAAU,MAAM,cAAc,UAAU,YAAY,MAAM,KAAG,MACV,CAAC;AAErE,eAAO,MAAM,QAAQ,eACP,UAAU,WACb,MAAM,KACd,MAAsD,CAAC;AAE1D,sFAAsF;AACtF,eAAO,MAAM,KAAK,cAAe,SAAS,MAAM,EAAE,KAAG,MACW,CAAC"}