@nowline/layout 0.8.5 → 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 (339) hide show
  1. package/dist/axis-columns.d.ts +70 -0
  2. package/dist/axis-columns.d.ts.map +1 -0
  3. package/dist/axis-columns.js +104 -0
  4. package/dist/axis-columns.js.map +1 -0
  5. package/dist/band-scale.d.ts.map +1 -1
  6. package/dist/calendar-resolver.d.ts +27 -0
  7. package/dist/calendar-resolver.d.ts.map +1 -0
  8. package/dist/calendar-resolver.js +132 -0
  9. package/dist/calendar-resolver.js.map +1 -0
  10. package/dist/calendar.d.ts +0 -19
  11. package/dist/calendar.d.ts.map +1 -1
  12. package/dist/calendar.js +4 -44
  13. package/dist/calendar.js.map +1 -1
  14. package/dist/canvas-width.d.ts +23 -0
  15. package/dist/canvas-width.d.ts.map +1 -0
  16. package/dist/canvas-width.js +26 -0
  17. package/dist/canvas-width.js.map +1 -0
  18. package/dist/capacity.d.ts +28 -0
  19. package/dist/capacity.d.ts.map +1 -1
  20. package/dist/capacity.js +64 -29
  21. package/dist/capacity.js.map +1 -1
  22. package/dist/chart-translation.d.ts +22 -0
  23. package/dist/chart-translation.d.ts.map +1 -0
  24. package/dist/chart-translation.js +83 -0
  25. package/dist/chart-translation.js.map +1 -0
  26. package/dist/container-header-geometry.d.ts +64 -0
  27. package/dist/container-header-geometry.d.ts.map +1 -0
  28. package/dist/container-header-geometry.js +89 -0
  29. package/dist/container-header-geometry.js.map +1 -0
  30. package/dist/dsl-utils.d.ts +3 -4
  31. package/dist/dsl-utils.d.ts.map +1 -1
  32. package/dist/dsl-utils.js +8 -25
  33. package/dist/dsl-utils.js.map +1 -1
  34. package/dist/edge-routing.d.ts +69 -78
  35. package/dist/edge-routing.d.ts.map +1 -1
  36. package/dist/edge-routing.js +271 -401
  37. package/dist/edge-routing.js.map +1 -1
  38. package/dist/frame-tab-geometry.d.ts +24 -14
  39. package/dist/frame-tab-geometry.d.ts.map +1 -1
  40. package/dist/frame-tab-geometry.js +69 -23
  41. package/dist/frame-tab-geometry.js.map +1 -1
  42. package/dist/header-card-geometry.d.ts +12 -0
  43. package/dist/header-card-geometry.d.ts.map +1 -1
  44. package/dist/header-card-geometry.js +14 -2
  45. package/dist/header-card-geometry.js.map +1 -1
  46. package/dist/header-logo.d.ts +28 -0
  47. package/dist/header-logo.d.ts.map +1 -0
  48. package/dist/header-logo.js +51 -0
  49. package/dist/header-logo.js.map +1 -0
  50. package/dist/i18n.d.ts +11 -0
  51. package/dist/i18n.d.ts.map +1 -1
  52. package/dist/i18n.js +11 -1
  53. package/dist/i18n.js.map +1 -1
  54. package/dist/index.d.ts +20 -8
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +17 -7
  57. package/dist/index.js.map +1 -1
  58. package/dist/inline-date-pin-geometry.d.ts +19 -11
  59. package/dist/inline-date-pin-geometry.d.ts.map +1 -1
  60. package/dist/inline-date-pin-geometry.js +45 -46
  61. package/dist/inline-date-pin-geometry.js.map +1 -1
  62. package/dist/item-bar-geometry.d.ts +192 -4
  63. package/dist/item-bar-geometry.d.ts.map +1 -1
  64. package/dist/item-bar-geometry.js +258 -5
  65. package/dist/item-bar-geometry.js.map +1 -1
  66. package/dist/item-port-geometry.d.ts +13 -0
  67. package/dist/item-port-geometry.d.ts.map +1 -0
  68. package/dist/item-port-geometry.js +63 -0
  69. package/dist/item-port-geometry.js.map +1 -0
  70. package/dist/layout-context.d.ts +115 -51
  71. package/dist/layout-context.d.ts.map +1 -1
  72. package/dist/layout-context.js +96 -5
  73. package/dist/layout-context.js.map +1 -1
  74. package/dist/layout-insights.d.ts.map +1 -1
  75. package/dist/layout-insights.js +73 -1
  76. package/dist/layout-insights.js.map +1 -1
  77. package/dist/layout.d.ts +35 -0
  78. package/dist/layout.d.ts.map +1 -1
  79. package/dist/layout.js +18 -1315
  80. package/dist/layout.js.map +1 -1
  81. package/dist/nodes/anchor-node.d.ts.map +1 -1
  82. package/dist/nodes/anchor-node.js +11 -4
  83. package/dist/nodes/anchor-node.js.map +1 -1
  84. package/dist/nodes/content-extent.d.ts +24 -0
  85. package/dist/nodes/content-extent.d.ts.map +1 -0
  86. package/dist/nodes/content-extent.js +100 -0
  87. package/dist/nodes/content-extent.js.map +1 -0
  88. package/dist/nodes/dependency-edges.d.ts +6 -0
  89. package/dist/nodes/dependency-edges.d.ts.map +1 -0
  90. package/dist/nodes/dependency-edges.js +148 -0
  91. package/dist/nodes/dependency-edges.js.map +1 -0
  92. package/dist/nodes/footnote-node.d.ts +24 -3
  93. package/dist/nodes/footnote-node.d.ts.map +1 -1
  94. package/dist/nodes/footnote-node.js +129 -25
  95. package/dist/nodes/footnote-node.js.map +1 -1
  96. package/dist/nodes/group-node.d.ts +10 -21
  97. package/dist/nodes/group-node.d.ts.map +1 -1
  98. package/dist/nodes/group-node.js +79 -154
  99. package/dist/nodes/group-node.js.map +1 -1
  100. package/dist/nodes/header-node.d.ts +56 -0
  101. package/dist/nodes/header-node.d.ts.map +1 -0
  102. package/dist/nodes/header-node.js +163 -0
  103. package/dist/nodes/header-node.js.map +1 -0
  104. package/dist/nodes/include-node.d.ts +22 -12
  105. package/dist/nodes/include-node.d.ts.map +1 -1
  106. package/dist/nodes/include-node.js +95 -62
  107. package/dist/nodes/include-node.js.map +1 -1
  108. package/dist/nodes/item-measure.d.ts +135 -0
  109. package/dist/nodes/item-measure.d.ts.map +1 -0
  110. package/dist/nodes/item-measure.js +514 -0
  111. package/dist/nodes/item-measure.js.map +1 -0
  112. package/dist/nodes/item-node.d.ts +162 -9
  113. package/dist/nodes/item-node.d.ts.map +1 -1
  114. package/dist/nodes/item-node.js +256 -69
  115. package/dist/nodes/item-node.js.map +1 -1
  116. package/dist/nodes/marker-band.d.ts +118 -0
  117. package/dist/nodes/marker-band.d.ts.map +1 -0
  118. package/dist/nodes/marker-band.js +303 -0
  119. package/dist/nodes/marker-band.js.map +1 -0
  120. package/dist/nodes/marker-geometry.js +1 -1
  121. package/dist/nodes/marker-geometry.js.map +1 -1
  122. package/dist/nodes/milestone-node.d.ts +112 -15
  123. package/dist/nodes/milestone-node.d.ts.map +1 -1
  124. package/dist/nodes/milestone-node.js +246 -95
  125. package/dist/nodes/milestone-node.js.map +1 -1
  126. package/dist/nodes/nowline-node.d.ts +8 -0
  127. package/dist/nodes/nowline-node.d.ts.map +1 -0
  128. package/dist/nodes/nowline-node.js +74 -0
  129. package/dist/nodes/nowline-node.js.map +1 -0
  130. package/dist/nodes/parallel-node.d.ts +7 -12
  131. package/dist/nodes/parallel-node.d.ts.map +1 -1
  132. package/dist/nodes/parallel-node.js +66 -32
  133. package/dist/nodes/parallel-node.js.map +1 -1
  134. package/dist/nodes/region-markers.d.ts +41 -0
  135. package/dist/nodes/region-markers.d.ts.map +1 -0
  136. package/dist/nodes/region-markers.js +130 -0
  137. package/dist/nodes/region-markers.js.map +1 -0
  138. package/dist/nodes/roadmap-node.d.ts +9 -72
  139. package/dist/nodes/roadmap-node.d.ts.map +1 -1
  140. package/dist/nodes/roadmap-node.js +38 -788
  141. package/dist/nodes/roadmap-node.js.map +1 -1
  142. package/dist/nodes/row-track.d.ts +33 -0
  143. package/dist/nodes/row-track.d.ts.map +1 -0
  144. package/dist/nodes/row-track.js +170 -0
  145. package/dist/nodes/row-track.js.map +1 -0
  146. package/dist/nodes/sequence-item.d.ts +25 -0
  147. package/dist/nodes/sequence-item.d.ts.map +1 -0
  148. package/dist/nodes/sequence-item.js +396 -0
  149. package/dist/nodes/sequence-item.js.map +1 -0
  150. package/dist/nodes/sequence-one.d.ts +5 -0
  151. package/dist/nodes/sequence-one.d.ts.map +1 -0
  152. package/dist/nodes/sequence-one.js +26 -0
  153. package/dist/nodes/sequence-one.js.map +1 -0
  154. package/dist/nodes/swimlane-node.d.ts +5 -17
  155. package/dist/nodes/swimlane-node.d.ts.map +1 -1
  156. package/dist/nodes/swimlane-node.js +62 -147
  157. package/dist/nodes/swimlane-node.js.map +1 -1
  158. package/dist/nodes/wave-node.d.ts +52 -0
  159. package/dist/nodes/wave-node.d.ts.map +1 -0
  160. package/dist/nodes/wave-node.js +483 -0
  161. package/dist/nodes/wave-node.js.map +1 -0
  162. package/dist/non-working-display.d.ts +14 -0
  163. package/dist/non-working-display.d.ts.map +1 -0
  164. package/dist/non-working-display.js +28 -0
  165. package/dist/non-working-display.js.map +1 -0
  166. package/dist/phases/date-window.d.ts +48 -0
  167. package/dist/phases/date-window.d.ts.map +1 -0
  168. package/dist/phases/date-window.js +130 -0
  169. package/dist/phases/date-window.js.map +1 -0
  170. package/dist/phases/finalize.d.ts +198 -0
  171. package/dist/phases/finalize.d.ts.map +1 -0
  172. package/dist/phases/finalize.js +1058 -0
  173. package/dist/phases/finalize.js.map +1 -0
  174. package/dist/phases/measure.d.ts +77 -0
  175. package/dist/phases/measure.d.ts.map +1 -0
  176. package/dist/phases/measure.js +222 -0
  177. package/dist/phases/measure.js.map +1 -0
  178. package/dist/phases/place.d.ts +28 -0
  179. package/dist/phases/place.d.ts.map +1 -0
  180. package/dist/phases/place.js +225 -0
  181. package/dist/phases/place.js.map +1 -0
  182. package/dist/renderable.d.ts.map +1 -1
  183. package/dist/renderable.js +23 -3
  184. package/dist/renderable.js.map +1 -1
  185. package/dist/resolve-today.d.ts +11 -1
  186. package/dist/resolve-today.d.ts.map +1 -1
  187. package/dist/resolve-today.js +26 -12
  188. package/dist/resolve-today.js.map +1 -1
  189. package/dist/row-packer.d.ts +42 -16
  190. package/dist/row-packer.d.ts.map +1 -1
  191. package/dist/row-packer.js +51 -78
  192. package/dist/row-packer.js.map +1 -1
  193. package/dist/schedule.d.ts +58 -1
  194. package/dist/schedule.d.ts.map +1 -1
  195. package/dist/schedule.js +280 -106
  196. package/dist/schedule.js.map +1 -1
  197. package/dist/start-rules.d.ts +27 -0
  198. package/dist/start-rules.d.ts.map +1 -0
  199. package/dist/start-rules.js +91 -0
  200. package/dist/start-rules.js.map +1 -0
  201. package/dist/start-terms.d.ts +23 -0
  202. package/dist/start-terms.d.ts.map +1 -0
  203. package/dist/start-terms.js +27 -0
  204. package/dist/start-terms.js.map +1 -0
  205. package/dist/status-dot.d.ts +46 -0
  206. package/dist/status-dot.d.ts.map +1 -0
  207. package/dist/status-dot.js +78 -0
  208. package/dist/status-dot.js.map +1 -0
  209. package/dist/style-resolution.d.ts.map +1 -1
  210. package/dist/style-resolution.js +23 -43
  211. package/dist/style-resolution.js.map +1 -1
  212. package/dist/text-measure.d.ts +28 -0
  213. package/dist/text-measure.d.ts.map +1 -0
  214. package/dist/text-measure.js +70 -0
  215. package/dist/text-measure.js.map +1 -0
  216. package/dist/themes/contrast.d.ts +4 -0
  217. package/dist/themes/contrast.d.ts.map +1 -0
  218. package/dist/themes/contrast.js +32 -0
  219. package/dist/themes/contrast.js.map +1 -0
  220. package/dist/themes/dark.d.ts.map +1 -1
  221. package/dist/themes/dark.js +28 -1
  222. package/dist/themes/dark.js.map +1 -1
  223. package/dist/themes/grayscale.d.ts.map +1 -1
  224. package/dist/themes/grayscale.js +28 -1
  225. package/dist/themes/grayscale.js.map +1 -1
  226. package/dist/themes/index.d.ts +4 -11
  227. package/dist/themes/index.d.ts.map +1 -1
  228. package/dist/themes/index.js +6 -4
  229. package/dist/themes/index.js.map +1 -1
  230. package/dist/themes/light.d.ts.map +1 -1
  231. package/dist/themes/light.js +28 -1
  232. package/dist/themes/light.js.map +1 -1
  233. package/dist/themes/shape.d.ts +31 -0
  234. package/dist/themes/shape.d.ts.map +1 -1
  235. package/dist/themes/shared.d.ts +44 -50
  236. package/dist/themes/shared.d.ts.map +1 -1
  237. package/dist/themes/shared.js +79 -83
  238. package/dist/themes/shared.js.map +1 -1
  239. package/dist/time-scale.d.ts +42 -6
  240. package/dist/time-scale.d.ts.map +1 -1
  241. package/dist/time-scale.js +109 -17
  242. package/dist/time-scale.js.map +1 -1
  243. package/dist/types.d.ts +528 -11
  244. package/dist/types.d.ts.map +1 -1
  245. package/dist/view-preset.d.ts +61 -6
  246. package/dist/view-preset.d.ts.map +1 -1
  247. package/dist/view-preset.js +439 -24
  248. package/dist/view-preset.js.map +1 -1
  249. package/dist/wave-barrier.d.ts +107 -0
  250. package/dist/wave-barrier.d.ts.map +1 -0
  251. package/dist/wave-barrier.js +174 -0
  252. package/dist/wave-barrier.js.map +1 -0
  253. package/dist/wave-hatch.d.ts +4 -0
  254. package/dist/wave-hatch.d.ts.map +1 -0
  255. package/dist/wave-hatch.js +21 -0
  256. package/dist/wave-hatch.js.map +1 -0
  257. package/dist/wave-layout.d.ts +99 -0
  258. package/dist/wave-layout.d.ts.map +1 -0
  259. package/dist/wave-layout.js +130 -0
  260. package/dist/wave-layout.js.map +1 -0
  261. package/dist/working-calendar.d.ts +128 -4
  262. package/dist/working-calendar.d.ts.map +1 -1
  263. package/dist/working-calendar.js +725 -51
  264. package/dist/working-calendar.js.map +1 -1
  265. package/dist/working-span.d.ts +11 -0
  266. package/dist/working-span.d.ts.map +1 -0
  267. package/dist/working-span.js +18 -0
  268. package/dist/working-span.js.map +1 -0
  269. package/package.json +7 -7
  270. package/src/axis-columns.ts +140 -0
  271. package/src/calendar-resolver.ts +161 -0
  272. package/src/calendar.ts +4 -45
  273. package/src/canvas-width.ts +36 -0
  274. package/src/capacity.ts +71 -30
  275. package/src/chart-translation.ts +88 -0
  276. package/src/container-header-geometry.ts +116 -0
  277. package/src/dsl-utils.ts +8 -26
  278. package/src/edge-routing.ts +347 -491
  279. package/src/frame-tab-geometry.ts +78 -25
  280. package/src/header-card-geometry.ts +17 -2
  281. package/src/header-logo.ts +67 -0
  282. package/src/i18n.ts +22 -1
  283. package/src/index.ts +97 -12
  284. package/src/inline-date-pin-geometry.ts +55 -58
  285. package/src/item-bar-geometry.ts +341 -5
  286. package/src/item-port-geometry.ts +69 -0
  287. package/src/layout-context.ts +210 -72
  288. package/src/layout-insights.ts +109 -2
  289. package/src/layout.ts +57 -1530
  290. package/src/nodes/anchor-node.ts +11 -4
  291. package/src/nodes/content-extent.ts +107 -0
  292. package/src/nodes/dependency-edges.ts +171 -0
  293. package/src/nodes/footnote-node.ts +171 -31
  294. package/src/nodes/group-node.ts +92 -215
  295. package/src/nodes/header-node.ts +255 -0
  296. package/src/nodes/include-node.ts +124 -110
  297. package/src/nodes/item-measure.ts +723 -0
  298. package/src/nodes/item-node.ts +358 -80
  299. package/src/nodes/marker-band.ts +406 -0
  300. package/src/nodes/marker-geometry.ts +1 -1
  301. package/src/nodes/milestone-node.ts +321 -136
  302. package/src/nodes/nowline-node.ts +87 -0
  303. package/src/nodes/parallel-node.ts +69 -39
  304. package/src/nodes/region-markers.ts +194 -0
  305. package/src/nodes/roadmap-node.ts +46 -950
  306. package/src/nodes/row-track.ts +217 -0
  307. package/src/nodes/sequence-item.ts +433 -0
  308. package/src/nodes/sequence-one.ts +40 -0
  309. package/src/nodes/swimlane-node.ts +66 -206
  310. package/src/nodes/wave-node.ts +609 -0
  311. package/src/non-working-display.ts +32 -0
  312. package/src/phases/date-window.ts +191 -0
  313. package/src/phases/finalize.ts +1303 -0
  314. package/src/phases/measure.ts +329 -0
  315. package/src/phases/place.ts +318 -0
  316. package/src/renderable.ts +23 -3
  317. package/src/resolve-today.ts +28 -25
  318. package/src/row-packer.ts +85 -84
  319. package/src/schedule.ts +362 -114
  320. package/src/start-rules.ts +113 -0
  321. package/src/start-terms.ts +38 -0
  322. package/src/status-dot.ts +81 -0
  323. package/src/style-resolution.ts +27 -57
  324. package/src/text-measure.ts +71 -0
  325. package/src/themes/contrast.ts +34 -0
  326. package/src/themes/dark.ts +28 -1
  327. package/src/themes/grayscale.ts +28 -1
  328. package/src/themes/index.ts +10 -7
  329. package/src/themes/light.ts +28 -1
  330. package/src/themes/shape.ts +38 -0
  331. package/src/themes/shared.ts +85 -93
  332. package/src/time-scale.ts +117 -19
  333. package/src/types.ts +529 -20
  334. package/src/view-preset.ts +520 -27
  335. package/src/wave-barrier.ts +242 -0
  336. package/src/wave-hatch.ts +25 -0
  337. package/src/wave-layout.ts +203 -0
  338. package/src/working-calendar.ts +875 -57
  339. package/src/working-span.ts +19 -0
