@knowvah/dot-engine 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +15 -0
  2. package/dist/cdt/bag.d.ts +6 -4
  3. package/dist/cdt/bag.d.ts.map +1 -1
  4. package/dist/common/graph-init.d.ts.map +1 -1
  5. package/dist/common/htmltable-lex.d.ts.map +1 -1
  6. package/dist/common/record.d.ts.map +1 -1
  7. package/dist/common/splines-clip.d.ts +8 -0
  8. package/dist/common/splines-clip.d.ts.map +1 -1
  9. package/dist/common/splines-routespl.d.ts +4 -0
  10. package/dist/common/splines-routespl.d.ts.map +1 -1
  11. package/dist/index.js +2038 -2004
  12. package/dist/index.js.map +4 -4
  13. package/dist/render.js +96 -62
  14. package/dist/render.js.map +3 -3
  15. package/dist/xdot/parse.d.ts.map +1 -1
  16. package/package.json +3 -2
  17. package/src/cdt/bag.ts +30 -52
  18. package/src/common/graph-init.ts +14 -9
  19. package/src/common/htmltable-lex.ts +17 -4
  20. package/src/common/htmltable-parse.ts +1 -1
  21. package/src/common/record.ts +3 -5
  22. package/src/common/splines-clip.ts +25 -0
  23. package/src/common/splines-routespl.ts +66 -0
  24. package/src/xdot/parse.ts +3 -1
  25. package/dist/gvc/textlayout.d.ts +0 -33
  26. package/dist/gvc/textlayout.d.ts.map +0 -1
  27. package/dist/layout/osage/layout.d.ts +0 -49
  28. package/dist/layout/osage/layout.d.ts.map +0 -1
  29. package/dist/layout/pack/test-helpers.d.ts +0 -7
  30. package/dist/layout/pack/test-helpers.d.ts.map +0 -1
  31. package/dist/layout/patchwork/tree-node.d.ts +0 -46
  32. package/dist/layout/patchwork/tree-node.d.ts.map +0 -1
  33. package/dist/xdot/lex.d.ts +0 -22
  34. package/dist/xdot/lex.d.ts.map +0 -1
  35. package/src/gvc/textlayout.ts +0 -44
  36. package/src/layout/osage/layout.ts +0 -254
  37. package/src/layout/pack/test-helpers.ts +0 -46
  38. package/src/layout/patchwork/tree-node.ts +0 -120
  39. package/src/xdot/lex.ts +0 -151
package/dist/render.js CHANGED
@@ -5450,12 +5450,15 @@ function parseAttrs(raw) {
5450
5450
  }
5451
5451
  return out;
5452
5452
  }
5453
+ function normalizeTag(tag) {
5454
+ return tag === "TH" ? "TR" : tag;
5455
+ }
5453
5456
  function parseCloseToken(inner) {
5454
5457
  const body = inner.slice(1).trim();
5455
5458
  const sp = body.search(/\s/);
5456
5459
  const tag = (sp === -1 ? body : body.slice(0, sp)).toUpperCase();
5457
5460
  checkTag(tag);
5458
- return { type: "close", tag };
5461
+ return { type: "close", tag: normalizeTag(tag) };
5459
5462
  }
