@nowline/renderer 0.8.6 → 0.9.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 (86) hide show
  1. package/dist/image-size.d.ts +9 -0
  2. package/dist/image-size.d.ts.map +1 -0
  3. package/dist/image-size.js +104 -0
  4. package/dist/image-size.js.map +1 -0
  5. package/dist/index.d.ts +4 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/logo.d.ts +24 -0
  10. package/dist/logo.d.ts.map +1 -0
  11. package/dist/logo.js +60 -0
  12. package/dist/logo.js.map +1 -0
  13. package/dist/stage.d.ts +78 -0
  14. package/dist/stage.d.ts.map +1 -0
  15. package/dist/stage.js +88 -0
  16. package/dist/stage.js.map +1 -0
  17. package/dist/svg/edges.d.ts +3 -0
  18. package/dist/svg/edges.d.ts.map +1 -0
  19. package/dist/svg/edges.js +144 -0
  20. package/dist/svg/edges.js.map +1 -0
  21. package/dist/svg/footnotes.d.ts +4 -0
  22. package/dist/svg/footnotes.d.ts.map +1 -0
  23. package/dist/svg/footnotes.js +81 -0
  24. package/dist/svg/footnotes.js.map +1 -0
  25. package/dist/svg/header.d.ts +6 -0
  26. package/dist/svg/header.d.ts.map +1 -0
  27. package/dist/svg/header.js +215 -0
  28. package/dist/svg/header.js.map +1 -0
  29. package/dist/svg/include-region.d.ts +4 -0
  30. package/dist/svg/include-region.d.ts.map +1 -0
  31. package/dist/svg/include-region.js +157 -0
  32. package/dist/svg/include-region.js.map +1 -0
  33. package/dist/svg/item.d.ts +36 -0
  34. package/dist/svg/item.d.ts.map +1 -0
  35. package/dist/svg/item.js +549 -0
  36. package/dist/svg/item.js.map +1 -0
  37. package/dist/svg/markers.d.ts +7 -0
  38. package/dist/svg/markers.d.ts.map +1 -0
  39. package/dist/svg/markers.js +151 -0
  40. package/dist/svg/markers.js.map +1 -0
  41. package/dist/svg/nowline.d.ts +4 -0
  42. package/dist/svg/nowline.d.ts.map +1 -0
  43. package/dist/svg/nowline.js +133 -0
  44. package/dist/svg/nowline.js.map +1 -0
  45. package/dist/svg/primitives.d.ts +7 -0
  46. package/dist/svg/primitives.d.ts.map +1 -0
  47. package/dist/svg/primitives.js +70 -0
  48. package/dist/svg/primitives.js.map +1 -0
  49. package/dist/svg/render.d.ts +13 -7
  50. package/dist/svg/render.d.ts.map +1 -1
  51. package/dist/svg/render.js +64 -1701
  52. package/dist/svg/render.js.map +1 -1
  53. package/dist/svg/sanitize.d.ts +10 -0
  54. package/dist/svg/sanitize.d.ts.map +1 -1
  55. package/dist/svg/sanitize.js +264 -16
  56. package/dist/svg/sanitize.js.map +1 -1
  57. package/dist/svg/swimlanes.d.ts +5 -0
  58. package/dist/svg/swimlanes.d.ts.map +1 -0
  59. package/dist/svg/swimlanes.js +228 -0
  60. package/dist/svg/swimlanes.js.map +1 -0
  61. package/dist/svg/timeline.d.ts +24 -0
  62. package/dist/svg/timeline.d.ts.map +1 -0
  63. package/dist/svg/timeline.js +284 -0
  64. package/dist/svg/timeline.js.map +1 -0
  65. package/dist/svg/waves.d.ts +62 -0
  66. package/dist/svg/waves.d.ts.map +1 -0
  67. package/dist/svg/waves.js +397 -0
  68. package/dist/svg/waves.js.map +1 -0
  69. package/package.json +6 -6
  70. package/src/image-size.ts +113 -0
  71. package/src/index.ts +10 -1
  72. package/src/logo.ts +82 -0
  73. package/src/stage.ts +191 -0
  74. package/src/svg/edges.ts +154 -0
  75. package/src/svg/footnotes.ts +115 -0
  76. package/src/svg/header.ts +285 -0
  77. package/src/svg/include-region.ts +201 -0
  78. package/src/svg/item.ts +672 -0
  79. package/src/svg/markers.ts +178 -0
  80. package/src/svg/nowline.ts +152 -0
  81. package/src/svg/primitives.ts +86 -0
  82. package/src/svg/render.ts +94 -2110
  83. package/src/svg/sanitize.ts +286 -16
  84. package/src/svg/swimlanes.ts +317 -0
  85. package/src/svg/timeline.ts +343 -0
  86. package/src/svg/waves.ts +502 -0