@@ -3,37 +3,56 @@
3
3
  // and either pins to a fixed `date:` or floats to the rightmost `after:`
4
4
  // predecessor. A non-binding (second-latest) predecessor drives the
5
5
  // "slack" arrow when present. Date-pinned milestones whose predecessors
6
- // would push past the date are flagged `isOverrun`.
6
+ // would push past the date are flagged `isOverrun` and slip: the diamond
7
+ // stays on the date, and a second one sits where the latest predecessor
8
+ // ends (`slipX`).
7
9
  //
8
- // Marker-row placement (row + label box + left/right side) is decided
9
- // once by `roadmap-node.ts::packMarkerRow`. Date-pinned entities are
10
- // pre-packed before swimlanes run; after-only milestones get a
11
- // PROVISIONAL row=0 placement here at build time which the unified
12
- // re-pack in `RoadmapNode.place` overwrites with the final tick-order
13
- // bottom-first slot once every centerX is known.
14
- import { parseDate, propValue, propValues } from '../dsl-utils.js';
10
+ // Placement decides x, slip, slack arrows and overrun only (`MilestonePlacement`).
11
+ // The marker row and label box come from the final marker pack in
12
+ // finalize (`packMarkers`, f5, through `marker-band.ts::packMarkerRow`),
13
+ // which runs once every centerX is known and the canvas is final;
14
+ // `positionMilestones` then builds each `PositionedMilestone` from its
15
+ // placement and its row (`placeMarkers`, f6). An arrow that starts on a
16
+ // marker row (from an anchor or milestone predecessor) waits for those
17
+ // rows too: placement records the marker, `positionMilestones` reads its
18
+ // row.
19
+ import { formatIsoDate, parseIsoDate, propValue, propValues } from '../dsl-utils.js';
20
+ import { itemSlackAttachY } from '../item-port-geometry.js';
15
21
  import { resolveStyle } from '../style-resolution.js';