5460
5463
  function cleanText(raw) {
5461
5464
  const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
@@ -5489,12 +5492,13 @@ function scanTag(src, start, tokens) {
5489
5492
  function parseOpenToken(inner) {
5490
5493
  const sp = inner.search(/\s/);
5491
5494
  if (sp === -1) {
5492
- checkTag(inner.toUpperCase());
5493
- return { type: "open", tag: inner.toUpperCase(), attrs: parseAttrs("") };
5495
+ const tag2 = inner.toUpperCase();
5496
+ checkTag(tag2);
5497
+ return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
5494
5498
  }
5495
5499
  const tag = inner.slice(0, sp).toUpperCase();
5496
5500
  checkTag(tag);
5497
- return { type: "open", tag, attrs: parseAttrs(inner.slice(sp + 1)) };
5501
+ return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
5498
5502
  }
5499
5503
  function tokenize(src) {
5500
5504
  const tokens = [];
@@ -5719,7 +5723,7 @@ var buildCell = (content, a) => ({
5719
5723
  });
5720
5724
  var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, attrs, fontStack), attrs);
5721
5725
  var processRowToken = (s, t, cells, fontStack) => {
5722
- if (t.type === "open" && (t.tag === "TD" || t.tag === "TH")) {
5726
+ if (t.type === "open" && t.tag === "TD") {
5723
5727
  consume(s);
5724
5728
  cells.push(parseCell(s, t.attrs, fontStack));
5725
5729
  return;
@@ -10749,10 +10753,7 @@ function posReclbl(f, ul, sides) {
10749
10753
  }
10750
10754
  }
10751
10755
  function attrBool(n, g, key) {
10752
- const s = nodeAttr(n, g, key);
10753
- if (!s || s.toLowerCase() === "false" || s.toLowerCase() === "no") return false;
10754
- if (s.toLowerCase() === "true" || s.toLowerCase() === "yes") return true;
10755
- return parseInt(s, 10) !== 0;
10756
+ return mapbool2(nodeAttr(n, g, key));
10756
10757
  }
10757
10758
  function recAttrSize(n, g) {
10758
10759
  const w = nodeAttr(n, g, "width");
@@ -16321,7 +16322,7 @@ function class2(g) {
16321
16322
 
16322
16323
  // src/common/edge-label-init.ts
16323
16324
  var MIN_FONTSIZE = 1;
16324
- function mapbool2(s) {
16325
+ function mapbool3(s) {
16325
16326
  if (!s || s.toLowerCase() === "false" || s.toLowerCase() === "no") return false;
16326
16327
  if (s.toLowerCase() === "true" || s.toLowerCase() === "yes") return true;
16327
16328
  const n = parseInt(s, 10);
@@ -16352,7 +16353,7 @@ function applyLabel(e, g, fi, measurer) {
16352
16353
  const content = isHtml ? htmlValueContent(str) : str;
16353
16354
  e.info.label = makeAnyLabel(content, isHtml, fi, measurer, e);
16354
16355
  g.root.info.has_labels |= EDGE_LABEL;
16355
- e.info.label_ontop = mapbool2(e.attrs.get("labelfloat")) ? 1 : 0;
16356
+ e.info.label_ontop = mapbool3(e.attrs.get("labelfloat")) ? 1 : 0;
16356
16357
  }
16357
16358
  function applyXLabel(e, g, fi, measurer) {
16358
16359
  const str = e.attrs.get("xlabel");
@@ -16512,10 +16513,12 @@ function parseRatioKind(g) {
16512
16513
  }
16513
16514
  function parseRatioDrawing(g) {
16514
16515
  const kind = parseRatioKind(g);
16515
- if (kind !== "compress" && kind !== "fill") return;
16516
+ if (kind !== "compress" && kind !== "fill" && kind !== "value") return;
16516
16517
  const sz = parseSizePoints(g.attrs.get("size"));
16517
16518
  g.info.drawing = makeDrawing({
16518
16519
  ratioKind: kind,
16520
+ // C: GD_drawing(g)->ratio = atof(p), set only for R_VALUE (setRatio).
16521
+ ratio: kind === "value" ? Number.parseFloat(g.attrs.get("ratio")) : 0,
16519
16522
  size: sz ? { x: sz.x, y: sz.y } : { x: 0, y: 0 },
16520
16523
  filled: sz?.filled ?? false
16521
16524
  });
@@ -16548,7 +16551,7 @@ function graphInit(g, useRankdir) {
16548
16551
  if (fn !== -1) g.info.fontnames = fn;
16549
16552
  parseRatioDrawing(g);
16550
16553
  setClType(maptoken(g.attrs.get("clusterrank"), RANK_NAMES, rankCodes()));
16551
- g.info.concentrate = mapbool3(g.attrs.get("concentrate"));
16554
+ g.info.concentrate = mapbool2(g.attrs.get("concentrate"));
16552
16555
  g.info.edgeLabelsDone = false;
16553
16556
  doGraphLabel(g, layoutMeasurer(g));
16554
16557
  }
@@ -16590,7 +16593,7 @@ function sameNonemptyGroup(e) {
16590
16593
  }
16591
16594
  function initEdgeConstraint(e) {
16592
16595
  const s = e.attrs.get("constraint");
16593
- if (s !== void 0 && s !== "") e.info.constraint = mapbool3(s);
16596
+ if (s !== void 0 && s !== "") e.info.constraint = mapbool2(s);
16594
16597
  }
16595
16598
  function applyGroupPenalty(e) {
16596
16599
  if (!sameNonemptyGroup(e)) return;
@@ -20100,7 +20103,23 @@ function clipAndInstall(fe, hn, ps, pn, info) {
20100
20103
  };
20101
20104
  SplineClipHelper.arrowClip(fe, hn, ps, bounds, newspl, info);
20102
20105
  SplineClipHelper.copyToBezier(newspl, ps, bounds.start, bounds.end, g.info.bb);
20106
+ if (clipDump) {
20107
+ let cur = fe;
20108
+ while (cur.info.to_orig != null && cur.info.edge_type !== 0) cur = cur.info.to_orig;
20109
+ clipDump("S5_CLIP", cur.tail.name, cur.head.name, {
20110
+ inputPn: pn,
20111
+ bounds: { start: bounds.start, end: bounds.end },
20112
+ sflag: newspl.sflag,
20113
+ eflag: newspl.eflag,
20114
+ sp: { ...newspl.sp },
20115
+ ep: { ...newspl.ep },
20116
+ size: newspl.size,
20117
+ // emit reads bz.size, not list.length (memory: bezier-emit-size-not-length)
20118
+ list: newspl.list.slice(0, newspl.size).map((p) => ({ ...p }))
20119
+ });
20120
+ }
20103
20121
  }
20122
+ var clipDump = null;
20104
20123
 
20105
20124
  // src/common/splines-selfedge.ts
20106
20125
  var SIDE_VERTICES = [12, 4, 6, 2, 3, 1, 9, 8];
@@ -21981,10 +22000,10 @@ function xgWeak(Xg, t, h, orig, st) {
21981
22000
  function isNonConstraint(e) {
21982
22001
  const v = e.attrs.get("constraint");
21983
22002
  if (!v) return false;
21984
- return !mapbool3(v);
22003
+ return !mapbool2(v);
21985
22004
  }
21986
22005
  function isAStrongCluster(g) {
21987
- return mapbool3(g.attrs.get("compact") ?? "");
22006
+ return mapbool2(g.attrs.get("compact") ?? "");
21988
22007
  }
21989
22008
  function dotLca(c0, c1) {
21990
22009
  let a = c0;
@@ -22259,7 +22278,7 @@ var clType = LOCAL;
22259
22278
  function setClType(t) {
22260
22279
  clType = t;
22261
22280
  }
22262
- function mapbool3(s) {
22281
+ function mapbool2(s) {
22263
22282
  if (!s || s === "") return false;
22264
22283
  const l = s.toLowerCase();
22265
22284
  if (l === "false" || l === "no") return false;
@@ -22275,7 +22294,7 @@ function scaleClamp(nnodes, scale) {
22275
22294
  function isACluster(g) {
22276
22295
  if (g === g.root) return true;
22277
22296
  if (g.name.toLowerCase().startsWith("cluster")) return true;
22278
- return mapbool3(g.attrs.get("cluster"));
22297
+ return mapbool2(g.attrs.get("cluster"));
22279
22298
  }
22280
22299
  function cleanup1ClearNode(n) {
22281
22300
  if (n.info.in) n.info.in.size = 0;
@@ -22623,7 +22642,7 @@ function dot1Rank(g) {
22623
22642
  cleanup1(g);
22624
22643
  }
22625
22644
  function dotRank(g) {
22626
- if (mapbool3(g.attrs.get("newrank"))) {
22645
+ if (mapbool2(g.attrs.get("newrank"))) {
22627
22646
  g.info.flags = (g.info.flags ?? 0) | NEW_RANK;
22628
22647
  dot2Rank(g);
22629
22648
  } else {
@@ -26494,6 +26513,19 @@ function obsPath(conf, p0, poly0, p1, poly1) {
26494
26513
  }
26495
26514
 
26496
26515
  // src/common/splines-routespl.ts
26516
+ var routeDump = null;
26517
+ function dumpIsVirtual(e) {
26518
+ return (e.info?.edge_type ?? 0) !== 0;
26519
+ }
26520
+ function dumpEdgeNames(pp) {
26521
+ let e = pp.data;
26522
+ while (e !== null && dumpIsVirtual(e)) e = e.info?.to_orig ?? null;
26523
+ if (e === null) return ["?", "?"];
26524
+ return [e.tail?.name ?? "?", e.head?.name ?? "?"];
26525
+ }
26526
+ function emitDump(stage, names, mk) {
26527
+ if (routeDump !== null && names !== null) routeDump(stage, names[0], names[1], mk());
26528
+ }
26497
26529
  function overlap(i0, i1, j0, j1) {
26498
26530
  if (i1 <= j0 || i0 >= j1) return 0;
26499
26531
  if (i0 <= j0 && i1 >= j1) return i1 - i0;
@@ -26745,8 +26777,21 @@ function runLimitLoop(boxes, boxn, ps, initLlx, initUrx) {
26745
26777
  }
26746
26778
  function routeSplinesInternal(pp, polyline) {
26747
26779
  const boxes = pp.boxes;
26780
+ const dumpNames = routeDump ? dumpEdgeNames(pp) : null;
26781
+ emitDump("S1_INPUT", dumpNames, () => ({
26782
+ nbox: pp.nbox,
26783
+ boxes: pp.boxes.slice(0, pp.nbox).map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } })),
26784
+ start: { p: { ...pp.start.p }, theta: pp.start.theta, constrained: pp.start.constrained },
26785
+ end: { p: { ...pp.end.p }, theta: pp.end.theta, constrained: pp.end.constrained }
26786
+ }));
26748
26787
  if (checkPath(pp.nbox, boxes, pp)) return null;
26749
26788
  const effectiveBoxn = pp.nbox;
26789
+ emitDump("S2_CHECKED", dumpNames, () => ({
26790
+ nbox: effectiveBoxn,
26791
+ boxes: boxes.slice(0, effectiveBoxn).map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } })),
26792
+ start: { p: { ...pp.start.p } },
26793
+ end: { p: { ...pp.end.p } }
26794
+ }));
26750
26795
  let flip = false;
26751
26796
  if (effectiveBoxn > 1 && boxes[0].ll.y > boxes[1].ll.y) {
26752
26797
  flip = true;
@@ -26774,6 +26819,11 @@ function routeSplinesInternal(pp, polyline) {
26774
26819
  console.warn("in routesplines, Pshortestpath failed");
26775
26820
  return null;
26776
26821
  }
26822
+ emitDump("S3_POLY", dumpNames, () => ({
26823
+ poly: polypoints.map((p) => ({ ...p })),
26824
+ eps: [{ ...eps[0] }, { ...eps[1] }],
26825
+ pl: pl.map((p) => ({ ...p }))
26826
+ }));
26777
26827
  let ps;
26778
26828
  if (polyline) {
26779
26829
  ps = makePolyline(pl);
@@ -26783,6 +26833,11 @@ function routeSplinesInternal(pp, polyline) {
26783
26833
  ps = routeSpline(edges, pl, evs);
26784
26834
  if (ps.length === 0) return null;
26785
26835
  }
26836
+ emitDump("S4_SPL", dumpNames, () => ({
26837
+ polyline,
26838
+ evs: polyline ? void 0 : buildConstraintVectors(pp).map((v) => ({ ...v })),
26839
+ ps: ps.map((p) => ({ ...p }))
26840
+ }));
26786
26841
  if (isTriviallyBounded(ps)) {
26787
26842
  applyTrivialBounds(boxes, effectiveBoxn, ps);
26788
26843
  return ps;
@@ -28167,31 +28222,13 @@ function splay(root, key, keyOf, compare) {
28167
28222
  }
28168
28223
 
28169
28224
  // src/cdt/bag.ts
28170
- function findByIdentity(start, target, key, keyOf, compare) {
28171
- let cur = start;
28172
- let parent = null;
28173
- while (cur !== null) {
28174
- if (cur.obj === target) return [cur, parent];
28175
- if (compare(key, keyOf(cur.obj)) !== 0) return [null, null];
28176
- parent = cur;
28177
- cur = cur.left;
28178
- }
28179
- return [null, null];
28180
- }
28181
- function unlinkNode(root, cur, parent) {
28182
- const left = cur.left;
28183
- const right = cur.right;
28184
- let replacement;
28185
- if (left === null) {
28186
- replacement = right;
28187
- } else {
28188
- const maxLeft = splayMax(left);
28189
- maxLeft.right = right;
28190
- replacement = maxLeft;
28191
- }
28192
- if (parent === null) return replacement;
28193
- parent.left = replacement;
28194
- return root;
28225
+ function removeRoot(root) {
28226
+ const left = root.left;
28227
+ const right = root.right;
28228
+ if (left === null) return right;
28229
+ const maxLeft = splayMax(left);
28230
+ maxLeft.right = right;
28231
+ return maxLeft;
28195
28232
  }
28196
28233
  var DtBag = class {
28197
28234
  _root = null;
@@ -28230,16 +28267,13 @@ var DtBag = class {
28230
28267
  const key = this._keyOf(obj);
28231
28268
  this._root = splay(this._root, key, this._keyOf, this._compare);
28232
28269
  if (this._compare(key, this._keyOf(this._root.obj)) !== 0) return false;
28233
- const [cur, parent] = findByIdentity(
28234
- this._root,
28235
- obj,
28236
- key,
28237
- this._keyOf,
28238
- this._compare
28239
- );
28240
- if (cur === null) return false;
28241
- const newRoot = unlinkNode(this._root, cur, parent);
28242
- this._root = newRoot;
28270
+ while (this._root.obj !== obj) {
28271
+ const nxt = this.next(this._root.obj);
28272
+ if (nxt === void 0 || this._compare(key, this._keyOf(nxt)) !== 0) {
28273
+ return false;
28274
+ }
28275
+ }
28276
+ this._root = removeRoot(this._root);
28243
28277
  this._size--;
28244
28278
  return true;
28245
28279
  }
@@ -29090,7 +29124,7 @@ function runPlacement(gp) {
29090
29124
  const nObjs = gp.nodes.size + nSetLbls + nClbls + nElbls;
29091
29125
  const { ctx } = buildArrays(gp, nObjs, nLbls, nClbls, et);
29092
29126
  const forceStr = gp.attrs.get("forcelabels");
29093
- const force = forceStr === void 0 ? true : mapbool3(forceStr);
29127
+ const force = forceStr === void 0 ? true : mapbool2(forceStr);
29094
29128
  const params = { bb: { ll: ctx.bb.ll, ur: ctx.bb.ur }, force };
29095
29129
  placeLabels(ctx.objs, ctx.lbls, params);
29096
29130
  writeBackLabels(gp, ctx.lbls, nLbls);
@@ -34320,7 +34354,7 @@ function dotPhasePostNoFinish(g) {
34320
34354
  removeFill(g);
34321
34355
  dotSameports(g);
34322
34356
  dotSplines(g);
34323
- if (mapbool3(g.attrs.get("compound") ?? g.root.attrs.get("compound"))) dotCompoundEdges(g);
34357
+ if (mapbool2(g.attrs.get("compound") ?? g.root.attrs.get("compound"))) dotCompoundEdges(g);
34324
34358
  }
34325
34359
  function dotPhasePost(g) {
34326
34360
  dotPhasePostNoFinish(g);
@@ -35311,7 +35345,7 @@ function userPos(n) {
35311
35345
  n.info.pos = [Number(m[1]), Number(m[2])];
35312
35346
  n.info.posSet = true;
35313
35347
  const pin = n.attrs.get("pin");
35314
- if (m[3] === "!" || pin !== void 0 && mapbool3(pin)) n.info.pinned = true;
35348
+ if (m[3] === "!" || pin !== void 0 && mapbool2(pin)) n.info.pinned = true;
35315
35349
  return true;
35316
35350
  }
35317
35351
  function assignNodeIds2(g) {
@@ -38562,7 +38596,7 @@ function splineEdgesImpl(g, sep, edgetype) {
38562
38596
  function splineEdges(g) {
38563
38597
  const edgetype = g.info.flags & 15;
38564
38598
  if (edgetype === EDGETYPE_NONE) return;
38565
- g.root.info.concentrate = mapbool3(g.root.attrs.get("concentrate"));
38599
+ g.root.info.concentrate = mapbool2(g.root.attrs.get("concentrate"));
38566
38600
  for (const n of nodesInSeq(g)) {
38567
38601
  for (const e of n.outEdges(g)) {
38568
38602
  if (e.info.tail_port.dyna) e.info.tail_port = resolvePort(e.tail, e.head, e.info.tail_port);
@@ -45458,7 +45492,7 @@ function PARENT(n) {
45458
45492
  function isCluster(g) {
45459
45493
  if (g === g.root) return true;
45460
45494
  if (g.name.toLowerCase().startsWith("cluster")) return true;
45461
- return mapbool3(g.attrs.get("cluster"));
45495
+ return mapbool2(g.attrs.get("cluster"));
45462
45496
  }
45463
45497
  function clusterInitGraph(g) {
45464
45498
  graphInit(g, false);
@@ -45985,7 +46019,7 @@ function walkTree(tree) {
45985
46019
  function isCluster2(g) {
45986
46020
  if (g === g.root) return true;
45987
46021
  if (g.name.toLowerCase().startsWith("cluster")) return true;
45988
- return mapbool3(g.attrs.get("cluster"));
46022
+ return mapbool2(g.attrs.get("cluster"));
45989
46023
  }
45990
46024
  function collectClusters2(g, clusters) {
45991
46025
  for (const subg of g.subgraphs.values()) {
@@ -46065,7 +46099,7 @@ var PATCHWORK_LAYOUT_ENGINE = {
46065
46099
  // src/gvc/edge-labels.ts
46066
46100
  function renderEdgeLabels(e, renderer, job) {
46067
46101
  const obj = job.obj;
46068
- const spl = mapbool3(e.attrs.get("decorate") ?? "false") ? e.info.spl : void 0;
46102
+ const spl = mapbool2(e.attrs.get("decorate") ?? "false") ? e.info.spl : void 0;
46069
46103
  if (obj === null) {
46070
46104
  renderOneLabel(e.info.label, renderer, job);
46071
46105
  if (spl) emitAttachment(e.info.label, spl, renderer, job);
@@ -52477,7 +52511,7 @@ var XdotParser = class _XdotParser {
52477
52511
  let accounted = 0;
52478
52512
  let j = 0;
52479
52513
  while (accounted < len) {
52480
- if (cur + j >= s.length) break;
52514
+ if (cur + j >= s.length) return null;
52481
52515
  const ch = s[cur + j];
52482
52516
  const prev = j > 0 ? s[cur + j - 1] : "";
52483
52517
  out += ch;