@diagrammo/dgmo 0.46.0 → 0.48.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.
- package/dist/advanced.d.ts +3 -855
- package/dist/advanced.js +541 -70107
- package/dist/analyzer-UYKBXAKR.js +15 -0
- package/dist/auto.js +1 -1
- package/dist/auto.mjs +1 -1
- package/dist/block.js +83 -69417
- package/dist/calculator-LDYQCDDY.js +11 -0
- package/dist/charts-d3-QOZHKTCT.js +25 -0
- package/dist/chunk-2DXMZRWJ.js +800 -0
- package/dist/chunk-2LACINWN.js +786 -0
- package/dist/chunk-33LCUH4H.js +893 -0
- package/dist/chunk-3CIOJ5YJ.js +35 -0
- package/dist/chunk-3HDBAXF5.js +86 -0
- package/dist/chunk-3JLKYGBQ.js +290 -0
- package/dist/chunk-3MQQNXPD.js +415 -0
- package/dist/chunk-3R5POCTZ.js +967 -0
- package/dist/chunk-3SMGIJDD.js +112 -0
- package/dist/chunk-44CM72SQ.js +409 -0
- package/dist/chunk-4GRI7MEB.js +1604 -0
- package/dist/chunk-4OHACBGX.js +606 -0
- package/dist/chunk-5DH3KYFH.js +21 -0
- package/dist/chunk-5MLYVTYM.js +76 -0
- package/dist/chunk-5QXL4NYS.js +553 -0
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-6EK55ART.js +117 -0
- package/dist/chunk-6FZYCKXB.js +2065 -0
- package/dist/chunk-6HO5ZTXK.js +277 -0
- package/dist/chunk-6KFWC4CO.js +7 -0
- package/dist/chunk-6MTWIQVO.js +121 -0
- package/dist/chunk-6NYWYNBI.js +329 -0
- package/dist/chunk-6SM5NJQH.js +620 -0
- package/dist/chunk-725LDASD.js +422 -0
- package/dist/chunk-76OWZ3BA.js +130 -0
- package/{src/block/parser.ts → dist/chunk-7JEGTRLD.js} +100 -189
- package/dist/chunk-A44USUV7.js +923 -0
- package/dist/chunk-A4GOY3PE.js +25 -0
- package/dist/chunk-A4VFQH5G.js +251 -0
- package/dist/chunk-AELOBFW5.js +375 -0
- package/dist/chunk-AN2MOO5T.js +522 -0
- package/dist/chunk-BMR4CIEO.js +41 -0
- package/dist/chunk-BS7SV7C3.js +51 -0
- package/dist/chunk-BUPDIHML.js +613 -0
- package/dist/chunk-BUVJFRPY.js +887 -0
- package/dist/chunk-C3Z4DX3V.js +112 -0
- package/dist/chunk-CI2G3OEB.js +1818 -0
- package/dist/chunk-CKNVO24D.js +54 -0
- package/dist/chunk-CUVHQHZ7.js +391 -0
- package/dist/chunk-CXK4DZH3.js +114 -0
- package/dist/{editor.cjs → chunk-DKEPS5LH.js} +14 -225
- package/dist/chunk-DU7W62N5.js +487 -0
- package/dist/chunk-DZAQBW35.js +751 -0
- package/dist/chunk-EB6FPQUP.js +316 -0
- package/dist/chunk-EMS2SK26.js +376 -0
- package/dist/chunk-ERLBPDGU.js +510 -0
- package/dist/chunk-EVCVDTXE.js +732 -0
- package/dist/chunk-FCIIHT24.js +384 -0
- package/dist/chunk-FFUN5D66.js +97 -0
- package/dist/chunk-FITOLXSX.js +714 -0
- package/dist/chunk-FMDSF3OV.js +68 -0
- package/dist/chunk-FNB3PNGF.js +410 -0
- package/dist/chunk-G2H74XJZ.js +2104 -0
- package/dist/chunk-GMR5MFHJ.js +339 -0
- package/dist/chunk-H6PI3KJT.js +305 -0
- package/dist/chunk-I46X5VUA.js +59 -0
- package/dist/chunk-I5IGB56C.js +255 -0
- package/dist/chunk-IH6ZMVQ5.js +3950 -0
- package/dist/chunk-IJZFN3HM.js +463 -0
- package/dist/chunk-IPWPWM6R.js +3079 -0
- package/dist/chunk-IYULMRBE.js +23 -0
- package/dist/chunk-IZMRON6C.js +167 -0
- package/dist/chunk-J5FIXQRT.js +813 -0
- package/dist/chunk-JED6ZDEE.js +73 -0
- package/dist/chunk-JEUJOX5X.js +136 -0
- package/dist/chunk-JM4LEPY3.js +436 -0
- package/dist/chunk-L3UHP6TD.js +101 -0
- package/dist/chunk-L66GEFB6.js +524 -0
- package/dist/chunk-LIOHW36Z.js +469 -0
- package/dist/chunk-LP7EC4MI.js +16 -0
- package/dist/chunk-MITI6NOL.js +548 -0
- package/dist/chunk-MO5YHHMQ.js +168 -0
- package/dist/chunk-MZSBFAPJ.js +885 -0
- package/dist/chunk-NNAAJVBU.js +9 -0
- package/dist/chunk-NOTA6TEI.js +47 -0
- package/dist/chunk-NURGB5Z4.js +335 -0
- package/dist/chunk-NX4EQS3U.js +1062 -0
- package/dist/chunk-NXMESY4J.js +1 -0
- package/dist/chunk-OJR3MQYV.js +1458 -0
- package/dist/chunk-OURHMODR.js +454 -0
- package/dist/chunk-P235SVAH.js +1057 -0
- package/dist/chunk-P4RH4OSP.js +1038 -0
- package/dist/chunk-P6T66CCZ.js +226 -0
- package/dist/chunk-PBAHEPLQ.js +223 -0
- package/dist/chunk-PBHE5UG6.js +1530 -0
- package/dist/chunk-PDKUANDZ.js +35 -0
- package/dist/chunk-PWIHZ6NJ.js +296 -0
- package/{src/c4/layout.ts → dist/chunk-QEBUY5NY.js} +384 -1140
- package/dist/chunk-QLCCJEJI.js +253 -0
- package/dist/chunk-QOOUC2J5.js +52 -0
- package/dist/chunk-QYTPPDAO.js +402 -0
- package/dist/chunk-R3XI2VC7.js +801 -0
- package/dist/chunk-RCERWOJR.js +154 -0
- package/dist/chunk-RJE5JTVK.js +362 -0
- package/dist/chunk-RTLBSQ3G.js +1155 -0
- package/dist/chunk-RUNNI6VE.js +448 -0
- package/dist/chunk-RVMRZAPB.js +354 -0
- package/dist/chunk-RYEGFMUO.js +955 -0
- package/dist/chunk-RZCF2VVM.js +528 -0
- package/dist/chunk-SML67VPV.js +1025 -0
- package/dist/chunk-SQ7IY53Q.js +44 -0
- package/dist/chunk-SQAG3UXH.js +161 -0
- package/dist/chunk-SRTU6HMQ.js +1851 -0
- package/dist/chunk-T2OE3YQB.js +550 -0
- package/dist/chunk-T3UBLACL.js +299 -0
- package/dist/chunk-TLVIHFRO.js +296 -0
- package/dist/chunk-TYS6CSS5.js +52 -0
- package/dist/chunk-U6EQI3U6.js +130 -0
- package/dist/chunk-UJ4FJLBF.js +86 -0
- package/dist/chunk-ULOEATBZ.js +347 -0
- package/dist/chunk-UNCCZ3NU.js +127 -0
- package/dist/chunk-USZW2HHU.js +197 -0
- package/dist/chunk-UWN33VNX.js +1610 -0
- package/dist/chunk-UZ7EZW3B.js +40 -0
- package/dist/chunk-VOKGH627.js +37 -0
- package/dist/chunk-WBRZJOEC.js +204 -0
- package/dist/chunk-WCSOJFU3.js +380 -0
- package/dist/chunk-WCT3NYCV.js +160 -0
- package/dist/chunk-WVAJFAIA.js +529 -0
- package/dist/chunk-X5LCYCL5.js +394 -0
- package/dist/chunk-XAKEUMEJ.js +1256 -0
- package/dist/chunk-Y2ZE3MSG.js +590 -0
- package/dist/chunk-Y3J7VR52.js +646 -0
- package/dist/chunk-Y5QGVTVC.js +33 -0
- package/dist/chunk-YAA6IID3.js +548 -0
- package/dist/chunk-YGJTDXVR.js +692 -0
- package/{src/utils/time-ticks.ts → dist/chunk-YRYKTYMQ.js} +45 -112
- package/dist/chunk-YYVTBZZC.js +61 -0
- package/dist/chunk-Z5CGSFJB.js +647 -0
- package/{src/gantt/calculator.ts → dist/chunk-Z72XRXD4.js} +236 -428
- package/dist/chunk-ZGR7ULFJ.js +978 -0
- package/dist/chunk-ZJEL4H2R.js +851 -0
- package/dist/chunk-ZO27FGJS.js +554 -0
- package/dist/collapse-CLPJD2RL.js +11 -0
- package/dist/collapse-SLINJQW6.js +9 -0
- package/dist/collapse-ZWUFFCK2.js +9 -0
- package/dist/compute-G55RG53N.js +8 -0
- package/dist/dgmo-router-DZCIDUO5.js +73 -0
- package/dist/dimensions-J3FHIMJ6.js +22 -0
- package/dist/element.js +1 -1
- package/dist/element.mjs +1 -1
- package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
- package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
- package/dist/index.d.ts +3 -469
- package/dist/index.js +137 -69685
- package/dist/layout-46N4JJYK.js +17 -0
- package/dist/layout-5RA6QWR6.js +26 -0
- package/dist/layout-5T6RH5M6.js +14 -0
- package/dist/layout-7QXCNOVS.js +13 -0
- package/dist/layout-EE6GE46Y.js +17 -0
- package/dist/layout-G23F7LDH.js +9 -0
- package/dist/layout-HRBZPFCN.js +23 -0
- package/dist/layout-HWDSRX5E.js +20 -0
- package/dist/layout-HYZPWAK5.js +18 -0
- package/dist/layout-N76NR4ZO.js +19 -0
- package/dist/layout-OB3RI63S.js +14 -0
- package/dist/layout-S2QBYSK2.js +15 -0
- package/dist/layout-UM5F4DJB.js +15 -0
- package/dist/layout-search-OYV77HHS.js +1655 -0
- package/dist/load-data-EHDDZ5ZS.js +8 -0
- package/dist/palettes-PRJ2RI6D.js +56 -0
- package/dist/parser-2MFP2H2E.js +11 -0
- package/dist/parser-3STE62GB.js +21 -0
- package/dist/parser-4FL2CMDG.js +18 -0
- package/dist/parser-4OGOBJJ4.js +13 -0
- package/dist/parser-6BTRLKRZ.js +15 -0
- package/dist/parser-AQETEVRW.js +21 -0
- package/dist/parser-CFZD5IBL.js +12 -0
- package/dist/parser-FUSKFGZN.js +16 -0
- package/dist/parser-I6KXEYFK.js +13 -0
- package/dist/parser-IXSZZQHY.js +18 -0
- package/dist/parser-JAL2HD4I.js +13 -0
- package/dist/parser-KNSQSKQO.js +20 -0
- package/dist/parser-N5O4IHUN.js +13 -0
- package/dist/parser-NGU3ETO6.js +16 -0
- package/dist/parser-NRAI6O25.js +19 -0
- package/dist/parser-O5J4VBII.js +11 -0
- package/dist/parser-OV7NOBW6.js +21 -0
- package/dist/parser-PQ3POX45.js +23 -0
- package/dist/parser-TFZFBVWN.js +11 -0
- package/dist/parser-TRTHDFPP.js +18 -0
- package/dist/parser-VQP2UJ6W.js +11 -0
- package/dist/parser-XDVELHRK.js +13 -0
- package/dist/parser-XKRP7QKP.js +11 -0
- package/dist/parser-Y6WTBU76.js +14 -0
- package/dist/parser-ZSDPZYQP.js +12 -0
- package/dist/renderer-2XQQQ6QR.js +28 -0
- package/dist/renderer-5NDVNDAZ.js +26 -0
- package/dist/renderer-6EEZHMH4.js +26 -0
- package/dist/renderer-6W5462RB.js +43 -0
- package/dist/renderer-7MVLWWQD.js +22 -0
- package/dist/renderer-AWWAF6XD.js +33 -0
- package/dist/renderer-BYCNMBF7.js +34 -0
- package/dist/renderer-CLJHQPBJ.js +29 -0
- package/dist/renderer-GHPZMFU2.js +15 -0
- package/dist/renderer-JGBKUCZD.js +16 -0
- package/dist/renderer-KQB7UGDS.js +19 -0
- package/dist/renderer-PGX2TKVS.js +24 -0
- package/dist/renderer-QIWVHWZO.js +15 -0
- package/dist/renderer-RPOA5YPZ.js +35 -0
- package/dist/renderer-SMIBCRVB.js +24 -0
- package/dist/renderer-T7YKC5VP.js +28 -0
- package/dist/renderer-TOCOVLHS.js +37 -0
- package/dist/renderer-UWA5XS74.js +39 -0
- package/dist/renderer-VACVQYML.js +25 -0
- package/dist/renderer-W4M6QLIJ.js +37 -0
- package/dist/renderer-WZRREQ2P.js +23 -0
- package/dist/renderer-YY2OSF6E.js +27 -0
- package/dist/renderer-Z7I3W2PP.js +24 -0
- package/dist/renderer-ZGNTUWC4.js +22 -0
- package/dist/renderer-ZTR3DER3.js +19 -0
- package/dist/renderer-radial-C32GPJQ7.js +21 -0
- package/dist/resolver-NOAA7ID7.js +13 -0
- package/dist/state-collapse-HCGD6IVJ.js +8 -0
- package/dist/state-parser-Z2V23ATR.js +18 -0
- package/dist/state-renderer-RFYHSP4K.js +34 -0
- package/dist/themes-1-CuKpeH.d.ts +908 -0
- package/package.json +19 -70
- package/dist/advanced.cjs +0 -71648
- package/dist/advanced.d.cts +0 -6571
- package/dist/auto.cjs +0 -70648
- package/dist/auto.d.cts +0 -54
- package/dist/block.cjs +0 -70208
- package/dist/block.d.cts +0 -115
- package/dist/editor.d.cts +0 -26
- package/dist/element.cjs +0 -70530
- package/dist/element.d.cts +0 -62
- package/dist/highlight.cjs +0 -852
- package/dist/highlight.d.cts +0 -49
- package/dist/index.cjs +0 -70491
- package/dist/index.d.cts +0 -626
- package/dist/pert.cjs +0 -325
- package/dist/pert.d.cts +0 -559
- package/src/advanced.ts +0 -873
- package/src/arc/parser.ts +0 -15
- package/src/arc/renderer.ts +0 -633
- package/src/auto/index.ts +0 -621
- package/src/auto/shared.ts +0 -370
- package/src/auto/styles.ts +0 -73
- package/src/block/layout.ts +0 -198
- package/src/block/renderer.ts +0 -484
- package/src/block/types.ts +0 -67
- package/src/boxes-and-lines/collapse.ts +0 -96
- package/src/boxes-and-lines/focus.ts +0 -257
- package/src/boxes-and-lines/label-placement.ts +0 -339
- package/src/boxes-and-lines/layout-grouped.ts +0 -912
- package/src/boxes-and-lines/layout-layered.ts +0 -722
- package/src/boxes-and-lines/layout-search.ts +0 -1678
- package/src/boxes-and-lines/layout.ts +0 -398
- package/src/boxes-and-lines/parser.ts +0 -1181
- package/src/boxes-and-lines/renderer.ts +0 -1465
- package/src/boxes-and-lines/types.ts +0 -66
- package/src/c4/parser.ts +0 -1158
- package/src/c4/renderer.ts +0 -2008
- package/src/c4/types.ts +0 -89
- package/src/chart-type-registry.ts +0 -529
- package/src/chart-types.ts +0 -225
- package/src/chart.ts +0 -685
- package/src/charts-d3/bar.ts +0 -338
- package/src/charts-d3/chord.ts +0 -140
- package/src/charts-d3/function.ts +0 -147
- package/src/charts-d3/funnel.ts +0 -104
- package/src/charts-d3/heatmap.ts +0 -145
- package/src/charts-d3/index.ts +0 -337
- package/src/charts-d3/interactions.ts +0 -477
- package/src/charts-d3/line.ts +0 -344
- package/src/charts-d3/mount.ts +0 -151
- package/src/charts-d3/pie.ts +0 -117
- package/src/charts-d3/polar.ts +0 -89
- package/src/charts-d3/radar.ts +0 -0
- package/src/charts-d3/sankey.ts +0 -0
- package/src/charts-d3/scatter.ts +0 -185
- package/src/charts-d3/shared.ts +0 -208
- package/src/class/layout.ts +0 -326
- package/src/class/parser.ts +0 -635
- package/src/class/renderer.ts +0 -793
- package/src/class/types.ts +0 -58
- package/src/cli-banner.ts +0 -106
- package/src/cli.ts +0 -1080
- package/src/colors-diagnostics.ts +0 -35
- package/src/colors.ts +0 -379
- package/src/completion-types.ts +0 -27
- package/src/completion.ts +0 -2668
- package/src/cycle/layout.ts +0 -1026
- package/src/cycle/parser.ts +0 -387
- package/src/cycle/renderer.ts +0 -653
- package/src/cycle/types.ts +0 -101
- package/src/d3.ts +0 -1434
- package/src/data-chart-parser.ts +0 -1007
- package/src/dgmo-router.ts +0 -296
- package/src/diagnostics-registry.ts +0 -108
- package/src/diagnostics.ts +0 -0
- package/src/dimensions.ts +0 -20
- package/src/directives-registry.ts +0 -396
- package/src/editor/dgmo.grammar +0 -76
- package/src/editor/dgmo.grammar.d.ts +0 -2
- package/src/editor/dgmo.grammar.js +0 -18
- package/src/editor/dgmo.grammar.terms.d.ts +0 -5
- package/src/editor/dgmo.grammar.terms.js +0 -35
- package/src/editor/highlight-api.ts +0 -596
- package/src/editor/highlight.ts +0 -36
- package/src/editor/index.ts +0 -27
- package/src/editor/keywords.ts +0 -128
- package/src/editor/tokens.ts +0 -30
- package/src/element/index.ts +0 -432
- package/src/embed/css.ts +0 -312
- package/src/embed/escape.ts +0 -15
- package/src/embed/index.ts +0 -280
- package/src/er/classify.ts +0 -228
- package/src/er/layout.ts +0 -530
- package/src/er/parser.ts +0 -750
- package/src/er/renderer.ts +0 -725
- package/src/er/types.ts +0 -52
- package/src/error-card.ts +0 -269
- package/src/event-line/diagnostics.ts +0 -117
- package/src/event-line/parser.ts +0 -643
- package/src/event-line/renderer.ts +0 -1742
- package/src/event-line/types.ts +0 -74
- package/src/fonts.ts +0 -3
- package/src/gantt/parser.ts +0 -1641
- package/src/gantt/renderer.ts +0 -3787
- package/src/gantt/resolver.ts +0 -172
- package/src/gantt/types.ts +0 -206
- package/src/graph/diagnostics.ts +0 -64
- package/src/graph/edge-spline.ts +0 -29
- package/src/graph/flowchart-parser.ts +0 -759
- package/src/graph/flowchart-renderer.ts +0 -817
- package/src/graph/layout.ts +0 -472
- package/src/graph/notes.ts +0 -21
- package/src/graph/state-collapse.ts +0 -78
- package/src/graph/state-parser.ts +0 -574
- package/src/graph/state-renderer.ts +0 -653
- package/src/graph/types.ts +0 -65
- package/src/index.ts +0 -261
- package/src/infra/compute.ts +0 -1385
- package/src/infra/layout.ts +0 -888
- package/src/infra/parser.ts +0 -1234
- package/src/infra/renderer.ts +0 -2534
- package/src/infra/roles.ts +0 -75
- package/src/infra/types.ts +0 -216
- package/src/infra/validation.ts +0 -201
- package/src/journey-map/layout.ts +0 -490
- package/src/journey-map/parser.ts +0 -557
- package/src/journey-map/renderer.ts +0 -1580
- package/src/journey-map/types.ts +0 -47
- package/src/kanban/mutations.ts +0 -175
- package/src/kanban/parser.ts +0 -509
- package/src/kanban/renderer.ts +0 -1449
- package/src/kanban/types.ts +0 -39
- package/src/label-layout.ts +0 -368
- package/src/map/colorize.ts +0 -54
- package/src/map/completion.ts +0 -316
- package/src/map/context-labels.ts +0 -609
- package/src/map/data/PROVENANCE.json +0 -1
- package/src/map/data/README.md +0 -40
- package/src/map/data/airport-collisions.json +0 -1
- package/src/map/data/airports.json +0 -1
- package/src/map/data/gazetteer.json +0 -1
- package/src/map/data/lakes.json +0 -1
- package/src/map/data/mountain-ranges.json +0 -1
- package/src/map/data/na-lakes.json +0 -1
- package/src/map/data/na-land.json +0 -1
- package/src/map/data/region-names.json +0 -1
- package/src/map/data/rivers.json +0 -1
- package/src/map/data/types.ts +0 -121
- package/src/map/data/us-states.json +0 -1
- package/src/map/data/water-bodies.json +0 -1
- package/src/map/data/world-coarse.json +0 -1
- package/src/map/data/world-detail.json +0 -1
- package/src/map/diagnostics.ts +0 -134
- package/src/map/dimensions.ts +0 -150
- package/src/map/geo-query.ts +0 -295
- package/src/map/geo.ts +0 -438
- package/src/map/invert.ts +0 -111
- package/src/map/layout.ts +0 -5069
- package/src/map/legend-band.ts +0 -127
- package/src/map/load-data.ts +0 -186
- package/src/map/parser.ts +0 -783
- package/src/map/renderer.ts +0 -1445
- package/src/map/resolved-types.ts +0 -160
- package/src/map/resolver.ts +0 -1146
- package/src/map/types.ts +0 -194
- package/src/mindmap/collapse.ts +0 -67
- package/src/mindmap/layout.ts +0 -649
- package/src/mindmap/parser.ts +0 -430
- package/src/mindmap/renderer.ts +0 -637
- package/src/mindmap/text-wrap.ts +0 -218
- package/src/mindmap/types.ts +0 -56
- package/src/org/collapse.ts +0 -151
- package/src/org/layout.ts +0 -1262
- package/src/org/parser.ts +0 -519
- package/src/org/renderer.ts +0 -866
- package/src/org/resolver.ts +0 -636
- package/src/palettes/atlas.ts +0 -77
- package/src/palettes/blueprint.ts +0 -73
- package/src/palettes/catppuccin.ts +0 -84
- package/src/palettes/color-utils.ts +0 -443
- package/src/palettes/index.ts +0 -67
- package/src/palettes/nord.ts +0 -67
- package/src/palettes/registry.ts +0 -114
- package/src/palettes/slate.ts +0 -73
- package/src/palettes/tidewater.ts +0 -73
- package/src/palettes/tokyo-night.ts +0 -86
- package/src/palettes/types.ts +0 -88
- package/src/pert/analyzer.ts +0 -1183
- package/src/pert/diagnostics.ts +0 -110
- package/src/pert/index.ts +0 -43
- package/src/pert/internal.ts +0 -252
- package/src/pert/layout.ts +0 -971
- package/src/pert/monte-carlo.ts +0 -446
- package/src/pert/parser.ts +0 -1606
- package/src/pert/renderer.ts +0 -4009
- package/src/pert/share-normalize.ts +0 -62
- package/src/pert/types.ts +0 -604
- package/src/pyramid/parser.ts +0 -185
- package/src/pyramid/renderer.ts +0 -768
- package/src/pyramid/types.ts +0 -28
- package/src/quadrant/parser.ts +0 -18
- package/src/quadrant/renderer.ts +0 -638
- package/src/raci/diagnostics.ts +0 -213
- package/src/raci/index.ts +0 -23
- package/src/raci/mutations.ts +0 -321
- package/src/raci/parser.ts +0 -699
- package/src/raci/renderer.ts +0 -1627
- package/src/raci/types.ts +0 -82
- package/src/raci/variants.ts +0 -320
- package/src/render.ts +0 -268
- package/src/ring/parser.ts +0 -212
- package/src/ring/renderer.ts +0 -490
- package/src/ring/types.ts +0 -27
- package/src/sequence/collapse.ts +0 -174
- package/src/sequence/parser.ts +0 -1596
- package/src/sequence/participant-inference.ts +0 -152
- package/src/sequence/renderer.ts +0 -3168
- package/src/sequence/tag-resolution.ts +0 -164
- package/src/sharing.ts +0 -211
- package/src/sitemap/collapse.ts +0 -100
- package/src/sitemap/layout.ts +0 -925
- package/src/sitemap/parser.ts +0 -755
- package/src/sitemap/renderer.ts +0 -828
- package/src/sitemap/types.ts +0 -42
- package/src/slope/parser.ts +0 -18
- package/src/slope/renderer.ts +0 -378
- package/src/swimlane/diagnostics.ts +0 -94
- package/src/swimlane/layout.ts +0 -597
- package/src/swimlane/parser.ts +0 -613
- package/src/swimlane/renderer.ts +0 -681
- package/src/swimlane/types.ts +0 -151
- package/src/tech-radar/interactive.ts +0 -1129
- package/src/tech-radar/layout.ts +0 -197
- package/src/tech-radar/parser.ts +0 -436
- package/src/tech-radar/renderer.ts +0 -1239
- package/src/tech-radar/shared.ts +0 -151
- package/src/tech-radar/types.ts +0 -86
- package/src/themes.ts +0 -22
- package/src/timeline/parser.ts +0 -472
- package/src/timeline/renderer.ts +0 -3024
- package/src/timeline/types.ts +0 -33
- package/src/timeline/viz-parser.ts +0 -21
- package/src/treemap/diagnostics.ts +0 -62
- package/src/treemap/layout-radial.ts +0 -233
- package/src/treemap/layout.ts +0 -189
- package/src/treemap/parser.ts +0 -463
- package/src/treemap/renderer-radial.ts +0 -438
- package/src/treemap/renderer.ts +0 -572
- package/src/treemap/treemap-shared.ts +0 -309
- package/src/treemap/types.ts +0 -60
- package/src/utils/arrow-markers.ts +0 -51
- package/src/utils/arrows-diagnostics.ts +0 -62
- package/src/utils/arrows.ts +0 -227
- package/src/utils/brand.ts +0 -61
- package/src/utils/card.ts +0 -183
- package/src/utils/collapse-engine/tree-edges.ts +0 -115
- package/src/utils/collapse-engine/tree.ts +0 -117
- package/src/utils/d3-helpers.ts +0 -219
- package/src/utils/d3-types.ts +0 -9
- package/src/utils/description-helpers.ts +0 -38
- package/src/utils/duration.ts +0 -312
- package/src/utils/export-container.ts +0 -41
- package/src/utils/expr-eval.ts +0 -27
- package/src/utils/fit-canvas.ts +0 -64
- package/src/utils/hover-styles.ts +0 -673
- package/src/utils/inline-markdown.ts +0 -96
- package/src/utils/legend-constants.ts +0 -48
- package/src/utils/legend-d3.ts +0 -618
- package/src/utils/legend-integration.ts +0 -107
- package/src/utils/legend-layout.ts +0 -776
- package/src/utils/legend-svg.ts +0 -214
- package/src/utils/legend-types.ts +0 -272
- package/src/utils/name-normalize.ts +0 -163
- package/src/utils/note-box/constants.ts +0 -25
- package/src/utils/note-box/index.ts +0 -11
- package/src/utils/note-box/metrics.ts +0 -90
- package/src/utils/note-box/svg.ts +0 -331
- package/src/utils/notes/bounds.ts +0 -30
- package/src/utils/notes/build.ts +0 -131
- package/src/utils/notes/index.ts +0 -18
- package/src/utils/notes/model.ts +0 -19
- package/src/utils/notes/parse.ts +0 -131
- package/src/utils/notes/place.ts +0 -177
- package/src/utils/notes/resolve.ts +0 -88
- package/src/utils/number-format.ts +0 -36
- package/src/utils/parsing.ts +0 -953
- package/src/utils/reserved-key-registry.ts +0 -239
- package/src/utils/safe-href.ts +0 -38
- package/src/utils/scaling.ts +0 -97
- package/src/utils/svg-embed.ts +0 -251
- package/src/utils/tag-groups.ts +0 -607
- package/src/utils/text-measure.ts +0 -122
- package/src/utils/title-constants.ts +0 -24
- package/src/utils/visual-conventions.ts +0 -61
- package/src/utils/wrapped-desc.ts +0 -87
- package/src/venn/parser.ts +0 -18
- package/src/venn/renderer.ts +0 -1047
- package/src/version-control/diagnostics.ts +0 -67
- package/src/version-control/parser.ts +0 -544
- package/src/version-control/renderer.ts +0 -724
- package/src/version-control/types.ts +0 -100
- package/src/visualizations/parse.ts +0 -1560
- package/src/visualizations/types.ts +0 -262
- package/src/wireframe/layout.ts +0 -479
- package/src/wireframe/parser.ts +0 -1114
- package/src/wireframe/renderer.ts +0 -1318
- package/src/wireframe/types.ts +0 -110
- package/src/wordcloud/parser.ts +0 -18
- package/src/wordcloud/renderer.ts +0 -357
|
@@ -1,56 +1,103 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Gantt Schedule Calculator
|
|
3
|
-
// ============================================================
|
|
4
|
-
//
|
|
5
|
-
// Takes a ParsedGantt and resolves all tasks to concrete start/end dates.
|
|
6
|
-
// Algorithm:
|
|
7
|
-
// 1. Flatten task tree, build dependency graph
|
|
8
|
-
// 2. Topological sort with cycle detection
|
|
9
|
-
// 3. Forward pass: resolve dates using universal max rule
|
|
10
|
-
// 4. (Optional) Critical path: backward pass to find zero-slack chain
|
|
11
|
-
|
|
12
|
-
import { makeDgmoError } from '../diagnostics';
|
|
13
|
-
import type { DgmoError } from '../diagnostics';
|
|
14
|
-
import type {
|
|
15
|
-
ParsedGantt,
|
|
16
|
-
GanttNode,
|
|
17
|
-
GanttTask,
|
|
18
|
-
GanttGroup,
|
|
19
|
-
GanttHolidays,
|
|
20
|
-
GanttOptions,
|
|
21
|
-
Duration,
|
|
22
|
-
ResolvedSchedule,
|
|
23
|
-
ResolvedSprint,
|
|
24
|
-
ResolvedGroup,
|
|
25
|
-
Offset,
|
|
26
|
-
} from './types';
|
|
27
|
-
import { collectTasks, resolveTaskName, isResolverError } from './resolver';
|
|
28
1
|
import {
|
|
29
2
|
addGanttDuration,
|
|
30
3
|
buildHolidaySet,
|
|
31
|
-
parseGanttDate
|
|
32
|
-
} from
|
|
33
|
-
|
|
34
|
-
|
|
4
|
+
parseGanttDate
|
|
5
|
+
} from "./chunk-USZW2HHU.js";
|
|
6
|
+
import {
|
|
7
|
+
normalizeName
|
|
8
|
+
} from "./chunk-NOTA6TEI.js";
|
|
9
|
+
import {
|
|
10
|
+
makeDgmoError
|
|
11
|
+
} from "./chunk-CXK4DZH3.js";
|
|
35
12
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
// src/gantt/resolver.ts
|
|
14
|
+
function isResolverError(r) {
|
|
15
|
+
return "kind" in r;
|
|
16
|
+
}
|
|
17
|
+
function collectTasks(nodes) {
|
|
18
|
+
const tasks = [];
|
|
19
|
+
function walk(children) {
|
|
20
|
+
for (const node of children) {
|
|
21
|
+
if (node.kind === "task") {
|
|
22
|
+
tasks.push(node);
|
|
23
|
+
} else if (node.kind === "group" || node.kind === "parallel") {
|
|
24
|
+
walk(node.children);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
walk(nodes);
|
|
29
|
+
return tasks;
|
|
30
|
+
}
|
|
31
|
+
var BRACKET_GROUP_RE = /^\[(.+?)\]\.(.+)$/;
|
|
32
|
+
function ambiguousTaskMessage(trimmed, suggestions) {
|
|
33
|
+
return `Multiple tasks match "${trimmed}". Did you mean ${suggestions.map((s) => `\`${s}\``).join(" or ")}?`;
|
|
34
|
+
}
|
|
35
|
+
function resolveTaskName(name, allTasks) {
|
|
36
|
+
let trimmed = name.trim();
|
|
37
|
+
const bracketMatch = trimmed.match(BRACKET_GROUP_RE);
|
|
38
|
+
if (bracketMatch) {
|
|
39
|
+
trimmed = `${bracketMatch[1]}.${bracketMatch[2]}`;
|
|
40
|
+
}
|
|
41
|
+
const normTrimmed = normalizeName(trimmed);
|
|
42
|
+
const exactMatches = allTasks.filter(
|
|
43
|
+
(t) => normalizeName(t.label) === normTrimmed
|
|
44
|
+
);
|
|
45
|
+
if (exactMatches.length === 1) {
|
|
46
|
+
return { task: exactMatches[0] };
|
|
47
|
+
}
|
|
48
|
+
if (exactMatches.length > 1) {
|
|
49
|
+
const suggestions = exactMatches.map(
|
|
50
|
+
(t) => t.groupPath.length > 0 ? `${t.groupPath.join(".")}.${t.label}` : t.label
|
|
51
|
+
);
|
|
52
|
+
return {
|
|
53
|
+
kind: "ambiguous",
|
|
54
|
+
message: ambiguousTaskMessage(trimmed, suggestions)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const lastDotIdx = trimmed.lastIndexOf(".");
|
|
58
|
+
if (lastDotIdx > 0) {
|
|
59
|
+
const groupPrefix = trimmed.substring(0, lastDotIdx);
|
|
60
|
+
const taskLabel = trimmed.substring(lastDotIdx + 1);
|
|
61
|
+
const normTaskLabel = normalizeName(taskLabel);
|
|
62
|
+
const matches = allTasks.filter((t) => {
|
|
63
|
+
if (normalizeName(t.label) !== normTaskLabel) return false;
|
|
64
|
+
return matchesGroupPath(t.groupPath, groupPrefix);
|
|
65
|
+
});
|
|
66
|
+
if (matches.length === 1) {
|
|
67
|
+
return { task: matches[0] };
|
|
68
|
+
}
|
|
69
|
+
if (matches.length > 1) {
|
|
70
|
+
const suggestions = matches.map(
|
|
71
|
+
(t) => t.groupPath.length > 0 ? `${t.groupPath.join(".")}.${t.label}` : t.label
|
|
72
|
+
);
|
|
73
|
+
return {
|
|
74
|
+
kind: "ambiguous",
|
|
75
|
+
message: ambiguousTaskMessage(trimmed, suggestions)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
kind: "not_found",
|
|
81
|
+
message: `No task found with name "${trimmed}".`
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function matchesGroupPath(groupPath, prefix) {
|
|
85
|
+
const normPrefix = normalizeName(prefix);
|
|
86
|
+
if (!prefix.includes(".")) {
|
|
87
|
+
return groupPath.some((g) => normalizeName(g) === normPrefix);
|
|
88
|
+
}
|
|
89
|
+
const pathStr = groupPath.map((g) => normalizeName(g)).join(".");
|
|
90
|
+
return pathStr === normPrefix || pathStr.endsWith("." + normPrefix) || pathStr.startsWith(normPrefix + ".") || pathStr.includes("." + normPrefix + ".");
|
|
43
91
|
}
|
|
44
92
|
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
const result: ResolvedSchedule = {
|
|
93
|
+
// src/gantt/calculator.ts
|
|
94
|
+
function calculateSchedule(parsed) {
|
|
95
|
+
const diagnostics = [...parsed.diagnostics];
|
|
96
|
+
const result = {
|
|
50
97
|
tasks: [],
|
|
51
98
|
groups: [],
|
|
52
|
-
startDate: new Date(),
|
|
53
|
-
endDate: new Date(),
|
|
99
|
+
startDate: /* @__PURE__ */ new Date(),
|
|
100
|
+
endDate: /* @__PURE__ */ new Date(),
|
|
54
101
|
holidays: parsed.holidays,
|
|
55
102
|
tagGroups: parsed.tagGroups.slice(),
|
|
56
103
|
eras: [],
|
|
@@ -58,127 +105,86 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
58
105
|
sprints: [],
|
|
59
106
|
options: parsed.options,
|
|
60
107
|
diagnostics,
|
|
61
|
-
error: parsed.error
|
|
108
|
+
error: parsed.error
|
|
62
109
|
};
|
|
63
|
-
|
|
64
110
|
if (parsed.error) return result;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
diagnostics.push(makeDgmoError(line, message, 'warning'));
|
|
111
|
+
const warn = (line, message) => {
|
|
112
|
+
diagnostics.push(makeDgmoError(line, message, "warning"));
|
|
68
113
|
};
|
|
69
|
-
|
|
70
|
-
// ── Build holiday set ───────────────────────────────────
|
|
71
|
-
|
|
72
114
|
const holidaySet = buildHolidaySet(parsed.holidays);
|
|
73
|
-
|
|
74
|
-
// ── Determine project start ─────────────────────────────
|
|
75
|
-
|
|
76
|
-
let projectStart: Date;
|
|
115
|
+
let projectStart;
|
|
77
116
|
if (parsed.options.start) {
|
|
78
117
|
projectStart = parseGanttDate(parsed.options.start);
|
|
79
118
|
} else {
|
|
80
|
-
|
|
81
|
-
projectStart = new Date(2000, 0, 1);
|
|
119
|
+
projectStart = new Date(2e3, 0, 1);
|
|
82
120
|
}
|
|
83
|
-
|
|
84
|
-
// ── Resolve offset-based eras and markers to absolute dates ──
|
|
85
|
-
|
|
86
121
|
result.eras = parsed.eras.map((era) => {
|
|
87
122
|
if (era.offsetStart && era.offsetEnd) {
|
|
88
123
|
const start = addGanttDuration(
|
|
89
124
|
projectStart,
|
|
90
125
|
era.offsetStart.duration,
|
|
91
126
|
parsed.holidays,
|
|
92
|
-
new Set(),
|
|
127
|
+
/* @__PURE__ */ new Set(),
|
|
93
128
|
era.offsetStart.direction
|
|
94
129
|
);
|
|
95
130
|
const end = addGanttDuration(
|
|
96
131
|
projectStart,
|
|
97
132
|
era.offsetEnd.duration,
|
|
98
133
|
parsed.holidays,
|
|
99
|
-
new Set(),
|
|
134
|
+
/* @__PURE__ */ new Set(),
|
|
100
135
|
era.offsetEnd.direction
|
|
101
136
|
);
|
|
102
137
|
return { ...era, startDate: formatDate(start), endDate: formatDate(end) };
|
|
103
138
|
}
|
|
104
139
|
return era;
|
|
105
140
|
});
|
|
106
|
-
|
|
107
141
|
result.markers = parsed.markers.map((m) => {
|
|
108
142
|
if (m.offsetDate) {
|
|
109
143
|
const d = addGanttDuration(
|
|
110
144
|
projectStart,
|
|
111
145
|
m.offsetDate.duration,
|
|
112
146
|
parsed.holidays,
|
|
113
|
-
new Set(),
|
|
147
|
+
/* @__PURE__ */ new Set(),
|
|
114
148
|
m.offsetDate.direction
|
|
115
149
|
);
|
|
116
150
|
return { ...m, date: formatDate(d) };
|
|
117
151
|
}
|
|
118
152
|
return m;
|
|
119
153
|
});
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const sprintOpts = parsed.options.sprintLength
|
|
124
|
-
? { sprintLength: parsed.options.sprintLength }
|
|
125
|
-
: undefined;
|
|
126
|
-
|
|
127
|
-
// ── Dep offset storage ─────────────────────────────────
|
|
128
|
-
|
|
129
|
-
const depOffsetMap = new Map<string, Offset>();
|
|
130
|
-
|
|
131
|
-
// ── Collect all tasks ───────────────────────────────────
|
|
132
|
-
|
|
154
|
+
const sprintOpts = parsed.options.sprintLength ? { sprintLength: parsed.options.sprintLength } : void 0;
|
|
155
|
+
const depOffsetMap = /* @__PURE__ */ new Map();
|
|
133
156
|
const allTasks = collectTasks(parsed.nodes);
|
|
134
157
|
if (allTasks.length === 0) {
|
|
135
|
-
return result;
|
|
158
|
+
return result;
|
|
136
159
|
}
|
|
137
|
-
|
|
138
|
-
// Build task map by ID
|
|
139
|
-
const taskMap = new Map<string, TaskNode>();
|
|
160
|
+
const taskMap = /* @__PURE__ */ new Map();
|
|
140
161
|
for (const task of allTasks) {
|
|
141
162
|
taskMap.set(task.id, {
|
|
142
163
|
task,
|
|
143
164
|
predecessors: [],
|
|
144
165
|
startDate: null,
|
|
145
|
-
endDate: null
|
|
166
|
+
endDate: null
|
|
146
167
|
});
|
|
147
168
|
}
|
|
148
|
-
|
|
149
|
-
// ── Build implicit sequential dependencies ──────────────
|
|
150
|
-
// New-mode charts have explicit graph structure (all deps from arrows).
|
|
151
|
-
// Legacy charts need implicit sequential deps between siblings.
|
|
152
|
-
|
|
153
|
-
if (parsed.syntaxMode === 'legacy') {
|
|
169
|
+
if (parsed.syntaxMode === "legacy") {
|
|
154
170
|
buildImplicitDeps(parsed.nodes, taskMap);
|
|
155
171
|
}
|
|
156
|
-
|
|
157
|
-
// ── Resolve explicit -> dependencies ────────────────────
|
|
158
|
-
|
|
159
172
|
for (const task of allTasks) {
|
|
160
173
|
for (const dep of task.dependencies) {
|
|
161
174
|
const resolved = resolveTaskName(dep.targetName, allTasks);
|
|
162
175
|
if (isResolverError(resolved)) {
|
|
163
|
-
warn(dep.lineNumber, `\`-> ${dep.targetName}\`
|
|
176
|
+
warn(dep.lineNumber, `\`-> ${dep.targetName}\` \u2014 ${resolved.message}`);
|
|
164
177
|
continue;
|
|
165
178
|
}
|
|
166
|
-
|
|
167
|
-
// The dependency means: target starts after source
|
|
168
|
-
// In our model: target's predecessor is source
|
|
169
179
|
const targetNode = taskMap.get(resolved.task.id);
|
|
170
180
|
if (targetNode) {
|
|
171
|
-
// Check for redundant dependency (already a sequential predecessor)
|
|
172
181
|
if (targetNode.predecessors.includes(task.id)) {
|
|
173
182
|
warn(
|
|
174
183
|
dep.lineNumber,
|
|
175
|
-
parsed.syntaxMode ===
|
|
176
|
-
? `Redundant dependency: "${dep.targetName}" already follows "${task.label}".`
|
|
177
|
-
: `Redundant dependency: "${dep.targetName}" already follows "${task.label}" sequentially. Did you mean to wrap groups in \`parallel\`?`
|
|
184
|
+
parsed.syntaxMode === "new" ? `Redundant dependency: "${dep.targetName}" already follows "${task.label}".` : `Redundant dependency: "${dep.targetName}" already follows "${task.label}" sequentially. Did you mean to wrap groups in \`parallel\`?`
|
|
178
185
|
);
|
|
179
186
|
} else {
|
|
180
187
|
targetNode.predecessors.push(task.id);
|
|
181
|
-
// Store dep offset info — we need it during scheduling
|
|
182
188
|
if (dep.offset) {
|
|
183
189
|
depOffsetMap.set(`${task.id}->${resolved.task.id}`, dep.offset);
|
|
184
190
|
}
|
|
@@ -186,25 +192,16 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
186
192
|
}
|
|
187
193
|
}
|
|
188
194
|
}
|
|
189
|
-
|
|
190
|
-
// ── Topological sort with cycle detection ───────────────
|
|
191
|
-
|
|
192
195
|
let sortedIds = topologicalSort(taskMap);
|
|
193
196
|
if (!sortedIds) {
|
|
194
|
-
// Find cycle, warn, and break it by removing one explicit dep edge
|
|
195
197
|
const cycle = findCycle(taskMap);
|
|
196
|
-
const cycleStr = cycle.map((id) => taskMap.get(id)
|
|
198
|
+
const cycleStr = cycle.map((id) => taskMap.get(id).task.label).join(" \u2192 ");
|
|
197
199
|
warn(
|
|
198
200
|
// Cycle is non-empty when topo sort failed; preserves prior crash-on-empty behavior.
|
|
199
|
-
taskMap.get(cycle[0]
|
|
201
|
+
taskMap.get(cycle[0]).task.lineNumber,
|
|
200
202
|
`Circular dependency detected: ${cycleStr}. The cycle-creating dependency was dropped.`
|
|
201
203
|
);
|
|
202
|
-
|
|
203
|
-
// Remove the last edge in the cycle to break it
|
|
204
|
-
// (prefer removing explicit -> deps over implicit sequential ones)
|
|
205
204
|
breakCycle(cycle, taskMap, depOffsetMap);
|
|
206
|
-
|
|
207
|
-
// Retry — if still cyclic after breaking, keep breaking until resolved
|
|
208
205
|
sortedIds = topologicalSort(taskMap);
|
|
209
206
|
let safety = 10;
|
|
210
207
|
while (!sortedIds && safety-- > 0) {
|
|
@@ -213,38 +210,24 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
213
210
|
breakCycle(nextCycle, taskMap, depOffsetMap);
|
|
214
211
|
sortedIds = topologicalSort(taskMap);
|
|
215
212
|
}
|
|
216
|
-
|
|
217
213
|
if (!sortedIds) {
|
|
218
|
-
// Truly unresolvable — fall back to task insertion order
|
|
219
214
|
sortedIds = [...taskMap.keys()];
|
|
220
215
|
}
|
|
221
216
|
}
|
|
222
|
-
|
|
223
|
-
// ── Forward pass: resolve dates ─────────────────────────
|
|
224
|
-
|
|
225
217
|
for (const taskId of sortedIds) {
|
|
226
|
-
const node = taskMap.get(taskId)
|
|
218
|
+
const node = taskMap.get(taskId);
|
|
227
219
|
const task = node.task;
|
|
228
|
-
|
|
229
|
-
// Determine start date: max of all predecessors' end dates (+ dep offset)
|
|
230
|
-
let start: Date;
|
|
231
|
-
|
|
220
|
+
let start;
|
|
232
221
|
if (task.explicitStart) {
|
|
233
|
-
// Explicit date anchor
|
|
234
222
|
start = parseGanttDate(task.explicitStart);
|
|
235
223
|
} else if (node.predecessors.length === 0) {
|
|
236
|
-
// No predecessors: starts at project start
|
|
237
224
|
start = new Date(projectStart);
|
|
238
225
|
} else {
|
|
239
|
-
|
|
240
|
-
start = new Date(-8640000000000000);
|
|
226
|
+
start = /* @__PURE__ */ new Date(-864e13);
|
|
241
227
|
for (const predId of node.predecessors) {
|
|
242
|
-
const predNode = taskMap.get(predId)
|
|
243
|
-
if (!predNode.endDate) continue;
|
|
244
|
-
|
|
228
|
+
const predNode = taskMap.get(predId);
|
|
229
|
+
if (!predNode.endDate) continue;
|
|
245
230
|
let predEnd = new Date(predNode.endDate);
|
|
246
|
-
|
|
247
|
-
// Apply dep offset if present
|
|
248
231
|
const depOffset = depOffsetMap.get(`${predId}->${taskId}`);
|
|
249
232
|
if (depOffset) {
|
|
250
233
|
predEnd = addGanttDuration(
|
|
@@ -256,15 +239,12 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
256
239
|
sprintOpts
|
|
257
240
|
);
|
|
258
241
|
}
|
|
259
|
-
|
|
260
242
|
if (predEnd.getTime() > start.getTime()) {
|
|
261
243
|
start = predEnd;
|
|
262
244
|
}
|
|
263
245
|
}
|
|
264
246
|
}
|
|
265
|
-
|
|
266
|
-
// Apply group offset as floor constraint (new mode only)
|
|
267
|
-
if (parsed.syntaxMode === 'new' && task.groupPath.length > 0) {
|
|
247
|
+
if (parsed.syntaxMode === "new" && task.groupPath.length > 0) {
|
|
268
248
|
const groupOffset = findGroupOffset(parsed.nodes, task.groupPath);
|
|
269
249
|
if (groupOffset) {
|
|
270
250
|
const groupFloor = addGanttDuration(
|
|
@@ -280,8 +260,6 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
280
260
|
}
|
|
281
261
|
}
|
|
282
262
|
}
|
|
283
|
-
|
|
284
|
-
// Apply task-level offset (shifts start forward or backward)
|
|
285
263
|
if (task.offset) {
|
|
286
264
|
start = addGanttDuration(
|
|
287
265
|
start,
|
|
@@ -305,32 +283,24 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
305
283
|
);
|
|
306
284
|
start = new Date(projectStart);
|
|
307
285
|
}
|
|
308
|
-
|
|
309
|
-
// If explicit start (+ offset) conflicts with predecessors, warn but honor explicit
|
|
310
286
|
if (task.explicitStart && node.predecessors.length > 0) {
|
|
311
|
-
let maxPredEnd = new Date(-
|
|
287
|
+
let maxPredEnd = /* @__PURE__ */ new Date(-864e13);
|
|
312
288
|
for (const predId of node.predecessors) {
|
|
313
|
-
const predNode = taskMap.get(predId)
|
|
314
|
-
if (
|
|
315
|
-
predNode.endDate &&
|
|
316
|
-
predNode.endDate.getTime() > maxPredEnd.getTime()
|
|
317
|
-
) {
|
|
289
|
+
const predNode = taskMap.get(predId);
|
|
290
|
+
if (predNode.endDate && predNode.endDate.getTime() > maxPredEnd.getTime()) {
|
|
318
291
|
maxPredEnd = predNode.endDate;
|
|
319
292
|
}
|
|
320
293
|
}
|
|
321
294
|
if (start.getTime() < maxPredEnd.getTime()) {
|
|
322
295
|
warn(
|
|
323
296
|
task.lineNumber,
|
|
324
|
-
`Explicit date ${task.explicitStart}${task.offset ?
|
|
297
|
+
`Explicit date ${task.explicitStart}${task.offset ? " (with offset)" : ""} overlaps with predecessor ending ${formatDate(maxPredEnd)}. Using explicit date.`
|
|
325
298
|
);
|
|
326
299
|
}
|
|
327
300
|
}
|
|
328
|
-
|
|
329
|
-
// Calculate end date
|
|
330
|
-
let end: Date;
|
|
301
|
+
let end;
|
|
331
302
|
if (task.duration) {
|
|
332
303
|
if (task.duration.amount === 0) {
|
|
333
|
-
// Milestone: zero duration, end = start
|
|
334
304
|
end = new Date(start);
|
|
335
305
|
} else {
|
|
336
306
|
end = addGanttDuration(
|
|
@@ -343,32 +313,22 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
343
313
|
);
|
|
344
314
|
}
|
|
345
315
|
} else {
|
|
346
|
-
// Explicit date task with no duration = milestone at that date
|
|
347
316
|
end = new Date(start);
|
|
348
317
|
}
|
|
349
|
-
|
|
350
318
|
node.startDate = start;
|
|
351
319
|
node.endDate = end;
|
|
352
320
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
parsed.holidays,
|
|
363
|
-
holidaySet,
|
|
364
|
-
sprintOpts
|
|
365
|
-
)
|
|
366
|
-
: new Set<string>();
|
|
367
|
-
|
|
368
|
-
// Cascading uncertainty: uncertain if task itself is uncertain OR any predecessor is
|
|
369
|
-
const uncertainSet = new Set<string>();
|
|
321
|
+
const criticalSet = parsed.options.criticalPath ? computeCriticalPath(
|
|
322
|
+
sortedIds,
|
|
323
|
+
taskMap,
|
|
324
|
+
depOffsetMap,
|
|
325
|
+
parsed.holidays,
|
|
326
|
+
holidaySet,
|
|
327
|
+
sprintOpts
|
|
328
|
+
) : /* @__PURE__ */ new Set();
|
|
329
|
+
const uncertainSet = /* @__PURE__ */ new Set();
|
|
370
330
|
for (const taskId of sortedIds) {
|
|
371
|
-
const node = taskMap.get(taskId)
|
|
331
|
+
const node = taskMap.get(taskId);
|
|
372
332
|
if (node.task.uncertain) {
|
|
373
333
|
uncertainSet.add(taskId);
|
|
374
334
|
} else {
|
|
@@ -380,33 +340,23 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
380
340
|
}
|
|
381
341
|
}
|
|
382
342
|
}
|
|
383
|
-
|
|
384
343
|
for (const taskId of sortedIds) {
|
|
385
|
-
const node = taskMap.get(taskId)
|
|
344
|
+
const node = taskMap.get(taskId);
|
|
386
345
|
result.tasks.push({
|
|
387
346
|
task: node.task,
|
|
388
|
-
startDate: node.startDate
|
|
389
|
-
endDate: node.endDate
|
|
347
|
+
startDate: node.startDate,
|
|
348
|
+
endDate: node.endDate,
|
|
390
349
|
isCriticalPath: criticalSet.has(taskId),
|
|
391
350
|
isUncertain: uncertainSet.has(taskId),
|
|
392
|
-
isMilestone:
|
|
393
|
-
node.task.duration?.amount === 0 ||
|
|
394
|
-
(!node.task.duration && !node.task.explicitStart),
|
|
351
|
+
isMilestone: node.task.duration?.amount === 0 || !node.task.duration && !node.task.explicitStart,
|
|
395
352
|
groupPath: node.task.groupPath.slice(),
|
|
396
|
-
effectiveMetadata: { ...node.task.metadata }
|
|
353
|
+
effectiveMetadata: { ...node.task.metadata }
|
|
397
354
|
});
|
|
398
355
|
}
|
|
399
|
-
|
|
400
|
-
// ── Build resolved groups ───────────────────────────────
|
|
401
|
-
|
|
402
356
|
buildResolvedGroups(parsed.nodes, taskMap, result.groups, 0);
|
|
403
|
-
|
|
404
|
-
// ── Compute overall date range ──────────────────────────
|
|
405
|
-
|
|
406
357
|
if (result.tasks.length > 0) {
|
|
407
|
-
|
|
408
|
-
let
|
|
409
|
-
let maxDate = result.tasks[0]!.endDate;
|
|
358
|
+
let minDate = result.tasks[0].startDate;
|
|
359
|
+
let maxDate = result.tasks[0].endDate;
|
|
410
360
|
for (const t of result.tasks) {
|
|
411
361
|
if (t.startDate.getTime() < minDate.getTime()) minDate = t.startDate;
|
|
412
362
|
if (t.endDate.getTime() > maxDate.getTime()) maxDate = t.endDate;
|
|
@@ -414,72 +364,40 @@ export function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule {
|
|
|
414
364
|
result.startDate = minDate;
|
|
415
365
|
result.endDate = maxDate;
|
|
416
366
|
}
|
|
417
|
-
|
|
418
|
-
// ── Generate sprint bands ──────────────────────────────
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
parsed.options.sprintMode &&
|
|
422
|
-
parsed.options.sprintLength &&
|
|
423
|
-
result.tasks.length > 0
|
|
424
|
-
) {
|
|
367
|
+
if (parsed.options.sprintMode && parsed.options.sprintLength && result.tasks.length > 0) {
|
|
425
368
|
result.sprints = generateSprintBands(
|
|
426
369
|
parsed.options,
|
|
427
370
|
result.startDate,
|
|
428
371
|
result.endDate,
|
|
429
372
|
projectStart
|
|
430
373
|
);
|
|
431
|
-
|
|
432
|
-
// Extend chart range to include the last sprint's end so it doesn't clip
|
|
433
374
|
if (result.sprints.length > 0) {
|
|
434
|
-
|
|
435
|
-
const lastSprintEnd = result.sprints[result.sprints.length - 1]!.endDate;
|
|
375
|
+
const lastSprintEnd = result.sprints[result.sprints.length - 1].endDate;
|
|
436
376
|
if (lastSprintEnd.getTime() > result.endDate.getTime()) {
|
|
437
377
|
result.endDate = lastSprintEnd;
|
|
438
378
|
}
|
|
439
379
|
}
|
|
440
380
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
// Missing parallel warning: 2+ top-level groups without parallel wrapper (legacy only)
|
|
445
|
-
if (parsed.syntaxMode === 'legacy') {
|
|
446
|
-
const topLevelGroups = parsed.nodes.filter((n) => n.kind === 'group');
|
|
381
|
+
if (parsed.syntaxMode === "legacy") {
|
|
382
|
+
const topLevelGroups = parsed.nodes.filter((n) => n.kind === "group");
|
|
447
383
|
if (topLevelGroups.length >= 2) {
|
|
448
384
|
const names = topLevelGroups.map(
|
|
449
|
-
(g) =>
|
|
385
|
+
(g) => g.name
|
|
450
386
|
);
|
|
451
387
|
warn(
|
|
452
|
-
topLevelGroups[0]
|
|
453
|
-
`${names.join(
|
|
388
|
+
topLevelGroups[0].lineNumber,
|
|
389
|
+
`${names.join(" and ")} are sequential. Wrap in \`parallel\` if they should run concurrently.`
|
|
454
390
|
);
|
|
455
391
|
}
|
|
456
392
|
}
|
|
457
|
-
|
|
458
393
|
return result;
|
|
459
394
|
}
|
|
460
|
-
|
|
461
|
-
// ── Implicit dependency builder ─────────────────────────────
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Walk the gantt tree and create implicit sequential dependencies.
|
|
465
|
-
* - Siblings are sequential (each task depends on the previous sibling)
|
|
466
|
-
* - Parallel block children all share the parent's predecessor
|
|
467
|
-
* - Groups: children are sequential within the group
|
|
468
|
-
*/
|
|
469
|
-
function buildImplicitDeps(
|
|
470
|
-
nodes: readonly GanttNode[],
|
|
471
|
-
taskMap: Map<string, TaskNode>
|
|
472
|
-
): void {
|
|
395
|
+
function buildImplicitDeps(nodes, taskMap) {
|
|
473
396
|
walkChildren(nodes, null);
|
|
474
|
-
|
|
475
|
-
function walkChildren(
|
|
476
|
-
children: readonly GanttNode[],
|
|
477
|
-
afterTaskId: string | null
|
|
478
|
-
) {
|
|
397
|
+
function walkChildren(children, afterTaskId) {
|
|
479
398
|
let prevTaskId = afterTaskId;
|
|
480
|
-
|
|
481
399
|
for (const node of children) {
|
|
482
|
-
if (node.kind ===
|
|
400
|
+
if (node.kind === "task") {
|
|
483
401
|
if (prevTaskId) {
|
|
484
402
|
const taskNode = taskMap.get(node.id);
|
|
485
403
|
if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
|
|
@@ -487,17 +405,13 @@ function buildImplicitDeps(
|
|
|
487
405
|
}
|
|
488
406
|
}
|
|
489
407
|
prevTaskId = node.id;
|
|
490
|
-
} else if (node.kind ===
|
|
491
|
-
// Walk group children sequentially, starting after prevTaskId
|
|
408
|
+
} else if (node.kind === "group") {
|
|
492
409
|
const lastId = walkSequential(node.children, prevTaskId);
|
|
493
410
|
if (lastId) prevTaskId = lastId;
|
|
494
|
-
} else if (node.kind ===
|
|
495
|
-
|
|
496
|
-
// The parallel block "ends" when all children end
|
|
497
|
-
// We need to find the last task in each branch
|
|
498
|
-
const branchLastIds: string[] = [];
|
|
411
|
+
} else if (node.kind === "parallel") {
|
|
412
|
+
const branchLastIds = [];
|
|
499
413
|
for (const child of node.children) {
|
|
500
|
-
if (child.kind ===
|
|
414
|
+
if (child.kind === "task") {
|
|
501
415
|
if (prevTaskId) {
|
|
502
416
|
const taskNode = taskMap.get(child.id);
|
|
503
417
|
if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
|
|
@@ -505,8 +419,7 @@ function buildImplicitDeps(
|
|
|
505
419
|
}
|
|
506
420
|
}
|
|
507
421
|
branchLastIds.push(child.id);
|
|
508
|
-
} else if (child.kind ===
|
|
509
|
-
// First task in group depends on prevTaskId
|
|
422
|
+
} else if (child.kind === "group") {
|
|
510
423
|
const firstId = findFirstTask(child.children);
|
|
511
424
|
if (firstId && prevTaskId) {
|
|
512
425
|
const taskNode = taskMap.get(firstId);
|
|
@@ -514,24 +427,20 @@ function buildImplicitDeps(
|
|
|
514
427
|
taskNode.predecessors.push(prevTaskId);
|
|
515
428
|
}
|
|
516
429
|
}
|
|
517
|
-
|
|
518
|
-
walkSequential(child.children, null); // internal deps only
|
|
430
|
+
walkSequential(child.children, null);
|
|
519
431
|
const lastId = findLastTask(child.children);
|
|
520
432
|
if (lastId) branchLastIds.push(lastId);
|
|
521
|
-
} else if (child.kind ===
|
|
522
|
-
// Nested parallel — recurse
|
|
433
|
+
} else if (child.kind === "parallel") {
|
|
523
434
|
walkChildren([child], prevTaskId);
|
|
524
435
|
const lastId = findLastTask(child.children);
|
|
525
436
|
if (lastId) branchLastIds.push(lastId);
|
|
526
437
|
}
|
|
527
438
|
}
|
|
528
|
-
// After parallel, next sibling depends on ALL branch ends
|
|
529
439
|
if (branchLastIds.length > 0) {
|
|
530
440
|
prevTaskId = null;
|
|
531
441
|
const nextIdx = children.indexOf(node) + 1;
|
|
532
442
|
if (nextIdx < children.length) {
|
|
533
|
-
|
|
534
|
-
const nextFirstId = findFirstTask([children[nextIdx]!]);
|
|
443
|
+
const nextFirstId = findFirstTask([children[nextIdx]]);
|
|
535
444
|
if (nextFirstId) {
|
|
536
445
|
const nextNode = taskMap.get(nextFirstId);
|
|
537
446
|
if (nextNode) {
|
|
@@ -547,14 +456,10 @@ function buildImplicitDeps(
|
|
|
547
456
|
}
|
|
548
457
|
}
|
|
549
458
|
}
|
|
550
|
-
|
|
551
|
-
function walkSequential(
|
|
552
|
-
children: readonly GanttNode[],
|
|
553
|
-
afterTaskId: string | null
|
|
554
|
-
): string | null {
|
|
459
|
+
function walkSequential(children, afterTaskId) {
|
|
555
460
|
let prevTaskId = afterTaskId;
|
|
556
461
|
for (const node of children) {
|
|
557
|
-
if (node.kind ===
|
|
462
|
+
if (node.kind === "task") {
|
|
558
463
|
if (prevTaskId) {
|
|
559
464
|
const taskNode = taskMap.get(node.id);
|
|
560
465
|
if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
|
|
@@ -562,10 +467,10 @@ function buildImplicitDeps(
|
|
|
562
467
|
}
|
|
563
468
|
}
|
|
564
469
|
prevTaskId = node.id;
|
|
565
|
-
} else if (node.kind ===
|
|
470
|
+
} else if (node.kind === "group") {
|
|
566
471
|
const lastId = walkSequential(node.children, prevTaskId);
|
|
567
472
|
if (lastId) prevTaskId = lastId;
|
|
568
|
-
} else if (node.kind ===
|
|
473
|
+
} else if (node.kind === "parallel") {
|
|
569
474
|
walkChildren([node], prevTaskId);
|
|
570
475
|
const lastId = findLastTask(node.children);
|
|
571
476
|
if (lastId) prevTaskId = lastId;
|
|
@@ -574,39 +479,30 @@ function buildImplicitDeps(
|
|
|
574
479
|
return prevTaskId;
|
|
575
480
|
}
|
|
576
481
|
}
|
|
577
|
-
|
|
578
|
-
/** Find the first task ID in a tree (depth-first). */
|
|
579
|
-
function findFirstTask(nodes: readonly GanttNode[]): string | null {
|
|
482
|
+
function findFirstTask(nodes) {
|
|
580
483
|
for (const node of nodes) {
|
|
581
|
-
if (node.kind ===
|
|
582
|
-
if (node.kind ===
|
|
484
|
+
if (node.kind === "task") return node.id;
|
|
485
|
+
if (node.kind === "group" || node.kind === "parallel") {
|
|
583
486
|
const found = findFirstTask(node.children);
|
|
584
487
|
if (found) return found;
|
|
585
488
|
}
|
|
586
489
|
}
|
|
587
490
|
return null;
|
|
588
491
|
}
|
|
589
|
-
|
|
590
|
-
/** Find the last task ID in a tree (depth-first, last branch). */
|
|
591
|
-
function findLastTask(nodes: readonly GanttNode[]): string | null {
|
|
492
|
+
function findLastTask(nodes) {
|
|
592
493
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (node.kind ===
|
|
596
|
-
if (node.kind === 'group' || node.kind === 'parallel') {
|
|
494
|
+
const node = nodes[i];
|
|
495
|
+
if (node.kind === "task") return node.id;
|
|
496
|
+
if (node.kind === "group" || node.kind === "parallel") {
|
|
597
497
|
const found = findLastTask(node.children);
|
|
598
498
|
if (found) return found;
|
|
599
499
|
}
|
|
600
500
|
}
|
|
601
501
|
return null;
|
|
602
502
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
function topologicalSort(taskMap: Map<string, TaskNode>): string[] | null {
|
|
607
|
-
const inDegree = new Map<string, number>();
|
|
608
|
-
const adjacency = new Map<string, string[]>();
|
|
609
|
-
|
|
503
|
+
function topologicalSort(taskMap) {
|
|
504
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
505
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
610
506
|
for (const [id, node] of taskMap) {
|
|
611
507
|
inDegree.set(id, node.predecessors.length);
|
|
612
508
|
for (const pred of node.predecessors) {
|
|
@@ -615,15 +511,13 @@ function topologicalSort(taskMap: Map<string, TaskNode>): string[] | null {
|
|
|
615
511
|
adjacency.set(pred, adj);
|
|
616
512
|
}
|
|
617
513
|
}
|
|
618
|
-
|
|
619
|
-
const queue: string[] = [];
|
|
514
|
+
const queue = [];
|
|
620
515
|
for (const [id, degree] of inDegree) {
|
|
621
516
|
if (degree === 0) queue.push(id);
|
|
622
517
|
}
|
|
623
|
-
|
|
624
|
-
const sorted: string[] = [];
|
|
518
|
+
const sorted = [];
|
|
625
519
|
while (queue.length > 0) {
|
|
626
|
-
const current = queue.shift()
|
|
520
|
+
const current = queue.shift();
|
|
627
521
|
sorted.push(current);
|
|
628
522
|
for (const succ of adjacency.get(current) ?? []) {
|
|
629
523
|
const newDegree = (inDegree.get(succ) ?? 1) - 1;
|
|
@@ -631,15 +525,12 @@ function topologicalSort(taskMap: Map<string, TaskNode>): string[] | null {
|
|
|
631
525
|
if (newDegree === 0) queue.push(succ);
|
|
632
526
|
}
|
|
633
527
|
}
|
|
634
|
-
|
|
635
528
|
return sorted.length === taskMap.size ? sorted : null;
|
|
636
529
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const parent = new Map<string, string>();
|
|
642
|
-
|
|
530
|
+
function findCycle(taskMap) {
|
|
531
|
+
const visited = /* @__PURE__ */ new Set();
|
|
532
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
533
|
+
const parent = /* @__PURE__ */ new Map();
|
|
643
534
|
for (const id of taskMap.keys()) {
|
|
644
535
|
if (!visited.has(id)) {
|
|
645
536
|
const cycle = dfs(id);
|
|
@@ -647,18 +538,15 @@ function findCycle(taskMap: Map<string, TaskNode>): string[] {
|
|
|
647
538
|
}
|
|
648
539
|
}
|
|
649
540
|
return [];
|
|
650
|
-
|
|
651
|
-
function dfs(id: string): string[] | null {
|
|
541
|
+
function dfs(id) {
|
|
652
542
|
visited.add(id);
|
|
653
543
|
onStack.add(id);
|
|
654
|
-
|
|
655
|
-
const successors: string[] = [];
|
|
544
|
+
const successors = [];
|
|
656
545
|
for (const [otherId, otherNode] of taskMap) {
|
|
657
546
|
if (otherNode.predecessors.includes(id)) {
|
|
658
547
|
successors.push(otherId);
|
|
659
548
|
}
|
|
660
549
|
}
|
|
661
|
-
|
|
662
550
|
for (const succ of successors) {
|
|
663
551
|
if (!visited.has(succ)) {
|
|
664
552
|
parent.set(succ, id);
|
|
@@ -669,33 +557,20 @@ function findCycle(taskMap: Map<string, TaskNode>): string[] {
|
|
|
669
557
|
let current = id;
|
|
670
558
|
while (current !== succ) {
|
|
671
559
|
cycle.push(current);
|
|
672
|
-
current = parent.get(current)
|
|
560
|
+
current = parent.get(current);
|
|
673
561
|
}
|
|
674
562
|
cycle.push(succ);
|
|
675
563
|
return cycle.reverse();
|
|
676
564
|
}
|
|
677
565
|
}
|
|
678
|
-
|
|
679
566
|
onStack.delete(id);
|
|
680
567
|
return null;
|
|
681
568
|
}
|
|
682
569
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
* the penultimate node, which breaks the cycle.
|
|
688
|
-
*/
|
|
689
|
-
function breakCycle(
|
|
690
|
-
cycle: string[],
|
|
691
|
-
taskMap: Map<string, TaskNode>,
|
|
692
|
-
depOffsetMap: Map<string, Offset>
|
|
693
|
-
): void {
|
|
694
|
-
if (cycle.length < 3) return; // need at least [A, B, A]
|
|
695
|
-
// Remove the edge from second-to-last → first (i.e. the edge that closes the cycle)
|
|
696
|
-
// In-bounds by cycle.length >= 3 guard above.
|
|
697
|
-
const fromId = cycle[cycle.length - 2]!;
|
|
698
|
-
const toId = cycle[0]!;
|
|
570
|
+
function breakCycle(cycle, taskMap, depOffsetMap) {
|
|
571
|
+
if (cycle.length < 3) return;
|
|
572
|
+
const fromId = cycle[cycle.length - 2];
|
|
573
|
+
const toId = cycle[0];
|
|
699
574
|
const toNode = taskMap.get(toId);
|
|
700
575
|
if (toNode) {
|
|
701
576
|
const idx = toNode.predecessors.indexOf(fromId);
|
|
@@ -705,31 +580,18 @@ function breakCycle(
|
|
|
705
580
|
}
|
|
706
581
|
}
|
|
707
582
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
sortedIds: string[],
|
|
713
|
-
taskMap: Map<string, TaskNode>,
|
|
714
|
-
depOffsetMap: Map<string, Offset>,
|
|
715
|
-
holidays: GanttHolidays,
|
|
716
|
-
holidaySet: Set<string>,
|
|
717
|
-
sprintOpts?: { sprintLength?: Duration }
|
|
718
|
-
): Set<string> {
|
|
719
|
-
if (sortedIds.length === 0) return new Set();
|
|
720
|
-
|
|
721
|
-
const latestEnd = new Map<string, number>();
|
|
722
|
-
const latestStart = new Map<string, number>();
|
|
723
|
-
|
|
583
|
+
function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet, sprintOpts) {
|
|
584
|
+
if (sortedIds.length === 0) return /* @__PURE__ */ new Set();
|
|
585
|
+
const latestEnd = /* @__PURE__ */ new Map();
|
|
586
|
+
const latestStart = /* @__PURE__ */ new Map();
|
|
724
587
|
let projectEnd = 0;
|
|
725
588
|
for (const id of sortedIds) {
|
|
726
|
-
const node = taskMap.get(id)
|
|
589
|
+
const node = taskMap.get(id);
|
|
727
590
|
if (node.endDate && node.endDate.getTime() > projectEnd) {
|
|
728
591
|
projectEnd = node.endDate.getTime();
|
|
729
592
|
}
|
|
730
593
|
}
|
|
731
|
-
|
|
732
|
-
const successors = new Map<string, string[]>();
|
|
594
|
+
const successors = /* @__PURE__ */ new Map();
|
|
733
595
|
for (const [id, node] of taskMap) {
|
|
734
596
|
for (const pred of node.predecessors) {
|
|
735
597
|
const succs = successors.get(pred) ?? [];
|
|
@@ -737,26 +599,20 @@ function computeCriticalPath(
|
|
|
737
599
|
successors.set(pred, succs);
|
|
738
600
|
}
|
|
739
601
|
}
|
|
740
|
-
|
|
741
|
-
// Backward pass (reverse order)
|
|
742
602
|
for (let i = sortedIds.length - 1; i >= 0; i--) {
|
|
743
|
-
|
|
744
|
-
const
|
|
745
|
-
const node = taskMap.get(id)!;
|
|
603
|
+
const id = sortedIds[i];
|
|
604
|
+
const node = taskMap.get(id);
|
|
746
605
|
const succs = successors.get(id) ?? [];
|
|
747
|
-
|
|
748
606
|
if (succs.length === 0) {
|
|
749
607
|
latestEnd.set(id, projectEnd);
|
|
750
608
|
} else {
|
|
751
609
|
let minVal = Infinity;
|
|
752
610
|
for (const succId of succs) {
|
|
753
611
|
let succLS = latestStart.get(succId);
|
|
754
|
-
if (succLS ===
|
|
755
|
-
|
|
756
|
-
// Reverse successor's task-level offset
|
|
757
|
-
const succTask = taskMap.get(succId)!.task;
|
|
612
|
+
if (succLS === void 0) continue;
|
|
613
|
+
const succTask = taskMap.get(succId).task;
|
|
758
614
|
if (succTask.offset) {
|
|
759
|
-
const reverseDir =
|
|
615
|
+
const reverseDir = succTask.offset.direction * -1;
|
|
760
616
|
const adjusted = addGanttDuration(
|
|
761
617
|
new Date(succLS),
|
|
762
618
|
succTask.offset.duration,
|
|
@@ -767,11 +623,9 @@ function computeCriticalPath(
|
|
|
767
623
|
);
|
|
768
624
|
succLS = adjusted.getTime();
|
|
769
625
|
}
|
|
770
|
-
|
|
771
|
-
// Reverse dep offset
|
|
772
626
|
const depOffset = depOffsetMap.get(`${id}->${succId}`);
|
|
773
627
|
if (depOffset) {
|
|
774
|
-
const reverseDir =
|
|
628
|
+
const reverseDir = depOffset.direction * -1;
|
|
775
629
|
const adjusted = addGanttDuration(
|
|
776
630
|
new Date(succLS),
|
|
777
631
|
depOffset.duration,
|
|
@@ -782,62 +636,48 @@ function computeCriticalPath(
|
|
|
782
636
|
);
|
|
783
637
|
succLS = adjusted.getTime();
|
|
784
638
|
}
|
|
785
|
-
|
|
786
639
|
if (succLS < minVal) {
|
|
787
640
|
minVal = succLS;
|
|
788
641
|
}
|
|
789
642
|
}
|
|
790
643
|
latestEnd.set(id, minVal);
|
|
791
644
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
latestStart.set(id, latestEnd.get(id)! - duration);
|
|
645
|
+
const duration = node.endDate.getTime() - node.startDate.getTime();
|
|
646
|
+
latestStart.set(id, latestEnd.get(id) - duration);
|
|
795
647
|
}
|
|
796
|
-
|
|
797
|
-
const critical = new Set<string>();
|
|
648
|
+
const critical = /* @__PURE__ */ new Set();
|
|
798
649
|
for (const id of sortedIds) {
|
|
799
|
-
const node = taskMap.get(id)
|
|
800
|
-
const slack = (latestStart.get(id) ?? 0) - node.startDate
|
|
801
|
-
if (Math.abs(slack) <
|
|
650
|
+
const node = taskMap.get(id);
|
|
651
|
+
const slack = (latestStart.get(id) ?? 0) - node.startDate.getTime();
|
|
652
|
+
if (Math.abs(slack) < 864e5) {
|
|
802
653
|
critical.add(id);
|
|
803
654
|
}
|
|
804
655
|
}
|
|
805
|
-
|
|
806
656
|
return critical;
|
|
807
657
|
}
|
|
808
|
-
|
|
809
|
-
// ── Resolved groups builder ─────────────────────────────────
|
|
810
|
-
|
|
811
|
-
function buildResolvedGroups(
|
|
812
|
-
nodes: readonly GanttNode[],
|
|
813
|
-
taskMap: Map<string, TaskNode>,
|
|
814
|
-
groups: ResolvedGroup[],
|
|
815
|
-
depth: number
|
|
816
|
-
): void {
|
|
658
|
+
function buildResolvedGroups(nodes, taskMap, groups, depth) {
|
|
817
659
|
for (const node of nodes) {
|
|
818
|
-
if (node.kind ===
|
|
660
|
+
if (node.kind === "group") {
|
|
819
661
|
const childTasks = collectTasks(node.children);
|
|
820
662
|
if (childTasks.length === 0) {
|
|
821
663
|
groups.push({
|
|
822
664
|
name: node.name,
|
|
823
665
|
color: node.color,
|
|
824
666
|
metadata: node.metadata,
|
|
825
|
-
startDate: new Date(),
|
|
826
|
-
endDate: new Date(),
|
|
667
|
+
startDate: /* @__PURE__ */ new Date(),
|
|
668
|
+
endDate: /* @__PURE__ */ new Date(),
|
|
827
669
|
progress: null,
|
|
828
670
|
lineNumber: node.lineNumber,
|
|
829
671
|
depth,
|
|
830
|
-
...
|
|
672
|
+
...node.collapsed && { collapsed: true }
|
|
831
673
|
});
|
|
832
674
|
continue;
|
|
833
675
|
}
|
|
834
|
-
|
|
835
676
|
let minStart = Infinity;
|
|
836
677
|
let maxEnd = -Infinity;
|
|
837
678
|
let totalProgress = 0;
|
|
838
679
|
let totalDuration = 0;
|
|
839
680
|
let hasProgress = false;
|
|
840
|
-
|
|
841
681
|
for (const task of childTasks) {
|
|
842
682
|
const resolved = taskMap.get(task.id);
|
|
843
683
|
if (!resolved?.startDate || !resolved?.endDate) continue;
|
|
@@ -852,123 +692,84 @@ function buildResolvedGroups(
|
|
|
852
692
|
hasProgress = true;
|
|
853
693
|
}
|
|
854
694
|
}
|
|
855
|
-
|
|
856
695
|
groups.push({
|
|
857
696
|
name: node.name,
|
|
858
697
|
color: node.color,
|
|
859
698
|
metadata: node.metadata,
|
|
860
699
|
startDate: new Date(minStart === Infinity ? 0 : minStart),
|
|
861
700
|
endDate: new Date(maxEnd === -Infinity ? 0 : maxEnd),
|
|
862
|
-
progress:
|
|
863
|
-
hasProgress && totalDuration > 0
|
|
864
|
-
? totalProgress / totalDuration
|
|
865
|
-
: null,
|
|
701
|
+
progress: hasProgress && totalDuration > 0 ? totalProgress / totalDuration : null,
|
|
866
702
|
lineNumber: node.lineNumber,
|
|
867
703
|
depth,
|
|
868
|
-
...
|
|
704
|
+
...node.collapsed && { collapsed: true }
|
|
869
705
|
});
|
|
870
|
-
|
|
871
706
|
buildResolvedGroups(node.children, taskMap, groups, depth + 1);
|
|
872
|
-
} else if (node.kind ===
|
|
707
|
+
} else if (node.kind === "parallel") {
|
|
873
708
|
buildResolvedGroups(node.children, taskMap, groups, depth);
|
|
874
709
|
}
|
|
875
710
|
}
|
|
876
711
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
function generateSprintBands(
|
|
881
|
-
options: GanttOptions,
|
|
882
|
-
chartStart: Date,
|
|
883
|
-
chartEnd: Date,
|
|
884
|
-
projectStart: Date
|
|
885
|
-
): ResolvedSprint[] {
|
|
886
|
-
const sprintLength = options.sprintLength!;
|
|
712
|
+
function generateSprintBands(options, chartStart, chartEnd, projectStart) {
|
|
713
|
+
const sprintLength = options.sprintLength;
|
|
887
714
|
const sprintNumber = options.sprintNumber ?? 1;
|
|
888
|
-
|
|
889
|
-
// Determine anchor date: sprint-start or chart start or today
|
|
890
|
-
let anchorDate: Date;
|
|
715
|
+
let anchorDate;
|
|
891
716
|
if (options.sprintStart) {
|
|
892
|
-
anchorDate = new Date(options.sprintStart +
|
|
717
|
+
anchorDate = /* @__PURE__ */ new Date(options.sprintStart + "T00:00:00");
|
|
893
718
|
} else if (options.start) {
|
|
894
719
|
anchorDate = new Date(projectStart);
|
|
895
720
|
} else {
|
|
896
|
-
const now = new Date();
|
|
721
|
+
const now = /* @__PURE__ */ new Date();
|
|
897
722
|
anchorDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
898
723
|
}
|
|
899
724
|
anchorDate.setHours(0, 0, 0, 0);
|
|
900
|
-
|
|
901
|
-
// Sprint length in whole days (parser ensures only d/w with integer day result)
|
|
902
725
|
const sprintDays = Math.round(
|
|
903
|
-
sprintLength.amount * (sprintLength.unit ===
|
|
726
|
+
sprintLength.amount * (sprintLength.unit === "w" ? 7 : 1)
|
|
904
727
|
);
|
|
905
|
-
if (sprintDays <= 0) return [];
|
|
906
|
-
|
|
907
|
-
// Bail if anchor date is invalid (e.g. sprint-start 2026-13-45)
|
|
728
|
+
if (sprintDays <= 0) return [];
|
|
908
729
|
if (Number.isNaN(anchorDate.getTime())) return [];
|
|
909
|
-
|
|
910
|
-
// Calculate which sprint chartStart falls in, relative to the anchor
|
|
911
730
|
const chartStartTime = new Date(chartStart);
|
|
912
731
|
chartStartTime.setHours(0, 0, 0, 0);
|
|
913
732
|
const chartEndTime = new Date(chartEnd);
|
|
914
733
|
chartEndTime.setHours(0, 0, 0, 0);
|
|
915
|
-
|
|
916
|
-
const msPerDay = 86400000;
|
|
734
|
+
const msPerDay = 864e5;
|
|
917
735
|
const dayDiff = Math.floor(
|
|
918
736
|
(chartStartTime.getTime() - anchorDate.getTime()) / msPerDay
|
|
919
737
|
);
|
|
920
|
-
// Floor division: which sprint index (from anchor) does chartStart fall in?
|
|
921
738
|
const startSprintIndex = Math.floor(dayDiff / sprintDays);
|
|
922
|
-
|
|
923
|
-
const
|
|
924
|
-
const maxSprints = 1000; // safety guard against infinite loops
|
|
925
|
-
|
|
926
|
-
// Generate sprints that overlap with [chartStart, chartEnd]
|
|
927
|
-
// Sprint at index i (relative to anchor) has number: sprintNumber + i
|
|
739
|
+
const sprints = [];
|
|
740
|
+
const maxSprints = 1e3;
|
|
928
741
|
for (let i = startSprintIndex; sprints.length < maxSprints; i++) {
|
|
929
742
|
const sprintStartDate = new Date(anchorDate);
|
|
930
743
|
sprintStartDate.setDate(sprintStartDate.getDate() + i * sprintDays);
|
|
931
744
|
sprintStartDate.setHours(0, 0, 0, 0);
|
|
932
|
-
|
|
933
745
|
const sprintEndDate = new Date(sprintStartDate);
|
|
934
746
|
sprintEndDate.setDate(sprintEndDate.getDate() + sprintDays);
|
|
935
747
|
sprintEndDate.setHours(0, 0, 0, 0);
|
|
936
|
-
|
|
937
|
-
// Stop when sprint start is past chart end
|
|
938
748
|
if (sprintStartDate.getTime() >= chartEndTime.getTime() + msPerDay) break;
|
|
939
|
-
|
|
940
749
|
sprints.push({
|
|
941
750
|
number: sprintNumber + i,
|
|
942
751
|
startDate: sprintStartDate,
|
|
943
|
-
endDate: sprintEndDate
|
|
752
|
+
endDate: sprintEndDate
|
|
944
753
|
});
|
|
945
754
|
}
|
|
946
|
-
|
|
947
755
|
return sprints;
|
|
948
756
|
}
|
|
949
|
-
|
|
950
|
-
// ── Utility ─────────────────────────────────────────────────
|
|
951
|
-
|
|
952
|
-
function formatDate(d: Date): string {
|
|
757
|
+
function formatDate(d) {
|
|
953
758
|
const y = d.getFullYear();
|
|
954
|
-
const m = String(d.getMonth() + 1).padStart(2,
|
|
955
|
-
const day = String(d.getDate()).padStart(2,
|
|
759
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
760
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
956
761
|
return `${y}-${m}-${day}`;
|
|
957
762
|
}
|
|
958
|
-
|
|
959
|
-
function findGroupOffset(
|
|
960
|
-
nodes: readonly GanttNode[],
|
|
961
|
-
groupPath: readonly string[]
|
|
962
|
-
): Offset | null {
|
|
763
|
+
function findGroupOffset(nodes, groupPath) {
|
|
963
764
|
if (groupPath.length === 0) return null;
|
|
964
|
-
const groupName = groupPath[groupPath.length - 1]
|
|
965
|
-
function search(children
|
|
765
|
+
const groupName = groupPath[groupPath.length - 1];
|
|
766
|
+
function search(children) {
|
|
966
767
|
for (const node of children) {
|
|
967
|
-
if (node.kind ===
|
|
768
|
+
if (node.kind === "group") {
|
|
968
769
|
if (node.name === groupName && node.offset) return node.offset;
|
|
969
770
|
const found = search(node.children);
|
|
970
771
|
if (found) return found;
|
|
971
|
-
} else if (node.kind ===
|
|
772
|
+
} else if (node.kind === "parallel") {
|
|
972
773
|
const found = search(node.children);
|
|
973
774
|
if (found) return found;
|
|
974
775
|
}
|
|
@@ -977,3 +778,10 @@ function findGroupOffset(
|
|
|
977
778
|
}
|
|
978
779
|
return search(nodes);
|
|
979
780
|
}
|
|
781
|
+
|
|
782
|
+
export {
|
|
783
|
+
collectTasks,
|
|
784
|
+
resolveTaskName,
|
|
785
|
+
calculateSchedule
|
|
786
|
+
};
|
|
787
|
+
//# sourceMappingURL=chunk-Z72XRXD4.js.map
|