16
- import { MARKER_BOLD_WIDTH_FACTOR, MARKER_DIAMOND_RADIUS_PX, MARKER_LABEL_GAP_PX, MARKER_LABEL_HEIGHT_PX, } from './marker-geometry.js';
22
+ import { isOnWaveBoundary, WAVE_EDGE_TOLERANCE_PX } from '../wave-layout.js';
23
+ import { MARKER_DIAMOND_RADIUS_PX } from './marker-geometry.js';
17
24
  /**
18
- * Resolve each `after:` reference into a `MilestonePredecessor`.
19
- * Items use their VISUAL right edge as the slack source so the
20
- * arrow leaves the painted bar instead of landing in the inter-
21
- * column gutter; markers (anchors / other milestones) fall back
22
- * to their cut-line centerX. Refs whose target is unknown drop
25
+ * Resolve each `after:` reference into a `MilestonePredecessor`. Its
26
+ * `endX` is the reference's right edge in time (`entityRightEdges`, an
27
+ * item's duration end, a marker's cut-line x), where its slack line
28
+ * starts: a bar spans exactly its dates, so its end date is its edge
29
+ * (specs/true-width-layout.md §3.5). Refs whose target is unknown drop
23
30
  * silently — matches the legacy continue path.
24
31
  */
25
32
  export function collectMilestonePredecessors(refs, ctx) {
26
33
  const out = [];
27
34
  for (const ref of refs) {
28
- const visualRight = ctx.entityVisualRightX.get(ref);
29
- const x = visualRight ?? ctx.entityRightEdges.get(ref);
30
- if (x === undefined)
35
+ // Items attach off their FINAL box (see `item-port-geometry.ts`),
36
+ // so a bar that a row growth moved down still sources its arrow.
37
+ const item = ctx.placedItems.get(ref);
38
+ const endX = ctx.entityRightEdges.get(ref);
39
+ if (endX === undefined)
31
40
  continue;
32
- const y = ctx.itemSlackAttachY.get(ref) ?? ctx.entityMidpoints.get(ref)?.y ?? 0;
41
+ const y = item ? itemSlackAttachY(item, ctx.bandScale.bandwidth()) : undefined;
42
+ // A wave reads its seeded end `E_k` (logical, not inset), so a
43
+ // milestone bound by it sits exactly on the boundary.
44
+ if (!item && ctx.waves?.plan.index.has(ref)) {
45
+ out.push({ ref, endX, y, flowKey: `wave:${ref}`, wave: ref });
46
+ continue;
47
+ }
33
48
  // Markers don't share a flow with anything, so use their id
34
49
  // as a unique flow key — every marker stands on its own.
35
50
  const flowKey = ctx.itemFlowKey.get(ref) ?? `marker:${ref}`;
36
- out.push({ ref, x, y, flowKey });
51
+ if (!item && ctx.markerIds.has(ref)) {
52
+ out.push({ ref, endX, y, marker: true, flowKey });
53
+ continue;
54
+ }
55
+ out.push({ ref, endX, y, flowKey });
37
56
  }
38
57
  return out;
39
58
  }