@@ -0,0 +1,9 @@
1
+ export interface ImageSize {
2
+ width: number;
3
+ height: number;
4
+ }
5
+ /** The raster formats `logo:` accepts. */
6
+ export type RasterLogoMime = 'image/png' | 'image/jpeg' | 'image/webp';
7
+ /** Width and height from a PNG, JPEG or WebP header; undefined when unreadable. */
8
+ export declare function rasterSize(bytes: Uint8Array, mime: RasterLogoMime): ImageSize | undefined;
9
+ //# sourceMappingURL=image-size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-size.d.ts","sourceRoot":"","sources":["../src/image-size.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC;AAEvE,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,SAAS,CAQzF"}
@@ -0,0 +1,104 @@
1
+ // Intrinsic pixel size of a raster logo, read from the file header so layout
2
+ // can size the logo slot before render. Browser-safe: no Buffer, no fs.
3
+ /** Width and height from a PNG, JPEG or WebP header; undefined when unreadable. */
4
+ export function rasterSize(bytes, mime) {
5
+ const size = mime === 'image/png'
6
+ ? pngSize(bytes)
7
+ : mime === 'image/jpeg'
8
+ ? jpegSize(bytes)
9
+ : webpSize(bytes);
10
+ return size && size.width > 0 && size.height > 0 ? size : undefined;
11
+ }
12
+ const PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
13
+ function u16be(b, i) {
14
+ return (b[i] << 8) | b[i + 1];
15
+ }
16
+ function u32be(b, i) {
17
+ return ((b[i] << 24) | (b[i + 1] << 16) | (b[i + 2] << 8) | b[i + 3]) >>> 0;
18
+ }
19
+ function u16le(b, i) {
20
+ return b[i] | (b[i + 1] << 8);
21
+ }
22
+ function u24le(b, i) {
23
+ return b[i] | (b[i + 1] << 8) | (b[i + 2] << 16);
24
+ }
25
+ function ascii(b, i, n) {
26
+ return String.fromCharCode(...b.subarray(i, i + n));
27
+ }
28
+ // The first chunk after the signature is always IHDR: width, height (u32 BE).
29
+ function pngSize(b) {
30
+ if (b.length < 24 || PNG_SIGNATURE.some((v, i) => b[i] !== v))
31
+ return undefined;
32
+ if (ascii(b, 12, 4) !== 'IHDR')
33
+ return undefined;
34
+ return { width: u32be(b, 16), height: u32be(b, 20) };
35
+ }
36
+ // Walk the marker segments to the first start-of-frame (SOF0..SOF15 minus
37
+ // DHT C4, JPG C8 and DAC CC), which carries height then width.
38
+ function jpegSize(b) {
39
+ if (b.length < 4 || b[0] !== 0xff || b[1] !== 0xd8)
40
+ return undefined;
41
+ let i = 2;
42
+ while (i + 3 < b.length) {
43
+ if (b[i] !== 0xff)
44
+ return undefined;
45
+ const marker = b[i + 1];
46
+ if (marker === 0xff) {
47
+ i += 1; // fill byte
48
+ continue;
49
+ }
50
+ // Standalone markers carry no length.
51
+ if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd9)) {
52
+ i += 2;
53
+ continue;
54
+ }
55
+ const length = u16be(b, i + 2);
56
+ const isSof = marker >= 0xc0 &&
57
+ marker <= 0xcf &&
58
+ marker !== 0xc4 &&
59
+ marker !== 0xc8 &&
60
+ marker !== 0xcc;
61
+ if (isSof) {
62
+ if (i + 8 >= b.length)
63
+ return undefined;
64
+ return { width: u16be(b, i + 7), height: u16be(b, i + 5) };
65
+ }
66
+ if (length < 2)
67
+ return undefined;
68
+ i += 2 + length;
69
+ }
70
+ return undefined;
71
+ }
72
+ // RIFF container; the first chunk says lossy (VP8), lossless (VP8L) or
73
+ // extended (VP8X, which records the canvas size directly).
74
+ function webpSize(b) {
75
+ if (b.length < 16 || ascii(b, 0, 4) !== 'RIFF' || ascii(b, 8, 4) !== 'WEBP')
76
+ return undefined;
77
+ const chunk = ascii(b, 12, 4);
78
+ // Bytes each chunk kind needs to reach its size fields.
79
+ const needed = chunk === 'VP8L' ? 25 : 30;
80
+ if (b.length < needed)
81
+ return undefined;
82
+ if (chunk === 'VP8 ') {
83
+ if (b[23] !== 0x9d || b[24] !== 0x01 || b[25] !== 0x2a)
84
+ return undefined;
85
+ return { width: u16le(b, 26) & 0x3fff, height: u16le(b, 28) & 0x3fff };
86
+ }
87
+ if (chunk === 'VP8L') {
88
+ if (b[20] !== 0x2f)
89
+ return undefined;
90
+ const b1 = b[21];
91
+ const b2 = b[22];
92
+ const b3 = b[23];
93
+ const b4 = b[24];
94
+ return {
95
+ width: 1 + (b1 | ((b2 & 0x3f) << 8)),
96
+ height: 1 + ((b2 >> 6) | (b3 << 2) | ((b4 & 0x0f) << 10)),
97
+ };
98
+ }
99
+ if (chunk === 'VP8X') {
100
+ return { width: 1 + u24le(b, 24), height: 1 + u24le(b, 27) };
101
+ }
102
+ return undefined;
103
+ }
104
+ //# sourceMappingURL=image-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-size.js","sourceRoot":"","sources":["../src/image-size.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ export { type ImageSize, type RasterLogoMime, rasterSize } from './image-size.js';
2
+ export { type LoadedLogo, loadLogo } from './logo.js';
3
+ export { type StagedRoadmap, type StageInputs, type StageLayout, type StageResult, stageRoadmap, } from './stage.js';
1
4
  export type { AssetBytes, AssetResolver, FontFamilies, RenderOptions, } from './svg/render.js';
