@knowvah/dot-engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +277 -0
- package/README.md +292 -0
- package/dist/api/builder.d.ts +78 -0
- package/dist/api/builder.d.ts.map +1 -0
- package/dist/api/edge-ops.d.ts +45 -0
- package/dist/api/edge-ops.d.ts.map +1 -0
- package/dist/api/geometry.d.ts +159 -0
- package/dist/api/geometry.d.ts.map +1 -0
- package/dist/api/index.d.ts +24 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api.js +719 -0
- package/dist/api.js.map +7 -0
- package/dist/bundle.js +101 -0
- package/dist/cdt/bag.d.ts +58 -0
- package/dist/cdt/bag.d.ts.map +1 -0
- package/dist/cdt/hash-core.d.ts +40 -0
- package/dist/cdt/hash-core.d.ts.map +1 -0
- package/dist/cdt/hash.d.ts +74 -0
- package/dist/cdt/hash.d.ts.map +1 -0
- package/dist/cdt/index.d.ts +16 -0
- package/dist/cdt/index.d.ts.map +1 -0
- package/dist/cdt/splay-core.d.ts +78 -0
- package/dist/cdt/splay-core.d.ts.map +1 -0
- package/dist/cdt/splay.d.ts +63 -0
- package/dist/cdt/splay.d.ts.map +1 -0
- package/dist/cdt/strhash.d.ts +26 -0
- package/dist/cdt/strhash.d.ts.map +1 -0
- package/dist/cdt/types.d.ts +11 -0
- package/dist/cdt/types.d.ts.map +1 -0
- package/dist/common/arith.d.ts +35 -0
- package/dist/common/arith.d.ts.map +1 -0
- package/dist/common/arm-pow-data.d.ts +17 -0
- package/dist/common/arm-pow-data.d.ts.map +1 -0
- package/dist/common/arm-pow.d.ts +12 -0
- package/dist/common/arm-pow.d.ts.map +1 -0
- package/dist/common/arrows-constants.d.ts +97 -0
- package/dist/common/arrows-constants.d.ts.map +1 -0
- package/dist/common/arrows-geometry.d.ts +24 -0
- package/dist/common/arrows-geometry.d.ts.map +1 -0
- package/dist/common/arrows-miter.d.ts +24 -0
- package/dist/common/arrows-miter.d.ts.map +1 -0
- package/dist/common/arrows-shapes-poly.d.ts +24 -0
- package/dist/common/arrows-shapes-poly.d.ts.map +1 -0
- package/dist/common/arrows-shapes-util.d.ts +77 -0
- package/dist/common/arrows-shapes-util.d.ts.map +1 -0
- package/dist/common/arrows-shapes.d.ts +48 -0
- package/dist/common/arrows-shapes.d.ts.map +1 -0
- package/dist/common/arrows-types.d.ts +59 -0
- package/dist/common/arrows-types.d.ts.map +1 -0
- package/dist/common/arrows.d.ts +69 -0
- package/dist/common/arrows.d.ts.map +1 -0
- package/dist/common/color.d.ts +66 -0
- package/dist/common/color.d.ts.map +1 -0
- package/dist/common/colorData.d.ts +10 -0
- package/dist/common/colorData.d.ts.map +1 -0
- package/dist/common/compass-port.d.ts +39 -0
- package/dist/common/compass-port.d.ts.map +1 -0
- package/dist/common/crand.d.ts +42 -0
- package/dist/common/crand.d.ts.map +1 -0
- package/dist/common/edge-label-init.d.ts +51 -0
- package/dist/common/edge-label-init.d.ts.map +1 -0
- package/dist/common/edge-offset.d.ts +66 -0
- package/dist/common/edge-offset.d.ts.map +1 -0
- package/dist/common/ellipse-wedge.d.ts +10 -0
- package/dist/common/ellipse-wedge.d.ts.map +1 -0
- package/dist/common/emit-types.d.ts +255 -0
- package/dist/common/emit-types.d.ts.map +1 -0
- package/dist/common/fma.d.ts +10 -0
- package/dist/common/fma.d.ts.map +1 -0
- package/dist/common/graph-init.d.ts +61 -0
- package/dist/common/graph-init.d.ts.map +1 -0
- package/dist/common/html-entities.d.ts +17 -0
- package/dist/common/html-entities.d.ts.map +1 -0
- package/dist/common/html-string.d.ts +14 -0
- package/dist/common/html-string.d.ts.map +1 -0
- package/dist/common/htmltable-emit-fill.d.ts +84 -0
- package/dist/common/htmltable-emit-fill.d.ts.map +1 -0
- package/dist/common/htmltable-emit-rules.d.ts +79 -0
- package/dist/common/htmltable-emit-rules.d.ts.map +1 -0
- package/dist/common/htmltable-emit.d.ts +63 -0
- package/dist/common/htmltable-emit.d.ts.map +1 -0
- package/dist/common/htmltable-lex.d.ts +16 -0
- package/dist/common/htmltable-lex.d.ts.map +1 -0
- package/dist/common/htmltable-parse.d.ts +37 -0
- package/dist/common/htmltable-parse.d.ts.map +1 -0
- package/dist/common/htmltable-port.d.ts +15 -0
- package/dist/common/htmltable-port.d.ts.map +1 -0
- package/dist/common/htmltable-pos-runs.d.ts +88 -0
- package/dist/common/htmltable-pos-runs.d.ts.map +1 -0
- package/dist/common/htmltable-pos.d.ts +192 -0
- package/dist/common/htmltable-pos.d.ts.map +1 -0
- package/dist/common/htmltable-types.d.ts +237 -0
- package/dist/common/htmltable-types.d.ts.map +1 -0
- package/dist/common/htmltable.d.ts +74 -0
- package/dist/common/htmltable.d.ts.map +1 -0
- package/dist/common/layers.d.ts +20 -0
- package/dist/common/layers.d.ts.map +1 -0
- package/dist/common/make-label.d.ts +60 -0
- package/dist/common/make-label.d.ts.map +1 -0
- package/dist/common/multicolor.d.ts +46 -0
- package/dist/common/multicolor.d.ts.map +1 -0
- package/dist/common/nodeinit.d.ts +45 -0
- package/dist/common/nodeinit.d.ts.map +1 -0
- package/dist/common/poly-gencode.d.ts +40 -0
- package/dist/common/poly-gencode.d.ts.map +1 -0
- package/dist/common/poly-init.d.ts +51 -0
- package/dist/common/poly-init.d.ts.map +1 -0
- package/dist/common/poly-inside.d.ts +37 -0
- package/dist/common/poly-inside.d.ts.map +1 -0
- package/dist/common/poly-shapes-cases.d.ts +31 -0
- package/dist/common/poly-shapes-cases.d.ts.map +1 -0
- package/dist/common/poly-shapes-cases2.d.ts +25 -0
- package/dist/common/poly-shapes-cases2.d.ts.map +1 -0
- package/dist/common/poly-shapes-util.d.ts +42 -0
- package/dist/common/poly-shapes-util.d.ts.map +1 -0
- package/dist/common/poly-shapes.d.ts +39 -0
- package/dist/common/poly-shapes.d.ts.map +1 -0
- package/dist/common/poly-sizing.d.ts +189 -0
- package/dist/common/poly-sizing.d.ts.map +1 -0
- package/dist/common/poly-vertices.d.ts +42 -0
- package/dist/common/poly-vertices.d.ts.map +1 -0
- package/dist/common/postproc.d.ts +49 -0
- package/dist/common/postproc.d.ts.map +1 -0
- package/dist/common/ps-fontalias.d.ts +36 -0
- package/dist/common/ps-fontalias.d.ts.map +1 -0
- package/dist/common/random.d.ts +8 -0
- package/dist/common/random.d.ts.map +1 -0
- package/dist/common/record-port.d.ts +34 -0
- package/dist/common/record-port.d.ts.map +1 -0
- package/dist/common/record.d.ts +105 -0
- package/dist/common/record.d.ts.map +1 -0
- package/dist/common/shapeData.d.ts +186 -0
- package/dist/common/shapeData.d.ts.map +1 -0
- package/dist/common/shapes.d.ts +36 -0
- package/dist/common/shapes.d.ts.map +1 -0
- package/dist/common/spline-midpoint.d.ts +31 -0
- package/dist/common/spline-midpoint.d.ts.map +1 -0
- package/dist/common/splines-clip.d.ts +21 -0
- package/dist/common/splines-clip.d.ts.map +1 -0
- package/dist/common/splines-constants.d.ts +42 -0
- package/dist/common/splines-constants.d.ts.map +1 -0
- package/dist/common/splines-geom.d.ts +51 -0
- package/dist/common/splines-geom.d.ts.map +1 -0
- package/dist/common/splines-path-begin.d.ts +17 -0
- package/dist/common/splines-path-begin.d.ts.map +1 -0
- package/dist/common/splines-path-end.d.ts +17 -0
- package/dist/common/splines-path-end.d.ts.map +1 -0
- package/dist/common/splines-path-shared.d.ts +53 -0
- package/dist/common/splines-path-shared.d.ts.map +1 -0
- package/dist/common/splines-routespl.d.ts +40 -0
- package/dist/common/splines-routespl.d.ts.map +1 -0
- package/dist/common/splines-selfedge.d.ts +21 -0
- package/dist/common/splines-selfedge.d.ts.map +1 -0
- package/dist/common/splines.d.ts +18 -0
- package/dist/common/splines.d.ts.map +1 -0
- package/dist/common/style-resolve.d.ts +197 -0
- package/dist/common/style-resolve.d.ts.map +1 -0
- package/dist/common/subst.d.ts +31 -0
- package/dist/common/subst.d.ts.map +1 -0
- package/dist/common/taper.d.ts +23 -0
- package/dist/common/taper.d.ts.map +1 -0
- package/dist/common/textmeasure-factory.d.ts +33 -0
- package/dist/common/textmeasure-factory.d.ts.map +1 -0
- package/dist/common/textmeasure-lookup.d.ts +17 -0
- package/dist/common/textmeasure-lookup.d.ts.map +1 -0
- package/dist/common/textmeasure-lut-data-a.d.ts +13 -0
- package/dist/common/textmeasure-lut-data-a.d.ts.map +1 -0
- package/dist/common/textmeasure-lut-data-b.d.ts +12 -0
- package/dist/common/textmeasure-lut-data-b.d.ts.map +1 -0
- package/dist/common/textmeasure-lut-data-c.d.ts +13 -0
- package/dist/common/textmeasure-lut-data-c.d.ts.map +1 -0
- package/dist/common/textmeasure-lut-data.d.ts +27 -0
- package/dist/common/textmeasure-lut-data.d.ts.map +1 -0
- package/dist/common/textmeasure.d.ts +120 -0
- package/dist/common/textmeasure.d.ts.map +1 -0
- package/dist/common/types.d.ts +316 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/xlabels-place.d.ts +125 -0
- package/dist/common/xlabels-place.d.ts.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/errors.d.ts +63 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/gvc/anchor.d.ts +86 -0
- package/dist/gvc/anchor.d.ts.map +1 -0
- package/dist/gvc/context.d.ts +177 -0
- package/dist/gvc/context.d.ts.map +1 -0
- package/dist/gvc/default-context.d.ts +20 -0
- package/dist/gvc/default-context.d.ts.map +1 -0
- package/dist/gvc/device-cluster.d.ts +25 -0
- package/dist/gvc/device-cluster.d.ts.map +1 -0
- package/dist/gvc/device.d.ts +99 -0
- package/dist/gvc/device.d.ts.map +1 -0
- package/dist/gvc/edge-labels.d.ts +10 -0
- package/dist/gvc/edge-labels.d.ts.map +1 -0
- package/dist/gvc/emit-walk.d.ts +22 -0
- package/dist/gvc/emit-walk.d.ts.map +1 -0
- package/dist/gvc/image-resolver.d.ts +44 -0
- package/dist/gvc/image-resolver.d.ts.map +1 -0
- package/dist/gvc/job.d.ts +234 -0
- package/dist/gvc/job.d.ts.map +1 -0
- package/dist/gvc/textlayout.d.ts +33 -0
- package/dist/gvc/textlayout.d.ts.map +1 -0
- package/dist/gvc/textspan-emit.d.ts +41 -0
- package/dist/gvc/textspan-emit.d.ts.map +1 -0
- package/dist/gvc/usershape.d.ts +25 -0
- package/dist/gvc/usershape.d.ts.map +1 -0
- package/dist/gvc/viewport.d.ts +71 -0
- package/dist/gvc/viewport.d.ts.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52862 -0
- package/dist/index.js.map +7 -0
- package/dist/label/index.d.ts +74 -0
- package/dist/label/index.d.ts.map +1 -0
- package/dist/label/node.d.ts +108 -0
- package/dist/label/node.d.ts.map +1 -0
- package/dist/label/rectangle.d.ts +60 -0
- package/dist/label/rectangle.d.ts.map +1 -0
- package/dist/label/split-q.d.ts +13 -0
- package/dist/label/split-q.d.ts.map +1 -0
- package/dist/label/xlabels-geom.d.ts +46 -0
- package/dist/label/xlabels-geom.d.ts.map +1 -0
- package/dist/label/xlabels-intersect.d.ts +79 -0
- package/dist/label/xlabels-intersect.d.ts.map +1 -0
- package/dist/label/xlabels.d.ts +67 -0
- package/dist/label/xlabels.d.ts.map +1 -0
- package/dist/layout/circo/blockpath.d.ts +120 -0
- package/dist/layout/circo/blockpath.d.ts.map +1 -0
- package/dist/layout/circo/blocks.d.ts +135 -0
- package/dist/layout/circo/blocks.d.ts.map +1 -0
- package/dist/layout/circo/blocktree.d.ts +51 -0
- package/dist/layout/circo/blocktree.d.ts.map +1 -0
- package/dist/layout/circo/circular.d.ts +59 -0
- package/dist/layout/circo/circular.d.ts.map +1 -0
- package/dist/layout/circo/index.d.ts +35 -0
- package/dist/layout/circo/index.d.ts.map +1 -0
- package/dist/layout/circo/init.d.ts +50 -0
- package/dist/layout/circo/init.d.ts.map +1 -0
- package/dist/layout/circo/position-helpers.d.ts +33 -0
- package/dist/layout/circo/position-helpers.d.ts.map +1 -0
- package/dist/layout/circo/position.d.ts +66 -0
- package/dist/layout/circo/position.d.ts.map +1 -0
- package/dist/layout/dot/acyclic.d.ts +8 -0
- package/dist/layout/dot/acyclic.d.ts.map +1 -0
- package/dist/layout/dot/aspect.d.ts +17 -0
- package/dist/layout/dot/aspect.d.ts.map +1 -0
- package/dist/layout/dot/classify.d.ts +52 -0
- package/dist/layout/dot/classify.d.ts.map +1 -0
- package/dist/layout/dot/cluster-path.d.ts +38 -0
- package/dist/layout/dot/cluster-path.d.ts.map +1 -0
- package/dist/layout/dot/cluster.d.ts +102 -0
- package/dist/layout/dot/cluster.d.ts.map +1 -0
- package/dist/layout/dot/compound-clip.d.ts +69 -0
- package/dist/layout/dot/compound-clip.d.ts.map +1 -0
- package/dist/layout/dot/compound-geom.d.ts +115 -0
- package/dist/layout/dot/compound-geom.d.ts.map +1 -0
- package/dist/layout/dot/compound.d.ts +56 -0
- package/dist/layout/dot/compound.d.ts.map +1 -0
- package/dist/layout/dot/conc.d.ts +88 -0
- package/dist/layout/dot/conc.d.ts.map +1 -0
- package/dist/layout/dot/decomp.d.ts +66 -0
- package/dist/layout/dot/decomp.d.ts.map +1 -0
- package/dist/layout/dot/edge-order.d.ts +27 -0
- package/dist/layout/dot/edge-order.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-arrow.d.ts +46 -0
- package/dist/layout/dot/edge-route-arrow.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-boxes.d.ts +75 -0
- package/dist/layout/dot/edge-route-boxes.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-chain.d.ts +67 -0
- package/dist/layout/dot/edge-route-chain.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-clip.d.ts +88 -0
- package/dist/layout/dot/edge-route-clip.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-faithful.d.ts +94 -0
- package/dist/layout/dot/edge-route-faithful.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-geom.d.ts +43 -0
- package/dist/layout/dot/edge-route-geom.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-helpers.d.ts +50 -0
- package/dist/layout/dot/edge-route-helpers.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-poly.d.ts +48 -0
- package/dist/layout/dot/edge-route-poly.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-rank.d.ts +57 -0
- package/dist/layout/dot/edge-route-rank.d.ts.map +1 -0
- package/dist/layout/dot/edge-route-routing.d.ts +99 -0
- package/dist/layout/dot/edge-route-routing.d.ts.map +1 -0
- package/dist/layout/dot/edge-route.d.ts +57 -0
- package/dist/layout/dot/edge-route.d.ts.map +1 -0
- package/dist/layout/dot/fastgr.d.ts +147 -0
- package/dist/layout/dot/fastgr.d.ts.map +1 -0
- package/dist/layout/dot/flat-utils.d.ts +21 -0
- package/dist/layout/dot/flat-utils.d.ts.map +1 -0
- package/dist/layout/dot/flat.d.ts +152 -0
- package/dist/layout/dot/flat.d.ts.map +1 -0
- package/dist/layout/dot/graph-label.d.ts +18 -0
- package/dist/layout/dot/graph-label.d.ts.map +1 -0
- package/dist/layout/dot/index.d.ts +128 -0
- package/dist/layout/dot/index.d.ts.map +1 -0
- package/dist/layout/dot/init.d.ts +93 -0
- package/dist/layout/dot/init.d.ts.map +1 -0
- package/dist/layout/dot/label-order.d.ts +45 -0
- package/dist/layout/dot/label-order.d.ts.map +1 -0
- package/dist/layout/dot/mincross-build.d.ts +52 -0
- package/dist/layout/dot/mincross-build.d.ts.map +1 -0
- package/dist/layout/dot/mincross-cross.d.ts +80 -0
- package/dist/layout/dot/mincross-cross.d.ts.map +1 -0
- package/dist/layout/dot/mincross-flat.d.ts +27 -0
- package/dist/layout/dot/mincross-flat.d.ts.map +1 -0
- package/dist/layout/dot/mincross-order.d.ts +89 -0
- package/dist/layout/dot/mincross-order.d.ts.map +1 -0
- package/dist/layout/dot/mincross-utils.d.ts +60 -0
- package/dist/layout/dot/mincross-utils.d.ts.map +1 -0
- package/dist/layout/dot/mincross.d.ts +75 -0
- package/dist/layout/dot/mincross.d.ts.map +1 -0
- package/dist/layout/dot/ns-core.d.ts +37 -0
- package/dist/layout/dot/ns-core.d.ts.map +1 -0
- package/dist/layout/dot/ns-range.d.ts +17 -0
- package/dist/layout/dot/ns-range.d.ts.map +1 -0
- package/dist/layout/dot/ns-subtree.d.ts +78 -0
- package/dist/layout/dot/ns-subtree.d.ts.map +1 -0
- package/dist/layout/dot/ns.d.ts +86 -0
- package/dist/layout/dot/ns.d.ts.map +1 -0
- package/dist/layout/dot/ortho-adapter.d.ts +19 -0
- package/dist/layout/dot/ortho-adapter.d.ts.map +1 -0
- package/dist/layout/dot/pack-components.d.ts +100 -0
- package/dist/layout/dot/pack-components.d.ts.map +1 -0
- package/dist/layout/dot/position-aux.d.ts +110 -0
- package/dist/layout/dot/position-aux.d.ts.map +1 -0
- package/dist/layout/dot/position-bbox.d.ts +57 -0
- package/dist/layout/dot/position-bbox.d.ts.map +1 -0
- package/dist/layout/dot/position-cluster.d.ts +48 -0
- package/dist/layout/dot/position-cluster.d.ts.map +1 -0
- package/dist/layout/dot/position-ycoords.d.ts +42 -0
- package/dist/layout/dot/position-ycoords.d.ts.map +1 -0
- package/dist/layout/dot/position.d.ts +47 -0
- package/dist/layout/dot/position.d.ts.map +1 -0
- package/dist/layout/dot/rank-dot2.d.ts +114 -0
- package/dist/layout/dot/rank-dot2.d.ts.map +1 -0
- package/dist/layout/dot/rank.d.ts +119 -0
- package/dist/layout/dot/rank.d.ts.map +1 -0
- package/dist/layout/dot/sameport.d.ts +70 -0
- package/dist/layout/dot/sameport.d.ts.map +1 -0
- package/dist/layout/dot/self-loop.d.ts +54 -0
- package/dist/layout/dot/self-loop.d.ts.map +1 -0
- package/dist/layout/dot/splines-clone.d.ts +33 -0
- package/dist/layout/dot/splines-clone.d.ts.map +1 -0
- package/dist/layout/dot/splines-flat-labeled.d.ts +101 -0
- package/dist/layout/dot/splines-flat-labeled.d.ts.map +1 -0
- package/dist/layout/dot/splines-flat-multi.d.ts +35 -0
- package/dist/layout/dot/splines-flat-multi.d.ts.map +1 -0
- package/dist/layout/dot/splines-flat.d.ts +116 -0
- package/dist/layout/dot/splines-flat.d.ts.map +1 -0
- package/dist/layout/dot/splines-groups.d.ts +38 -0
- package/dist/layout/dot/splines-groups.d.ts.map +1 -0
- package/dist/layout/dot/splines-label.d.ts +105 -0
- package/dist/layout/dot/splines-label.d.ts.map +1 -0
- package/dist/layout/dot/splines-route-type.d.ts +28 -0
- package/dist/layout/dot/splines-route-type.d.ts.map +1 -0
- package/dist/layout/dot/splines-route.d.ts +99 -0
- package/dist/layout/dot/splines-route.d.ts.map +1 -0
- package/dist/layout/dot/splines.d.ts +157 -0
- package/dist/layout/dot/splines.d.ts.map +1 -0
- package/dist/layout/dot/straight-edges.d.ts +39 -0
- package/dist/layout/dot/straight-edges.d.ts.map +1 -0
- package/dist/layout/fdp/cluster-edges.d.ts +31 -0
- package/dist/layout/fdp/cluster-edges.d.ts.map +1 -0
- package/dist/layout/fdp/comp.d.ts +29 -0
- package/dist/layout/fdp/comp.d.ts.map +1 -0
- package/dist/layout/fdp/derive.d.ts +39 -0
- package/dist/layout/fdp/derive.d.ts.map +1 -0
- package/dist/layout/fdp/fdp-model.d.ts +101 -0
- package/dist/layout/fdp/fdp-model.d.ts.map +1 -0
- package/dist/layout/fdp/grid.d.ts +49 -0
- package/dist/layout/fdp/grid.d.ts.map +1 -0
- package/dist/layout/fdp/index.d.ts +36 -0
- package/dist/layout/fdp/index.d.ts.map +1 -0
- package/dist/layout/fdp/init.d.ts +26 -0
- package/dist/layout/fdp/init.d.ts.map +1 -0
- package/dist/layout/fdp/layout.d.ts +57 -0
- package/dist/layout/fdp/layout.d.ts.map +1 -0
- package/dist/layout/fdp/normalize.d.ts +18 -0
- package/dist/layout/fdp/normalize.d.ts.map +1 -0
- package/dist/layout/fdp/ports.d.ts +41 -0
- package/dist/layout/fdp/ports.d.ts.map +1 -0
- package/dist/layout/fdp/tlayout-init.d.ts +21 -0
- package/dist/layout/fdp/tlayout-init.d.ts.map +1 -0
- package/dist/layout/fdp/tlayout-parms.d.ts +98 -0
- package/dist/layout/fdp/tlayout-parms.d.ts.map +1 -0
- package/dist/layout/fdp/tlayout.d.ts +43 -0
- package/dist/layout/fdp/tlayout.d.ts.map +1 -0
- package/dist/layout/fdp/xlayout.d.ts +26 -0
- package/dist/layout/fdp/xlayout.d.ts.map +1 -0
- package/dist/layout/neato/bfs.d.ts +43 -0
- package/dist/layout/neato/bfs.d.ts.map +1 -0
- package/dist/layout/neato/cdt-surface.d.ts +16 -0
- package/dist/layout/neato/cdt-surface.d.ts.map +1 -0
- package/dist/layout/neato/conjgrad.d.ts +61 -0
- package/dist/layout/neato/conjgrad.d.ts.map +1 -0
- package/dist/layout/neato/delaunay.d.ts +28 -0
- package/dist/layout/neato/delaunay.d.ts.map +1 -0
- package/dist/layout/neato/dijkstra.d.ts +80 -0
- package/dist/layout/neato/dijkstra.d.ts.map +1 -0
- package/dist/layout/neato/fdp-adjust.d.ts +31 -0
- package/dist/layout/neato/fdp-adjust.d.ts.map +1 -0
- package/dist/layout/neato/index.d.ts +58 -0
- package/dist/layout/neato/index.d.ts.map +1 -0
- package/dist/layout/neato/init.d.ts +207 -0
- package/dist/layout/neato/init.d.ts.map +1 -0
- package/dist/layout/neato/legal.d.ts +7 -0
- package/dist/layout/neato/legal.d.ts.map +1 -0
- package/dist/layout/neato/matrix-ops.d.ts +28 -0
- package/dist/layout/neato/matrix-ops.d.ts.map +1 -0
- package/dist/layout/neato/multispline-router.d.ts +80 -0
- package/dist/layout/neato/multispline-router.d.ts.map +1 -0
- package/dist/layout/neato/multispline.d.ts +24 -0
- package/dist/layout/neato/multispline.d.ts.map +1 -0
- package/dist/layout/neato/overlap-prism.d.ts +26 -0
- package/dist/layout/neato/overlap-prism.d.ts.map +1 -0
- package/dist/layout/neato/overlap.d.ts +85 -0
- package/dist/layout/neato/overlap.d.ts.map +1 -0
- package/dist/layout/neato/sc-adjust.d.ts +33 -0
- package/dist/layout/neato/sc-adjust.d.ts.map +1 -0
- package/dist/layout/neato/sep-factor.d.ts +41 -0
- package/dist/layout/neato/sep-factor.d.ts.map +1 -0
- package/dist/layout/neato/set-aspect.d.ts +33 -0
- package/dist/layout/neato/set-aspect.d.ts.map +1 -0
- package/dist/layout/neato/sgd.d.ts +166 -0
- package/dist/layout/neato/sgd.d.ts.map +1 -0
- package/dist/layout/neato/splines.d.ts +153 -0
- package/dist/layout/neato/splines.d.ts.map +1 -0
- package/dist/layout/neato/stress-kernel.d.ts +53 -0
- package/dist/layout/neato/stress-kernel.d.ts.map +1 -0
- package/dist/layout/neato/stress.d.ts +158 -0
- package/dist/layout/neato/stress.d.ts.map +1 -0
- package/dist/layout/osage/index.d.ts +158 -0
- package/dist/layout/osage/index.d.ts.map +1 -0
- package/dist/layout/osage/layout.d.ts +49 -0
- package/dist/layout/osage/layout.d.ts.map +1 -0
- package/dist/layout/osage/types.d.ts +28 -0
- package/dist/layout/osage/types.d.ts.map +1 -0
- package/dist/layout/pack/array-pack.d.ts +114 -0
- package/dist/layout/pack/array-pack.d.ts.map +1 -0
- package/dist/layout/pack/index.d.ts +157 -0
- package/dist/layout/pack/index.d.ts.map +1 -0
- package/dist/layout/pack/poly-pack.d.ts +126 -0
- package/dist/layout/pack/poly-pack.d.ts.map +1 -0
- package/dist/layout/pack/poly-place.d.ts +27 -0
- package/dist/layout/pack/poly-place.d.ts.map +1 -0
- package/dist/layout/pack/spiral-search.d.ts +18 -0
- package/dist/layout/pack/spiral-search.d.ts.map +1 -0
- package/dist/layout/pack/test-helpers.d.ts +7 -0
- package/dist/layout/pack/test-helpers.d.ts.map +1 -0
- package/dist/layout/pack/types.d.ts +74 -0
- package/dist/layout/pack/types.d.ts.map +1 -0
- package/dist/layout/patchwork/index.d.ts +136 -0
- package/dist/layout/patchwork/index.d.ts.map +1 -0
- package/dist/layout/patchwork/tree-map.d.ts +32 -0
- package/dist/layout/patchwork/tree-map.d.ts.map +1 -0
- package/dist/layout/patchwork/tree-node.d.ts +46 -0
- package/dist/layout/patchwork/tree-node.d.ts.map +1 -0
- package/dist/layout/sfdp/index.d.ts +39 -0
- package/dist/layout/sfdp/index.d.ts.map +1 -0
- package/dist/layout/sfdp/init.d.ts +61 -0
- package/dist/layout/sfdp/init.d.ts.map +1 -0
- package/dist/layout/sfdp/multilevel.d.ts +23 -0
- package/dist/layout/sfdp/multilevel.d.ts.map +1 -0
- package/dist/layout/sfdp/quadtree.d.ts +45 -0
- package/dist/layout/sfdp/quadtree.d.ts.map +1 -0
- package/dist/layout/sfdp/sparse-matrix-multiply.d.ts +34 -0
- package/dist/layout/sfdp/sparse-matrix-multiply.d.ts.map +1 -0
- package/dist/layout/sfdp/sparse-matrix.d.ts +101 -0
- package/dist/layout/sfdp/sparse-matrix.d.ts.map +1 -0
- package/dist/layout/sfdp/sparse-solve.d.ts +14 -0
- package/dist/layout/sfdp/sparse-solve.d.ts.map +1 -0
- package/dist/layout/sfdp/spring-driver.d.ts +18 -0
- package/dist/layout/sfdp/spring-driver.d.ts.map +1 -0
- package/dist/layout/sfdp/spring-electrical.d.ts +61 -0
- package/dist/layout/sfdp/spring-electrical.d.ts.map +1 -0
- package/dist/layout/twopi/circle.d.ts +83 -0
- package/dist/layout/twopi/circle.d.ts.map +1 -0
- package/dist/layout/twopi/index.d.ts +24 -0
- package/dist/layout/twopi/index.d.ts.map +1 -0
- package/dist/layout/twopi/init.d.ts +85 -0
- package/dist/layout/twopi/init.d.ts.map +1 -0
- package/dist/layout/twopi/pipeline.d.ts +37 -0
- package/dist/layout/twopi/pipeline.d.ts.map +1 -0
- package/dist/layout/twopi/twopi-test-helpers.d.ts +12 -0
- package/dist/layout/twopi/twopi-test-helpers.d.ts.map +1 -0
- package/dist/model/algData.d.ts +175 -0
- package/dist/model/algData.d.ts.map +1 -0
- package/dist/model/cgraph-ops.d.ts +86 -0
- package/dist/model/cgraph-ops.d.ts.map +1 -0
- package/dist/model/edge.d.ts +80 -0
- package/dist/model/edge.d.ts.map +1 -0
- package/dist/model/edgeInfo.d.ts +299 -0
- package/dist/model/edgeInfo.d.ts.map +1 -0
- package/dist/model/geom.d.ts +149 -0
- package/dist/model/geom.d.ts.map +1 -0
- package/dist/model/graph.d.ts +135 -0
- package/dist/model/graph.d.ts.map +1 -0
- package/dist/model/graphInfo.d.ts +418 -0
- package/dist/model/graphInfo.d.ts.map +1 -0
- package/dist/model/index.d.ts +10 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/layoutParams.d.ts +85 -0
- package/dist/model/layoutParams.d.ts.map +1 -0
- package/dist/model/node.d.ts +101 -0
- package/dist/model/node.d.ts.map +1 -0
- package/dist/model/nodeInfo.d.ts +278 -0
- package/dist/model/nodeInfo.d.ts.map +1 -0
- package/dist/model/rankEntry.d.ts +80 -0
- package/dist/model/rankEntry.d.ts.map +1 -0
- package/dist/ortho/chan-dict.d.ts +82 -0
- package/dist/ortho/chan-dict.d.ts.map +1 -0
- package/dist/ortho/fpq.d.ts +54 -0
- package/dist/ortho/fpq.d.ts.map +1 -0
- package/dist/ortho/index.d.ts +35 -0
- package/dist/ortho/index.d.ts.map +1 -0
- package/dist/ortho/maze-channels.d.ts +47 -0
- package/dist/ortho/maze-channels.d.ts.map +1 -0
- package/dist/ortho/maze.d.ts +27 -0
- package/dist/ortho/maze.d.ts.map +1 -0
- package/dist/ortho/ortho-parallel.d.ts +26 -0
- package/dist/ortho/ortho-parallel.d.ts.map +1 -0
- package/dist/ortho/ortho-route.d.ts +31 -0
- package/dist/ortho/ortho-route.d.ts.map +1 -0
- package/dist/ortho/partition.d.ts +34 -0
- package/dist/ortho/partition.d.ts.map +1 -0
- package/dist/ortho/rawgraph.d.ts +41 -0
- package/dist/ortho/rawgraph.d.ts.map +1 -0
- package/dist/ortho/sgraph.d.ts +74 -0
- package/dist/ortho/sgraph.d.ts.map +1 -0
- package/dist/ortho/trap-query.d.ts +32 -0
- package/dist/ortho/trap-query.d.ts.map +1 -0
- package/dist/ortho/trap-segment.d.ts +23 -0
- package/dist/ortho/trap-segment.d.ts.map +1 -0
- package/dist/ortho/trap-types.d.ts +91 -0
- package/dist/ortho/trap-types.d.ts.map +1 -0
- package/dist/ortho/trap-update.d.ts +12 -0
- package/dist/ortho/trap-update.d.ts.map +1 -0
- package/dist/ortho/trapezoid.d.ts +18 -0
- package/dist/ortho/trapezoid.d.ts.map +1 -0
- package/dist/ortho/types.d.ts +241 -0
- package/dist/ortho/types.d.ts.map +1 -0
- package/dist/parser/ast.d.ts +49 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/builder.d.ts +75 -0
- package/dist/parser/builder.d.ts.map +1 -0
- package/dist/parser/index.d.ts +97 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/pathplan/index.d.ts +8 -0
- package/dist/pathplan/index.d.ts.map +1 -0
- package/dist/pathplan/route.d.ts +9 -0
- package/dist/pathplan/route.d.ts.map +1 -0
- package/dist/pathplan/shortest.d.ts +5 -0
- package/dist/pathplan/shortest.d.ts.map +1 -0
- package/dist/pathplan/solvers.d.ts +5 -0
- package/dist/pathplan/solvers.d.ts.map +1 -0
- package/dist/pathplan/triang.d.ts +25 -0
- package/dist/pathplan/triang.d.ts.map +1 -0
- package/dist/pathplan/types.d.ts +22 -0
- package/dist/pathplan/types.d.ts.map +1 -0
- package/dist/pathplan/visibility.d.ts +13 -0
- package/dist/pathplan/visibility.d.ts.map +1 -0
- package/dist/pathplan/vispath.d.ts +9 -0
- package/dist/pathplan/vispath.d.ts.map +1 -0
- package/dist/rbtree/index.d.ts +127 -0
- package/dist/rbtree/index.d.ts.map +1 -0
- package/dist/render/color-resolve.d.ts +38 -0
- package/dist/render/color-resolve.d.ts.map +1 -0
- package/dist/render/dot.d.ts +379 -0
- package/dist/render/dot.d.ts.map +1 -0
- package/dist/render/index.d.ts +24 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/json.d.ts +89 -0
- package/dist/render/json.d.ts.map +1 -0
- package/dist/render/map-test-helpers.d.ts +13 -0
- package/dist/render/map-test-helpers.d.ts.map +1 -0
- package/dist/render/map.d.ts +197 -0
- package/dist/render/map.d.ts.map +1 -0
- package/dist/render/public.d.ts +64 -0
- package/dist/render/public.d.ts.map +1 -0
- package/dist/render/svg-arrow-ops.d.ts +10 -0
- package/dist/render/svg-arrow-ops.d.ts.map +1 -0
- package/dist/render/svg-cluster.d.ts +9 -0
- package/dist/render/svg-cluster.d.ts.map +1 -0
- package/dist/render/svg-edge-ortho-radius.d.ts +31 -0
- package/dist/render/svg-edge-ortho-radius.d.ts.map +1 -0
- package/dist/render/svg-edge-split.d.ts +48 -0
- package/dist/render/svg-edge-split.d.ts.map +1 -0
- package/dist/render/svg-gradient.d.ts +46 -0
- package/dist/render/svg-gradient.d.ts.map +1 -0
- package/dist/render/svg-graph.d.ts +97 -0
- package/dist/render/svg-graph.d.ts.map +1 -0
- package/dist/render/svg-helpers.d.ts +122 -0
- package/dist/render/svg-helpers.d.ts.map +1 -0
- package/dist/render/svg-id.d.ts +28 -0
- package/dist/render/svg-id.d.ts.map +1 -0
- package/dist/render/svg-multicolor.d.ts +60 -0
- package/dist/render/svg-multicolor.d.ts.map +1 -0
- package/dist/render/svg-parallel-edge.d.ts +28 -0
- package/dist/render/svg-parallel-edge.d.ts.map +1 -0
- package/dist/render/svg-tapered-edge.d.ts +18 -0
- package/dist/render/svg-tapered-edge.d.ts.map +1 -0
- package/dist/render/svg.d.ts +104 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/xdot-public.d.ts +95 -0
- package/dist/render/xdot-public.d.ts.map +1 -0
- package/dist/render/xml-escape.d.ts +21 -0
- package/dist/render/xml-escape.d.ts.map +1 -0
- package/dist/render.js +52556 -0
- package/dist/render.js.map +7 -0
- package/dist/util/agxbuf.d.ts +72 -0
- package/dist/util/agxbuf.d.ts.map +1 -0
- package/dist/util/bsd-qsort.d.ts +22 -0
- package/dist/util/bsd-qsort.d.ts.map +1 -0
- package/dist/util/index.d.ts +11 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/list.d.ts +47 -0
- package/dist/util/list.d.ts.map +1 -0
- package/dist/util/math.d.ts +54 -0
- package/dist/util/math.d.ts.map +1 -0
- package/dist/util/mt19937.d.ts +40 -0
- package/dist/util/mt19937.d.ts.map +1 -0
- package/dist/util/printf-round.d.ts +45 -0
- package/dist/util/printf-round.d.ts.map +1 -0
- package/dist/util/xml.d.ts +24 -0
- package/dist/util/xml.d.ts.map +1 -0
- package/dist/vpsc/Block.d.ts +116 -0
- package/dist/vpsc/Block.d.ts.map +1 -0
- package/dist/vpsc/Blocks.d.ts +66 -0
- package/dist/vpsc/Blocks.d.ts.map +1 -0
- package/dist/vpsc/Constraint.d.ts +51 -0
- package/dist/vpsc/Constraint.d.ts.map +1 -0
- package/dist/vpsc/HeapUtils.d.ts +37 -0
- package/dist/vpsc/HeapUtils.d.ts.map +1 -0
- package/dist/vpsc/Solver.d.ts +107 -0
- package/dist/vpsc/Solver.d.ts.map +1 -0
- package/dist/vpsc/SweepLine.d.ts +38 -0
- package/dist/vpsc/SweepLine.d.ts.map +1 -0
- package/dist/vpsc/Variable.d.ts +38 -0
- package/dist/vpsc/Variable.d.ts.map +1 -0
- package/dist/vpsc/index.d.ts +54 -0
- package/dist/vpsc/index.d.ts.map +1 -0
- package/dist/vpsc/sweepTypes.d.ts +29 -0
- package/dist/vpsc/sweepTypes.d.ts.map +1 -0
- package/dist/xdot/index.d.ts +6 -0
- package/dist/xdot/index.d.ts.map +1 -0
- package/dist/xdot/lex.d.ts +22 -0
- package/dist/xdot/lex.d.ts.map +1 -0
- package/dist/xdot/misc.d.ts +13 -0
- package/dist/xdot/misc.d.ts.map +1 -0
- package/dist/xdot/parse.d.ts +21 -0
- package/dist/xdot/parse.d.ts.map +1 -0
- package/dist/xdot/types.d.ts +152 -0
- package/dist/xdot/types.d.ts.map +1 -0
- package/package.json +113 -0
- package/src/api/builder.ts +277 -0
- package/src/api/edge-ops.ts +113 -0
- package/src/api/geometry.ts +307 -0
- package/src/api/index.ts +46 -0
- package/src/cdt/bag.ts +196 -0
- package/src/cdt/hash-core.ts +84 -0
- package/src/cdt/hash.ts +207 -0
- package/src/cdt/index.ts +17 -0
- package/src/cdt/splay-core.ts +301 -0
- package/src/cdt/splay.ts +191 -0
- package/src/cdt/strhash.ts +52 -0
- package/src/cdt/types.ts +13 -0
- package/src/common/arith.ts +39 -0
- package/src/common/arm-pow-data.ts +201 -0
- package/src/common/arm-pow.ts +296 -0
- package/src/common/arrows-constants.ts +175 -0
- package/src/common/arrows-geometry.ts +62 -0
- package/src/common/arrows-miter.ts +84 -0
- package/src/common/arrows-shapes-poly.ts +241 -0
- package/src/common/arrows-shapes-util.ts +162 -0
- package/src/common/arrows-shapes.ts +360 -0
- package/src/common/arrows-types.ts +59 -0
- package/src/common/arrows.ts +209 -0
- package/src/common/color.ts +340 -0
- package/src/common/colorData.ts +264 -0
- package/src/common/compass-port.ts +384 -0
- package/src/common/crand.ts +79 -0
- package/src/common/edge-label-init.ts +310 -0
- package/src/common/edge-offset.ts +140 -0
- package/src/common/ellipse-wedge.ts +189 -0
- package/src/common/emit-types.ts +332 -0
- package/src/common/fma.ts +52 -0
- package/src/common/graph-init.ts +359 -0
- package/src/common/html-entities.ts +299 -0
- package/src/common/html-string.ts +22 -0
- package/src/common/htmltable-emit-fill.ts +367 -0
- package/src/common/htmltable-emit-rules.ts +293 -0
- package/src/common/htmltable-emit.ts +345 -0
- package/src/common/htmltable-lex.ts +138 -0
- package/src/common/htmltable-parse.ts +539 -0
- package/src/common/htmltable-port.ts +32 -0
- package/src/common/htmltable-pos-runs.ts +313 -0
- package/src/common/htmltable-pos.ts +601 -0
- package/src/common/htmltable-types.ts +262 -0
- package/src/common/htmltable.ts +477 -0
- package/src/common/layers.ts +113 -0
- package/src/common/make-label.ts +192 -0
- package/src/common/multicolor.ts +167 -0
- package/src/common/nodeinit.ts +339 -0
- package/src/common/poly-gencode.ts +475 -0
- package/src/common/poly-init.ts +133 -0
- package/src/common/poly-inside.ts +202 -0
- package/src/common/poly-shapes-cases.ts +253 -0
- package/src/common/poly-shapes-cases2.ts +170 -0
- package/src/common/poly-shapes-util.ts +124 -0
- package/src/common/poly-shapes.ts +181 -0
- package/src/common/poly-sizing.ts +639 -0
- package/src/common/poly-vertices.ts +237 -0
- package/src/common/postproc.ts +436 -0
- package/src/common/ps-fontalias.ts +112 -0
- package/src/common/random.ts +37 -0
- package/src/common/record-port.ts +89 -0
- package/src/common/record.ts +523 -0
- package/src/common/shapeData.ts +502 -0
- package/src/common/shapes.ts +187 -0
- package/src/common/spline-midpoint.ts +105 -0
- package/src/common/splines-clip.ts +449 -0
- package/src/common/splines-constants.ts +53 -0
- package/src/common/splines-geom.ts +194 -0
- package/src/common/splines-path-begin.ts +243 -0
- package/src/common/splines-path-end.ts +231 -0
- package/src/common/splines-path-shared.ts +258 -0
- package/src/common/splines-routespl.ts +444 -0
- package/src/common/splines-selfedge.ts +403 -0
- package/src/common/splines.ts +33 -0
- package/src/common/style-resolve.ts +481 -0
- package/src/common/subst.ts +126 -0
- package/src/common/taper.ts +219 -0
- package/src/common/textmeasure-factory.ts +86 -0
- package/src/common/textmeasure-lookup.ts +50 -0
- package/src/common/textmeasure-lut-data-a.ts +182 -0
- package/src/common/textmeasure-lut-data-b.ts +140 -0
- package/src/common/textmeasure-lut-data-c.ts +221 -0
- package/src/common/textmeasure-lut-data.ts +78 -0
- package/src/common/textmeasure.ts +321 -0
- package/src/common/types.ts +425 -0
- package/src/common/xlabels-place.ts +475 -0
- package/src/debug.ts +38 -0
- package/src/errors.ts +95 -0
- package/src/gvc/anchor.ts +530 -0
- package/src/gvc/context.ts +260 -0
- package/src/gvc/default-context.ts +70 -0
- package/src/gvc/device-cluster.ts +114 -0
- package/src/gvc/device.ts +598 -0
- package/src/gvc/edge-labels.ts +116 -0
- package/src/gvc/emit-walk.ts +98 -0
- package/src/gvc/image-resolver.ts +137 -0
- package/src/gvc/job.ts +401 -0
- package/src/gvc/textlayout.ts +44 -0
- package/src/gvc/textspan-emit.ts +100 -0
- package/src/gvc/usershape.ts +33 -0
- package/src/gvc/viewport.ts +203 -0
- package/src/index.ts +165 -0
- package/src/label/index.ts +302 -0
- package/src/label/node.ts +278 -0
- package/src/label/rectangle.ts +123 -0
- package/src/label/split-q.ts +237 -0
- package/src/label/xlabels-geom.ts +132 -0
- package/src/label/xlabels-intersect.ts +421 -0
- package/src/label/xlabels.ts +212 -0
- package/src/layout/circo/blockpath.ts +560 -0
- package/src/layout/circo/blocks.ts +234 -0
- package/src/layout/circo/blocktree.ts +246 -0
- package/src/layout/circo/circular.ts +227 -0
- package/src/layout/circo/index.ts +90 -0
- package/src/layout/circo/init.ts +84 -0
- package/src/layout/circo/position-helpers.ts +104 -0
- package/src/layout/circo/position.ts +196 -0
- package/src/layout/dot/__fixtures__/xcoord-pivot-divergence.gv +79 -0
- package/src/layout/dot/acyclic.ts +60 -0
- package/src/layout/dot/aspect.ts +22 -0
- package/src/layout/dot/classify.ts +462 -0
- package/src/layout/dot/cluster-path.ts +200 -0
- package/src/layout/dot/cluster.ts +480 -0
- package/src/layout/dot/compound-clip.ts +224 -0
- package/src/layout/dot/compound-geom.ts +282 -0
- package/src/layout/dot/compound.ts +294 -0
- package/src/layout/dot/conc.ts +433 -0
- package/src/layout/dot/decomp.ts +165 -0
- package/src/layout/dot/edge-order.ts +62 -0
- package/src/layout/dot/edge-route-arrow.ts +87 -0
- package/src/layout/dot/edge-route-boxes.ts +99 -0
- package/src/layout/dot/edge-route-chain.ts +420 -0
- package/src/layout/dot/edge-route-clip.ts +253 -0
- package/src/layout/dot/edge-route-faithful.ts +404 -0
- package/src/layout/dot/edge-route-geom.ts +90 -0
- package/src/layout/dot/edge-route-helpers.ts +170 -0
- package/src/layout/dot/edge-route-poly.ts +174 -0
- package/src/layout/dot/edge-route-rank.ts +136 -0
- package/src/layout/dot/edge-route-routing.ts +219 -0
- package/src/layout/dot/edge-route.ts +490 -0
- package/src/layout/dot/fastgr.ts +377 -0
- package/src/layout/dot/flat-utils.ts +52 -0
- package/src/layout/dot/flat.ts +518 -0
- package/src/layout/dot/graph-label.ts +114 -0
- package/src/layout/dot/index.ts +302 -0
- package/src/layout/dot/init.ts +300 -0
- package/src/layout/dot/label-order.ts +161 -0
- package/src/layout/dot/mincross-build.ts +373 -0
- package/src/layout/dot/mincross-cross.ts +409 -0
- package/src/layout/dot/mincross-flat.ts +213 -0
- package/src/layout/dot/mincross-order.ts +401 -0
- package/src/layout/dot/mincross-utils.ts +170 -0
- package/src/layout/dot/mincross.ts +386 -0
- package/src/layout/dot/ns-core.ts +122 -0
- package/src/layout/dot/ns-range.ts +228 -0
- package/src/layout/dot/ns-subtree.ts +347 -0
- package/src/layout/dot/ns.ts +506 -0
- package/src/layout/dot/ortho-adapter.ts +133 -0
- package/src/layout/dot/pack-components.ts +433 -0
- package/src/layout/dot/position-aux.ts +382 -0
- package/src/layout/dot/position-bbox.ts +221 -0
- package/src/layout/dot/position-cluster.ts +286 -0
- package/src/layout/dot/position-ycoords.ts +287 -0
- package/src/layout/dot/position.ts +194 -0
- package/src/layout/dot/rank-dot2.ts +528 -0
- package/src/layout/dot/rank.ts +547 -0
- package/src/layout/dot/sameport.ts +278 -0
- package/src/layout/dot/self-loop.ts +147 -0
- package/src/layout/dot/splines-clone.ts +121 -0
- package/src/layout/dot/splines-flat-labeled.ts +408 -0
- package/src/layout/dot/splines-flat-multi.ts +188 -0
- package/src/layout/dot/splines-flat.ts +598 -0
- package/src/layout/dot/splines-groups.ts +190 -0
- package/src/layout/dot/splines-label.ts +432 -0
- package/src/layout/dot/splines-route-type.ts +44 -0
- package/src/layout/dot/splines-route.ts +478 -0
- package/src/layout/dot/splines.ts +538 -0
- package/src/layout/dot/straight-edges.ts +332 -0
- package/src/layout/fdp/cluster-edges.ts +0 -0
- package/src/layout/fdp/comp.ts +160 -0
- package/src/layout/fdp/derive.ts +272 -0
- package/src/layout/fdp/fdp-model.ts +238 -0
- package/src/layout/fdp/grid.ts +77 -0
- package/src/layout/fdp/index.ts +113 -0
- package/src/layout/fdp/init.ts +116 -0
- package/src/layout/fdp/layout.ts +485 -0
- package/src/layout/fdp/normalize.ts +100 -0
- package/src/layout/fdp/ports.ts +161 -0
- package/src/layout/fdp/tlayout-init.ts +230 -0
- package/src/layout/fdp/tlayout-parms.ts +234 -0
- package/src/layout/fdp/tlayout.ts +317 -0
- package/src/layout/fdp/xlayout.ts +350 -0
- package/src/layout/neato/bfs.ts +131 -0
- package/src/layout/neato/cdt-surface.ts +693 -0
- package/src/layout/neato/conjgrad.ts +159 -0
- package/src/layout/neato/delaunay.ts +259 -0
- package/src/layout/neato/dijkstra.ts +296 -0
- package/src/layout/neato/fdp-adjust.ts +124 -0
- package/src/layout/neato/index.ts +310 -0
- package/src/layout/neato/init.ts +505 -0
- package/src/layout/neato/legal.ts +316 -0
- package/src/layout/neato/matrix-ops.ts +112 -0
- package/src/layout/neato/multispline-router.ts +417 -0
- package/src/layout/neato/multispline.ts +427 -0
- package/src/layout/neato/overlap-prism.ts +503 -0
- package/src/layout/neato/overlap.ts +158 -0
- package/src/layout/neato/sc-adjust.ts +206 -0
- package/src/layout/neato/sep-factor.ts +118 -0
- package/src/layout/neato/set-aspect.ts +178 -0
- package/src/layout/neato/sgd.ts +461 -0
- package/src/layout/neato/splines.ts +1014 -0
- package/src/layout/neato/stress-kernel.ts +362 -0
- package/src/layout/neato/stress.ts +420 -0
- package/src/layout/osage/index.ts +548 -0
- package/src/layout/osage/layout.ts +254 -0
- package/src/layout/osage/types.ts +31 -0
- package/src/layout/pack/array-pack.ts +254 -0
- package/src/layout/pack/index.ts +570 -0
- package/src/layout/pack/poly-pack.ts +266 -0
- package/src/layout/pack/poly-place.ts +426 -0
- package/src/layout/pack/spiral-search.ts +106 -0
- package/src/layout/pack/test-helpers.ts +46 -0
- package/src/layout/pack/types.ts +85 -0
- package/src/layout/patchwork/index.ts +441 -0
- package/src/layout/patchwork/tree-map.ts +183 -0
- package/src/layout/patchwork/tree-node.ts +120 -0
- package/src/layout/sfdp/index.ts +231 -0
- package/src/layout/sfdp/init.ts +224 -0
- package/src/layout/sfdp/multilevel.ts +262 -0
- package/src/layout/sfdp/quadtree.ts +267 -0
- package/src/layout/sfdp/sparse-matrix-multiply.ts +160 -0
- package/src/layout/sfdp/sparse-matrix.ts +367 -0
- package/src/layout/sfdp/sparse-solve.ts +122 -0
- package/src/layout/sfdp/spring-driver.ts +209 -0
- package/src/layout/sfdp/spring-electrical.ts +431 -0
- package/src/layout/twopi/circle.ts +339 -0
- package/src/layout/twopi/index.ts +78 -0
- package/src/layout/twopi/init.ts +174 -0
- package/src/layout/twopi/pipeline.ts +98 -0
- package/src/layout/twopi/twopi-test-helpers.ts +44 -0
- package/src/model/algData.ts +194 -0
- package/src/model/cgraph-ops.ts +175 -0
- package/src/model/edge.ts +104 -0
- package/src/model/edgeInfo.ts +431 -0
- package/src/model/geom.ts +204 -0
- package/src/model/graph.ts +172 -0
- package/src/model/graphInfo.ts +528 -0
- package/src/model/index.ts +10 -0
- package/src/model/layoutParams.ts +127 -0
- package/src/model/node.ts +138 -0
- package/src/model/nodeInfo.ts +424 -0
- package/src/model/rankEntry.ts +95 -0
- package/src/ortho/chan-dict.ts +236 -0
- package/src/ortho/fpq.ts +149 -0
- package/src/ortho/index.ts +206 -0
- package/src/ortho/maze-channels.ts +196 -0
- package/src/ortho/maze.ts +311 -0
- package/src/ortho/ortho-parallel.ts +254 -0
- package/src/ortho/ortho-route.ts +349 -0
- package/src/ortho/partition.ts +303 -0
- package/src/ortho/rawgraph.ts +119 -0
- package/src/ortho/sgraph.ts +283 -0
- package/src/ortho/trap-query.ts +174 -0
- package/src/ortho/trap-segment.ts +303 -0
- package/src/ortho/trap-types.ts +171 -0
- package/src/ortho/trap-update.ts +89 -0
- package/src/ortho/trapezoid.ts +120 -0
- package/src/ortho/types.ts +286 -0
- package/src/parser/__fixtures__/directed.dot +10 -0
- package/src/parser/__fixtures__/simple.dot +7 -0
- package/src/parser/__fixtures__/subgraph.dot +17 -0
- package/src/parser/ast.ts +64 -0
- package/src/parser/builder.ts +401 -0
- package/src/parser/dot.d.ts +208 -0
- package/src/parser/dot.js +3321 -0
- package/src/parser/dot.pegjs +263 -0
- package/src/parser/index.ts +353 -0
- package/src/pathplan/index.ts +9 -0
- package/src/pathplan/route.ts +284 -0
- package/src/pathplan/shortest.ts +268 -0
- package/src/pathplan/solvers.ts +65 -0
- package/src/pathplan/triang.ts +221 -0
- package/src/pathplan/types.ts +16 -0
- package/src/pathplan/visibility.ts +170 -0
- package/src/pathplan/vispath.ts +118 -0
- package/src/rbtree/index.ts +418 -0
- package/src/render/color-resolve.ts +171 -0
- package/src/render/dot.ts +1514 -0
- package/src/render/index.ts +29 -0
- package/src/render/json.ts +734 -0
- package/src/render/map-test-helpers.ts +61 -0
- package/src/render/map.ts +528 -0
- package/src/render/public.ts +131 -0
- package/src/render/svg-arrow-ops.ts +113 -0
- package/src/render/svg-cluster.ts +24 -0
- package/src/render/svg-edge-ortho-radius.ts +228 -0
- package/src/render/svg-edge-split.ts +180 -0
- package/src/render/svg-gradient.ts +185 -0
- package/src/render/svg-graph.ts +415 -0
- package/src/render/svg-helpers.ts +623 -0
- package/src/render/svg-id.ts +76 -0
- package/src/render/svg-multicolor.ts +313 -0
- package/src/render/svg-parallel-edge.ts +123 -0
- package/src/render/svg-tapered-edge.ts +56 -0
- package/src/render/svg.ts +307 -0
- package/src/render/xdot-public.ts +164 -0
- package/src/render/xml-escape.ts +56 -0
- package/src/util/agxbuf.ts +138 -0
- package/src/util/bsd-qsort.ts +251 -0
- package/src/util/index.ts +25 -0
- package/src/util/list.ts +122 -0
- package/src/util/math.ts +104 -0
- package/src/util/mt19937.ts +143 -0
- package/src/util/printf-round.ts +163 -0
- package/src/util/xml.ts +184 -0
- package/src/vpsc/Block.ts +375 -0
- package/src/vpsc/Blocks.ts +164 -0
- package/src/vpsc/Constraint.ts +94 -0
- package/src/vpsc/HeapUtils.ts +88 -0
- package/src/vpsc/Solver.ts +274 -0
- package/src/vpsc/SweepLine.ts +214 -0
- package/src/vpsc/Variable.ts +54 -0
- package/src/vpsc/index.ts +122 -0
- package/src/vpsc/sweepTypes.ts +31 -0
- package/src/xdot/index.ts +7 -0
- package/src/xdot/lex.ts +151 -0
- package/src/xdot/misc.ts +226 -0
- package/src/xdot/parse.ts +349 -0
- package/src/xdot/types.ts +158 -0
|
@@ -0,0 +1,1014 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EPL-2.0
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Neato spline routing entry point.
|
|
5
|
+
*
|
|
6
|
+
* Faithful port of lib/neatogen/neatosplines.c — splineEdges dispatch,
|
|
7
|
+
* makeObstacle, makeSelfArcs, and supporting helpers.
|
|
8
|
+
*
|
|
9
|
+
* Full multispline.c routing is stubbed: when pathplan-based routing is
|
|
10
|
+
* attempted but would require multi-path resolution, the code falls back to
|
|
11
|
+
* straight-line edges. This covers the acceptance criteria surface area.
|
|
12
|
+
*
|
|
13
|
+
* @see lib/neatogen/neatosplines.c
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { Graph } from '../../model/graph.js';
|
|
17
|
+
import type { Node } from '../../model/node.js';
|
|
18
|
+
import type { Edge } from '../../model/edge.js';
|
|
19
|
+
import type { Point } from '../../model/geom.js';
|
|
20
|
+
import type { SplineInfo, PolygonT, TextlabelT } from '../../common/types.js';
|
|
21
|
+
import { polygonOutlineRing } from '../../common/poly-sizing.js';
|
|
22
|
+
import { ShapeKind } from '../../common/types.js';
|
|
23
|
+
import type { ExpandT } from './sep-factor.js';
|
|
24
|
+
import { esepFactor } from './sep-factor.js';
|
|
25
|
+
import type { Poly, VConfig } from '../../pathplan/types.js';
|
|
26
|
+
import {
|
|
27
|
+
obsOpen, obsClose, obsPath,
|
|
28
|
+
routeSpline, polyBarriers,
|
|
29
|
+
POLYID_NONE, inPoly,
|
|
30
|
+
} from '../../pathplan/index.js';
|
|
31
|
+
import { makeSelfEdge } from '../../common/splines.js';
|
|
32
|
+
import { newSpline, clipAndInstall } from '../../common/splines-clip.js';
|
|
33
|
+
import { orthoEdges } from '../../ortho/index.js';
|
|
34
|
+
import type { OrthoGraph, OrthoEdge, OrthoPoint } from '../../ortho/index.js';
|
|
35
|
+
import {
|
|
36
|
+
EDGETYPE_NONE, EDGETYPE_LINE, EDGETYPE_ORTHO,
|
|
37
|
+
EDGETYPE_PLINE,
|
|
38
|
+
} from '../dot/splines.js';
|
|
39
|
+
import { shiftGraphBBs } from '../pack/index.js';
|
|
40
|
+
import { neatoSetAspect } from './init.js';
|
|
41
|
+
import { nodesInSeq } from '../dot/decomp.js';
|
|
42
|
+
import { mapbool } from '../dot/rank.js';
|
|
43
|
+
import { lateDouble } from '../../common/nodeinit.js';
|
|
44
|
+
import { makeStraightEdges, addEdgeLabels } from '../dot/straight-edges.js';
|
|
45
|
+
import { makeMultiSpline, mkRouter } from './multispline.js';
|
|
46
|
+
import { legalArrangement } from './legal.js';
|
|
47
|
+
import type { Router } from './multispline.js';
|
|
48
|
+
import { updateBB } from '../dot/splines-label.js';
|
|
49
|
+
import { resolvePort } from '../../common/splines-path-shared.js';
|
|
50
|
+
import { cround } from '../../common/arith.js';
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Re-export EDGETYPE constants for consumers of this module
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
EDGETYPE_NONE, EDGETYPE_LINE, EDGETYPE_ORTHO,
|
|
58
|
+
EDGETYPE_PLINE, EDGETYPE_SPLINE,
|
|
59
|
+
} from '../dot/splines.js';
|
|
60
|
+
export const EDGETYPE_CURVED = 2;
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Named type aliases — avoids inline generics/brackets that confuse lizard
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
/** Vertex array matching Poly.ps. */
|
|
67
|
+
type PolyPoints = Point[];
|
|
68
|
+
|
|
69
|
+
/** Node list matching OrthoGraph.nodes. */
|
|
70
|
+
type OrthoNodeList = OrthoGraph['nodes'];
|
|
71
|
+
|
|
72
|
+
/** Open visibility config produced by obsOpen(). */
|
|
73
|
+
type VisConfig = VConfig;
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// SplineInfo: neato always uses identity callbacks (no merge, no swap)
|
|
77
|
+
// @see lib/neatogen/neatosplines.c:sinfo
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/** @see lib/neatogen/neatosplines.c:swap_ends_p */
|
|
81
|
+
export function swapEndsP(_e: unknown): boolean { return false; }
|
|
82
|
+
|
|
83
|
+
/** @see lib/neatogen/neatosplines.c:spline_merge */
|
|
84
|
+
export function splineMerge(_n: unknown): boolean { return false; }
|
|
85
|
+
|
|
86
|
+
/** @see lib/neatogen/neatosplines.c:sinfo */
|
|
87
|
+
export const SINFO: SplineInfo = {
|
|
88
|
+
swapEnds: swapEndsP,
|
|
89
|
+
splineMerge: splineMerge,
|
|
90
|
+
ignoreSwap: false,
|
|
91
|
+
isOrtho: false,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/** @see lib/ortho/ortho.c:1269 — {swap_ends_p, spline_merge, true, true} */
|
|
95
|
+
const ORTHO_SINFO: SplineInfo = {
|
|
96
|
+
...SINFO,
|
|
97
|
+
ignoreSwap: true,
|
|
98
|
+
isOrtho: true,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// ObstacleHelper — makeObstacle internals
|
|
103
|
+
// Class wrapper resets lizard's brace counter at each class boundary.
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
class ObstacleHelper {
|
|
107
|
+
static halfHeight(ht: number, sepY: number): number {
|
|
108
|
+
return ht / 2 + sepY;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static vertices(
|
|
112
|
+
cx: number, cy: number,
|
|
113
|
+
hw: number, rw: number, hh: number,
|
|
114
|
+
): PolyPoints {
|
|
115
|
+
return [
|
|
116
|
+
{ x: cx - hw, y: cy - hh },
|
|
117
|
+
{ x: cx - hw, y: cy + hh },
|
|
118
|
+
{ x: cx + rw, y: cy + hh },
|
|
119
|
+
{ x: cx + rw, y: cy - hh },
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// makeObstacle
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
/** Slope of the ellipse tangent at p. @see neatosplines.c:ellipse_tangent_slope */
|
|
129
|
+
function ellipseTangentSlope(a: number, b: number, p: Point): number {
|
|
130
|
+
const signY = p.y >= 0 ? 1 : -1;
|
|
131
|
+
return (-signY * (b * p.x)) / (a * Math.sqrt(a * a - p.x * p.x));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Corner i of an nsides-gon circumscribed about the ellipse (a, b).
|
|
135
|
+
* @see neatosplines.c:circumscribed_polygon_corner_about_ellipse */
|
|
136
|
+
function circumscribedCorner(a: number, b: number, i: number, nsides: number): Point {
|
|
137
|
+
const angle0 = (2 * Math.PI * (i - 0.5)) / nsides;
|
|
138
|
+
const angle1 = (2 * Math.PI * (i + 0.5)) / nsides;
|
|
139
|
+
const p0 = { x: a * Math.cos(angle0), y: b * Math.sin(angle0) };
|
|
140
|
+
const p1 = { x: a * Math.cos(angle1), y: b * Math.sin(angle1) };
|
|
141
|
+
const m0 = ellipseTangentSlope(a, b, p0);
|
|
142
|
+
const m1 = ellipseTangentSlope(a, b, p1);
|
|
143
|
+
// line_intersection of the two tangents.
|
|
144
|
+
const x = (m0 * p0.x - p0.y - m1 * p1.x + p1.y) / (m0 - m1);
|
|
145
|
+
const y = p0.y + m0 * (x - p0.x);
|
|
146
|
+
return { x, y };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Margin displacement for corner j of a 4-sided polygon (CCW box order:
|
|
150
|
+
* LL, LR, UR, UL — C's case 0..3). @see makeObstacle (doAdd, sides==4) */
|
|
151
|
+
function boxCornerMargin(j: number, m: Point): Point {
|
|
152
|
+
if (j === 0) return { x: m.x, y: m.y };
|
|
153
|
+
if (j === 1) return { x: -m.x, y: m.y };
|
|
154
|
+
if (j === 2) return { x: -m.x, y: -m.y };
|
|
155
|
+
return { x: m.x, y: -m.y };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The poly-vertices (sides >= 3) branch of C makeObstacle. */
|
|
159
|
+
function polyObstacle(
|
|
160
|
+
n: Node, poly: PolygonT, pmargin: ExpandT,
|
|
161
|
+
): Poly | null {
|
|
162
|
+
const sides = poly.sides;
|
|
163
|
+
const stored = poly.vertices;
|
|
164
|
+
if (stored == null) return null;
|
|
165
|
+
const penwidth = poly.penwidth ?? 1;
|
|
166
|
+
const extraPeripheries = poly.peripheries >= 1 && penwidth > 0 ? 1 : 0;
|
|
167
|
+
const outlinePeriphery = poly.peripheries + extraPeripheries;
|
|
168
|
+
const ringIdx = outlinePeriphery >= 1 ? outlinePeriphery - 1 : 0;
|
|
169
|
+
// C stores the half-penwidth OUTLINE ring in poly->vertices
|
|
170
|
+
// (shapes.c:poly_init outp); the port keeps only the periphery rings and
|
|
171
|
+
// derives the outline on demand, exactly like poly_inside does.
|
|
172
|
+
const storedRings = Math.max(poly.peripheries, 1);
|
|
173
|
+
let verts: Point[];
|
|
174
|
+
if (ringIdx < storedRings) {
|
|
175
|
+
verts = stored.slice(ringIdx * sides, (ringIdx + 1) * sides);
|
|
176
|
+
} else {
|
|
177
|
+
const outer = stored.slice((storedRings - 1) * sides, storedRings * sides);
|
|
178
|
+
verts = polygonOutlineRing(outer, sides, penwidth);
|
|
179
|
+
}
|
|
180
|
+
if (verts.length < sides) return null;
|
|
181
|
+
const ps: Point[] = new Array(sides);
|
|
182
|
+
for (let j = 0; j < sides; j++) {
|
|
183
|
+
const v = verts[j];
|
|
184
|
+
if (v === undefined) return null;
|
|
185
|
+
let polyp: Point;
|
|
186
|
+
if (pmargin.doAdd) {
|
|
187
|
+
if (sides === 4) {
|
|
188
|
+
// C's corner cases assume the CCW box vertex order LL,LR,UR,UL.
|
|
189
|
+
const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
|
|
190
|
+
polyp = { x: v.x + m.x, y: v.y + m.y };
|
|
191
|
+
} else {
|
|
192
|
+
const h = Math.hypot(v.x, v.y);
|
|
193
|
+
polyp = { x: v.x * (1 + pmargin.x / h), y: v.y * (1 + pmargin.y / h) };
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
|
|
197
|
+
}
|
|
198
|
+
// CW output: ps[sides - j - 1].
|
|
199
|
+
ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
|
|
200
|
+
}
|
|
201
|
+
return { ps };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** The ellipse (sides < 3) branch: 8-gon circumscribed about the OUTLINE
|
|
205
|
+
* ellipse, margin added only when doAdd. */
|
|
206
|
+
function ellipseObstacle(n: Node, pmargin: ExpandT): Poly {
|
|
207
|
+
const sides = 8;
|
|
208
|
+
const width = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
|
|
209
|
+
const height = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
|
|
210
|
+
const mx = pmargin.doAdd ? pmargin.x : 0;
|
|
211
|
+
const my = pmargin.doAdd ? pmargin.y : 0;
|
|
212
|
+
const a = (width + mx) / 2;
|
|
213
|
+
const b = (height + my) / 2;
|
|
214
|
+
const ps: Point[] = new Array(sides);
|
|
215
|
+
for (let j = 0; j < sides; j++) {
|
|
216
|
+
const polyp = circumscribedCorner(a, b, j, sides);
|
|
217
|
+
ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
|
|
218
|
+
}
|
|
219
|
+
return { ps };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Rectangle obstacle around (llx,lly)-(urx,ury) relative to coord, with
|
|
223
|
+
* additive or multiplicative margins (C's genPt/recPt cases, CW order). */
|
|
224
|
+
function rectObstacle(
|
|
225
|
+
n: Node, llx: number, lly: number, urx: number, ury: number, pmargin: ExpandT,
|
|
226
|
+
): Poly {
|
|
227
|
+
const pt = n.info.coord;
|
|
228
|
+
let x0: number; let y0: number; let x1: number; let y1: number;
|
|
229
|
+
if (pmargin.doAdd) {
|
|
230
|
+
x0 = llx - pmargin.x; y0 = lly - pmargin.y;
|
|
231
|
+
x1 = urx + pmargin.x; y1 = ury + pmargin.y;
|
|
232
|
+
} else {
|
|
233
|
+
x0 = llx * pmargin.x; y0 = lly * pmargin.y;
|
|
234
|
+
x1 = urx * pmargin.x; y1 = ury * pmargin.y;
|
|
235
|
+
}
|
|
236
|
+
// C order: LL, UL, UR, LR (CW).
|
|
237
|
+
return {
|
|
238
|
+
ps: [
|
|
239
|
+
{ x: x0 + pt.x, y: y0 + pt.y },
|
|
240
|
+
{ x: x0 + pt.x, y: y1 + pt.y },
|
|
241
|
+
{ x: x1 + pt.x, y: y1 + pt.y },
|
|
242
|
+
{ x: x1 + pt.x, y: y0 + pt.y },
|
|
243
|
+
],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Obstacle polygon reflecting the node's geometry, vertices in CW order:
|
|
249
|
+
* the shape's own outline-periphery vertices (+margin) for polygons, an
|
|
250
|
+
* 8-gon circumscribed about the outline ellipse for ellipses, the field
|
|
251
|
+
* box for records, the node box for EPSF. Null = unsupported shape (the
|
|
252
|
+
* node is skipped as an obstacle, C returns NULL).
|
|
253
|
+
*
|
|
254
|
+
* @see lib/neatogen/neatosplines.c:makeObstacle
|
|
255
|
+
*/
|
|
256
|
+
export function makeObstacle(n: Node, pmargin: ExpandT): Poly | null {
|
|
257
|
+
const shape = n.info.shape as { kind?: ShapeKind } | undefined;
|
|
258
|
+
const kind = shape?.kind;
|
|
259
|
+
if (kind === ShapeKind.SH_POLY || kind === ShapeKind.SH_POINT) {
|
|
260
|
+
const poly = n.info.shape_info as PolygonT | undefined;
|
|
261
|
+
if (poly !== undefined && poly.sides >= 3) return polyObstacle(n, poly, pmargin);
|
|
262
|
+
return ellipseObstacle(n, pmargin);
|
|
263
|
+
}
|
|
264
|
+
if (kind === ShapeKind.SH_RECORD) {
|
|
265
|
+
const fld = n.info.shape_info as { b?: { ll: Point; ur: Point } } | undefined;
|
|
266
|
+
const b = fld?.b;
|
|
267
|
+
if (b) return rectObstacle(n, b.ll.x, b.ll.y, b.ur.x, b.ur.y, pmargin);
|
|
268
|
+
return rectObstacle(n, -n.info.lw, -n.info.ht / 2, n.info.rw, n.info.ht / 2, pmargin);
|
|
269
|
+
}
|
|
270
|
+
// SH_EPSF and unbound shapes: the node box (C returns NULL only for
|
|
271
|
+
// SH_UNSET, which cannot occur post-init; unbound port-side shapes keep
|
|
272
|
+
// the legacy box so measurer-less runs still route).
|
|
273
|
+
return rectObstacle(n, -n.info.lw, -n.info.ht / 2, n.info.rw, n.info.ht / 2, pmargin);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** bb of a polygon's vertex array. @see lib/common/utils.c:polyBB */
|
|
277
|
+
function polyVertexBB(vertices: Point[]): { ll: Point; ur: Point } {
|
|
278
|
+
const bb = { ll: { x: Infinity, y: Infinity }, ur: { x: -Infinity, y: -Infinity } };
|
|
279
|
+
for (const v of vertices) {
|
|
280
|
+
bb.ll.x = Math.min(bb.ll.x, v.x);
|
|
281
|
+
bb.ll.y = Math.min(bb.ll.y, v.y);
|
|
282
|
+
bb.ur.x = Math.max(bb.ur.x, v.x);
|
|
283
|
+
bb.ur.y = Math.max(bb.ur.y, v.y);
|
|
284
|
+
}
|
|
285
|
+
return bb;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* The isOrtho branch of C makeObstacle for SH_POLY/SH_POINT nodes: the
|
|
290
|
+
* obstacle is the node's OUTLINE box (size + penwidth outline) with NO
|
|
291
|
+
* margin — margin stays {0,0}, so tightly packed layouts (osage's 4pt
|
|
292
|
+
* gutters) remain a legal arrangement and the maze routes them; the
|
|
293
|
+
* margined rectangle makes neighbours touch and forces the straight
|
|
294
|
+
* fallback. Records fall through to the margined box like C's SH_RECORD
|
|
295
|
+
* branch (no isOrtho special case there).
|
|
296
|
+
*
|
|
297
|
+
* @see lib/neatogen/neatosplines.c:makeObstacle (isOrtho, vs[0..3])
|
|
298
|
+
*/
|
|
299
|
+
export function makeOrthoObstacle(n: Node, sep: ExpandT): Poly | null {
|
|
300
|
+
const info = n.info;
|
|
301
|
+
const shape = info.shape as { kind?: ShapeKind } | undefined;
|
|
302
|
+
const kind = shape?.kind;
|
|
303
|
+
if (kind !== undefined && kind !== ShapeKind.SH_POLY && kind !== ShapeKind.SH_POINT) {
|
|
304
|
+
return makeObstacle(n, sep); // SH_RECORD etc.: C applies pmargin as usual
|
|
305
|
+
}
|
|
306
|
+
const poly = info.shape_info as { option?: { fixedshape?: boolean }; vertices?: Point[] | null } | undefined;
|
|
307
|
+
let lw: number;
|
|
308
|
+
let rw: number;
|
|
309
|
+
let hh: number;
|
|
310
|
+
let cx = info.coord.x;
|
|
311
|
+
let cy = info.coord.y;
|
|
312
|
+
if (poly?.option?.fixedshape === true && poly.vertices != null) {
|
|
313
|
+
// C: b = polyBB(poly) — the actual shape, not the label-padded size.
|
|
314
|
+
const bb = polyVertexBB(poly.vertices);
|
|
315
|
+
lw = -bb.ll.x;
|
|
316
|
+
rw = bb.ur.x;
|
|
317
|
+
hh = (bb.ur.y - bb.ll.y) / 2;
|
|
318
|
+
cy += (bb.ur.y + bb.ll.y) / 2;
|
|
319
|
+
cx += 0;
|
|
320
|
+
} else {
|
|
321
|
+
const width = info.lw + info.rw;
|
|
322
|
+
const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width;
|
|
323
|
+
const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
|
|
324
|
+
// C: outline_lw = ND_lw * outline_width / width, box spans ±outline_lw
|
|
325
|
+
// (SYMMETRIC — vs[0].x=-outline_lw, vs[1].x=+outline_lw).
|
|
326
|
+
const outlineLw = width > 0 ? (info.lw * outlineW) / width : outlineW / 2;
|
|
327
|
+
lw = outlineLw;
|
|
328
|
+
rw = outlineLw;
|
|
329
|
+
hh = outlineH / 2;
|
|
330
|
+
}
|
|
331
|
+
const ps = ObstacleHelper.vertices(cx, cy, lw, rw, hh);
|
|
332
|
+
return { ps };
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
// EdgeHelper — straight-edge and self-arc internals
|
|
337
|
+
// ---------------------------------------------------------------------------
|
|
338
|
+
|
|
339
|
+
class EdgeHelper {
|
|
340
|
+
static endpoint(coord: Point, port: Point): Point {
|
|
341
|
+
return { x: coord.x + port.x, y: coord.y + port.y };
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static selfChain(e: Edge, cnt: number): Edge[] {
|
|
345
|
+
const edges: Edge[] = [];
|
|
346
|
+
let cur: Edge | undefined = e;
|
|
347
|
+
for (let i = 0; i < cnt && cur !== undefined; i++) {
|
|
348
|
+
edges.push(cur);
|
|
349
|
+
cur = cur.info.to_virt;
|
|
350
|
+
}
|
|
351
|
+
return edges;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ---------------------------------------------------------------------------
|
|
356
|
+
// makeStraightEdge
|
|
357
|
+
// ---------------------------------------------------------------------------
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Install a straight-line (two-point) spline on an edge.
|
|
361
|
+
*
|
|
362
|
+
* Used when pathplan routing is unavailable or edgetype == EDGETYPE_LINE.
|
|
363
|
+
*
|
|
364
|
+
* @see lib/neatogen/neatosplines.c (straight-line fallback in spline_edges_)
|
|
365
|
+
*/
|
|
366
|
+
export function makeStraightEdge(e: Edge, sinfo: SplineInfo): void {
|
|
367
|
+
const tp = EdgeHelper.endpoint(e.tail.info.coord, e.info.tail_port.p);
|
|
368
|
+
const hp = EdgeHelper.endpoint(e.head.info.coord, e.info.head_port.p);
|
|
369
|
+
clipAndInstall(e, e.head, [tp, tp, hp, hp], 4, sinfo);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* GD_nodesep for the neato-family routing sites. C parses nodesep
|
|
375
|
+
* engine-neutrally at graph_init (input.c:665-667: POINTS(late_double(g,
|
|
376
|
+
* "nodesep", 0.25, 0.02))); the port only did so in dot's init, so
|
|
377
|
+
* neato/circo/twopi self-loops and straight fans silently used the
|
|
378
|
+
* default 18 regardless of the attr (1949 sets nodesep=0.4 -> 29).
|
|
379
|
+
* Parses on demand and caches in root.info, mirroring C's assignment.
|
|
380
|
+
*/
|
|
381
|
+
function graphNodesep(g: Graph): number {
|
|
382
|
+
const root = g.root;
|
|
383
|
+
if (root.info.nodesep === undefined) {
|
|
384
|
+
const inches = lateDouble(root.attrs.get('nodesep'), 0.25, 0.02);
|
|
385
|
+
// C POINTS(a) = ROUND(a*72), half away from zero. @see lib/common/geom.h:62
|
|
386
|
+
root.info.nodesep = cround(inches * 72);
|
|
387
|
+
}
|
|
388
|
+
return root.info.nodesep;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ---------------------------------------------------------------------------
|
|
392
|
+
// makeSelfArcs
|
|
393
|
+
// ---------------------------------------------------------------------------
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Route self-loop edges via makeSelfEdge, handling single and chained cases.
|
|
397
|
+
* Under concentrate only the representative is routed (C: cnt==1||Concentrate).
|
|
398
|
+
*
|
|
399
|
+
* @see lib/neatogen/neatosplines.c:makeSelfArcs
|
|
400
|
+
*/
|
|
401
|
+
export function makeSelfArcs(e: Edge, stepx: number): void {
|
|
402
|
+
const cnt = e.info.count ?? 1;
|
|
403
|
+
const concentrate = e.tail.root.info.concentrate ?? false;
|
|
404
|
+
if (cnt <= 1 || concentrate) {
|
|
405
|
+
makeSelfEdge([e], 1, stepx, stepx, SINFO);
|
|
406
|
+
// C: the self-loop LABEL extends the graph bb (updateBB), and head/tail
|
|
407
|
+
// port labels are placed here. @see neatosplines.c:227-229
|
|
408
|
+
if (e.info.label) updateBB(e.tail.root, e.info.label as TextlabelT);
|
|
409
|
+
addEdgeLabels(e); // makePortLabels
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
const edges = EdgeHelper.selfChain(e, cnt);
|
|
413
|
+
makeSelfEdge(edges, edges.length, stepx, stepx, SINFO);
|
|
414
|
+
for (const e0 of edges) {
|
|
415
|
+
if (e0.info.label) updateBB(e0.tail.root, e0.info.label as TextlabelT);
|
|
416
|
+
addEdgeLabels(e0);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
// Equivalent-edge coalescing — the C splineEdges wrapper
|
|
422
|
+
// ---------------------------------------------------------------------------
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Equivalence key mirroring equivEdge (neatosplines.c:equivEdge): edges with
|
|
426
|
+
* the same endpoint pair — UNORDERED, so A->B and B->A coalesce — and the same
|
|
427
|
+
* resolved port points belong to one class. C orders (n1,n2) by node pointer
|
|
428
|
+
* (allocation = creation order); node id is the port's stand-in. Self-loops
|
|
429
|
+
* normalize the two port points by x then y.
|
|
430
|
+
*/
|
|
431
|
+
function equivKey(e: Edge): string {
|
|
432
|
+
const tp = e.info.tail_port?.p ?? { x: 0, y: 0 };
|
|
433
|
+
const hp = e.info.head_port?.p ?? { x: 0, y: 0 };
|
|
434
|
+
const t = e.tail.id;
|
|
435
|
+
const h = e.head.id;
|
|
436
|
+
let n1: number, n2: number, p1: Point, p2: Point;
|
|
437
|
+
if (t < h) {
|
|
438
|
+
n1 = t; p1 = tp; n2 = h; p2 = hp;
|
|
439
|
+
} else if (t > h) {
|
|
440
|
+
n2 = t; p2 = tp; n1 = h; p1 = hp;
|
|
441
|
+
} else {
|
|
442
|
+
if (tp.x < hp.x) { p1 = tp; p2 = hp; }
|
|
443
|
+
else if (tp.x > hp.x) { p1 = hp; p2 = tp; }
|
|
444
|
+
else if (tp.y < hp.y) { p1 = tp; p2 = hp; }
|
|
445
|
+
else if (tp.y > hp.y) { p1 = hp; p2 = tp; }
|
|
446
|
+
else { p1 = p2 = tp; }
|
|
447
|
+
n1 = n2 = t;
|
|
448
|
+
}
|
|
449
|
+
return `${n1}|${p1.x}|${p1.y}|${n2}|${p2.x}|${p2.y}`;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Coalesce equivalent edges, mirroring the C splineEdges wrapper
|
|
454
|
+
* (neatosplines.c:753-773): the FIRST edge of a class (agfstnode/agfstout
|
|
455
|
+
* order) becomes the leader with ED_count = 1 (set by newitem on dict
|
|
456
|
+
* insert); each later member increments the leader's count, gets count 0,
|
|
457
|
+
* and is prepended to the leader's ED_to_virt chain. The routing loop then
|
|
458
|
+
* skips count==0 members and routes the leader's whole chain (or only the
|
|
459
|
+
* representative under concentrate).
|
|
460
|
+
*
|
|
461
|
+
* @see lib/neatogen/neatosplines.c:splineEdges (find equivalent edges)
|
|
462
|
+
* @see lib/neatogen/neatosplines.c:newitem (ED_count(leader) = 1)
|
|
463
|
+
*/
|
|
464
|
+
export function coalesceEdges(g: Graph): void {
|
|
465
|
+
const map = new Map<string, Edge>();
|
|
466
|
+
for (const n of nodesInSeq(g)) {
|
|
467
|
+
for (const e of n.outEdges(g)) {
|
|
468
|
+
const key = equivKey(e);
|
|
469
|
+
const leader = map.get(key);
|
|
470
|
+
if (leader === undefined) {
|
|
471
|
+
map.set(key, e);
|
|
472
|
+
e.info.count = 1;
|
|
473
|
+
e.info.to_virt = undefined;
|
|
474
|
+
} else {
|
|
475
|
+
leader.info.count = (leader.info.count ?? 1) + 1;
|
|
476
|
+
e.info.count = 0;
|
|
477
|
+
e.info.to_virt = leader.info.to_virt;
|
|
478
|
+
leader.info.to_virt = e;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// ---------------------------------------------------------------------------
|
|
485
|
+
// SplineHelper — pathplan routing internals
|
|
486
|
+
// ---------------------------------------------------------------------------
|
|
487
|
+
|
|
488
|
+
class SplineHelper {
|
|
489
|
+
static polylinePoints(pts: Point[]): Point[] {
|
|
490
|
+
if (pts.length === 0) return [];
|
|
491
|
+
const out: Point[] = [pts[0], pts[0]];
|
|
492
|
+
for (let i = 1; i + 1 < pts.length; i++) out.push(pts[i], pts[i], pts[i]);
|
|
493
|
+
out.push(pts[pts.length - 1], pts[pts.length - 1]);
|
|
494
|
+
return out;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
static tryRouteSpline(
|
|
498
|
+
barriers: ReturnType<typeof polyBarriers>,
|
|
499
|
+
route: ReturnType<typeof obsPath>,
|
|
500
|
+
): Point[] | null {
|
|
501
|
+
const slopes: [Point, Point] = [{ x: 0, y: 0 }, { x: 0, y: 0 }];
|
|
502
|
+
try {
|
|
503
|
+
const pts = routeSpline(barriers, route, slopes);
|
|
504
|
+
return pts.length >= 4 ? pts : null;
|
|
505
|
+
} catch {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
static installPline(e: Edge, route: Point[]): void {
|
|
511
|
+
const pts = SplineHelper.polylinePoints(route);
|
|
512
|
+
clipAndInstall(e, e.head, pts, pts.length, SINFO);
|
|
513
|
+
addEdgeLabels(e); // C makePolyline. @see neatosplines.c:526
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
static installSpline(e: Edge, obstacles: Poly[], route: Point[]): void {
|
|
517
|
+
// C makeSpline re-derives the endpoint-containing polys from the PATH
|
|
518
|
+
// endpoints via in_poly (neatosplines.c:554-562) rather than reusing
|
|
519
|
+
// ND_lim: a boundary port point (e.g. a compass port) is NOT strictly
|
|
520
|
+
// inside its node's poly, so that poly stays a BARRIER and Proutespline
|
|
521
|
+
// subdivides the spline around it.
|
|
522
|
+
const p = route[0];
|
|
523
|
+
const q = route[route.length - 1];
|
|
524
|
+
let pp = POLYID_NONE;
|
|
525
|
+
let qp = POLYID_NONE;
|
|
526
|
+
for (let i = 0; i < obstacles.length; i++) {
|
|
527
|
+
if (pp === POLYID_NONE && inPoly(obstacles[i].ps, p)) pp = i;
|
|
528
|
+
if (qp === POLYID_NONE && inPoly(obstacles[i].ps, q)) qp = i;
|
|
529
|
+
}
|
|
530
|
+
const barrierPolys = obstacles.filter((_, i) => i !== pp && i !== qp);
|
|
531
|
+
const splinePts = SplineHelper.tryRouteSpline(polyBarriers(barrierPolys), route);
|
|
532
|
+
if (splinePts === null) { makeStraightEdge(e, SINFO); return; }
|
|
533
|
+
clipAndInstall(e, e.head, splinePts, splinePts.length, SINFO);
|
|
534
|
+
addEdgeLabels(e); // C makeSpline. @see neatosplines.c:585
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// ---------------------------------------------------------------------------
|
|
539
|
+
// makeSplineEdge — single-edge pathplan routing
|
|
540
|
+
// ---------------------------------------------------------------------------
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* The pathfinding half of C's two passes: ED_path(e) = getPath(e, vconfig).
|
|
544
|
+
* @see lib/neatogen/neatosplines.c:getPath
|
|
545
|
+
*/
|
|
546
|
+
export function edgePath(e: Edge, vconfig: VisConfig): Point[] {
|
|
547
|
+
const p = EdgeHelper.endpoint(e.tail.info.coord, e.info.tail_port.p);
|
|
548
|
+
const pp = e.tail.info.lim ?? POLYID_NONE;
|
|
549
|
+
const qp = e.head.info.lim ?? POLYID_NONE;
|
|
550
|
+
const q = EdgeHelper.endpoint(e.head.info.coord, e.info.head_port.p);
|
|
551
|
+
// C: Pobspath(vconfig, p, pp, q, qp, &line) — poly id comes before end-point
|
|
552
|
+
return obsPath(vconfig, p, pp, q, qp);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/** @see lib/neatogen/neatosplines.c:makeSpline */
|
|
556
|
+
export function makeSplineEdge(
|
|
557
|
+
e: Edge, obstacles: Poly[], vconfig: VisConfig, edgetype: number,
|
|
558
|
+
): void {
|
|
559
|
+
const route = edgePath(e, vconfig);
|
|
560
|
+
if (edgetype === EDGETYPE_PLINE) { SplineHelper.installPline(e, route); return; }
|
|
561
|
+
SplineHelper.installSpline(e, obstacles, route);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// ---------------------------------------------------------------------------
|
|
565
|
+
// OrthoHelper — bridge between Graph model and ortho module
|
|
566
|
+
// ---------------------------------------------------------------------------
|
|
567
|
+
|
|
568
|
+
/** An OrthoEdge carrying the originating model Edge for result installation. */
|
|
569
|
+
interface TaggedOrthoEdge extends OrthoEdge {
|
|
570
|
+
_edge: Edge;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
class OrthoHelper {
|
|
574
|
+
static buildNodes(nodeArr: Node[]): OrthoNodeList {
|
|
575
|
+
return nodeArr.map((n) => ({
|
|
576
|
+
bb: {
|
|
577
|
+
LL: { x: n.info.coord.x - n.info.lw, y: n.info.coord.y - n.info.ht / 2 },
|
|
578
|
+
UR: { x: n.info.coord.x + n.info.rw, y: n.info.coord.y + n.info.ht / 2 },
|
|
579
|
+
},
|
|
580
|
+
// C mkMaze reads ND_coord / ND_xsize (= lw+rw) / ND_ysize (= ht)
|
|
581
|
+
// directly; avoids the bb round-trip ULP loss (see OrthoNode).
|
|
582
|
+
coord: { x: n.info.coord.x, y: n.info.coord.y },
|
|
583
|
+
xsize: n.info.lw + n.info.rw,
|
|
584
|
+
ysize: n.info.ht,
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
static buildEdges(
|
|
589
|
+
g: Graph, nodeArr: Node[], orthoNodes: OrthoNodeList,
|
|
590
|
+
): TaggedOrthoEdge[] {
|
|
591
|
+
// C orthoEdges collects es[] via agfstnode/agfstout (ortho.c:1220) — the
|
|
592
|
+
// COLLECTION order matters: edgeLen ties keep qsort's permutation of the
|
|
593
|
+
// input, which decides seg_list order and therefore parallel-segment
|
|
594
|
+
// track assignment. Under concentrate, one edge per UNORDERED endpoint
|
|
595
|
+
// pair is routed (ortho.c:1223-1233). Self-loops are NOT filtered — the
|
|
596
|
+
// maze routes them via addLoop.
|
|
597
|
+
const concentrate = g.root.info.concentrate ?? false;
|
|
598
|
+
const seen = new Set<string>();
|
|
599
|
+
const edges: TaggedOrthoEdge[] = [];
|
|
600
|
+
for (const n of nodesInSeq(g)) {
|
|
601
|
+
for (const e of n.outEdges(g)) {
|
|
602
|
+
if (concentrate) {
|
|
603
|
+
const ti = e.tail.id;
|
|
604
|
+
const hi = e.head.id;
|
|
605
|
+
const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
|
|
606
|
+
if (seen.has(key)) continue;
|
|
607
|
+
seen.add(key);
|
|
608
|
+
}
|
|
609
|
+
// C attachOrthoEdges endpoints: p1 = ND_coord(tail) + ED_tail_port.p,
|
|
610
|
+
// q1 = ND_coord(head) + ED_head_port.p (ortho.c:1075-1076). Plumb the
|
|
611
|
+
// port offset so compass/record ports (tailport=s, headport=n, …) exit
|
|
612
|
+
// on the correct node side; without it buildSpline falls back to the bb
|
|
613
|
+
// centre and every ported ortho edge starts/ends at the node centre.
|
|
614
|
+
const tc = e.tail.info.coord;
|
|
615
|
+
const hc = e.head.info.coord;
|
|
616
|
+
const tp = e.info.tail_port.p;
|
|
617
|
+
const hp = e.info.head_port.p;
|
|
618
|
+
edges.push({
|
|
619
|
+
tail: orthoNodes[nodeArr.indexOf(e.tail)],
|
|
620
|
+
head: orthoNodes[nodeArr.indexOf(e.head)],
|
|
621
|
+
tailPoint: { x: tc.x + tp.x, y: tc.y + tp.y },
|
|
622
|
+
headPoint: { x: hc.x + hp.x, y: hc.y + hp.y },
|
|
623
|
+
_edge: e,
|
|
624
|
+
} as TaggedOrthoEdge);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return edges;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
static buildGraph(g: Graph): OrthoGraph {
|
|
631
|
+
const nodeArr = [...g.nodes.values()];
|
|
632
|
+
const orthoNodes = OrthoHelper.buildNodes(nodeArr);
|
|
633
|
+
return { nodes: orthoNodes, edges: OrthoHelper.buildEdges(g, nodeArr, orthoNodes) };
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
static installResult(oe: OrthoEdge, pts: OrthoPoint[]): void {
|
|
637
|
+
const origEdge = (oe as TaggedOrthoEdge)._edge;
|
|
638
|
+
if (!origEdge) return;
|
|
639
|
+
// C attachOrthoEdges installs with ortho.c's OWN sinfo {swap_ends_p,
|
|
640
|
+
// spline_merge, ignoreSwap=true, isOrtho=true} (ortho.c:1269) — its static
|
|
641
|
+
// callbacks return false, identical to neato's. isOrtho selects the
|
|
642
|
+
// segment-truncating ortho clip; the generic bezier clip reparameterizes
|
|
643
|
+
// the control points and diverges from native.
|
|
644
|
+
clipAndInstall(origEdge, origEdge.head, pts, pts.length, ORTHO_SINFO);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// ---------------------------------------------------------------------------
|
|
649
|
+
// RoutingHelper — splineEdgesImpl internals
|
|
650
|
+
// ---------------------------------------------------------------------------
|
|
651
|
+
|
|
652
|
+
class RoutingHelper {
|
|
653
|
+
static buildObstacles(g: Graph, pmargin: ExpandT, edgetype: number): Poly[] {
|
|
654
|
+
const obstacles: Poly[] = [];
|
|
655
|
+
let idx = 0;
|
|
656
|
+
for (const n of g.nodes.values()) {
|
|
657
|
+
if (edgetype >= EDGETYPE_PLINE) {
|
|
658
|
+
// C: makeObstacle(n, pmargin, edgetype == EDGETYPE_ORTHO) —
|
|
659
|
+
// ortho obstacles are the unmargined outline box. A null obstacle
|
|
660
|
+
// (unsupported shape) leaves the node out (ND_lim = POLYID_NONE).
|
|
661
|
+
const obp = edgetype === EDGETYPE_ORTHO
|
|
662
|
+
? makeOrthoObstacle(n, pmargin)
|
|
663
|
+
: makeObstacle(n, pmargin);
|
|
664
|
+
if (obp !== null) {
|
|
665
|
+
n.info.lim = idx++;
|
|
666
|
+
obstacles.push(obp);
|
|
667
|
+
} else {
|
|
668
|
+
n.info.lim = POLYID_NONE;
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
n.info.lim = POLYID_NONE;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return obstacles;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
static withVconfig(
|
|
678
|
+
g: Graph, obstacles: Poly[], vconfig: VisConfig, edgetype: number,
|
|
679
|
+
): void {
|
|
680
|
+
const stepx = graphNodesep(g);
|
|
681
|
+
const concentrate = g.root.info.concentrate ?? false;
|
|
682
|
+
let rtr: Router | null = null;
|
|
683
|
+
for (const n of nodesInSeq(g)) {
|
|
684
|
+
for (const e of n.outEdges(g)) {
|
|
685
|
+
// C spline_edges_: ED_count==0 -> continue (only do representative).
|
|
686
|
+
if ((e.info.count ?? 0) === 0) continue;
|
|
687
|
+
if (e.tail === e.head) { makeSelfArcs(e, stepx); continue; }
|
|
688
|
+
// HAVE_GTS branch (neatosplines.c:681): multiplicity or a boundary
|
|
689
|
+
// port routes through the triangle router; a straight 2-point path
|
|
690
|
+
// without ports shortcuts to the perpendicular fan. Only on router
|
|
691
|
+
// FAILURE does the edge fall through to the plain pathplan loop.
|
|
692
|
+
const boundaryPort =
|
|
693
|
+
(e.info.tail_port.side | e.info.head_port.side) !== 0;
|
|
694
|
+
if ((e.info.count ?? 1) > 1 || boundaryPort) {
|
|
695
|
+
let fail = 0;
|
|
696
|
+
const route = edgePath(e, vconfig);
|
|
697
|
+
if (route.length === 2 && !boundaryPort) {
|
|
698
|
+
// if a straight line can connect the ends
|
|
699
|
+
const chain = RoutingHelper.chainList(e);
|
|
700
|
+
makeStraightEdges(g, chain, chain.length, edgetype, SINFO);
|
|
701
|
+
} else {
|
|
702
|
+
if (rtr === null) rtr = mkRouter(obstacles);
|
|
703
|
+
fail = makeMultiSpline(
|
|
704
|
+
g, e, rtr, route, edgetype === EDGETYPE_PLINE);
|
|
705
|
+
}
|
|
706
|
+
if (!fail) continue;
|
|
707
|
+
}
|
|
708
|
+
let cur: Edge | undefined = e;
|
|
709
|
+
let cnt = e.info.count ?? 1;
|
|
710
|
+
if (concentrate) cnt = 1; // only do representative
|
|
711
|
+
for (let i = 0; i < cnt && cur !== undefined; i++) {
|
|
712
|
+
makeSplineEdge(cur, obstacles, vconfig, edgetype);
|
|
713
|
+
cur = cur.info.to_virt;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/** Full ED_to_virt chain from a leader (C makeStraightEdge's walk). */
|
|
720
|
+
static chainList(e: Edge): Edge[] {
|
|
721
|
+
const list: Edge[] = [e];
|
|
722
|
+
let e0: Edge = e;
|
|
723
|
+
while (e0.info.to_virt !== undefined && e0.info.to_virt !== e0) {
|
|
724
|
+
e0 = e0.info.to_virt;
|
|
725
|
+
list.push(e0);
|
|
726
|
+
}
|
|
727
|
+
return list;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
static straight(g: Graph, et: number): void {
|
|
731
|
+
const stepx = graphNodesep(g);
|
|
732
|
+
for (const n of nodesInSeq(g)) {
|
|
733
|
+
for (const e of n.outEdges(g)) {
|
|
734
|
+
// C spline_edges_: ED_count==0 -> continue (only do representative).
|
|
735
|
+
if ((e.info.count ?? 0) === 0) continue;
|
|
736
|
+
if (e.tail === e.head) { makeSelfArcs(e, stepx); continue; }
|
|
737
|
+
// C makeStraightEdge routes the WHOLE equivalence chain at once —
|
|
738
|
+
// makeStraightEdges fans parallels out perpendicular to the segment
|
|
739
|
+
// and handles the concentrate representative-only case internally.
|
|
740
|
+
// @see lib/common/routespl.c:956 makeStraightEdge
|
|
741
|
+
const chain = RoutingHelper.chainList(e);
|
|
742
|
+
makeStraightEdges(g, chain, chain.length, et, SINFO);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
static ortho(g: Graph, et: number): void {
|
|
748
|
+
const og = OrthoHelper.buildGraph(g);
|
|
749
|
+
orthoEdges(og, false, (_og, oe, pts) => OrthoHelper.installResult(oe, pts));
|
|
750
|
+
// C spline_edges_ drawing loop: vconfig is NEVER built for ortho
|
|
751
|
+
// (neatosplines.c:618 gates Pobsopen on edgetype != ORTHO), so an edge the
|
|
752
|
+
// maze failed to route — attachOrthoEdges skips empty routes — has no
|
|
753
|
+
// ED_spl, fails the `useEdges && ED_spl(e)` test, and falls through to
|
|
754
|
+
// makeSelfArcs / makeStraightEdge with neato's NORMAL sinfo (generic
|
|
755
|
+
// bezier clip). Self-loops are never maze-routed and always land here.
|
|
756
|
+
const stepx = graphNodesep(g);
|
|
757
|
+
for (const n of nodesInSeq(g)) {
|
|
758
|
+
for (const e of n.outEdges(g)) {
|
|
759
|
+
if (e.info.spl != null) {
|
|
760
|
+
// C: `useEdges && ED_spl(e)` — maze-routed edges still get their
|
|
761
|
+
// head/tail port labels. @see neatosplines.c:655
|
|
762
|
+
addEdgeLabels(e);
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
if ((e.info.count ?? 0) === 0) continue; // only do representative
|
|
766
|
+
if (e.tail === e.head) { makeSelfArcs(e, stepx); continue; }
|
|
767
|
+
const chain = RoutingHelper.chainList(e);
|
|
768
|
+
makeStraightEdges(g, chain, chain.length, et, SINFO);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
static routed(g: Graph, obstacles: Poly[], edgetype: number): void {
|
|
774
|
+
const vconfig = obsOpen(obstacles);
|
|
775
|
+
RoutingHelper.withVconfig(g, obstacles, vconfig, edgetype);
|
|
776
|
+
obsClose(vconfig);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// ---------------------------------------------------------------------------
|
|
781
|
+
// splineEdgesImpl — inner routing loop
|
|
782
|
+
// ---------------------------------------------------------------------------
|
|
783
|
+
|
|
784
|
+
/** @see lib/neatogen/neatosplines.c:spline_edges_ */
|
|
785
|
+
export function splineEdgesImpl(g: Graph, sep: ExpandT, edgetype: number): void {
|
|
786
|
+
const obstacles = RoutingHelper.buildObstacles(g, sep, edgetype);
|
|
787
|
+
// C: legal = Plegal_arrangement(obs, npoly) — sweep-line segment
|
|
788
|
+
// intersection + nesting, NOT a bbox test: circo octagon obstacles
|
|
789
|
+
// routinely overlap in bbox while the polygons are disjoint.
|
|
790
|
+
const legal = legalArrangement(obstacles);
|
|
791
|
+
if (legal && edgetype === EDGETYPE_ORTHO) { RoutingHelper.ortho(g, edgetype); return; }
|
|
792
|
+
if (obstacles.length > 0 && legal) { RoutingHelper.routed(g, obstacles, edgetype); return; }
|
|
793
|
+
RoutingHelper.straight(g, edgetype);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// ---------------------------------------------------------------------------
|
|
797
|
+
// splineEdges — public entry point
|
|
798
|
+
// ---------------------------------------------------------------------------
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Main spline routing entry point for neato layout.
|
|
802
|
+
*
|
|
803
|
+
* Dispatch:
|
|
804
|
+
* 1. EDGETYPE_NONE → skip
|
|
805
|
+
* 2. EDGETYPE_LINE → straight lines for all edges
|
|
806
|
+
* 3. EDGETYPE_ORTHO → orthoEdges (if obstacles legal, else straight)
|
|
807
|
+
* 4. EDGETYPE_SPLINE / EDGETYPE_PLINE → pathplan routing with straight fallback
|
|
808
|
+
*
|
|
809
|
+
* @see lib/neatogen/neatosplines.c:spline_edges0, spline_edges1, splineEdges
|
|
810
|
+
*/
|
|
811
|
+
export function splineEdges(g: Graph): void {
|
|
812
|
+
const edgetype = g.info.flags & 0xf;
|
|
813
|
+
if (edgetype === EDGETYPE_NONE) return;
|
|
814
|
+
// C graph_init caches Concentrate for every engine (input.c:708-709); the
|
|
815
|
+
// routing gates (spline_edges_, makeSelfArcs, makeStraightEdges) read it.
|
|
816
|
+
g.root.info.concentrate = mapbool(g.root.attrs.get('concentrate'));
|
|
817
|
+
// C splineEdges wrapper: resolve dynamic ports first (neatosplines.c:748) —
|
|
818
|
+
// a record/compass port stays .dyna until fixed against the OTHER endpoint;
|
|
819
|
+
// equivEdge then keys on the resolved port points.
|
|
820
|
+
for (const n of nodesInSeq(g)) {
|
|
821
|
+
for (const e of n.outEdges(g)) {
|
|
822
|
+
if (e.info.tail_port.dyna) e.info.tail_port = resolvePort(e.tail, e.head, e.info.tail_port);
|
|
823
|
+
if (e.info.head_port.dyna) e.info.head_port = resolvePort(e.head, e.tail, e.info.head_port);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
// C splineEdges wrapper: coalesce equivalent edges before routing.
|
|
827
|
+
coalesceEdges(g);
|
|
828
|
+
if (edgetype === EDGETYPE_LINE) { RoutingHelper.straight(g, edgetype); return; }
|
|
829
|
+
// C: margin = esepFactor(g) — the edge separation, default {3.2, 3.2, add}.
|
|
830
|
+
// @see lib/neatogen/neatosplines.c:746
|
|
831
|
+
splineEdgesImpl(g, esepFactor(g), edgetype);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// ---------------------------------------------------------------------------
|
|
835
|
+
// splineEdgesShifted — the C spline_edges wrapper
|
|
836
|
+
// ---------------------------------------------------------------------------
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Graph bounding box in points derived from node pos (inches) and node
|
|
840
|
+
* sizes, expanded by any existing edge splines. xlabels are not ported
|
|
841
|
+
* (no engine sets them yet).
|
|
842
|
+
* @see lib/common/utils.c:compute_bb
|
|
843
|
+
*/
|
|
844
|
+
export function computeBBFromPos(g: Graph): { ll: Point; ur: Point } {
|
|
845
|
+
const bb = {
|
|
846
|
+
ll: { x: Infinity, y: Infinity },
|
|
847
|
+
ur: { x: -Infinity, y: -Infinity },
|
|
848
|
+
};
|
|
849
|
+
for (const n of g.nodes.values()) {
|
|
850
|
+
const px = (n.info.pos?.[0] ?? 0) * 72;
|
|
851
|
+
const py = (n.info.pos?.[1] ?? 0) * 72;
|
|
852
|
+
const sx = (n.info.lw + n.info.rw) / 2;
|
|
853
|
+
const sy = n.info.ht / 2;
|
|
854
|
+
bb.ll.x = Math.min(bb.ll.x, px - sx);
|
|
855
|
+
bb.ll.y = Math.min(bb.ll.y, py - sy);
|
|
856
|
+
bb.ur.x = Math.max(bb.ur.x, px + sx);
|
|
857
|
+
bb.ur.y = Math.max(bb.ur.y, py + sy);
|
|
858
|
+
}
|
|
859
|
+
// C compute_bb: an empty graph keeps bb = {0,0,0,0}. @see utils.c:641
|
|
860
|
+
if (!Number.isFinite(bb.ll.x)) {
|
|
861
|
+
return { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } };
|
|
862
|
+
}
|
|
863
|
+
return bb;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* The C spline_edges wrapper: translate pos so the drawing's lower
|
|
868
|
+
* left corner is the origin, shift cluster bbs along, sync coord from
|
|
869
|
+
* pos (neato_set_aspect), then route edges by edge type.
|
|
870
|
+
* @see lib/neatogen/neatosplines.c:spline_edges
|
|
871
|
+
* @see lib/neatogen/neatosplines.c:spline_edges0
|
|
872
|
+
* @see lib/neatogen/neatosplines.c:shiftClusters
|
|
873
|
+
*/
|
|
874
|
+
/** Shift every node pos (inches) by the given offset. */
|
|
875
|
+
function shiftAllPos(g: Graph, ox: number, oy: number): void {
|
|
876
|
+
for (const n of g.nodes.values()) {
|
|
877
|
+
if (!n.info.pos) n.info.pos = [0, 0];
|
|
878
|
+
n.info.pos[0] = (n.info.pos[0] ?? 0) - ox;
|
|
879
|
+
n.info.pos[1] = (n.info.pos[1] ?? 0) - oy;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/** Shift all top-level cluster bbs. @see lib/neatogen/neatosplines.c:shiftClusters */
|
|
884
|
+
function shiftClusters(g: Graph, dx: number, dy: number): void {
|
|
885
|
+
const nClust = g.info.n_cluster ?? 0;
|
|
886
|
+
for (let c = 1; c <= nClust; c++) {
|
|
887
|
+
const sub = g.info.clust?.[c - 1];
|
|
888
|
+
if (sub) shiftGraphBBs(sub, dx, dy);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* T1 (iterative-parity-campaign, batch-1) injection hook: when
|
|
894
|
+
* `GVTS_POS_INJECT` names a dump file, overwrite `n.info.pos` for every
|
|
895
|
+
* matching node name before this module's own routing runs — mirroring the
|
|
896
|
+
* native `spline_edges` entry point where the session-local POS_DUMP patch
|
|
897
|
+
* captures oracle `ND_pos` (see
|
|
898
|
+
* `plans/iterative-parity-campaign/diagrams/injection-recipe.md`). This lets
|
|
899
|
+
* the attribution harness separate "port routing/emission is wrong" from
|
|
900
|
+
* "the port's own node placement is just a different (but internally
|
|
901
|
+
* consistent) FP-drift outcome" for the iterative engines (D1: pre-routing
|
|
902
|
+
* `ND_pos` stage only).
|
|
903
|
+
*
|
|
904
|
+
* Dump lines look like `GVTS_POS <name> <x> <y>` (any other line, e.g. dot's
|
|
905
|
+
* own stderr warnings mixed into the same capture, is ignored). Reads via
|
|
906
|
+
* `process.getBuiltinModule` rather than a static `node:fs` import so the
|
|
907
|
+
* browser bundle (esbuild, no `--platform=node`) never tries to resolve a
|
|
908
|
+
* Node builtin — this whole function is inert (returns immediately) unless
|
|
909
|
+
* `process` exists and `GVTS_POS_INJECT` is set, which is true only inside
|
|
910
|
+
* the Node test harness, never in a browser render.
|
|
911
|
+
*
|
|
912
|
+
* An optional `GVTS_BB <llx> <lly> <urx> <ury>` line (points) overwrites the
|
|
913
|
+
* graph bb as well. It is emitted only by the *fdp* dump site, and it is
|
|
914
|
+
* load-bearing there: neato/sfdp reach this hook at the top of `spline_edges`,
|
|
915
|
+
* one line ABOVE the `compute_bb` that derives GD_bb — so their bb is a pure
|
|
916
|
+
* function of the injected positions and needs no injection of its own. fdp is
|
|
917
|
+
* the exception: `GD_bb` is a product of `fdpLayout` itself (`finalCC` →
|
|
918
|
+
* `setBB`, layout.c:1030), which has already run and returned by the time the
|
|
919
|
+
* hook fires, so without this line the injected render keeps the port's OWN
|
|
920
|
+
* (drifted) bb while emitting the oracle's node positions — a bb that belongs
|
|
921
|
+
* to neither layout. That mismatch, not any defect in the port's bb code, is
|
|
922
|
+
* what made `graph/bb`+`graph/_draw_` the largest not-cleared fdp bucket (60
|
|
923
|
+
* ids, bb short on 24 and TALL on 18 — a sign-split no bb bug can produce).
|
|
924
|
+
* The bb is layout-stage state exactly like `ND_pos`; neutralizing it is what
|
|
925
|
+
* lets the comparison isolate routing/emission, which is all the harness
|
|
926
|
+
* claims to measure.
|
|
927
|
+
* @see lib/fdpgen/layout.c:1063 fdp_layout
|
|
928
|
+
*/
|
|
929
|
+
export function injectOraclePositions(g: Graph): void {
|
|
930
|
+
if (typeof process === 'undefined') return;
|
|
931
|
+
const dumpPath = process.env?.['GVTS_POS_INJECT'];
|
|
932
|
+
if (!dumpPath || typeof process.getBuiltinModule !== 'function') return;
|
|
933
|
+
const fs = process.getBuiltinModule('node:fs');
|
|
934
|
+
if (!fs) return;
|
|
935
|
+
// fdp also emits GVTS_CLUST_BB per cluster: like GD_bb, cluster boxes are a
|
|
936
|
+
// product of fdpLayout's setBB (upstream of this hook) and are NOT re-derived
|
|
937
|
+
// from injected positions, so they must be carried across too — otherwise the
|
|
938
|
+
// injected render draws every cluster at the port's own (drifted) extent.
|
|
939
|
+
// Map cluster name → subgraph so a dump line can find its target.
|
|
940
|
+
const clustByName = new Map<string, Graph>();
|
|
941
|
+
const collectClusters = (sg: Graph): void => {
|
|
942
|
+
const n = sg.info.n_cluster ?? 0;
|
|
943
|
+
const cl = sg.info.clust;
|
|
944
|
+
if (!cl) return;
|
|
945
|
+
for (let i = 0; i < n; i++) {
|
|
946
|
+
const c = cl[i];
|
|
947
|
+
if (c) {
|
|
948
|
+
clustByName.set(c.name, c);
|
|
949
|
+
collectClusters(c);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
collectClusters(g);
|
|
954
|
+
const text = fs.readFileSync(dumpPath, 'utf8');
|
|
955
|
+
for (const line of text.split('\n')) {
|
|
956
|
+
// Name is greedy: node names can contain spaces (and literal "\n" from
|
|
957
|
+
// multi-line labels used as ids), so x and y are the trailing two tokens
|
|
958
|
+
// and the name is everything between. `(.*)` (not `(.+)`) so a node with
|
|
959
|
+
// the EMPTY name "" also injects — `\S+` skipped space-named nodes (2193),
|
|
960
|
+
// `(.+)` still skipped empty-named nodes (2095's single "" node, which drags
|
|
961
|
+
// its two incident edges ~1000pt when left un-injected).
|
|
962
|
+
const m = /^GVTS_POS (.*) (\S+) (\S+)$/.exec(line);
|
|
963
|
+
if (m) {
|
|
964
|
+
const n = g.nodes.get(m[1]!);
|
|
965
|
+
if (n) n.info.pos = [Number(m[2]), Number(m[3])];
|
|
966
|
+
continue;
|
|
967
|
+
}
|
|
968
|
+
const cb = /^GVTS_CLUST_BB (\S+) (\S+) (\S+) (\S+) (\S+)/.exec(line);
|
|
969
|
+
if (cb) {
|
|
970
|
+
const c = clustByName.get(cb[1]!);
|
|
971
|
+
if (c) {
|
|
972
|
+
c.info.bb = {
|
|
973
|
+
ll: { x: Number(cb[2]), y: Number(cb[3]) },
|
|
974
|
+
ur: { x: Number(cb[4]), y: Number(cb[5]) },
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
continue;
|
|
978
|
+
}
|
|
979
|
+
const b = /^GVTS_BB (\S+) (\S+) (\S+) (\S+)/.exec(line);
|
|
980
|
+
if (b) {
|
|
981
|
+
g.info.bb = {
|
|
982
|
+
ll: { x: Number(b[1]), y: Number(b[2]) },
|
|
983
|
+
ur: { x: Number(b[3]), y: Number(b[4]) },
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
export function splineEdgesShifted(g: Graph): void {
|
|
990
|
+
injectOraclePositions(g);
|
|
991
|
+
const bb = computeBBFromPos(g);
|
|
992
|
+
if (typeof process !== 'undefined' && process.env['STRESS_DEBUG']) console.error('shiftBB', JSON.stringify(bb));
|
|
993
|
+
shiftAllPos(g, bb.ll.x / 72, bb.ll.y / 72);
|
|
994
|
+
shiftClusters(g, -bb.ll.x, -bb.ll.y);
|
|
995
|
+
// C spline_edges leaves GD_bb = the shifted node-extent box (LL at origin);
|
|
996
|
+
// _neato_set_aspect reads it for the fill/expand/value factors.
|
|
997
|
+
g.info.bb = {
|
|
998
|
+
ll: { x: 0, y: 0 },
|
|
999
|
+
ur: { x: bb.ur.x - bb.ll.x, y: bb.ur.y - bb.ll.y },
|
|
1000
|
+
};
|
|
1001
|
+
neatoSetAspect(g); // spline_edges0(g, true): aspect + pos -> coord
|
|
1002
|
+
// The bb was seeded above (and scaled by the aspect pass); C never
|
|
1003
|
+
// recomputes it here — clip_and_install only EXPANDS it during routing.
|
|
1004
|
+
// Recomputing from node extents would clobber the ratio=fill scale
|
|
1005
|
+
// (scaleBB sets bb to exactly size; node extents land short of it).
|
|
1006
|
+
splineEdges(g);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// ---------------------------------------------------------------------------
|
|
1010
|
+
// Exports for testing
|
|
1011
|
+
// ---------------------------------------------------------------------------
|
|
1012
|
+
|
|
1013
|
+
export { newSpline };
|
|
1014
|
+
export type { Poly as NeatoPoly };
|