@@ -50,23 +69,64 @@ export function lastPredecessorPerFlow(preds) {
50
69
  const m = new Map();
51
70
  for (const p of preds) {
52
71
  const existing = m.get(p.flowKey);
53
- if (!existing || p.x > existing.x)
72
+ if (!existing || p.endX > existing.endX)
54
73
  m.set(p.flowKey, p);
55
74
  }
56
75
  return Array.from(m.values());
57
76
  }
58
- function decideLabelBoxForCanvas(centerX, centerY, radius, title, fontSize, bold, chartLeftX, chartRightX) {
59
- const labelWidth = title.length * fontSize * 0.58 * (bold ? MARKER_BOLD_WIDTH_FACTOR : 1);
60
- const naturalRightX = centerX + radius + MARKER_LABEL_GAP_PX;
61
- const naturalLeftX = centerX - radius - MARKER_LABEL_GAP_PX - labelWidth;
62
- const fitsRight = naturalRightX + labelWidth <= chartRightX;
63
- const fitsLeft = naturalLeftX >= chartLeftX;
64
- const side = fitsRight ? 'right' : fitsLeft ? 'left' : 'right';
65
- const xLeft = side === 'right' ? naturalRightX : naturalLeftX;
66
- return {
67
- box: { x: xLeft, y: centerY - 4, width: labelWidth, height: MARKER_LABEL_HEIGHT_PX },
68
- side,
69
- };
77
+ /**
78
+ * Whether a marker predecessor sits on top of the milestone at `x`: their
79
+ * diamonds touch or overlap. It draws no arrow then, since the arrow would
80
+ * run between two diamonds that already meet.
81
+ */
82
+ function isOnTopOf(p, x) {
83
+ return Math.abs(x - p.endX) <= 2 * MARKER_DIAMOND_RADIUS_PX;
84
+ }
85
+ /**
86
+ * The slack arrow a non-binding predecessor of an after-only milestone at
87
+ * `maxEnd` draws, or null: it must end before the milestone and be an
88
+ * item or a marker clear of the milestone's diamond. A wave, a group and
89
+ * a parallel draw none.
90
+ */
91
+ function slackArrowStart(p, maxEnd) {
92
+ if (p.endX >= maxEnd || p.wave !== undefined)
93
+ return null;
94
+ if (p.y !== undefined)
95
+ return { x: p.endX, y: p.y };
96
+ if (p.marker && !isOnTopOf(p, maxEnd))
97
+ return { x: p.endX, marker: p.ref };
98
+ return null;
99
+ }
100
+ /**
101
+ * The predecessor a dated milestone slips to: the one that ends latest in
102
+ * time and is not a wave (an overrunning wave is taken separately, by
103
+ * `overrunningWave`).
104
+ */
105
+ export function latestArrowPredecessor(preds) {
106
+ let maxPred = null;
107
+ for (const p of preds) {
108
+ if (p.wave !== undefined)
109
+ continue;
110
+ if (!maxPred || p.endX > maxPred.endX)
111
+ maxPred = p;
112
+ }
113
+ return maxPred;
114
+ }
115
+ /**
116
+ * The wave predecessor that overruns a dated milestone at `x`: the
117
+ * latest-ending one whose end lies past `x` (by more than the boundary
118
+ * tolerance, so a wave ending on the date does not count). Ties keep the
119
+ * first listed.
120
+ */
121
+ function overrunningWave(preds, x) {
122
+ let latest;
123
+ for (const p of preds) {
124
+ if (p.wave === undefined || p.endX - x < WAVE_EDGE_TOLERANCE_PX)
125
+ continue;
126
+ if (!latest || p.endX > latest.endX)
127
+ latest = p;
128
+ }
129
+ return latest;
70
130
  }
71
131
  export class MilestoneNode {
72
132
  id;
@@ -79,56 +139,57 @@ export class MilestoneNode {
79
139
  * Returns null when the milestone is neither date-pinned nor has a
80
140
  * resolvable `after:` predecessor (skipped silently — matches the
81
141
  * legacy `buildMilestones` continue-paths).
142
+ *
143
+ * Writes the milestone's entity edges and midpoint; later milestones'
144
+ * `after:` references read the edges. The midpoint's y is an
145
+ * estimate: the pre-pack row of a dated milestone, the band's first
146
+ * row for an after-only one. Nothing reads it before f6 replaces it
147
+ * with the final pack's row, except f6's coverage trace, which
148
+ * reports a milestone whose row differs from it.
82
149
  */
83
150
  place(ctx) {
84
151
  const m = this.milestone;
85
152
  const style = resolveStyle('milestone', m.properties, ctx.styleCtx);
86
153
  const dateRaw = propValue(m.properties, 'date');
87
154
  const afterRaw = propValues(m.properties, 'after');
88
- const date = parseDate(dateRaw);
155
+ const date = parseIsoDate(dateRaw);
89
156
  const inRowY = ctx.timeline.markerRow.y;
90
157
  const radius = MARKER_DIAMOND_RADIUS_PX;
91
158
  const title = m.title ?? this.id;
92
159
  let centerX = null;
93
- let centerY = inRowY;
94
- let labelBox = null;
95
- let labelSide = 'right';
160
+ let estimatedCenterY = inRowY;
96
161
  let fixed = false;
97
162
  let slackArrows;
98
163
  let isOverrun = false;
164
+ let slipX;
165
+ let overrunByWave;
99
166
  if (date) {
100
167
  const x = ctx.scale.forwardWithinDomain(date);
101
168
  if (x === null)
102
169
  return null;
103
170
  centerX = x;
104
171
  fixed = true;
105
- const placement = ctx.markerRowPlacements.get(this.id);
106
- if (placement) {
107
- centerY = placement.centerY;
108
- labelBox = placement.labelBox;
109
- labelSide = placement.labelSide;
110
- }
172
+ const prePacked = ctx.markerRowPlacements.get(this.id);
173
+ if (prePacked)
174
+ estimatedCenterY = prePacked.centerY;
111
175
  // Date-pinned milestones whose `after:` predecessors finish
112
- // past the pinned date are flagged `isOverrun`; the latest
113
- // last-of-flow predecessor draws a single overrun arrow
114
- // pointing back from its visual right edge to the
115
- // milestone's column. Flow-dedupe avoids stacking redundant
116
- // arrows from sibling items in one chained flow.
176
+ // past the pinned date are flagged `isOverrun` and slip to the
177
+ // latest one's end: the diamond stays on the date, a second
178
+ // one and the cut line move to `slipX` (specs/rendering.md,
179
+ // Milestones). The wave-deadline idiom (specs/waves.md §5.3,
180
+ // Example 11) counts too: a wave listed in `after:` that ends
181
+ // past the date.
117
182
  const preds = collectMilestonePredecessors(afterRaw, ctx);
118
183
  const dedupedPreds = lastPredecessorPerFlow(preds);
119
- let maxPred = null;
120
- for (const p of dedupedPreds) {
121
- if (!maxPred || p.x > maxPred.x)
122
- maxPred = p;
123
- }
124
- if (maxPred && maxPred.x > x) {
184
+ const maxPred = latestArrowPredecessor(dedupedPreds);
185
+ const wave = overrunningWave(dedupedPreds, x);
186
+ overrunByWave = wave?.wave;
187
+ const landsAt = Math.max(maxPred && maxPred.endX > x ? maxPred.endX : x, wave?.endX ?? x);
188
+ if (landsAt > x) {
125
189
  isOverrun = true;
126
- slackArrows = [
127
- {
128
- x: maxPred.x,
129
- y: maxPred.y > 0 ? maxPred.y : centerY,
130
- },
131
- ];
190
+ // Two diamonds that would meet draw as one, on the date.
191
+ if (landsAt - x > 2 * MARKER_DIAMOND_RADIUS_PX)
192
+ slipX = landsAt;
132
193
  }
133
194
  }
134
195
  else if (afterRaw.length > 0) {
@@ -143,49 +204,29 @@ export class MilestoneNode {
143
204
  // last-of-flow arrow.
144
205
  const preds = collectMilestonePredecessors(afterRaw, ctx);
145
206
  const dedupedPreds = lastPredecessorPerFlow(preds);
146
- dedupedPreds.sort((a, b) => b.x - a.x);
147
- const maxEnd = dedupedPreds[0]?.x ?? ctx.timeline.originX;
207
+ dedupedPreds.sort((a, b) => b.endX - a.endX);
208
+ const maxEnd = dedupedPreds[0]?.endX ?? ctx.timeline.originX;
148
209
  centerX = maxEnd;
149
210
  fixed = false;
150
- // Provisional placement — RoadmapNode runs a unified
151
- // tick-order pack across all markers (date-pinned anchors,
152
- // date-pinned milestones, after-only milestones) once
153
- // everyone's centerX is known. That pass overwrites the
154
- // rowIndex / centerY / labelBox / labelSide we set here.
155
- const provisional = decideLabelBoxForCanvas(centerX, inRowY, radius, title, 10, true, ctx.timeline.box.x, ctx.chartRightX);
156
- centerY = inRowY;
157
- labelBox = provisional.box;
158
- labelSide = provisional.side;
159
- ctx.markerRowPlacements.set(this.id, {
160
- rowIndex: 0,
161
- centerY,
162
- labelBox,
163
- labelSide,
164
- });
165
211
  const arrows = [];
166
212
  for (let i = 1; i < dedupedPreds.length; i++) {
167
- const p = dedupedPreds[i];
168
- if (p.x < maxEnd && p.y > 0)
169
- arrows.push({ x: p.x, y: p.y });
213
+ const arrow = slackArrowStart(dedupedPreds[i], maxEnd);
214
+ if (arrow)
215
+ arrows.push(arrow);
170
216
  }
171
217
  if (arrows.length > 0)
172
218
  slackArrows = arrows;
173
219
  }
174
220
  if (centerX === null)
175
221
  return null;
176
- if (!labelBox) {
177
- const fallback = decideLabelBoxForCanvas(centerX, centerY, radius, title, 10, true, ctx.timeline.box.x, ctx.chartRightX);
178
- labelBox = fallback.box;
179
- labelSide = fallback.side;
180
- }
181
- const center = { x: centerX, y: centerY };
182
- ctx.entityLeftEdges.set(this.id, center.x);
183
- ctx.entityRightEdges.set(this.id, center.x);
184
- ctx.entityMidpoints.set(this.id, center);
185
- return {
222
+ const midpoint = { x: centerX, y: estimatedCenterY };
223
+ ctx.entityLeftEdges.set(this.id, midpoint.x);
224
+ ctx.entityRightEdges.set(this.id, midpoint.x);
225
+ ctx.entityMidpoints.set(this.id, midpoint);
226
+ const placement = {
186
227
  id: this.id,
187
228
  title,
188
- center,
229
+ x: centerX,
189
230
  radius,
190
231
  fixed,
191
232
  slackArrows,
@@ -193,17 +234,127 @@ export class MilestoneNode {
193
234
  style,
194
235
  cutTopY: ctx.chartTopY,
195
236
  cutBottomY: ctx.swimlaneBottomY,
196
- labelBox,
197
- labelSide,
198
237
  };
238
+ if (slipX !== undefined)
239
+ placement.slipX = slipX;
240
+ // On a wave boundary the boundary line carries the vertical. A
241
+ // slipped milestone's cut line sits at `slipX`; an overrun one that
242
+ // did not slip keeps its red cut line, so it never counts as on a
243
+ // boundary.
244
+ const cutX = slipX ?? centerX;
245
+ if (ctx.waves && (slipX !== undefined || !isOverrun) && isOnWaveBoundary(ctx.waves, cutX)) {
246
+ placement.onWaveBoundary = true;
247
+ }
248
+ if (overrunByWave !== undefined && date) {
249
+ placement.overrunByWave = overrunByWave;
250
+ placement.overrunDate = formatIsoDate(date);
251
+ }
252
+ // A date the axis hides keeps its own day as a tooltip
253
+ // (specs/working-calendar.md §7.4). Under `show` the day is drawn,
254
+ // and the milestone sits on it.
255
+ if (date && !ctx.scale.showsNonWorking && !ctx.calendar.isWorkingDay(date)) {
256
+ placement.hiddenDate = formatIsoDate(date);
257
+ }
258
+ return placement;
199
259
  }
200
260
  }
201
261
  export function buildMilestones(milestones, ctx) {
202
262
  const out = [];
203
263
  for (const [id, m] of milestones) {
204
- const positioned = new MilestoneNode(id, m).place(ctx);
205
- if (positioned)
206
- out.push(positioned);
264
+ const placement = new MilestoneNode(id, m).place(ctx);
265
+ if (placement)
266
+ out.push(placement);
267
+ }
268
+ return out;
269
+ }
270
+ /**
271
+ * Build the positioned milestones from their placements and the unified
272
+ * marker re-pack (`rows`, keyed by id), in placement order. The re-pack
273
+ * packs every placed milestone and anchor, so a missing row is an
274
+ * invariant violation and throws. An arrow that starts on a marker row
275
+ * takes that row's centre, already final; one from an item keeps its
276
+ * chart y. Optional keys stay omitted when the placement omits them.
277
+ */
278
+ export function positionMilestones(placements, rows) {
279
+ const rowOf = (id) => {
280
+ const row = rows.get(id);
281
+ if (!row) {
282
+ throw new Error(`layout: marker "${id}" has no marker-row placement`);
283
+ }
284
+ return row;
285
+ };
286
+ return placements.map((p) => {
287
+ const row = rowOf(p.id);
288
+ const positioned = {
289
+ id: p.id,
290
+ title: p.title,
291
+ center: { x: p.x, y: row.centerY },
292
+ radius: p.radius,
293
+ fixed: p.fixed,
294
+ slackArrows: p.slackArrows?.map((a) => 'y' in a ? { x: a.x, y: a.y } : { x: a.x, y: rowOf(a.marker).centerY }),
295
+ isOverrun: p.isOverrun,
296
+ style: p.style,
297
+ cutTopY: p.cutTopY,
298
+ cutBottomY: p.cutBottomY,
299
+ labelBox: row.labelBox,
300
+ labelSide: row.labelSide,
301
+ };
302
+ if (p.slipX !== undefined)
303
+ positioned.slip = { x: p.slipX };
304
+ if (p.onWaveBoundary)
305
+ positioned.onWaveBoundary = true;
306
+ if (p.overrunByWave !== undefined)
307
+ positioned.overrunByWave = p.overrunByWave;
308
+ if (p.overrunDate !== undefined)
309
+ positioned.overrunDate = p.overrunDate;
310
+ if (p.hiddenDate !== undefined)
311
+ positioned.hiddenDate = p.hiddenDate;
312
+ return positioned;
313
+ });
314
+ }
315
+ /**
316
+ * Collect slack-arrow corridors from the resolved milestones using the
317
+ * current entity-edge maps. The result mirrors what
318
+ * `MilestoneNode.place` would emit on `slackArrows`, so the row-packer
319
+ * and the renderer agree on every arrow's geometry.
320
+ *
321
+ * Each non-binding item predecessor (`x < maxEnd`) of an after-only
322
+ * milestone becomes one corridor. A date-pinned milestone draws no arrow
323
+ * (an overrun slips it, in the marker band), so it owns none. An arrow
324
+ * from a marker runs in the marker band, above the lanes, so it owns no
325
+ * corridor; nor does a wave predecessor, which draws no slack arrow (a
326
+ * floating milestone bound by a wave still sets `maxEnd`).
327
+ */
328
+ export function collectSlackCorridors(milestones, ctx) {
329
+ const out = [];
330
+ for (const [id, m] of milestones) {
331
+ // A dated milestone draws no arrow, so it owns no corridor.
332
+ if (parseIsoDate(propValue(m.properties, 'date')))
333
+ continue;
334
+ // Reuse MilestoneNode's helpers so the corridor set agrees
335
+ // exactly with the rendered slack-arrow set: same source x
336
+ // (visual edge for items / cut-line for markers), same
337
+ // attach y, and the same flow-dedupe rule that collapses
338
+ // chained predecessors to one arrow per flow.
339
+ const preds = collectMilestonePredecessors(propValues(m.properties, 'after'), ctx);
340
+ const dedupedPreds = lastPredecessorPerFlow(preds);
341
+ if (dedupedPreds.length === 0)
342
+ continue;
343
+ dedupedPreds.sort((a, b) => b.endX - a.endX);
344
+ const maxEnd = dedupedPreds[0].endX;
345
+ for (let i = 1; i < dedupedPreds.length; i++) {
346
+ const p = dedupedPreds[i];
347
+ const arrow = slackArrowStart(p, maxEnd);
348
+ if (arrow && 'y' in arrow) {
349
+ out.push({
350
+ xStart: p.endX,
351
+ xEnd: maxEnd,
352
+ y: arrow.y,
353
+ slackPredId: p.ref,
354
+ milestoneId: id,
355
+ });
356
+ }
357
+ }
207
358
  }
208
359
  return out;
209
360
  }
@@ -1 +1 @@
1
- {"version":3,"file":"milestone-node.js","sourceRoot":"","sources":["../../src/nodes/milestone-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"milestone-node.js","sourceRoot":"","sources":["../../src/nodes/milestone-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { LayoutContext } from '../layout-context.js';
2
+ import type { PositionedNowline } from '../types.js';
3
+ /**
4
+ * The now-line on the final scale. `chartRightX` is the final canvas right
5
+ * edge; a pill that would cross it flips to flag mode.
6
+ */
7
+ export declare function buildNowline(today: Date | undefined, ctx: LayoutContext, locale: string, chartRightX: number): PositionedNowline | null;
8
+ //# sourceMappingURL=nowline-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nowline-node.d.ts","sourceRoot":"","sources":["../../src/nodes/nowline-node.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAS1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;GAGG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,IAAI,GAAG,SAAS,EACvB,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GACpB,iBAAiB,GAAG,IAAI,CA8D1B"}
@@ -0,0 +1,74 @@
1
+ // The now-line (finalize step f12): the line at `today` on the final
2
+ // scale, with its pill in the reserved row above the tick panel.
3
+ import { localeStrings } from '../i18n.js';
4
+ import { resolveStyle } from '../style-resolution.js';
5
+ import { estimateTextWidth } from '../text-measure.js';
6
+ import { GUTTER_PX, NOW_PILL_LABEL_FONT_SIZE_PX, NOW_PILL_LABEL_INSET_X_PX, NOW_PILL_WIDTH_PX, } from '../themes/shared.js';
7
+ /**
8
+ * The now-line on the final scale. `chartRightX` is the final canvas right
9
+ * edge; a pill that would cross it flips to flag mode.
10
+ */
11
+ export function buildNowline(today, ctx, locale, chartRightX) {
12
+ if (!today)
13
+ return null;
14
+ const x = ctx.scale.forwardWithinDomain(today);
15
+ if (x === null)
16
+ return null;
17
+ // Pill row is the band reserved at the very top of the timeline area.
18
+ // The line drops from the bottom of the pill (top of the date headers)
19
+ // through any marker row and into the chart, so the pill and line stay
20
+ // visually connected.
21
+ const pillTopY = ctx.timeline.box.y;
22
+ const lineTopY = ctx.timeline.tickPanelY;
23
+ // Pill width is locale-aware: en-US's `'now'` (3 chars) fits the
24
+ // 36 px default trivially; longer strings like fr's `'maint.'`
25
+ // (6 chars) need a wider pill to avoid clipping. Floor at the
26
+ // default so en-US output stays byte-stable; grow when the
27
+ // measured label needs it. The 2× inset matches the renderer's
28
+ // flag-mode label inset (`NOW_PILL_LABEL_INSET_X_PX`) and gives
29
+ // the same visual padding to centered-mode strings.
30
+ const label = localeStrings(locale).nowLabel;
31
+ const labelTextWidth = estimateTextWidth(label, NOW_PILL_LABEL_FONT_SIZE_PX);
32
+ const pillWidth = Math.max(NOW_PILL_WIDTH_PX, Math.ceil(labelTextWidth + 2 * NOW_PILL_LABEL_INSET_X_PX));
33
+ // The "chart's left edge" the pill must clear is `chartLeftX` (in
34
+ // beside-mode, the right edge of the header card; in above-mode,
35
+ // the canvas left edge at x=0). originX = chartLeftX + GUTTER_PX,
36
+ // so we recover chartLeftX as `originX - GUTTER_PX`.
37
+ const chartLeftX = ctx.timeline.originX - GUTTER_PX;
38
+ const halfPill = pillWidth / 2;
39
+ let pillMode;
40
+ if (x - halfPill < chartLeftX) {
41
+ // Centered pill would intrude into the header card / past the
42
+ // canvas left edge — anchor the pill's LEFT side to the line
43
+ // and let it extend right into the chart.
44
+ pillMode = 'flag-right';
45
+ }
46
+ else if (x + halfPill > chartRightX) {
47
+ // Centered pill would clip past the canvas right edge — anchor
48
+ // the pill's RIGHT side to the line and let it extend left.
49
+ pillMode = 'flag-left';
50
+ }
51
+ else {
52
+ pillMode = 'center';
53
+ }
54
+ // Bottom-most Y the now-line should reach. When a mirrored bottom
55
+ // tick panel exists, thread the line through it (so the line ties
56
+ // the two date strips together visually). Otherwise stop at the
57
+ // last swimlane — never extend into the footnote area below.
58
+ const bottomTickPanelY = ctx.timeline.bottomTickPanelY;
59
+ const bottomTickPanelHeight = ctx.timeline.bottomTickPanelHeight ?? 0;
60
+ const lineBottomY = bottomTickPanelY !== undefined && bottomTickPanelHeight > 0
61
+ ? bottomTickPanelY + bottomTickPanelHeight
62
+ : ctx.swimlaneBottomY;
63
+ return {
64
+ x,
65
+ topY: lineTopY,
66
+ bottomY: lineBottomY,
67
+ pillTopY,
68
+ pillMode,
69
+ label,
70
+ pillWidth,
71
+ style: resolveStyle('item', [], ctx.styleCtx),
72
+ };
73
+ }
74
+ //# sourceMappingURL=nowline-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nowline-node.js","sourceRoot":"","sources":["../../src/nodes/nowline-node.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,iEAAiE;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACH,SAAS,EACT,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAG7B;;;GAGG;AACH,MAAM,UAAU,YAAY,CACxB,KAAuB,EACvB,GAAkB,EAClB,MAAc,EACd,WAAmB;IAEnB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,sEAAsE;IACtE,uEAAuE;IACvE,uEAAuE;IACvE,sBAAsB;IACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;IACzC,iEAAiE;IACjE,+DAA+D;IAC/D,8DAA8D;IAC9D,2DAA2D;IAC3D,+DAA+D;IAC/D,gEAAgE;IAChE,oDAAoD;IACpD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC;IAC7C,MAAM,cAAc,GAAG,iBAAiB,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACtB,iBAAiB,EACjB,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,yBAAyB,CAAC,CAC5D,CAAC;IACF,kEAAkE;IAClE,iEAAiE;IACjE,kEAAkE;IAClE,qDAAqD;IACrD,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC;IACpD,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC;IAC/B,IAAI,QAA+C,CAAC;IACpD,IAAI,CAAC,GAAG,QAAQ,GAAG,UAAU,EAAE,CAAC;QAC5B,8DAA8D;QAC9D,6DAA6D;QAC7D,0CAA0C;QAC1C,QAAQ,GAAG,YAAY,CAAC;IAC5B,CAAC;SAAM,IAAI,CAAC,GAAG,QAAQ,GAAG,WAAW,EAAE,CAAC;QACpC,+DAA+D;QAC/D,4DAA4D;QAC5D,QAAQ,GAAG,WAAW,CAAC;IAC3B,CAAC;SAAM,CAAC;QACJ,QAAQ,GAAG,QAAQ,CAAC;IACxB,CAAC;IACD,kEAAkE;IAClE,kEAAkE;IAClE,gEAAgE;IAChE,6DAA6D;IAC7D,MAAM,gBAAgB,GAAG,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IACvD,MAAM,qBAAqB,GAAG,GAAG,CAAC,QAAQ,CAAC,qBAAqB,IAAI,CAAC,CAAC;IACtE,MAAM,WAAW,GACb,gBAAgB,KAAK,SAAS,IAAI,qBAAqB,GAAG,CAAC;QACvD,CAAC,CAAC,gBAAgB,GAAG,qBAAqB;QAC1C,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9B,OAAO;QACH,CAAC;QACD,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,WAAW;QACpB,QAAQ;QACR,QAAQ;QACR,KAAK;QACL,SAAS;QACT,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;KAChD,CAAC;AACN,CAAC"}
@@ -1,20 +1,15 @@
1
- import type { GroupBlock, ItemDeclaration, ParallelBlock } from '@nowline/core';
2
- import type { LayoutContext, TrackCursor } from '../layout-context.js';
3
- import type { PositionedParallel, PositionedTrackChild } from '../types.js';
4
- export interface ParallelNodeDeps {
5
- sequenceOne: (child: ItemDeclaration | GroupBlock | ParallelBlock, cursor: TrackCursor, ctx: LayoutContext) => PositionedTrackChild;
6
- newCursor: (x: number, y: number) => TrackCursor;
7
- }
1
+ import type { ParallelBlock } from '@nowline/core';
2
+ import { type LayoutContext, type LayoutHelpers, type TrackCursor } from '../layout-context.js';
3
+ import type { PositionedParallel } from '../types.js';
8
4
  export declare class ParallelNode {
9
5
  readonly node: ParallelBlock;
10
- private readonly deps;
11
- constructor(node: ParallelBlock, deps: ParallelNodeDeps);
6
+ private readonly helpers;
7
+ constructor(node: ParallelBlock, helpers: LayoutHelpers);
12
8
  get id(): string;
13
9
  /**
14
10
  * Sequence children into stacked sub-tracks, advance the parent
15
- * `cursor` past the parallel's right edge plus
16
- * `TRACK_BLOCK_TAIL_GUTTER_PX` of breathing room, and return a
17
- * `PositionedParallel`.
11
+ * `cursor` to the parallel's end in time (the latest track end), and
12
+ * return a `PositionedParallel`.
18
13
  */
19
14
  place(cursor: TrackCursor, ctx: LayoutContext): PositionedParallel;
20
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"parallel-node.d.ts","sourceRoot":"","sources":["../../src/nodes/parallel-node.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGhF,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,KAAK,EAAe,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEzF,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,CACT,KAAK,EAAE,eAAe,GAAG,UAAU,GAAG,aAAa,EACnD,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,aAAa,KACjB,oBAAoB,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,WAAW,CAAC;CACpD;AAED,qBAAa,YAAY;aAED,IAAI,EAAE,aAAa;IAEnC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFL,IAAI,EAAE,aAAa,EAElB,IAAI,EAAE,gBAAgB;IAG3C,IAAI,EAAE,IAAI,MAAM,CAEf;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,GAAG,kBAAkB;CAqErE"}
1
+ {"version":3,"file":"parallel-node.d.ts","sourceRoot":"","sources":["../../src/nodes/parallel-node.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAA+B,aAAa,EAAE,MAAM,eAAe,CAAC;AAIhF,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,aAAa,EAElB,KAAK,WAAW,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAe,kBAAkB,EAAwB,MAAM,aAAa,CAAC;AAGzF,qBAAa,YAAY;aAED,IAAI,EAAE,aAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAF5B,YACoB,IAAI,EAAE,aAAa,EAClB,OAAO,EAAE,aAAa,EACvC;IAEJ,IAAI,EAAE,IAAI,MAAM,CAEf;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAsGjE;CACJ"}