2
5
  export { renderSvg } from './svg/render.js';
3
- export { sanitizeSvg } from './svg/sanitize.js';
6
+ export { sanitizeSvg, svgIntrinsicSize } from './svg/sanitize.js';
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,KAAK,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,YAAY,GACf,MAAM,YAAY,CAAC;AACpB,YAAY,EACR,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ export { rasterSize } from './image-size.js';
2
+ export { loadLogo } from './logo.js';
3
+ export { stageRoadmap, } from './stage.js';
1
4
  export { renderSvg } from './svg/render.js';
2
- export { sanitizeSvg } from './svg/sanitize.js';
5
+ export { sanitizeSvg, svgIntrinsicSize } from './svg/sanitize.js';
3
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAmB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAKH,YAAY,GACf,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/logo.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import type { LogoDimensions } from '@nowline/layout';
2
+ import type { AssetBytes, AssetResolver } from './svg/render.js';
3
+ /**
4
+ * A logo read once: its size for layout and the bytes for the renderer, so no
5
+ * later step resolves the asset again.
6
+ */
7
+ export interface LoadedLogo {
8
+ /** The `logo:` reference, as the roadmap declared it. */
9
+ ref: string;
10
+ /** The intrinsic size, passed to layout as `LayoutOptions.logo`. */
11
+ dimensions: LogoDimensions;
12
+ /** The bytes and MIME type the resolver returned, which `renderSvg` embeds. */
13
+ asset: AssetBytes;
14
+ }
15
+ /**
16
+ * Load the `logo:` asset and read its intrinsic size, to pass to layout as
17
+ * `LayoutOptions.logo` (`.dimensions`), keeping the bytes for
18
+ * `RenderOptions.logo`. Returns undefined, after a `warn` call, when the
19
+ * extension is unsupported or the file is missing or unreadable. Returns
20
+ * undefined silently when there is no `ref` or no resolver (a surface with
21
+ * no asset access, such as the embed).
22
+ */
23
+ export declare function loadLogo(ref: string | undefined, resolver: AssetResolver | undefined, warn: (message: string) => void): Promise<LoadedLogo | undefined>;
24
+ //# sourceMappingURL=logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.d.ts","sourceRoot":"","sources":["../src/logo.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiBjE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,UAAU,EAAE,cAAc,CAAC;IAC3B,+EAA+E;IAC/E,KAAK,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA8BjC"}
package/dist/logo.js ADDED
@@ -0,0 +1,60 @@
1
+ // Pre-layout logo loading (specs/rendering.md § Company Logo Error Handling).
2
+ //
3
+ // Pipelines call `loadLogo` before layout so layout can size the logo slot
4
+ // from the asset's intrinsic aspect ratio. Every failure is a warning, never
5
+ // a throw: the caller decides whether `--strict` turns it into an error, and
6
+ // a failed load lays out as if no logo were declared.
7
+ import { rasterSize } from './image-size.js';
8
+ import { svgIntrinsicSize } from './svg/sanitize.js';
9
+ const LOGO_MIME_BY_EXTENSION = {
10
+ '.svg': 'image/svg+xml',
11
+ '.png': 'image/png',
12
+ '.jpg': 'image/jpeg',
13
+ '.jpeg': 'image/jpeg',
14
+ '.webp': 'image/webp',
15
+ };
16
+ function extensionOf(ref) {
17
+ const base = ref.slice(ref.lastIndexOf('/') + 1);
18
+ const dot = base.lastIndexOf('.');
19
+ return dot > 0 ? base.slice(dot).toLowerCase() : '';
20
+ }
21
+ /**
22
+ * Load the `logo:` asset and read its intrinsic size, to pass to layout as
23
+ * `LayoutOptions.logo` (`.dimensions`), keeping the bytes for
24
+ * `RenderOptions.logo`. Returns undefined, after a `warn` call, when the
25
+ * extension is unsupported or the file is missing or unreadable. Returns
26
+ * undefined silently when there is no `ref` or no resolver (a surface with
27
+ * no asset access, such as the embed).
28
+ */
29
+ export async function loadLogo(ref, resolver, warn) {
30
+ if (!ref || !resolver)
31
+ return undefined;
32
+ const ext = extensionOf(ref);
33
+ const mime = LOGO_MIME_BY_EXTENSION[ext];
34
+ if (!mime) {
35
+ warn(`unsupported logo format: ${ext || '(none)'} (${ref})`);
36
+ return undefined;
37
+ }
38
+ let asset;
39
+ try {
40
+ asset = await resolver(ref);
41
+ }
42
+ catch (err) {
43
+ const reason = err instanceof Error ? err.message : String(err);
44
+ warn(`logo file not found: ${ref} (${reason})`);
45
+ return undefined;
46
+ }
47
+ const bytes = asset.bytes;
48
+ const size = mime === 'image/svg+xml'
49
+ ? svgIntrinsicSize(new TextDecoder().decode(bytes))
50
+ : rasterSize(bytes, mime);
51
+ if (!size) {
52
+ const why = mime === 'image/svg+xml'
53
+ ? 'no viewBox and no pixel width/height on the root <svg>'
54
+ : `not a readable ${ext.slice(1).toUpperCase()} header`;
55
+ warn(`logo could not be parsed: ${ref} (${why})`);
56
+ return undefined;
57
+ }
58
+ return { ref, dimensions: size, asset };
59
+ }
60
+ //# sourceMappingURL=logo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.js","sourceRoot":"","sources":["../src/logo.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,6EAA6E;AAC7E,sDAAsD;AAGtD,OAAO,EAAuB,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,sBAAsB,GAAqD;IAC7E,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,YAAY;CACxB,CAAC;AAEF,SAAS,WAAW,CAAC,GAAW;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC;AAeD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC1B,GAAuB,EACvB,QAAmC,EACnC,IAA+B;IAE/B,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,IAAI,CAAC,4BAA4B,GAAG,IAAI,QAAQ,KAAK,GAAG,GAAG,CAAC,CAAC;QAC7D,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,IAAI,KAAiB,CAAC;IACtB,IAAI,CAAC;QACD,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,CAAC,wBAAwB,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC;QAChD,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,IAAI,GACN,IAAI,KAAK,eAAe;QACpB,CAAC,CAAC,gBAAgB,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,GAAG,GACL,IAAI,KAAK,eAAe;YACpB,CAAC,CAAC,wDAAwD;YAC1D,CAAC,CAAC,kBAAkB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC;QAChE,IAAI,CAAC,6BAA6B,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { type NowlineFile, type NowlineServices, type RawDiagnostic, type ResolveDiagnostic, type ResolveResult, type WavePlan } from '@nowline/core';
2
+ import { type LayoutOptions, type PositionedRoadmap, type RoadmapSchedule } from '@nowline/layout';
3
+ import { type LangiumDocument, type LangiumSharedCoreServices } from 'langium';
4
+ import { type LoadedLogo } from './logo.js';
5
+ import type { AssetResolver } from './svg/render.js';
6
+ /** The layout options a stage reads; a staged roadmap records the values it used. */
7
+ export type StageLayout = Pick<LayoutOptions, 'theme' | 'today' | 'width' | 'locale' | 'nonWorking'>;
8
+ export interface StageInputs {
9
+ source: string;
10
+ /** Absolute path: base for includes and assets. */
11
+ sourcePath: string;
12
+ /** The caller's Langium services (each pipeline keeps its own instance). */
13
+ services: {
14
+ shared: LangiumSharedCoreServices;
15
+ Nowline: NowlineServices;
16
+ };
17
+ readSource: (absPath: string) => Promise<string>;
18
+ /** Omitted: no asset access (the embed), so a `logo:` lays out as if absent. */
19
+ assetResolver?: AssetResolver;
20
+ /** A document the caller already parsed and validated from `source`. */
21
+ document?: LangiumDocument<NowlineFile>;
22
+ layout: StageLayout;
23
+ /**
24
+ * An include error the caller tolerates, such as the browser's
25
+ * single-file mode skipping every include: it takes no part in the
26
+ * include-error precedence and stays in `resolved.diagnostics` for the
27
+ * caller to report. Omitted: every include error counts.
28
+ */
29
+ isToleratedIncludeError?: (diagnostic: ResolveDiagnostic) => boolean;
30
+ }
31
+ export type StageResult = {
32
+ kind: 'invalid';
33
+ document: LangiumDocument<NowlineFile>;
34
+ /** Lexer, parser and validator diagnostics with errors among them. */
35
+ diagnostics: RawDiagnostic[];
36
+ } | {
37
+ kind: 'include-error';
38
+ document: LangiumDocument<NowlineFile>;
39
+ /** The first uncoded include error, when one exists: it wins (waves.md §6.1). */
40
+ legacy?: ResolveDiagnostic;
41
+ /** Routed (wave-rule) diagnostics, errors and warnings; empty when `legacy` is set. */
42
+ routed: ResolveDiagnostic[];
43
+ /** Every resolver diagnostic in order, for callers that report more than the winner. */
44
+ resolved: ResolveResult;
45
+ } | {
46
+ kind: 'staged';
47
+ document: LangiumDocument<NowlineFile>;
48
+ ast: NowlineFile;
49
+ resolved: ResolveResult;
50
+ /** Routed warnings (no errors). */
51
+ routed: ResolveDiagnostic[];
52
+ /** The loaded logo: size for layout, bytes for `RenderOptions.logo`. */
53
+ logo?: LoadedLogo;
54
+ /** Asset warnings (missing or unreadable logo); the caller applies `strict`. */
55
+ warnings: string[];
56
+ /** The wave plan (`buildWavePlan`); `null` when the roadmap declares no waves. */
57
+ plan: WavePlan | null;
58
+ /**
59
+ * The day schedule `model` was laid out with (`scheduleRoadmap`,
60
+ * `plan` included as `schedule.plan`); exporters reuse it through
61
+ * `ExportInputs.schedule` (specs/scheduler-unification.md §3.6).
62
+ */
63
+ schedule: RoadmapSchedule;
64
+ model: PositionedRoadmap;
65
+ /** The layout options `model` was laid out with, picked from `StageInputs.layout`. */
66
+ layout: StageLayout;
67
+ };
68
+ /** A roadmap that staged without errors, ready to render or export. */
69
+ export type StagedRoadmap = Extract<StageResult, {
70
+ kind: 'staged';
71
+ }>;
72
+ /**
73
+ * Parse, validate, resolve includes, load the logo, schedule and lay out `source`.
74
+ * Returns `invalid` on a lexer, parser or validator error, `include-error`
75
+ * on a resolver error, and `staged` with the positioned model otherwise.
76
+ */
77
+ export declare function stageRoadmap(inputs: StageInputs): Promise<StageResult>;
78
+ //# sourceMappingURL=stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AAOA,OAAO,EAIH,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,QAAQ,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,KAAK,aAAa,EAElB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAGvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,yBAAyB,EAAO,MAAM,SAAS,CAAC;AACpF,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,qFAAqF;AACrF,MAAM,MAAM,WAAW,GAAG,IAAI,CAC1B,aAAa,EACb,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,CACxD,CAAC;AAKF,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,EAAE;QAAE,MAAM,EAAE,yBAAyB,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,CAAC;IAC1E,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,gFAAgF;IAChF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAAC;CACxE;AAED,MAAM,MAAM,WAAW,GACjB;IACI,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACvC,sEAAsE;IACtE,WAAW,EAAE,aAAa,EAAE,CAAC;CAChC,GACD;IACI,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACvC,iFAAiF;IACjF,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,uFAAuF;IACvF,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,EAAE,aAAa,CAAC;CAC3B,GACD;IACI,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACvC,GAAG,EAAE,WAAW,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC;IACxB,mCAAmC;IACnC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB;;;;OAIG;IACH,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,iBAAiB,CAAC;IACzB,sFAAsF;IACtF,MAAM,EAAE,WAAW,CAAC;CACvB,CAAC;AAER,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAyBrE;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAyD5E"}
package/dist/stage.js ADDED
@@ -0,0 +1,88 @@
1
+ // One staging function for every render surface (specs/surface-options.md
2
+ // §3.3): parse and validate, resolve includes, apply the include-error
3
+ // precedence, load the logo, build the wave plan and the day schedule, lay
4
+ // out. Rendering, diagnostics formatting,
5
+ // `strict` and layout insights stay with each caller, which maps the result
6
+ // to its own shape.
7
+ import { buildWavePlan, collectDocumentDiagnostics, isRoutedResolveDiagnostic, resolveIncludes, } from '@nowline/core';
8
+ import { layoutRoadmap, roadmapLogoRef, scheduleRoadmap, } from '@nowline/layout';
9
+ import { URI } from 'langium';
10
+ import { loadLogo } from './logo.js';
11
+ /** Langium's `DiagnosticSeverity.Error`. */
12
+ const SEVERITY_ERROR = 1;
13
+ let documentCounter = 0;
14
+ function freshUri() {
15
+ // A fresh URI per stage: reusing one lets Langium mutate the prior
16
+ // document in place.
17
+ return URI.parse(`memory:///stage-${++documentCounter}.nowline`);
18
+ }
19
+ async function buildDocument(inputs) {
20
+ if (inputs.document)
21
+ return inputs.document;
22
+ const { workspace } = inputs.services.shared;
23
+ const document = workspace.LangiumDocumentFactory.fromString(inputs.source, freshUri());
24
+ await workspace.DocumentBuilder.build([document], { validation: true });
25
+ return document;
26
+ }
27
+ function isErrorDiagnostic(raw) {
28
+ return raw.origin !== 'validation' || raw.diagnostic.severity === SEVERITY_ERROR;
29
+ }
30
+ /**
31
+ * Parse, validate, resolve includes, load the logo, schedule and lay out `source`.
32
+ * Returns `invalid` on a lexer, parser or validator error, `include-error`
33
+ * on a resolver error, and `staged` with the positioned model otherwise.
34
+ */
35
+ export async function stageRoadmap(inputs) {
36
+ const document = await buildDocument(inputs);
37
+ const diagnostics = collectDocumentDiagnostics(document);
38
+ if (diagnostics.some(isErrorDiagnostic)) {
39
+ return { kind: 'invalid', document, diagnostics };
40
+ }
41
+ const ast = document.parseResult.value;
42
+ const resolved = await resolveIncludes(ast, inputs.sourcePath, {
43
+ services: inputs.services.Nowline,
44
+ readFile: inputs.readSource,
45
+ });
46
+ // An uncoded include error is more fundamental than the wave-rule
47
+ // errors: the first one wins and hides the routed diagnostics.
48
+ const isTolerated = inputs.isToleratedIncludeError ?? (() => false);
49
+ const errors = resolved.diagnostics.filter((d) => d.severity === 'error' && !isTolerated(d));
50
+ const routed = resolved.diagnostics.filter(isRoutedResolveDiagnostic);
51
+ const legacy = errors.find((d) => !isRoutedResolveDiagnostic(d));
52
+ if (legacy) {
53
+ return { kind: 'include-error', document, legacy, routed: [], resolved };
54
+ }
55
+ if (errors.length > 0) {
56
+ return { kind: 'include-error', document, routed, resolved };
57
+ }
58
+ // A failed logo load warns and lays out as if no logo were declared.
59
+ const warnings = [];
60
+ const logo = await loadLogo(roadmapLogoRef(ast), inputs.assetResolver, (message) => warnings.push(message));
61
+ // Named keys, not a spread: a caller may pass a wider options object.
62
+ const { theme, today, width, locale, nonWorking } = inputs.layout;
63
+ const layout = { theme, today, width, locale, nonWorking };
64
+ // One wave plan and one day schedule per staging: layout reuses the
65
+ // schedule and the exporters read it from `ExportInputs`
66
+ // (specs/scheduler-unification.md §3.6).
67
+ const plan = buildWavePlan(resolved) ?? null;
68
+ const schedule = scheduleRoadmap(ast, resolved, { today, plan });
69
+ const model = layoutRoadmap(ast, resolved, {
70
+ ...layout,
71
+ schedule,
72
+ logo: logo?.dimensions,
73
+ });
74
+ return {
75
+ kind: 'staged',
76
+ document,
77
+ ast,
78
+ resolved,
79
+ routed,
80
+ logo,
81
+ warnings,
82
+ plan,
83
+ schedule,
84
+ model,
85
+ layout,
86
+ };
87
+ }
88
+ //# sourceMappingURL=stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PositionedDependencyEdge, Theme } from '@nowline/layout';
2
+ export declare function renderEdge(e: PositionedDependencyEdge, palette: Theme): string;
3
+ //# sourceMappingURL=edges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.d.ts","sourceRoot":"","sources":["../../src/svg/edges.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAS,wBAAwB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAY9E,wBAAgB,UAAU,CAAC,CAAC,EAAE,wBAAwB,EAAE,OAAO,EAAE,KAAK,GAAG,MAAM,CA6C9E"}
@@ -0,0 +1,144 @@
1
+ // The dependency-edge layer: the arrows that join one item to another, their
2
+ // solid and dotted slack legs, and the rounded orthogonal paths they follow.
3
+ import { ARROW_HEAD_LENGTH_PX, ARROW_HEAD_WIDTH_PX, EDGE_CORNER_RADIUS } from '@nowline/layout';
4
+ import { num, tag } from './xml.js';
5
+ /** Dash pattern of a dependency's slack leg: the dotted look of milestone slack lines. */
6
+ const SLACK_DASH = '3 3';
7
+ // A dependency arrow (specs/true-width-layout.md §3.4). It paints behind
8
+ // the bars (see `renderRoadmap`), so a leg that crosses a bar passes behind
9
+ // it. Vertical legs are solid; the horizontal leg is dotted when the target
10
+ // waits. The head is drawn, not a marker, so it can shrink to a narrow
11
+ // target and become a dot (§8 O6).
12
+ export function renderEdge(e, palette) {
13
+ const points = e.waypoints;
14
+ if (points.length < 2)
15
+ return '';
16
+ const color = palette.dependency.edgeStroke;
17
+ const tip = points[points.length - 1];
18
+ const prev = points[points.length - 2];
19
+ const len = Math.hypot(tip.x - prev.x, tip.y - prev.y);
20
+ if (len === 0)
21
+ return '';
22
+ const ux = (tip.x - prev.x) / len;
23
+ const uy = (tip.y - prev.y) / len;
24
+ const half = e.headWidth / 2;
25
+ // The leg stops where the head starts, so a dotted leg never shows
26
+ // through it.
27
+ const headLength = e.head === 'dot' ? half : (e.headWidth * ARROW_HEAD_LENGTH_PX) / ARROW_HEAD_WIDTH_PX;
28
+ // A last leg no longer than the head is all head.
29
+ const leg = len > headLength
30
+ ? [...points.slice(0, -1), { x: tip.x - ux * headLength, y: tip.y - uy * headLength }]
31
+ : points.slice(0, -1);
32
+ const parts = [legPaths(leg, e.slack, color)];
33
+ const headFill = palette.arrowhead.neutral;
34
+ if (e.head === 'dot') {
35
+ parts.push(tag('circle', {
36
+ cx: num(tip.x - ux * half),
37
+ cy: num(tip.y - uy * half),
38
+ r: num(half),
39
+ fill: headFill,
40
+ }));
41
+ }
42
+ else {
43
+ const bx = tip.x - ux * headLength;
44
+ const by = tip.y - uy * headLength;
45
+ parts.push(tag('path', {
46
+ d: `M${num(bx - uy * half)} ${num(by + ux * half)} ` +
47
+ `L${num(tip.x)} ${num(tip.y)} ` +
48
+ `L${num(bx + uy * half)} ${num(by - ux * half)} z`,
49
+ fill: headFill,
50
+ }));
51
+ }
52
+ return tag('g', { 'data-layer': 'dependency' }, parts.join(''));
53
+ }
54
+ // An arrow's legs: one rounded path, or for a slack arrow its solid
55
+ // vertical legs and its dotted horizontal ones. Empty when the head is all
56
+ // there is (a leg no longer than the head).
57
+ function legPaths(leg, slack, color) {
58
+ if (leg.length < 2)
59
+ return '';
60
+ const stroke = { fill: 'none', stroke: color, 'stroke-width': 1.1, 'stroke-linejoin': 'round' };
61
+ if (!slack)
62
+ return tag('path', { d: roundedOrthogonalPath(leg, EDGE_CORNER_RADIUS), ...stroke });
63
+ const { solid, dotted } = splitSlackPath(leg, EDGE_CORNER_RADIUS);
64
+ return ((solid ? tag('path', { d: solid, ...stroke }) : '') +
65
+ (dotted
66
+ ? tag('path', {
67
+ d: dotted,
68
+ ...stroke,
69
+ 'stroke-dasharray': SLACK_DASH,
70
+ 'stroke-linecap': 'round',
71
+ })
72
+ : ''));
73
+ }
74
+ // A slack arrow's path in two parts: its vertical legs with the rounded
75
+ // corners (solid) and its horizontal legs (dotted), so the dash pattern
76
+ // marks the wait alone.
77
+ function splitSlackPath(points, radius) {
78
+ const n = points.length;
79
+ const before = [];
80
+ const after = [];
81
+ const solid = [];
82
+ for (let i = 1; i < n - 1; i++) {
83
+ const prev = points[i - 1];
84
+ const cur = points[i];
85
+ const next = points[i + 1];
86
+ const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);
87
+ const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);
88
+ const r = Math.min(radius, inLen / 2, outLen / 2);
89
+ const dIn = { x: Math.sign(cur.x - prev.x), y: Math.sign(cur.y - prev.y) };
90
+ const dOut = { x: Math.sign(next.x - cur.x), y: Math.sign(next.y - cur.y) };
91
+ before[i] = { x: cur.x - dIn.x * r, y: cur.y - dIn.y * r };
92
+ after[i] = { x: cur.x + dOut.x * r, y: cur.y + dOut.y * r };
93
+ if (r > 0) {
94
+ solid.push(`M${num(before[i].x)} ${num(before[i].y)} ` +
95
+ `Q${num(cur.x)} ${num(cur.y)} ${num(after[i].x)} ${num(after[i].y)}`);
96
+ }
97
+ }
98
+ const dotted = [];
99
+ for (let i = 0; i < n - 1; i++) {
100
+ const a = i === 0 ? points[0] : after[i];
101
+ const b = i === n - 2 ? points[n - 1] : before[i + 1];
102
+ const piece = `M${num(a.x)} ${num(a.y)} L${num(b.x)} ${num(b.y)}`;
103
+ if (Math.abs(points[i + 1].y - points[i].y) < 1e-9)
104
+ dotted.push(piece);
105
+ else
106
+ solid.push(piece);
107
+ }
108
+ return { solid: solid.join(' '), dotted: dotted.join(' ') };
109
+ }
110
+ // Build an SVG path for a sequence of orthogonal waypoints, inserting a
111
+ // quarter-arc at every interior bend. Falls back to straight segments when
112
+ // adjacent points aren't axis-aligned (defensive — the layout always emits
113
+ // orthogonal segments).
114
+ function roundedOrthogonalPath(points, radius) {
115
+ if (points.length < 2)
116
+ return '';
117
+ const parts = [`M${num(points[0].x)} ${num(points[0].y)}`];
118
+ for (let i = 1; i < points.length; i++) {
119
+ const prev = points[i - 1];
120
+ const cur = points[i];
121
+ if (i === points.length - 1) {
122
+ parts.push(`L${num(cur.x)} ${num(cur.y)}`);
123
+ continue;
124
+ }
125
+ const next = points[i + 1];
126
+ const dxIn = Math.sign(cur.x - prev.x);
127
+ const dyIn = Math.sign(cur.y - prev.y);
128
+ const dxOut = Math.sign(next.x - cur.x);
129
+ const dyOut = Math.sign(next.y - cur.y);
130
+ const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);
131
+ const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);
132
+ const r = Math.min(radius, inLen / 2, outLen / 2);
133
+ if (r <= 0 || (dxIn !== 0 && dxOut !== 0) || (dyIn !== 0 && dyOut !== 0)) {
134
+ parts.push(`L${num(cur.x)} ${num(cur.y)}`);
135
+ continue;
136
+ }
137
+ const beforeBend = { x: cur.x - dxIn * r, y: cur.y - dyIn * r };
138
+ const afterBend = { x: cur.x + dxOut * r, y: cur.y + dyOut * r };
139
+ parts.push(`L${num(beforeBend.x)} ${num(beforeBend.y)}`);
140
+ parts.push(`Q${num(cur.x)} ${num(cur.y)} ${num(afterBend.x)} ${num(afterBend.y)}`);
141
+ }
142
+ return parts.join(' ');
143
+ }
144
+ //# sourceMappingURL=edges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.js","sourceRoot":"","sources":["../../src/svg/edges.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PositionedFootnoteArea, Theme } from '@nowline/layout';
2
+ import type { FontFamilies } from './render.js';
3
+ export declare function renderFootnotes(f: PositionedFootnoteArea, idPrefix: string, palette: Theme, fonts: FontFamilies): string;
4
+ //# sourceMappingURL=footnotes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footnotes.d.ts","sourceRoot":"","sources":["../../src/svg/footnotes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,wBAAgB,eAAe,CAC3B,CAAC,EAAE,sBAAsB,EACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,KAAK,EACd,KAAK,EAAE,YAAY,GACpB,MAAM,CAoGR"}