@knowvah/dot-engine 2.6.12 → 2.7.1

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 (198) hide show
  1. package/README.md +1 -1
  2. package/dist/api.js +18 -4
  3. package/dist/api.js.map +3 -3
  4. package/dist/common/attr-get.d.ts +30 -0
  5. package/dist/common/attr-get.d.ts.map +1 -0
  6. package/dist/common/htmltable-emit-fill.d.ts +20 -2
  7. package/dist/common/htmltable-emit-fill.d.ts.map +1 -1
  8. package/dist/common/htmltable-emit.d.ts.map +1 -1
  9. package/dist/common/htmltable-lex-expat.d.ts.map +1 -1
  10. package/dist/common/htmltable-pos-runs.d.ts +7 -4
  11. package/dist/common/htmltable-pos-runs.d.ts.map +1 -1
  12. package/dist/common/htmltable.d.ts.map +1 -1
  13. package/dist/common/libm-trig.d.ts +5 -0
  14. package/dist/common/libm-trig.d.ts.map +1 -0
  15. package/dist/common/make-label.d.ts.map +1 -1
  16. package/dist/common/multicolor.d.ts +21 -13
  17. package/dist/common/multicolor.d.ts.map +1 -1
  18. package/dist/common/poly-gencode.d.ts +1 -2
  19. package/dist/common/poly-gencode.d.ts.map +1 -1
  20. package/dist/common/poly-init.d.ts +2 -12
  21. package/dist/common/poly-init.d.ts.map +1 -1
  22. package/dist/common/splines-clip.d.ts +7 -0
  23. package/dist/common/splines-clip.d.ts.map +1 -1
  24. package/dist/gvc/context.d.ts +6 -0
  25. package/dist/gvc/context.d.ts.map +1 -1
  26. package/dist/gvc/device-cluster.d.ts +15 -0
  27. package/dist/gvc/device-cluster.d.ts.map +1 -1
  28. package/dist/gvc/device.d.ts.map +1 -1
  29. package/dist/gvc/first-layer.d.ts +9 -0
  30. package/dist/gvc/first-layer.d.ts.map +1 -0
  31. package/dist/gvc/gvrender-set-style.d.ts +28 -0
  32. package/dist/gvc/gvrender-set-style.d.ts.map +1 -0
  33. package/dist/gvc/usershape.d.ts +18 -0
  34. package/dist/gvc/usershape.d.ts.map +1 -1
  35. package/dist/index.js +2478 -912
  36. package/dist/index.js.map +4 -4
  37. package/dist/layout/dot/compound.d.ts.map +1 -1
  38. package/dist/layout/dot/edge-route-clip.d.ts +14 -4
  39. package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
  40. package/dist/layout/dot/edge-route-routing.d.ts.map +1 -1
  41. package/dist/layout/dot/graph-label.d.ts.map +1 -1
  42. package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts +11 -0
  43. package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts.map +1 -0
  44. package/dist/layout/neato/__fixtures__/hier-imds.d.ts +36 -0
  45. package/dist/layout/neato/__fixtures__/hier-imds.d.ts.map +1 -0
  46. package/dist/layout/neato/__fixtures__/hier-majorization.d.ts +32 -0
  47. package/dist/layout/neato/__fixtures__/hier-majorization.d.ts.map +1 -0
  48. package/dist/layout/neato/cdt-surface.d.ts.map +1 -1
  49. package/dist/layout/neato/compute-hierarchy.d.ts +24 -0
  50. package/dist/layout/neato/compute-hierarchy.d.ts.map +1 -0
  51. package/dist/layout/neato/conjgrad-mkernel.d.ts +20 -0
  52. package/dist/layout/neato/conjgrad-mkernel.d.ts.map +1 -0
  53. package/dist/layout/neato/conjgrad.d.ts +19 -0
  54. package/dist/layout/neato/conjgrad.d.ts.map +1 -1
  55. package/dist/layout/neato/constrained-majorization.d.ts +26 -0
  56. package/dist/layout/neato/constrained-majorization.d.ts.map +1 -0
  57. package/dist/layout/neato/dijkstra.d.ts +33 -16
  58. package/dist/layout/neato/dijkstra.d.ts.map +1 -1
  59. package/dist/layout/neato/gts-triangle.d.ts +14 -0
  60. package/dist/layout/neato/gts-triangle.d.ts.map +1 -0
  61. package/dist/layout/neato/init.d.ts +2 -12
  62. package/dist/layout/neato/init.d.ts.map +1 -1
  63. package/dist/layout/neato/kkutils.d.ts +20 -0
  64. package/dist/layout/neato/kkutils.d.ts.map +1 -0
  65. package/dist/layout/neato/make-graph-data.d.ts +43 -0
  66. package/dist/layout/neato/make-graph-data.d.ts.map +1 -0
  67. package/dist/layout/neato/matrix-ops.d.ts +46 -0
  68. package/dist/layout/neato/matrix-ops.d.ts.map +1 -1
  69. package/dist/layout/neato/opt-arrangement.d.ts +20 -0
  70. package/dist/layout/neato/opt-arrangement.d.ts.map +1 -0
  71. package/dist/layout/neato/quad-prog-solve.d.ts +44 -0
  72. package/dist/layout/neato/quad-prog-solve.d.ts.map +1 -0
  73. package/dist/layout/neato/smart-ini-x.d.ts +9 -0
  74. package/dist/layout/neato/smart-ini-x.d.ts.map +1 -0
  75. package/dist/layout/neato/splines.d.ts +1 -1
  76. package/dist/layout/neato/splines.d.ts.map +1 -1
  77. package/dist/layout/neato/start.d.ts +4 -1
  78. package/dist/layout/neato/start.d.ts.map +1 -1
  79. package/dist/layout/neato/stress.d.ts +8 -0
  80. package/dist/layout/neato/stress.d.ts.map +1 -1
  81. package/dist/model/edge.d.ts +1 -1
  82. package/dist/model/edge.d.ts.map +1 -1
  83. package/dist/model/lazy-attrs.d.ts +10 -0
  84. package/dist/model/lazy-attrs.d.ts.map +1 -0
  85. package/dist/model/node.d.ts +1 -1
  86. package/dist/model/node.d.ts.map +1 -1
  87. package/dist/ortho/index.d.ts.map +1 -1
  88. package/dist/render/dot/edge-draw.d.ts +1 -1
  89. package/dist/render/dot/edge-draw.d.ts.map +1 -1
  90. package/dist/render/svg-multicolor.d.ts +2 -2
  91. package/dist/render/svg-multicolor.d.ts.map +1 -1
  92. package/dist/render.js +2358 -792
  93. package/dist/render.js.map +4 -4
  94. package/package.json +1 -1
  95. package/src/common/attr-get.ts +46 -0
  96. package/src/common/graph-init.ts +1 -1
  97. package/src/common/htmltable-emit-fill.ts +56 -11
  98. package/src/common/htmltable-emit.ts +4 -3
  99. package/src/common/htmltable-lex-expat.ts +21 -3
  100. package/src/common/htmltable-pos-runs.ts +11 -6
  101. package/src/common/htmltable.ts +28 -116
  102. package/src/common/libm-trig.ts +43 -0
  103. package/src/common/make-label.ts +14 -2
  104. package/src/common/multicolor.ts +88 -24
  105. package/src/common/poly-gencode.ts +16 -8
  106. package/src/common/poly-init.ts +23 -19
  107. package/src/common/postproc.ts +2 -2
  108. package/src/common/splines-clip.ts +15 -12
  109. package/src/common/splines-routespl.ts +2 -2
  110. package/src/common/textmeasure-lookup.ts +1 -1
  111. package/src/gvc/context.ts +8 -0
  112. package/src/gvc/device-cluster.ts +63 -8
  113. package/src/gvc/device.ts +16 -2
  114. package/src/gvc/first-layer.ts +26 -0
  115. package/src/gvc/gvrender-set-style.ts +114 -0
  116. package/src/gvc/usershape.ts +26 -0
  117. package/src/layout/dot/cluster.ts +1 -1
  118. package/src/layout/dot/compound.ts +3 -4
  119. package/src/layout/dot/conc.ts +1 -1
  120. package/src/layout/dot/edge-route-clip.ts +19 -7
  121. package/src/layout/dot/edge-route-routing.ts +11 -3
  122. package/src/layout/dot/fastgr.ts +2 -2
  123. package/src/layout/dot/graph-label.ts +1 -15
  124. package/src/layout/neato/__fixtures__/dijkstra-f.ts +17 -0
  125. package/src/layout/neato/__fixtures__/hier/c1554.gv +33 -0
  126. package/src/layout/neato/__fixtures__/hier/c1554.plain +26 -0
  127. package/src/layout/neato/__fixtures__/hier/c1554.xdot +161 -0
  128. package/src/layout/neato/__fixtures__/hier/cases/cycle.gv +1 -0
  129. package/src/layout/neato/__fixtures__/hier/cases/cycle.plain +10 -0
  130. package/src/layout/neato/__fixtures__/hier/cases/cycle.stderr +0 -0
  131. package/src/layout/neato/__fixtures__/hier/cases/dirnone.gv +1 -0
  132. package/src/layout/neato/__fixtures__/hier/cases/dirnone.plain +11 -0
  133. package/src/layout/neato/__fixtures__/hier/cases/dirnone.stderr +0 -0
  134. package/src/layout/neato/__fixtures__/hier/cases/epsilon.gv +1 -0
  135. package/src/layout/neato/__fixtures__/hier/cases/epsilon.plain +13 -0
  136. package/src/layout/neato/__fixtures__/hier/cases/epsilon.stderr +0 -0
  137. package/src/layout/neato/__fixtures__/hier/cases/levelsgap.gv +1 -0
  138. package/src/layout/neato/__fixtures__/hier/cases/levelsgap.plain +8 -0
  139. package/src/layout/neato/__fixtures__/hier/cases/levelsgap.stderr +0 -0
  140. package/src/layout/neato/__fixtures__/hier/cases/mds.gv +1 -0
  141. package/src/layout/neato/__fixtures__/hier/cases/mds.plain +10 -0
  142. package/src/layout/neato/__fixtures__/hier/cases/mds.stderr +0 -0
  143. package/src/layout/neato/__fixtures__/hier/cases/multiedge.gv +1 -0
  144. package/src/layout/neato/__fixtures__/hier/cases/multiedge.plain +10 -0
  145. package/src/layout/neato/__fixtures__/hier/cases/multiedge.stderr +0 -0
  146. package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.gv +1 -0
  147. package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.plain +8 -0
  148. package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.stderr +0 -0
  149. package/src/layout/neato/__fixtures__/hier/cases/startrandom.gv +1 -0
  150. package/src/layout/neato/__fixtures__/hier/cases/startrandom.plain +10 -0
  151. package/src/layout/neato/__fixtures__/hier/cases/startrandom.stderr +0 -0
  152. package/src/layout/neato/__fixtures__/hier/cases/startregular.gv +1 -0
  153. package/src/layout/neato/__fixtures__/hier/cases/startregular.plain +10 -0
  154. package/src/layout/neato/__fixtures__/hier/cases/startregular.stderr +0 -0
  155. package/src/layout/neato/__fixtures__/hier/cases/tdist.gv +1 -0
  156. package/src/layout/neato/__fixtures__/hier/cases/tdist.plain +13 -0
  157. package/src/layout/neato/__fixtures__/hier/cases/tdist.stderr +0 -0
  158. package/src/layout/neato/__fixtures__/hier/cases/undirected.gv +1 -0
  159. package/src/layout/neato/__fixtures__/hier/cases/undirected.plain +10 -0
  160. package/src/layout/neato/__fixtures__/hier/cases/undirected.stderr +0 -0
  161. package/src/layout/neato/__fixtures__/hier/hier-probe.gv +1 -0
  162. package/src/layout/neato/__fixtures__/hier/hier-probe.plain +16 -0
  163. package/src/layout/neato/__fixtures__/hier/hier-probe.xdot +62 -0
  164. package/src/layout/neato/__fixtures__/hier-imds.ts +151 -0
  165. package/src/layout/neato/__fixtures__/hier-majorization.ts +145 -0
  166. package/src/layout/neato/cdt-surface.ts +6 -16
  167. package/src/layout/neato/compute-hierarchy.ts +90 -0
  168. package/src/layout/neato/conjgrad-mkernel.ts +141 -0
  169. package/src/layout/neato/conjgrad.ts +208 -0
  170. package/src/layout/neato/constrained-majorization.ts +479 -0
  171. package/src/layout/neato/dijkstra.ts +218 -92
  172. package/src/layout/neato/edge-len.ts +2 -2
  173. package/src/layout/neato/fdp-adjust.ts +3 -3
  174. package/src/layout/neato/gts-triangle.ts +42 -0
  175. package/src/layout/neato/init.ts +57 -57
  176. package/src/layout/neato/kk.ts +2 -2
  177. package/src/layout/neato/kkutils.ts +96 -0
  178. package/src/layout/neato/make-graph-data.ts +166 -0
  179. package/src/layout/neato/matrix-ops.ts +138 -0
  180. package/src/layout/neato/opt-arrangement.ts +86 -0
  181. package/src/layout/neato/quad-prog-solve.ts +489 -0
  182. package/src/layout/neato/smart-ini-x.ts +503 -0
  183. package/src/layout/neato/splines.ts +4 -4
  184. package/src/layout/neato/start.ts +7 -6
  185. package/src/layout/neato/stress.ts +28 -0
  186. package/src/model/edge.ts +3 -2
  187. package/src/model/lazy-attrs.ts +36 -0
  188. package/src/model/node.ts +3 -2
  189. package/src/ortho/index.ts +2 -3
  190. package/src/parser/dot.js +1 -1
  191. package/src/parser/dot.pegjs +1 -1
  192. package/src/parser/index.ts +1 -1
  193. package/src/render/color-resolve.ts +2 -2
  194. package/src/render/dot/edge-draw.ts +6 -3
  195. package/src/render/dot.ts +1 -1
  196. package/src/render/svg-edge-split.ts +2 -2
  197. package/src/render/svg-multicolor.ts +4 -3
  198. package/src/render/svg-parallel-edge.ts +2 -2
package/dist/index.js CHANGED
@@ -299,7 +299,7 @@ function peg$parse(input, options) {
299
299
  return s;
300
300
  }
301
301
  function peg$f13(t, m, attrs) {
302
- if (m) agwarningf("attribute macros not implemented", "error");
302
+ if (m) agwarningf("attribute macros not implemented");
303
303
  return { type: "attr", target: t, attrs };
304
304
  }
305
305
  function peg$f14(a) {
@@ -3688,6 +3688,20 @@ var Graph = class {
3688
3688
  }
3689
3689
  };
3690
3690
 
3691
+ // src/model/lazy-attrs.ts
3692
+ var SharedEmptyAttrs = class extends Map {
3693
+ set(key, _value) {
3694
+ throw new Error(`attrs.set("${key}") on a shared empty map; use ownAttrs()`);
3695
+ }
3696
+ delete(key) {
3697
+ throw new Error(`attrs.delete("${key}") on a shared empty map; use ownAttrs()`);
3698
+ }
3699
+ clear() {
3700
+ throw new Error("attrs.clear() on a shared empty map; use ownAttrs()");
3701
+ }
3702
+ };
3703
+ var EMPTY_ATTRS = new SharedEmptyAttrs();
3704
+
3691
3705
  // src/model/algData.ts
3692
3706
  var THETA_UNSET = 10;
3693
3707
 
@@ -3790,10 +3804,10 @@ var Node = class {
3790
3804
  */
3791
3805
  nodeDefaultsSnapshot;
3792
3806
  /** @see lib/cgraph/node.c:agnode */
3793
- constructor(id, name, root) {
3807
+ constructor(id, name, root, lazyAttrs = false) {
3794
3808
  this.id = id;
3795
3809
  this.name = name;
3796
- this.attrs = /* @__PURE__ */ new Map();
3810
+ this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
3797
3811
  this.info = makeNodeInfo();
3798
3812
  this.root = root;
3799
3813
  }
@@ -3963,12 +3977,12 @@ var Edge = class _Edge {
3963
3977
  */
3964
3978
  info;
3965
3979
  /** @see lib/cgraph/edge.c:agedge */
3966
- constructor(tail, head, name) {
3980
+ constructor(tail, head, name, lazyAttrs = false) {
3967
3981
  this.seq = _Edge._nextSeq++;
3968
3982
  this.tail = tail;
3969
3983
  this.head = head;
3970
3984
  this.name = name;
3971
- this.attrs = /* @__PURE__ */ new Map();
3985
+ this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
3972
3986
  this.info = makeEdgeInfo(makePort(), makePort());
3973
3987
  }
3974
3988
  };
@@ -4854,7 +4868,7 @@ function isPeggyError(err) {
4854
4868
  function warnNumberAmbiguities(src, upTo) {
4855
4869
  for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
4856
4870
  if (a.offset > upTo) break;
4857
- agerrFinished(numberAmbiguityMessage(a), "error");
4871
+ agerrFinished(numberAmbiguityMessage(a));
4858
4872
  }
4859
4873
  }
4860
4874
  function parse(src) {
@@ -5627,6 +5641,12 @@ var GvcContext = class {
5627
5641
  * rendering happens in between and must see the layout state
5628
5642
  * (e.g. cluster arrays).
5629
5643
  *
5644
+ * Contract (AD-4/AD-8): first resets the C process state (RNG streams,
5645
+ * sequence counters, once-only warnings), so each `layout` call behaves
5646
+ * as one native run — drive one graph per `layout`. Caller-installed hooks
5647
+ * (setTextMeasurer, setImageSizer, setImageResolver, the per-context
5648
+ * measurer/sizer/resolver) are configuration and are not reset.
5649
+ *
5630
5650
  * @throws TypeError (ERR_INVALID_ARG_TYPE / ERR_INVALID_ARG_VALUE) for a
5631
5651
  * bad `g`, or an engine argument that is not registered
5632
5652
  * @throws RenderError (UNKNOWN_LAYOUT) if the `layout` attribute names no
@@ -5637,6 +5657,7 @@ var GvcContext = class {
5637
5657
  * @see lib/gvc/gvlayout.c:gvLayoutJobs
5638
5658
  */
5639
5659
  layout(g, engineName) {
5660
+ resetRenderState();
5640
5661
  const selected = this.checkLayoutArgs(g, engineName);
5641
5662
  const attr2 = g.attrs?.get("layout");
5642
5663
  let engine = selected;
@@ -8793,6 +8814,16 @@ function colorxlate(str, color, targetType) {
8793
8814
  }
8794
8815
 
8795
8816
  // src/common/multicolor.ts
8817
+ var parseSegsState = { warned: false };
8818
+ registerRenderState(() => {
8819
+ parseSegsState.warned = false;
8820
+ });
8821
+ function claimWarned() {
8822
+ if (parseSegsState.warned) return false;
8823
+ parseSegsState.warned = true;
8824
+ return true;
8825
+ }
8826
+ var claimNever = () => false;
8796
8827
  var EPS = 1e-5;
8797
8828
  function aeq0(x) {
8798
8829
  return x < EPS && x > -EPS;
@@ -8806,17 +8837,14 @@ function getSegLen(token) {
8806
8837
  const parsed = parseFloat(rest);
8807
8838
  return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
8808
8839
  }
8809
- function appendSeg(token, left2, segs, warnedExceeded) {
8840
+ function appendSeg(token, left2, segs, claim) {
8810
8841
  const { color, v } = getSegLen(token);
8811
8842
  if (v < 0) return null;
8812
8843
  let t = v;
8813
8844
  let rval = 0;
8814
8845
  const del = t - left2;
8815
8846
  if (del > 0) {
8816
- if (!aeq0(del) && !warnedExceeded.v) {
8817
- warnedExceeded.v = true;
8818
- rval = 3;
8819
- }
8847
+ if (!aeq0(del) && claim()) rval = 3;
8820
8848
  t = left2;
8821
8849
  }
8822
8850
  left2 -= t;
@@ -8840,19 +8868,13 @@ function trimTrailing(segs) {
8840
8868
  segs.pop();
8841
8869
  }
8842
8870
  }
8843
- function parseSegs(colorlist) {
8871
+ function scanSegs(colorlist, claim) {
8844
8872
  const segs = [];
8845
8873
  let left2 = 1;
8846
8874
  let rval = 0;
8847
- let badFloatCount = 0;
8848
- const warnedExceeded = { v: false };
8849
8875
  for (const token of colorlist.split(":")) {
8850
- const result = appendSeg(token, left2, segs, warnedExceeded);
8851
- if (result === null) {
8852
- const errCode = badFloatCount === 0 ? 2 : 1;
8853
- badFloatCount++;
8854
- return { segs: [], error: errCode };
8855
- }
8876
+ const result = appendSeg(token, left2, segs, claim);
8877
+ if (result === null) return { segs: [], error: claim() ? 2 : 1 };
8856
8878
  if (result.rval === 3) rval = 3;
8857
8879
  left2 = result.left;
8858
8880
  if (aeq0(left2)) {
@@ -8864,6 +8886,26 @@ function parseSegs(colorlist) {
8864
8886
  trimTrailing(segs);
8865
8887
  return { segs, error: rval };
8866
8888
  }
8889
+ function parseSegs(colorlist, context) {
8890
+ const result = scanSegs(colorlist, claimWarned);
8891
+ if (result.error === 3) {
8892
+ const tail = context === void 0 ? "" : context();
8893
+ agwarningf(`Total size > 1 in "${colorlist}" color spec ${tail}`);
8894
+ } else if (result.error === 2) {
8895
+ agerrorf(`Illegal value in "${colorlist}" color attribute; float expected after ';'`);
8896
+ if (context !== void 0) agerr("prev", context());
8897
+ }
8898
+ return result;
8899
+ }
8900
+ function parseSegsSilent(colorlist) {
8901
+ return scanSegs(colorlist, claimNever);
8902
+ }
8903
+ function edgeSegsContext(e) {
8904
+ return () => {
8905
+ const directed = !e.tail.root.kind.endsWith("undirected");
8906
+ return `in edge ${e.tail.name}${directed ? " -> " : " -- "}${e.head.name}`;
8907
+ };
8908
+ }
8867
8909
 
8868
8910
  // src/common/style-resolve.ts
8869
8911
  var DEFAULT_COLOR = "black";
@@ -9283,7 +9325,7 @@ function countChar(s, ch) {
9283
9325
  return s.split(ch).length - 1;
9284
9326
  }
9285
9327
  function multicolorNames(color, arrows) {
9286
- const { segs, error } = parseSegs(color);
9328
+ const { segs, error } = parseSegsSilent(color);
9287
9329
  if (error === 1 || error === 2) return null;
9288
9330
  const out = [];
9289
9331
  const front = segs[0]?.color ?? null;
@@ -9870,6 +9912,71 @@ function htmlStyle(style2) {
9870
9912
  return s;
9871
9913
  }
9872
9914
 
9915
+ // src/gvc/gvrender-set-style.ts
9916
+ var SUPPORTED_STYLES = /* @__PURE__ */ new Set([
9917
+ "solid",
9918
+ "dashed",
9919
+ "dotted",
9920
+ "invis",
9921
+ "invisible",
9922
+ "bold",
9923
+ "setlinewidth",
9924
+ "filled",
9925
+ "unfilled",
9926
+ "tapered"
9927
+ ]);
9928
+ var BOX_ORIENTATION_TOLERANCE = 0.5;
9929
+ var BOX_ORIENTATION_STEP = 90;
9930
+ var BOX_SIDES = 4;
9931
+ var ELLIPSE_MAX_SIDES = 2;
9932
+ function styleName(token) {
9933
+ const paren = token.indexOf("(");
9934
+ return paren < 0 ? token : token.slice(0, paren);
9935
+ }
9936
+ function gvrenderSetStyle(styles) {
9937
+ if (styles === null) return;
9938
+ for (const token of styles) {
9939
+ const name = styleName(token);
9940
+ if (!SUPPORTED_STYLES.has(name)) {
9941
+ agwarningf(`gvrender_set_style: unsupported style ${name} - ignoring`);
9942
+ }
9943
+ }
9944
+ }
9945
+ function isBox(p) {
9946
+ if (p === null) return false;
9947
+ return p.sides === BOX_SIDES && Math.abs(p.orientation % BOX_ORIENTATION_STEP) < BOX_ORIENTATION_TOLERANCE && p.distortion === 0 && p.skew === 0;
9948
+ }
9949
+ function isEllipse(p) {
9950
+ return p !== null && p.sides <= ELLIPSE_MAX_SIDES;
9951
+ }
9952
+ function checkStyleTokens(styles, shape) {
9953
+ return styles.filter((p) => {
9954
+ if (p === "rounded" || p === "diagonals" || p === "radial") return false;
9955
+ if (p === "striped") return !isBox(shape);
9956
+ if (p === "wedged") return !isEllipse(shape);
9957
+ return true;
9958
+ });
9959
+ }
9960
+ function checkClusterStyleTokens(styles) {
9961
+ return styles.filter((p) => p !== "radial" && p !== "striped" && p !== "rounded");
9962
+ }
9963
+ function countChar2(s, ch) {
9964
+ return [...s].filter((c) => c === ch).length;
9965
+ }
9966
+ function multicolorTaken(color) {
9967
+ if (countChar2(color, ";") === 0 || countChar2(color, ":") === 0) return false;
9968
+ const { error } = parseSegsSilent(color);
9969
+ return error !== 1 && error !== 2;
9970
+ }
9971
+ function edgeStyleResets(e, styles) {
9972
+ const spl = e.info.spl;
9973
+ if (spl === void 0 || spl.size <= 1 || styles.length === 0) return 0;
9974
+ const color = e.attrs.get("color") ?? "";
9975
+ const otherBranch = styles.includes("tapered") || countChar2(color, ":") > 0;
9976
+ if (otherBranch && !multicolorTaken(color)) return 0;
9977
+ return spl.list.filter((bz) => bz.sflag !== 0 || bz.eflag !== 0).length;
9978
+ }
9979
+
9873
9980
  // src/common/htmltable-types.ts
9874
9981
  var HtmlParseError = class extends DotEngineError {
9875
9982
  type = "semantic";
@@ -9889,13 +9996,21 @@ var BORDER_BOTTOM = 1 << 13;
9889
9996
  var BORDER_MASK = BORDER_LEFT | BORDER_TOP | BORDER_RIGHT | BORDER_BOTTOM;
9890
9997
 
9891
9998
  // src/common/htmltable-emit-fill.ts
9999
+ var MSG_MANY_COLORS = "More than 2 colors specified for a gradient - ignoring remaining";
10000
+ function findHtmlStopColor(color, silent = false) {
10001
+ const { segs, error } = silent ? parseSegsSilent(color) : parseSegs(color);
10002
+ const first = segs[0];
10003
+ const second = segs[1];
10004
+ if (error !== 0 || first === void 0 || second === void 0 || first.color === null) {
10005
+ return null;
10006
+ }
10007
+ if (segs.length > 2 && !silent) agwarningf(MSG_MANY_COLORS);
10008
+ const frac = first.hasFraction ? first.t : second.hasFraction ? 1 - second.t : 0;
10009
+ return { fill: first.color, stop: second.color, frac };
10010
+ }
9892
10011
  function parseGradientSpec(color) {
9893
- const idx = color.indexOf(":");
9894
- if (idx < 1) return null;
9895
- const c0 = color.slice(0, idx).trim();
9896
- const c1 = color.slice(idx + 1).trim();
9897
- if (c0.length === 0) return null;
9898
- return [c0, c1.length > 0 ? c1 : "black"];
10012
+ const spec = findHtmlStopColor(color, true);
10013
+ return spec === null ? null : [spec.fill, spec.stop ?? "black"];
9899
10014
  }
9900
10015
  var paintObj = {
9901
10016
  parent: null,
@@ -9952,6 +10067,12 @@ function resetHtmlFillPenWidth() {
9952
10067
  htmlFillPen = 1;
9953
10068
  }
9954
10069
  registerRenderState(resetHtmlFillPenWidth);
10070
+ var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
10071
+ function htmlBorderStyle(pen) {
10072
+ if (pen === 1 /* Dashed */) return ["dashed"];
10073
+ if (pen === 2 /* Dotted */) return ["dotted"];
10074
+ return DEFAULT_LINE_STYLE;
10075
+ }
9955
10076
  function penTypeOf(style2) {
9956
10077
  const st = htmlStyle(style2);
9957
10078
  if (st.dashed) return 1 /* Dashed */;
@@ -9959,12 +10080,13 @@ function penTypeOf(style2) {
9959
10080
  return 3 /* Solid */;
9960
10081
  }
9961
10082
  function withHtmlPaint(paint, job, drawFn) {
9962
- paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(paint.fill) : { type: "none" };
10083
+ paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(firstColor(paint.fill)) : { type: "none" };
9963
10084
  paintObj.penColor = paint.pen !== void 0 ? resolveRenderColor(paint.pen) : { type: "string", s: "transparent" };
9964
10085
  applyHtmlFill(paint);
9965
10086
  paintObj.pen = penTypeOf(paint.penStyle);
9966
10087
  paintObj.penWidth = paint.penWidth !== void 0 ? paint.penWidth : 1;
9967
10088
  paintObj.rawStyle = paintObj.pen === 3 /* Solid */ ? ["solid"] : [];
10089
+ gvrenderSetStyle(htmlBorderStyle(paintObj.pen));
9968
10090
  paintObj.emitState = job.obj?.emitState ?? 8 /* NDraw */;
9969
10091
  job.pushObj(paintObj);
9970
10092
  try {
@@ -9978,7 +10100,7 @@ function applyHtmlFill(paint) {
9978
10100
  paintObj.fill = paint.radial === true ? 3 /* Radial */ : 2 /* Linear */;
9979
10101
  paintObj.stopColor = resolveRenderColor(paint.stop);
9980
10102
  paintObj.gradientAngle = paint.gradientAngle ?? 0;
9981
- paintObj.gradientFrac = 0;
10103
+ paintObj.gradientFrac = paint.gradientFrac ?? 0;
9982
10104
  return;
9983
10105
  }
9984
10106
  paintObj.fill = paint.fill !== void 0 ? 1 /* Solid */ : 0 /* None */;
@@ -10247,11 +10369,12 @@ function emitHtmlLine(line, pos, renderer, job) {
10247
10369
  }
10248
10370
  function bgFillPaint(ctx) {
10249
10371
  const penWidth = htmlFillPenWidth();
10250
- const spec = parseGradientSpec(ctx.bgcolor);
10372
+ const spec = findHtmlStopColor(ctx.bgcolor);
10251
10373
  if (spec === null) return { fill: ctx.bgcolor, penWidth };
10252
10374
  return {
10253
- fill: spec[0],
10254
- stop: spec[1],
10375
+ fill: spec.fill,
10376
+ stop: spec.stop ?? "black",
10377
+ gradientFrac: spec.frac,
10255
10378
  gradientAngle: ctx.gradientangle ?? 0,
10256
10379
  radial: htmlStyle(ctx.style).radial,
10257
10380
  penWidth
@@ -10395,6 +10518,17 @@ function emitHtmlLabel(placed, pos, renderer, job) {
10395
10518
  }
10396
10519
  }
10397
10520
 
10521
+ // src/common/attr-get.ts
10522
+ function nodeAttr(n, g, key) {
10523
+ const own = n.attrs.get(key);
10524
+ if (own !== void 0) return own;
10525
+ if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
10526
+ return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
10527
+ }
10528
+ function graphAttrInherited(sg, key) {
10529
+ return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
10530
+ }
10531
+
10398
10532
  // src/common/htmltable-attr-warn.ts
10399
10533
  var accepted = (v) => ({ keep: v, text: [], warn: false });
10400
10534
  var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
@@ -11126,9 +11260,15 @@ function scanCdata(text, p, base, dataOf, tokens) {
11126
11260
  if (end > p) tokens.push({ kind: "cdata", start: base + p, end: base + end, data: dataOf(base + p, base + end) });
11127
11261
  return close < 0 ? -1 : close + CDATA_CLOSE.length;
11128
11262
  }
11263
+ var CONTENT_NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
11129
11264
  function scanText(text, p, base, tokens) {
11130
11265
  const e = text.indexOf("<", p);
11131
11266
  const slice = text.slice(p, e < 0 ? text.length : e);
11267
+ const bad = CONTENT_NON_XML.exec(slice)?.index;
11268
+ if (bad !== void 0) {
11269
+ if (bad > 0) tokens.push({ kind: "text", start: base + p, end: base + p + bad });
11270
+ return { at: p + bad, held: false, invalid: p + bad };
11271
+ }
11132
11272
  const from = e < 0 ? heldRefStart(slice) : void 0;
11133
11273
  const end = from === void 0 ? p + slice.length : p + from;
11134
11274
  if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
@@ -11148,6 +11288,7 @@ function scanContent(text, base, inCdata, dataOf) {
11148
11288
  }
11149
11289
  if (text[p] !== "<") {
11150
11290
  const scanned = scanText(text, p, base, tokens);
11291
+ if (scanned.invalid !== void 0) return { tokens, consumed: scanned.at, invalid: base + scanned.invalid, inCdata: false };
11151
11292
  if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
11152
11293
  p = scanned.at;
11153
11294
  continue;
@@ -12154,6 +12295,72 @@ var parseHtmlLabelRv = (src, stderr) => {
12154
12295
  };
12155
12296
  var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
12156
12297
 
12298
+ // src/gvc/image-resolver.ts
12299
+ var activeResolver = null;
12300
+ function setImageResolver(fn) {
12301
+ if (fn !== null && typeof fn !== "function") {
12302
+ throw invalidArgType("resolver", "function or null", fn);
12303
+ }
12304
+ activeResolver = fn;
12305
+ }
12306
+ var EXT_MIME = {
12307
+ png: "image/png",
12308
+ jpg: "image/jpeg",
12309
+ jpeg: "image/jpeg",
12310
+ gif: "image/gif",
12311
+ svg: "image/svg+xml",
12312
+ webp: "image/webp"
12313
+ };
12314
+ var FALLBACK_MIME = "application/octet-stream";
12315
+ function inferMimeFromSrc(src) {
12316
+ const dot = src.lastIndexOf(".");
12317
+ if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
12318
+ const ext = src.slice(dot + 1).toLowerCase();
12319
+ return EXT_MIME[ext] ?? FALLBACK_MIME;
12320
+ }
12321
+ function findImageBytes(src, resolver) {
12322
+ const active = resolver ?? activeResolver;
12323
+ if (active === null) return null;
12324
+ const result = active(src);
12325
+ if (result === null) return null;
12326
+ if (result instanceof Uint8Array) {
12327
+ return { bytes: result, mime: inferMimeFromSrc(src) };
12328
+ }
12329
+ return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
12330
+ }
12331
+ var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
12332
+ function base64Encode(bytes) {
12333
+ const len = bytes.length;
12334
+ const out = [];
12335
+ let i = 0;
12336
+ for (; i + 2 < len; i += 3) {
12337
+ const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
12338
+ out.push(
12339
+ B64_CHARS[n >> 18 & 63],
12340
+ B64_CHARS[n >> 12 & 63],
12341
+ B64_CHARS[n >> 6 & 63],
12342
+ B64_CHARS[n & 63]
12343
+ );
12344
+ }
12345
+ const remaining = len - i;
12346
+ if (remaining === 1) {
12347
+ const n = bytes[i] << 16;
12348
+ out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
12349
+ } else if (remaining === 2) {
12350
+ const n = bytes[i] << 16 | bytes[i + 1] << 8;
12351
+ out.push(
12352
+ B64_CHARS[n >> 18 & 63],
12353
+ B64_CHARS[n >> 12 & 63],
12354
+ B64_CHARS[n >> 6 & 63],
12355
+ "="
12356
+ );
12357
+ }
12358
+ return out.join("");
12359
+ }
12360
+ function toDataUri(bytes, mime) {
12361
+ return "data:" + mime + ";base64," + base64Encode(bytes);
12362
+ }
12363
+
12157
12364
  // src/gvc/usershape.ts
12158
12365
  var activeSizer = null;
12159
12366
  function setImageSizer(sizer) {
@@ -12165,6 +12372,14 @@ function setImageSizer(sizer) {
12165
12372
  function findImageSize(src) {
12166
12373
  return activeSizer !== null ? activeSizer(src) : null;
12167
12374
  }
12375
+ var STRERROR_ENOENT = "No such file or directory";
12376
+ function imageIsSupplied(name, sizer, resolver) {
12377
+ const size = sizer !== void 0 ? sizer(name) : findImageSize(name);
12378
+ return size !== null || findImageBytes(name, resolver) !== null;
12379
+ }
12380
+ function imageOpenWarning(name) {
12381
+ return `${STRERROR_ENOENT} while opening ${name}`;
12382
+ }
12168
12383
 
12169
12384
  // src/common/pointset.ts
12170
12385
  function cmpPair(a, b) {
@@ -12217,363 +12432,6 @@ var PointSet = class {
12217
12432
  }
12218
12433
  };
12219
12434
 
12220
- // src/common/htmltable-fontinfo.ts
12221
- var SIZE_SAVEF = { fontsize: 0 };
12222
- var EMIT_SAVEF = { fontsize: 0 };
12223
- var pushFontInfo = (env, fp, savp) => {
12224
- if (fp.fontFace !== void 0) {
12225
- savp.fontname = env.fontname;
12226
- env.fontname = fp.fontFace;
12227
- } else savp.fontname = void 0;
12228
- if (env.fontcolor !== void 0) {
12229
- if (fp.fontColor !== void 0) {
12230
- savp.fontcolor = env.fontcolor;
12231
- env.fontcolor = fp.fontColor;
12232
- } else savp.fontcolor = void 0;
12233
- }
12234
- if (env.fontsize >= 0) {
12235
- if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
12236
- savp.fontsize = env.fontsize;
12237
- env.fontsize = fp.fontSize;
12238
- } else savp.fontsize = -1;
12239
- }
12240
- };
12241
- var popFontInfo = (env, savp) => {
12242
- if (savp.fontname !== void 0) env.fontname = savp.fontname;
12243
- if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
12244
- if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
12245
- };
12246
- var withTableFont = (env, font, slot, fn) => {
12247
- if (font === void 0) return fn();
12248
- const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
12249
- pushFontInfo(env, font, savp);
12250
- const r = fn();
12251
- popFontInfo(env, savp);
12252
- return r;
12253
- };
12254
-
12255
- // src/common/htmltable.ts
12256
- var DEFAULT_BORDER = 1;
12257
- var DEFAULT_CELLPADDING = 2;
12258
- var DEFAULT_CELLSPACING = 2;
12259
- var DEFAULT_FONTSIZE = 14;
12260
- var findCol = (ps, row, startCol, colspan, rowspan) => {
12261
- let col = startCol;
12262
- let notFound = true;
12263
- const end = colspan - 1;
12264
- while (notFound) {
12265
- const lastc = col + end;
12266
- let c;
12267
- for (c = lastc; c >= col; c--) {
12268
- if (ps.isInPS(c, row)) break;
12269
- }
12270
- if (c >= col) col = c + 1;
12271
- else notFound = false;
12272
- }
12273
- for (let j = col; j < col + colspan; j++) {
12274
- for (let i = row; i < row + rowspan; i++) {
12275
- ps.addPS(j, i);
12276
- }
12277
- }
12278
- return col;
12279
- };
12280
- var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
12281
- var itemFont = (item, env) => ({
12282
- fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
12283
- face: item.fontFace !== void 0 ? item.fontFace : env.fontname
12284
- });
12285
- var measureItem = (item, measurer, env) => {
12286
- const { fs, face } = itemFont(item, env);
12287
- const flags = item.bold === true || item.italic === true ? { bold: item.bold === true, italic: item.italic === true } : void 0;
12288
- return measurer.measure(item.text ?? "", face, fs, flags);
12289
- };
12290
- var splitSizedLines = (texts, measurer, env) => {
12291
- const lines = [];
12292
- let cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
12293
- const accumulate = (item) => {
12294
- const sz = measureItem(item, measurer, env);
12295
- cur.items.push(item);
12296
- cur.width += sz.w;
12297
- cur.mxysize = Math.max(cur.mxysize, sz.h);
12298
- cur.mxfsize = Math.max(cur.mxfsize, itemFont(item, env).fs);
12299
- };
12300
- const flush = (br) => {
12301
- if (cur.items.length === 0 && br !== void 0) {
12302
- const { br: _b, brAlign: _a, ...fontProps } = br;
12303
- accumulate({ text: "", ...fontProps });
12304
- }
12305
- lines.push(cur);
12306
- cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
12307
- };
12308
- for (const txt of texts) {
12309
- for (const item of txt.items) {
12310
- if (item.br) {
12311
- flush(item);
12312
- continue;
12313
- }
12314
- if (item.text === void 0) continue;
12315
- accumulate(item);
12316
- }
12317
- if (cur.items.length > 0) flush();
12318
- }
12319
- return lines;
12320
- };
12321
- var itemHasFlags = (i) => i.bold === true || i.italic === true || i.underline === true || i.strikethrough === true || i.overline === true || i.subscript === true || i.superscript === true;
12322
- var htmlTextIsSimple = (lines, env) => {
12323
- let prevFs = -1;
12324
- let prevFace = null;
12325
- for (const ln of lines) {
12326
- const item = ln.items[0];
12327
- if (ln.items.length > 1 || itemHasFlags(item)) return false;
12328
- const { fs, face } = itemFont(item, env);
12329
- if (prevFs < 0) prevFs = fs;
12330
- else if (fs !== prevFs) return false;
12331
- if (prevFace === null) prevFace = face;
12332
- else if (face !== prevFace) return false;
12333
- }
12334
- return true;
12335
- };
12336
- var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
12337
- const lines = splitSizedLines(texts, measurer, env);
12338
- const simple = htmlTextIsSimple(lines, env);
12339
- let w = 0;
12340
- let h = 0;
12341
- for (const ln of lines) {
12342
- w = Math.max(w, ln.width);
12343
- const lsize = simple ? ln.mxysize : ln.mxfsize;
12344
- h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
12345
- }
12346
- if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].mxysize : DEFAULT_FONTSIZE;
12347
- return { w, h };
12348
- };
12349
- var missingImages = /* @__PURE__ */ new WeakSet();
12350
- var sizeHtmlImg = (img, { imageSizer, stderr }) => {
12351
- if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
12352
- const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
12353
- if (sz !== null) {
12354
- img.width = sz.w;
12355
- img.height = sz.h;
12356
- return 0;
12357
- }
12358
- agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
12359
- img.width = 0;
12360
- img.height = 0;
12361
- missingImages.add(img);
12362
- return 1;
12363
- };
12364
- var sizeContentItem = (item, measurer, env) => {
12365
- if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
12366
- if (item.kind === "table") {
12367
- const rv = sizeTableInner(item, measurer, env);
12368
- return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
12369
- }
12370
- if (item.kind === "image") {
12371
- const rv = sizeHtmlImg(item, env);
12372
- return { w: item.width ?? 0, h: item.height ?? 0, rv };
12373
- }
12374
- return { w: 0, h: 0, rv: 0 };
12375
- };
12376
- var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
12377
- var cellBorder = (cell2, tbl) => {
12378
- if (cell2.border !== void 0) return cell2.border;
12379
- const cb = tbl.cellborder;
12380
- if (cb !== void 0 && cb >= 0) return cb;
12381
- if (tbl.border !== void 0) return tbl.border;
12382
- return DEFAULT_BORDER;
12383
- };
12384
- function inheritTablePenColor(tbl, parentColor) {
12385
- if (tbl.color === void 0) tbl.color = parentColor;
12386
- const tblColor = tbl.color;
12387
- for (const row of tbl.rows) {
12388
- for (const cell2 of row.cells) {
12389
- if (cell2.color === void 0) cell2.color = tblColor;
12390
- for (const item of cell2.content) {
12391
- if (item.kind === "table") inheritTablePenColor(item, cell2.color);
12392
- }
12393
- }
12394
- }
12395
- }
12396
- var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
12397
- var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
12398
- var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
12399
- var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
12400
- var sizeWarned = /* @__PURE__ */ new WeakSet();
12401
- var fixedCellCheck = (cell2, sz, warn, out) => {
12402
- if (!cell2.fixedsize) return { rv: 0, zero: false };
12403
- if (cell2.width && cell2.height) {
12404
- const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
12405
- if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
12406
- return { rv: small ? 1 : 0, zero: true };
12407
- }
12408
- if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
12409
- return { rv: 1, zero: false };
12410
- };
12411
- var getCellSize = (cell2, tbl, measurer, env) => {
12412
- const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
12413
- let cw = 0, ch = 0, rv = 0;
12414
- for (const item of cell2.content) {
12415
- const s = sizeContentItem(item, measurer, env);
12416
- cw = Math.max(cw, s.w);
12417
- ch += s.h;
12418
- rv |= s.rv;
12419
- }
12420
- let szx = cw + margin;
12421
- let szy = ch + margin;
12422
- const warn = !sizeWarned.has(cell2);
12423
- sizeWarned.add(cell2);
12424
- const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
12425
- rv |= fixed.rv;
12426
- if (fixed.zero) {
12427
- szx = 0;
12428
- szy = 0;
12429
- }
12430
- const bw = cell2.width !== void 0 ? cell2.width : 0;
12431
- const bh = cell2.height !== void 0 ? cell2.height : 0;
12432
- return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
12433
- };
12434
- var buildLayouts = (tbl, measurer, env) => {
12435
- const entries = [];
12436
- let rv = 0;
12437
- const ps = new PointSet();
12438
- let rowIdx = 0;
12439
- for (const row of tbl.rows) {
12440
- let col = 0;
12441
- for (const c of row.cells) {
12442
- if (c.kind !== "cell") {
12443
- continue;
12444
- }
12445
- const colspan = c.colspan !== void 0 ? c.colspan : 1;
12446
- const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
12447
- const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
12448
- rv |= cellRv;
12449
- col = findCol(ps, rowIdx, col, colspan, rowspan);
12450
- entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
12451
- col += colspan;
12452
- }
12453
- rowIdx++;
12454
- }
12455
- return { entries, rv };
12456
- };
12457
- var setColWidths = (entries, ncols, spacing) => {
12458
- const widths = new Array(ncols + 1).fill(0);
12459
- for (const e of entries)
12460
- if (e.colspan === 1) widths[e.col] = Math.max(widths[e.col], e.w);
12461
- for (const e of entries) {
12462
- if (e.colspan === 1) continue;
12463
- const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
12464
- const need = e.w - spanW - (e.colspan - 1) * spacing;
12465
- if (need > 0) {
12466
- const add2 = need / e.colspan;
12467
- for (let j = 0; j < e.colspan; j++) widths[e.col + j] += add2;
12468
- }
12469
- }
12470
- for (const e of entries) {
12471
- const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
12472
- e.w = Math.max(e.w, spanW + (e.colspan - 1) * spacing);
12473
- }
12474
- return widths;
12475
- };
12476
- var setRowHeights = (entries, nrows, spacing) => {
12477
- const heights = new Array(nrows + 1).fill(0);
12478
- for (const e of entries)
12479
- if (e.rowspan === 1) heights[e.row] = Math.max(heights[e.row], e.h);
12480
- for (const e of entries) {
12481
- if (e.rowspan === 1) continue;
12482
- const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
12483
- const need = e.h - spanH - (e.rowspan - 1) * spacing;
12484
- if (need > 0) {
12485
- const add2 = need / e.rowspan;
12486
- for (let j = 0; j < e.rowspan; j++) heights[e.row + j] += add2;
12487
- }
12488
- }
12489
- for (const e of entries) {
12490
- const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
12491
- e.h = Math.max(e.h, spanH + (e.rowspan - 1) * spacing);
12492
- }
12493
- return heights;
12494
- };
12495
- var getSpacing = (tbl) => tbl.cellspacing !== void 0 ? tbl.cellspacing : DEFAULT_CELLSPACING;
12496
- var getBorder = (tbl) => tbl.border !== void 0 ? tbl.border : DEFAULT_BORDER;
12497
- var isTblFixed = (tbl) => tbl.fixedsize === true && tbl.width !== void 0 && tbl.height !== void 0;
12498
- var sumTableDims = (a) => {
12499
- let wd = (a.ncols + 1) * a.spacing + 2 * a.border;
12500
- let ht = (a.nrows + 1) * a.spacing + 2 * a.border;
12501
- for (let i = 0; i < a.ncols; i++) wd += a.widths[i];
12502
- for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
12503
- return { wd, ht };
12504
- };
12505
- var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
12506
- const spacing = getSpacing(tbl);
12507
- const border2 = getBorder(tbl);
12508
- const { entries, rv } = buildLayouts(tbl, measurer, env);
12509
- if (entries.length === 0) {
12510
- return { entries, widths: [], heights: [], spacing, border: border2, rv };
12511
- }
12512
- const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
12513
- const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
12514
- const widths = setColWidths(entries, ncols, spacing);
12515
- const heights = setRowHeights(entries, nrows, spacing);
12516
- return { entries, widths, heights, spacing, border: border2, rv };
12517
- };
12518
- var warnFixedTable = (tbl, dims, out) => {
12519
- const warn = !sizeWarned.has(tbl);
12520
- sizeWarned.add(tbl);
12521
- if (tbl.fixedsize !== true) return 0;
12522
- if (tbl.width && tbl.height) {
12523
- if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
12524
- if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
12525
- return 1;
12526
- }
12527
- if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
12528
- return 1;
12529
- };
12530
- var sizeTableBody = (tbl, measurer, env) => {
12531
- const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
12532
- if (entries.length === 0) {
12533
- const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
12534
- tbl.dimen = { w: 0, h: 0 };
12535
- return rv | fixed2;
12536
- }
12537
- const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
12538
- const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
12539
- for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
12540
- const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
12541
- const baseWd = tbl.width !== void 0 ? tbl.width : 0;
12542
- const baseHt = tbl.height !== void 0 ? tbl.height : 0;
12543
- const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
12544
- const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
12545
- tbl.dimen = {
12546
- w: Math.max(zeroContent ? 0 : wd, baseWd),
12547
- h: Math.max(zeroContent ? 0 : ht, baseHt)
12548
- };
12549
- return rv | fixed;
12550
- };
12551
- var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
12552
- var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
12553
- if (label.kind === "table") {
12554
- const rv = sizeTableInner(label.table, measurer, env);
12555
- label.dimen = label.table.dimen;
12556
- return rv;
12557
- }
12558
- label.dimen = sizeTextContent(label.texts, measurer, env);
12559
- return 0;
12560
- };
12561
-
12562
- // src/common/splines-constants.ts
12563
- var REGULAREDGE = 1;
12564
- var FLATEDGE = 2;
12565
- var ARR_NONE = 0;
12566
- var BOTTOM = 1 << 0;
12567
- var RIGHT = 1 << 1;
12568
- var TOP = 1 << 2;
12569
- var LEFT = 1 << 3;
12570
- var SELF_EDGE_SIZE = 18;
12571
- var MILLIPOINT = 1e-3;
12572
- var FUDGE = 2;
12573
- var INIT_DELTA = 10;
12574
- var LOOP_TRIES = 15;
12575
- var ROUTESPL_FUDGE = 1e-4;
12576
-
12577
12435
  // src/common/textmeasure-lut-data-a.ts
12578
12436
  var TR = [
12579
12437
  -1,
@@ -17416,7 +17274,7 @@ function getFamilyMetrics(fontName) {
17416
17274
  if (!warnedFontNames.has(fontName)) {
17417
17275
  warnedFontNames.add(fontName);
17418
17276
  agwarningf(
17419
- `no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
17277
+ `Warning: no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
17420
17278
  );
17421
17279
  }
17422
17280
  return TIMES_FALLBACK;
@@ -17757,7 +17615,7 @@ function itemFace(item, finfo) {
17757
17615
  face: item.fontFace !== void 0 ? item.fontFace : finfo.fontname
17758
17616
  };
17759
17617
  }
17760
- function measureItem2(item, finfo, measurer) {
17618
+ function measureItem(item, finfo, measurer) {
17761
17619
  if (item.text === void 0) return null;
17762
17620
  const { fs, face } = itemFace(item, finfo);
17763
17621
  const flags = itemFontFlags(item);
@@ -17792,7 +17650,7 @@ function buildLineRuns(texts, finfo, measurer) {
17792
17650
  if (cur.items.length === 0 && br !== void 0) {
17793
17651
  const { br: _b, brAlign: _a, ...fontProps } = br;
17794
17652
  const empty = { text: "", ...fontProps };
17795
- const m = measureItem2(empty, finfo, measurer);
17653
+ const m = measureItem(empty, finfo, measurer);
17796
17654
  if (m !== null) accumulateItem(cur, empty, m);
17797
17655
  }
17798
17656
  cur.just = br?.brAlign;
@@ -17805,7 +17663,7 @@ function buildLineRuns(texts, finfo, measurer) {
17805
17663
  flush(item);
17806
17664
  continue;
17807
17665
  }
17808
- const m = measureItem2(item, finfo, measurer);
17666
+ const m = measureItem(item, finfo, measurer);
17809
17667
  if (m !== null) accumulateItem(cur, item, m);
17810
17668
  }
17811
17669
  if (cur.items.length > 0) flush();
@@ -17896,6 +17754,313 @@ function placeComplexRuns(runs, box, finfo, measurer) {
17896
17754
  return lines;
17897
17755
  }
17898
17756
 
17757
+ // src/common/htmltable-fontinfo.ts
17758
+ var SIZE_SAVEF = { fontsize: 0 };
17759
+ var EMIT_SAVEF = { fontsize: 0 };
17760
+ var pushFontInfo = (env, fp, savp) => {
17761
+ if (fp.fontFace !== void 0) {
17762
+ savp.fontname = env.fontname;
17763
+ env.fontname = fp.fontFace;
17764
+ } else savp.fontname = void 0;
17765
+ if (env.fontcolor !== void 0) {
17766
+ if (fp.fontColor !== void 0) {
17767
+ savp.fontcolor = env.fontcolor;
17768
+ env.fontcolor = fp.fontColor;
17769
+ } else savp.fontcolor = void 0;
17770
+ }
17771
+ if (env.fontsize >= 0) {
17772
+ if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
17773
+ savp.fontsize = env.fontsize;
17774
+ env.fontsize = fp.fontSize;
17775
+ } else savp.fontsize = -1;
17776
+ }
17777
+ };
17778
+ var popFontInfo = (env, savp) => {
17779
+ if (savp.fontname !== void 0) env.fontname = savp.fontname;
17780
+ if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
17781
+ if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
17782
+ };
17783
+ var withTableFont = (env, font, slot, fn) => {
17784
+ if (font === void 0) return fn();
17785
+ const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
17786
+ pushFontInfo(env, font, savp);
17787
+ const r = fn();
17788
+ popFontInfo(env, savp);
17789
+ return r;
17790
+ };
17791
+
17792
+ // src/common/htmltable.ts
17793
+ var DEFAULT_BORDER = 1;
17794
+ var DEFAULT_CELLPADDING = 2;
17795
+ var DEFAULT_CELLSPACING = 2;
17796
+ var DEFAULT_FONTSIZE = 14;
17797
+ var findCol = (ps, row, startCol, colspan, rowspan) => {
17798
+ let col = startCol;
17799
+ let notFound = true;
17800
+ const end = colspan - 1;
17801
+ while (notFound) {
17802
+ const lastc = col + end;
17803
+ let c;
17804
+ for (c = lastc; c >= col; c--) {
17805
+ if (ps.isInPS(c, row)) break;
17806
+ }
17807
+ if (c >= col) col = c + 1;
17808
+ else notFound = false;
17809
+ }
17810
+ for (let j = col; j < col + colspan; j++) {
17811
+ for (let i = row; i < row + rowspan; i++) {
17812
+ ps.addPS(j, i);
17813
+ }
17814
+ }
17815
+ return col;
17816
+ };
17817
+ var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
17818
+ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
17819
+ const lines = buildLineRuns(texts, env, measurer);
17820
+ const simple = runsAreSimple(lines, env);
17821
+ let w = 0;
17822
+ let h = 0;
17823
+ for (const ln of lines) {
17824
+ w = Math.max(w, ln.width);
17825
+ const lsize = simple ? ln.height : ln.fontSize;
17826
+ h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
17827
+ }
17828
+ if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].height : DEFAULT_FONTSIZE;
17829
+ return { w, h };
17830
+ };
17831
+ var missingImages = { set: /* @__PURE__ */ new WeakSet() };
17832
+ var sizeHtmlImg = (img, { imageSizer, stderr }) => {
17833
+ if (img.width !== void 0 && img.height !== void 0) return missingImages.set.has(img) ? 1 : 0;
17834
+ const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
17835
+ if (sz !== null) {
17836
+ img.width = sz.w;
17837
+ img.height = sz.h;
17838
+ return 0;
17839
+ }
17840
+ if (!imageIsSupplied(img.src, imageSizer)) agerrLine(stderr, `Warning: ${imageOpenWarning(img.src)}`);
17841
+ agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
17842
+ img.width = 0;
17843
+ img.height = 0;
17844
+ missingImages.set.add(img);
17845
+ return 1;
17846
+ };
17847
+ var sizeContentItem = (item, measurer, env) => {
17848
+ if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
17849
+ if (item.kind === "table") {
17850
+ const rv = sizeTableInner(item, measurer, env);
17851
+ return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
17852
+ }
17853
+ if (item.kind === "image") {
17854
+ const rv = sizeHtmlImg(item, env);
17855
+ return { w: item.width ?? 0, h: item.height ?? 0, rv };
17856
+ }
17857
+ return { w: 0, h: 0, rv: 0 };
17858
+ };
17859
+ var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
17860
+ var cellBorder = (cell2, tbl) => {
17861
+ if (cell2.border !== void 0) return cell2.border;
17862
+ const cb = tbl.cellborder;
17863
+ if (cb !== void 0 && cb >= 0) return cb;
17864
+ if (tbl.border !== void 0) return tbl.border;
17865
+ return DEFAULT_BORDER;
17866
+ };
17867
+ function inheritTablePenColor(tbl, parentColor) {
17868
+ if (tbl.color === void 0) tbl.color = parentColor;
17869
+ const tblColor = tbl.color;
17870
+ for (const row of tbl.rows) {
17871
+ for (const cell2 of row.cells) {
17872
+ if (cell2.color === void 0) cell2.color = tblColor;
17873
+ for (const item of cell2.content) {
17874
+ if (item.kind === "table") inheritTablePenColor(item, cell2.color);
17875
+ }
17876
+ }
17877
+ }
17878
+ }
17879
+ var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
17880
+ var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
17881
+ var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
17882
+ var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
17883
+ var sizeWarned = { set: /* @__PURE__ */ new WeakSet() };
17884
+ registerRenderState(() => {
17885
+ missingImages.set = /* @__PURE__ */ new WeakSet();
17886
+ sizeWarned.set = /* @__PURE__ */ new WeakSet();
17887
+ });
17888
+ var fixedCellCheck = (cell2, sz, warn, out) => {
17889
+ if (!cell2.fixedsize) return { rv: 0, zero: false };
17890
+ if (cell2.width && cell2.height) {
17891
+ const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
17892
+ if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
17893
+ return { rv: small ? 1 : 0, zero: true };
17894
+ }
17895
+ if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
17896
+ return { rv: 1, zero: false };
17897
+ };
17898
+ var getCellSize = (cell2, tbl, measurer, env) => {
17899
+ const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
17900
+ let cw = 0, ch = 0, rv = 0;
17901
+ for (const item of cell2.content) {
17902
+ const s = sizeContentItem(item, measurer, env);
17903
+ cw = Math.max(cw, s.w);
17904
+ ch += s.h;
17905
+ rv |= s.rv;
17906
+ }
17907
+ let szx = cw + margin;
17908
+ let szy = ch + margin;
17909
+ const warn = !sizeWarned.set.has(cell2);
17910
+ sizeWarned.set.add(cell2);
17911
+ const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
17912
+ rv |= fixed.rv;
17913
+ if (fixed.zero) {
17914
+ szx = 0;
17915
+ szy = 0;
17916
+ }
17917
+ const bw = cell2.width !== void 0 ? cell2.width : 0;
17918
+ const bh = cell2.height !== void 0 ? cell2.height : 0;
17919
+ return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
17920
+ };
17921
+ var buildLayouts = (tbl, measurer, env) => {
17922
+ const entries = [];
17923
+ let rv = 0;
17924
+ const ps = new PointSet();
17925
+ let rowIdx = 0;
17926
+ for (const row of tbl.rows) {
17927
+ let col = 0;
17928
+ for (const c of row.cells) {
17929
+ if (c.kind !== "cell") {
17930
+ continue;
17931
+ }
17932
+ const colspan = c.colspan !== void 0 ? c.colspan : 1;
17933
+ const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
17934
+ const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
17935
+ rv |= cellRv;
17936
+ col = findCol(ps, rowIdx, col, colspan, rowspan);
17937
+ entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
17938
+ col += colspan;
17939
+ }
17940
+ rowIdx++;
17941
+ }
17942
+ return { entries, rv };
17943
+ };
17944
+ var setColWidths = (entries, ncols, spacing) => {
17945
+ const widths = new Array(ncols + 1).fill(0);
17946
+ for (const e of entries)
17947
+ if (e.colspan === 1) widths[e.col] = Math.max(widths[e.col], e.w);
17948
+ for (const e of entries) {
17949
+ if (e.colspan === 1) continue;
17950
+ const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
17951
+ const need = e.w - spanW - (e.colspan - 1) * spacing;
17952
+ if (need > 0) {
17953
+ const add2 = need / e.colspan;
17954
+ for (let j = 0; j < e.colspan; j++) widths[e.col + j] += add2;
17955
+ }
17956
+ }
17957
+ for (const e of entries) {
17958
+ const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
17959
+ e.w = Math.max(e.w, spanW + (e.colspan - 1) * spacing);
17960
+ }
17961
+ return widths;
17962
+ };
17963
+ var setRowHeights = (entries, nrows, spacing) => {
17964
+ const heights = new Array(nrows + 1).fill(0);
17965
+ for (const e of entries)
17966
+ if (e.rowspan === 1) heights[e.row] = Math.max(heights[e.row], e.h);
17967
+ for (const e of entries) {
17968
+ if (e.rowspan === 1) continue;
17969
+ const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
17970
+ const need = e.h - spanH - (e.rowspan - 1) * spacing;
17971
+ if (need > 0) {
17972
+ const add2 = need / e.rowspan;
17973
+ for (let j = 0; j < e.rowspan; j++) heights[e.row + j] += add2;
17974
+ }
17975
+ }
17976
+ for (const e of entries) {
17977
+ const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
17978
+ e.h = Math.max(e.h, spanH + (e.rowspan - 1) * spacing);
17979
+ }
17980
+ return heights;
17981
+ };
17982
+ var getSpacing = (tbl) => tbl.cellspacing !== void 0 ? tbl.cellspacing : DEFAULT_CELLSPACING;
17983
+ var getBorder = (tbl) => tbl.border !== void 0 ? tbl.border : DEFAULT_BORDER;
17984
+ var isTblFixed = (tbl) => tbl.fixedsize === true && tbl.width !== void 0 && tbl.height !== void 0;
17985
+ var sumTableDims = (a) => {
17986
+ let wd = (a.ncols + 1) * a.spacing + 2 * a.border;
17987
+ let ht = (a.nrows + 1) * a.spacing + 2 * a.border;
17988
+ for (let i = 0; i < a.ncols; i++) wd += a.widths[i];
17989
+ for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
17990
+ return { wd, ht };
17991
+ };
17992
+ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
17993
+ const spacing = getSpacing(tbl);
17994
+ const border2 = getBorder(tbl);
17995
+ const { entries, rv } = buildLayouts(tbl, measurer, env);
17996
+ if (entries.length === 0) {
17997
+ return { entries, widths: [], heights: [], spacing, border: border2, rv };
17998
+ }
17999
+ const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
18000
+ const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
18001
+ const widths = setColWidths(entries, ncols, spacing);
18002
+ const heights = setRowHeights(entries, nrows, spacing);
18003
+ return { entries, widths, heights, spacing, border: border2, rv };
18004
+ };
18005
+ var warnFixedTable = (tbl, dims, out) => {
18006
+ const warn = !sizeWarned.set.has(tbl);
18007
+ sizeWarned.set.add(tbl);
18008
+ if (tbl.fixedsize !== true) return 0;
18009
+ if (tbl.width && tbl.height) {
18010
+ if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
18011
+ if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
18012
+ return 1;
18013
+ }
18014
+ if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
18015
+ return 1;
18016
+ };
18017
+ var sizeTableBody = (tbl, measurer, env) => {
18018
+ const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
18019
+ if (entries.length === 0) {
18020
+ const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
18021
+ tbl.dimen = { w: 0, h: 0 };
18022
+ return rv | fixed2;
18023
+ }
18024
+ const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
18025
+ const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
18026
+ for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
18027
+ const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
18028
+ const baseWd = tbl.width !== void 0 ? tbl.width : 0;
18029
+ const baseHt = tbl.height !== void 0 ? tbl.height : 0;
18030
+ const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
18031
+ const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
18032
+ tbl.dimen = {
18033
+ w: Math.max(zeroContent ? 0 : wd, baseWd),
18034
+ h: Math.max(zeroContent ? 0 : ht, baseHt)
18035
+ };
18036
+ return rv | fixed;
18037
+ };
18038
+ var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
18039
+ var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
18040
+ if (label.kind === "table") {
18041
+ const rv = sizeTableInner(label.table, measurer, env);
18042
+ label.dimen = label.table.dimen;
18043
+ return rv;
18044
+ }
18045
+ label.dimen = sizeTextContent(label.texts, measurer, env);
18046
+ return 0;
18047
+ };
18048
+
18049
+ // src/common/splines-constants.ts
18050
+ var REGULAREDGE = 1;
18051
+ var FLATEDGE = 2;
18052
+ var ARR_NONE = 0;
18053
+ var BOTTOM = 1 << 0;
18054
+ var RIGHT = 1 << 1;
18055
+ var TOP = 1 << 2;
18056
+ var LEFT = 1 << 3;
18057
+ var SELF_EDGE_SIZE = 18;
18058
+ var MILLIPOINT = 1e-3;
18059
+ var FUDGE = 2;
18060
+ var INIT_DELTA = 10;
18061
+ var LOOP_TRIES = 15;
18062
+ var ROUTESPL_FUDGE = 1e-4;
18063
+
17899
18064
  // src/common/htmltable-pos.ts
17900
18065
  function alignContentBox(box, cell2, w, h) {
17901
18066
  const out = { ll: { ...box.ll }, ur: { ...box.ur } };
@@ -18291,12 +18456,17 @@ var DEFAULT_FONTNAME = "Times-Roman";
18291
18456
  var DEFAULT_COLOR3 = "black";
18292
18457
  function getPenColor(obj) {
18293
18458
  if (obj === void 0) return void 0;
18294
- const pc = obj.attrs.get("pencolor");
18459
+ const pc = aggetObj(obj, "pencolor");
18295
18460
  if (pc !== void 0 && pc !== "") return pc;
18296
- const c = obj.attrs.get("color");
18461
+ const c = aggetObj(obj, "color");
18297
18462
  if (c !== void 0 && c !== "") return c;
18298
18463
  return void 0;
18299
18464
  }
18465
+ function aggetObj(obj, key) {
18466
+ if (obj instanceof Node) return nodeAttr(obj, obj.root, key);
18467
+ if (obj instanceof Graph) return graphAttrInherited(obj, key);
18468
+ return obj.attrs.get(key);
18469
+ }
18300
18470
  function rootOf(obj) {
18301
18471
  return obj instanceof Edge ? obj.tail.root : obj.root;
18302
18472
  }
@@ -18693,7 +18863,7 @@ function transformUnitVertex(R2, g, c, bb) {
18693
18863
  const r = libmHypot(D.x, D.y);
18694
18864
  return { x: r * Math.cos(alpha) * bb.x, y: r * Math.sin(alpha) * bb.y };
18695
18865
  }
18696
- function polygonVertices(bb, g, isBox3) {
18866
+ function polygonVertices(bb, g, isBox4) {
18697
18867
  const sectorangle = 2 * Math.PI / g.sides;
18698
18868
  const sidelength = Math.sin(sectorangle / 2);
18699
18869
  const c = {
@@ -18711,7 +18881,7 @@ function polygonVertices(bb, g, isBox3) {
18711
18881
  R2.y = fma(sidelength, Math.sin(angle), R2.y);
18712
18882
  const P = transformUnitVertex(R2, g, c, bb);
18713
18883
  verts.push(P);
18714
- if (isBox3) {
18884
+ if (isBox4) {
18715
18885
  verts.push({ x: -P.x, y: P.y }, { x: -P.x, y: -P.y }, { x: P.x, y: -P.y });
18716
18886
  break;
18717
18887
  }
@@ -18802,14 +18972,14 @@ function starVertexGen(bb) {
18802
18972
  }
18803
18973
  return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
18804
18974
  }
18805
- function polygonBB(bb, minSize, p, sides2, isBox3) {
18975
+ function polygonBB(bb, minSize, p, sides2, isBox4) {
18806
18976
  const geom = {
18807
18977
  sides: sides2,
18808
18978
  orientation: p.orientation,
18809
18979
  distortion: p.distortion,
18810
18980
  skew: p.skew
18811
18981
  };
18812
- const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox3);
18982
+ const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox4);
18813
18983
  const xmax2 = 2 * xmax;
18814
18984
  const ymax2 = 2 * ymax;
18815
18985
  const nbb = { x: Math.max(minSize.x, xmax2), y: Math.max(minSize.y, ymax2) };
@@ -18821,7 +18991,7 @@ function polygonBB(bb, minSize, p, sides2, isBox3) {
18821
18991
  v.x *= scalex;
18822
18992
  v.y *= scaley;
18823
18993
  }
18824
- return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
18994
+ return { ...polygonPeripheryBB(verts, isBox4 ? 4 : sides2, p, nbb), base: nbb };
18825
18995
  }
18826
18996
  function gvNodesize(widthPts, heightPts, flip) {
18827
18997
  if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
@@ -18846,9 +19016,9 @@ function applySizeConstraints(p, bb0, width0, height0) {
18846
19016
  function polySize(p) {
18847
19017
  const init = initialSizePts(p);
18848
19018
  const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
18849
- const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
19019
+ const { sides: sides2, isBox: isBox4 } = effectiveShape(p);
18850
19020
  let bb = { x: dimen.x, y: dimen.y };
18851
- if (isBox3) {
19021
+ if (isBox4) {
18852
19022
  } else if (p.optionShape === STAR) {
18853
19023
  bb = starSize(bb);
18854
19024
  } else if (p.optionShape === CYLINDER) {
@@ -18860,16 +19030,16 @@ function polySize(p) {
18860
19030
  const c = applySizeConstraints(p, bb, init.width, init.height);
18861
19031
  const penwidth = p.penwidth ?? 1;
18862
19032
  const hasOutline = penwidth > 0 || p.peripheries < 1;
18863
- const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2, isBox3);
19033
+ const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2, isBox4);
18864
19034
  const result = assembleResult(p, dimen, grown, c.fixedshape);
18865
- return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
19035
+ return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox4, c.fixedshape) };
18866
19036
  }
18867
- function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
19037
+ function labelSpace(p, dimen, bb, minBb, isBox4, fixedshape) {
18868
19038
  const spacex = dimen.x - p.labelDimen.x;
18869
19039
  let spaceX;
18870
19040
  if (p.nojustify) {
18871
19041
  spaceX = dimen.x - spacex;
18872
- } else if (isBox3) {
19042
+ } else if (isBox4) {
18873
19043
  spaceX = Math.max(dimen.x, bb.x) - spacex;
18874
19044
  } else if (dimen.y < bb.y) {
18875
19045
  spaceX = Math.max(dimen.x, bb.x * Math.sqrt(1 - dimen.y * dimen.y / (bb.y * bb.y))) - spacex;
@@ -18882,8 +19052,8 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
18882
19052
  function effectiveShape(p) {
18883
19053
  let sides2 = p.sides;
18884
19054
  if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
18885
- const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
18886
- return { sides: sides2, isBox: isBox3 };
19055
+ const isBox4 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
19056
+ return { sides: sides2, isBox: isBox4 };
18887
19057
  }
18888
19058
  function labelValign(p) {
18889
19059
  const ll = p.labelloc?.[0];
@@ -18977,7 +19147,7 @@ function copyVirtualEdgeInfo(e, orig) {
18977
19147
  e.seq = orig.seq;
18978
19148
  }
18979
19149
  function newVirtualEdge(u, v, orig) {
18980
- const e = new Edge(u, v, "");
19150
+ const e = new Edge(u, v, "", true);
18981
19151
  e.info.edge_type = VIRTUAL;
18982
19152
  if (orig) {
18983
19153
  copyVirtualEdgeInfo(e, orig);
@@ -19078,7 +19248,7 @@ function removeFromRank(g, n) {
19078
19248
  }
19079
19249
  }
19080
19250
  function virtualNode(g) {
19081
- const n = new Node(0, "", g.root);
19251
+ const n = new Node(0, "", g.root, true);
19082
19252
  n.info.node_type = VIRTUAL;
19083
19253
  n.info.lw = 1;
19084
19254
  n.info.rw = 1;
@@ -19370,10 +19540,10 @@ var ARROW_EPSILON = 1e-4;
19370
19540
  var vsub2 = (p, q) => ({ x: p.x - q.x, y: p.y - q.y });
19371
19541
  var vadd2 = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
19372
19542
  var vscale = (c, p) => ({ x: c * p.x, y: c * p.y });
19373
- var negUnit = (u, dist4) => {
19543
+ var negUnit = (u, dist5) => {
19374
19544
  if (u.x === 0 && u.y === 0) return { x: 0, y: 0 };
19375
19545
  const h = Math.hypot(u.x, u.y);
19376
- return { x: dist4 * (-u.x / h), y: dist4 * (-u.y / h) };
19546
+ return { x: dist5 * (-u.x / h), y: dist5 * (-u.y / h) };
19377
19547
  };
19378
19548
  var backwardDelta = (u, penwidth) => negUnit(u, penwidth / 2);
19379
19549
  function axialProjection(phiSrc, from, to, sign2) {
@@ -19922,9 +20092,9 @@ function makeEllipseInsideFn(rx, ry, penwidth = DEFAULT_NODEPENWIDTH) {
19922
20092
  return (lx, ly) => lx * lx / (erx * erx) + ly * ly / (ery * ery) < 1;
19923
20093
  }
19924
20094
  function tailArrowEndClip(path4, tailTip, elen) {
19925
- if (elen <= 0) return path4;
19926
- const inside = (lx, ly) => Math.hypot(lx, ly) <= elen;
19927
- return bezierClipNode(path4, tailTip.x, tailTip.y, inside, true);
20095
+ const sp = [path4[3], path4[2], path4[1], tailTip];
20096
+ const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, tailTip) <= elen, false) : sp;
20097
+ return [clipped[3], clipped[2], clipped[1], clipped[0]];
19928
20098
  }
19929
20099
 
19930
20100
  // src/layout/dot/edge-route-geom.ts
@@ -19983,6 +20153,7 @@ function arrowDrawOpsForEnd(e, end, tip2, dir, penwidth) {
19983
20153
 
19984
20154
  // src/common/splines-clip.ts
19985
20155
  var ARR_NORM = 1;
20156
+ var dist = distFused;
19986
20157
  var SplineClipHelper = class _SplineClipHelper {
19987
20158
  static makeEmptySpl() {
19988
20159
  return { list: [], size: 0, bb: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } } };
@@ -20075,15 +20246,11 @@ var SplineClipHelper = class _SplineClipHelper {
20075
20246
  if (j) return [eflag, sflag];
20076
20247
  return [sflag, eflag];
20077
20248
  }
20078
- /** DIST(p, q). */
20079
- static dist(p, q) {
20080
- return Math.hypot(p.x - q.x, p.y - q.y);
20081
- }
20082
20249
  /** Sphere inside-fn around `tip` with radius `r` for bezierClip. */
20083
20250
  static sphereCtx(tip2, r) {
20084
20251
  return {
20085
20252
  ctx: { nodeCoord: { x: 0, y: 0 }, rw: 0, bp: null },
20086
- fn: (_c, p) => _SplineClipHelper.dist(p, tip2) <= r
20253
+ fn: (_c, p) => dist(p, tip2) <= r
20087
20254
  };
20088
20255
  }
20089
20256
  /**
@@ -20115,7 +20282,7 @@ var SplineClipHelper = class _SplineClipHelper {
20115
20282
  );
20116
20283
  spl.eflag = eflag;
20117
20284
  spl.ep = ps[endp + 3];
20118
- if (endp > startp && _SplineClipHelper.dist(ps[endp], ps[endp + 3]) < elen) {
20285
+ if (endp > startp && dist(ps[endp], ps[endp + 3]) < elen) {
20119
20286
  endp -= 3;
20120
20287
  }
20121
20288
  const sp = [spl.ep, ps[endp + 2], ps[endp + 1], ps[endp]];
@@ -20142,7 +20309,7 @@ var SplineClipHelper = class _SplineClipHelper {
20142
20309
  );
20143
20310
  spl.sflag = sflag;
20144
20311
  spl.sp = ps[startp];
20145
- if (endp > startp && _SplineClipHelper.dist(ps[startp], ps[startp + 3]) < slen) {
20312
+ if (endp > startp && dist(ps[startp], ps[startp + 3]) < slen) {
20146
20313
  startp += 3;
20147
20314
  }
20148
20315
  const sp = [ps[startp + 3], ps[startp + 2], ps[startp + 1], spl.sp];
@@ -20243,7 +20410,7 @@ var SplineClipHelper = class _SplineClipHelper {
20243
20410
  if (sflag && eflag && endp === startp) {
20244
20411
  const p = ps[endp];
20245
20412
  const q = ps[endp + 3];
20246
- const d = _SplineClipHelper.dist(p, q);
20413
+ const d = dist(p, q);
20247
20414
  let hlen = hlen0;
20248
20415
  let tlen = tlen0;
20249
20416
  if (hlen + tlen >= d) {
@@ -20286,7 +20453,7 @@ var SplineClipHelper = class _SplineClipHelper {
20286
20453
  let hlen = hlen0;
20287
20454
  const p = ps[endp];
20288
20455
  const q = ps[endp + 3];
20289
- const maxd = 0.9 * _SplineClipHelper.dist(p, q);
20456
+ const maxd = 0.9 * dist(p, q);
20290
20457
  if (hlen >= maxd) hlen = maxd;
20291
20458
  const r = { x: p.x, y: p.y };
20292
20459
  if (p.y === q.y) {
@@ -20306,7 +20473,7 @@ var SplineClipHelper = class _SplineClipHelper {
20306
20473
  let tlen = tlen0;
20307
20474
  const p = ps[startp];
20308
20475
  const q = ps[startp + 3];
20309
- const maxd = 0.9 * _SplineClipHelper.dist(p, q);
20476
+ const maxd = 0.9 * dist(p, q);
20310
20477
  if (tlen >= maxd) tlen = maxd;
20311
20478
  const r = { x: p.x, y: p.y };
20312
20479
  if (p.y === q.y) {
@@ -21017,9 +21184,6 @@ function readLabelPos(sg) {
21017
21184
  }
21018
21185
  return pos;
21019
21186
  }
21020
- function graphAttrInherited(sg, key) {
21021
- return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
21022
- }
21023
21187
  function readFontParams(sg) {
21024
21188
  return {
21025
21189
  fontsize: parseFloat(graphAttrInherited(sg, "fontsize") ?? "") || DEFAULT_FONTSIZE2,
@@ -22538,13 +22702,13 @@ function dfsNode(Xg, v, frames) {
22538
22702
  frames.push({ v, edges: v.outEdges(Xg).slice(), i: 0 });
22539
22703
  }
22540
22704
  function dfsStep2(Xg, frames) {
22541
- const fr3 = frames[frames.length - 1];
22542
- if (fr3.i < fr3.edges.length) {
22543
- const e = fr3.edges[fr3.i++];
22705
+ const fr7 = frames[frames.length - 1];
22706
+ if (fr7.i < fr7.edges.length) {
22707
+ const e = fr7.edges[fr7.i++];
22544
22708
  if (e.head.info.onstack) reverseEdge2(Xg, e);
22545
22709
  else if (!e.head.info.mark) dfsNode(Xg, e.head, frames);
22546
22710
  } else {
22547
- fr3.v.info.onstack = 0;
22711
+ fr7.v.info.onstack = 0;
22548
22712
  frames.pop();
22549
22713
  }
22550
22714
  }
@@ -23718,7 +23882,7 @@ function pruneForeignClusterNodes(par, clust) {
23718
23882
  }
23719
23883
  function markClusterNode(clust, n, g) {
23720
23884
  if ((n.info.ranktype ?? 0) !== 0) {
23721
- agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`, "error");
23885
+ agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`);
23722
23886
  agDeleteFromCluster(clust, n);
23723
23887
  return;
23724
23888
  }
@@ -24943,12 +25107,6 @@ function drawRecordBox(job, n, ll, ur, filled) {
24943
25107
  var DEFAULT_LW = 27;
24944
25108
  var DEFAULT_RW = 27;
24945
25109
  var DEFAULT_HT = 36;
24946
- function nodeAttr(n, g, key) {
24947
- const own = n.attrs.get(key);
24948
- if (own !== void 0) return own;
24949
- if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
24950
- return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
24951
- }
24952
25110
  function readFontAttrs(n, g) {
24953
25111
  return {
24954
25112
  fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
@@ -24973,17 +25131,27 @@ function buildNodeLabel(n, g, measurer) {
24973
25131
  const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
24974
25132
  n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
24975
25133
  }
25134
+ function warnMissingImage(n, g, shapefile) {
25135
+ if (shapefile !== void 0 && shapefile !== "" && nodeAttr(n, g, "shape") !== "epsf") return;
25136
+ const image = nodeAttr(n, g, "image");
25137
+ if (image === void 0 || image === "") return;
25138
+ const gvc = g.root.info.gvc;
25139
+ if (imageIsSupplied(image, gvc?.imageSizer, gvc?.imageResolver)) return;
25140
+ agwarningf(imageOpenWarning(image));
25141
+ agwarningf(`No or improper image="${image}" for node "${n.name}"`);
25142
+ }
24976
25143
  function polyInit(n, g, measurer) {
24977
25144
  const shapeName2 = nodeAttr(n, g, "shape") ?? "ellipse";
24978
25145
  const shapefile = nodeAttr(n, g, "shapefile");
24979
25146
  n.info.shape = bindShape(shapeName2, shapefile);
24980
25147
  if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
24981
- agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`, "error");
25148
+ agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`);
24982
25149
  }
24983
25150
  if (n.info.shape.kind === 2 /* SH_RECORD */) {
24984
25151
  if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
24985
25152
  return;
24986
25153
  }
25154
+ warnMissingImage(n, g, shapefile);
24987
25155
  buildNodeLabel(n, g, measurer);
24988
25156
  if (n.info.shape_info !== void 0) return;
24989
25157
  const polyDesc = n.info.shape.polygon;
@@ -25109,8 +25277,8 @@ function drawWedge(seg2, e, ctx) {
25109
25277
  ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
25110
25278
  return angle1;
25111
25279
  }
25112
- function wedgedEllipse(job, pf, clrs, renderer) {
25113
- const { segs, error } = parseSegs(clrs);
25280
+ function wedgedEllipse(job, pf, clrs, renderer, context) {
25281
+ const { segs, error } = parseSegs(clrs, context);
25114
25282
  if (error === 1 || error === 2) return error;
25115
25283
  const ctrX = (pf[0].x + pf[1].x) / 2;
25116
25284
  const ctrY = (pf[0].y + pf[1].y) / 2;
@@ -25142,8 +25310,8 @@ function drawBand(p, seg2, ctx) {
25142
25310
  ctx.renderer.polygon([...p], true, ctx.job);
25143
25311
  p[0].x = p[3].x = p[1].x;
25144
25312
  }
25145
- function stripedBox(job, pts, clrs, rotate, renderer) {
25146
- const { segs, error } = parseSegs(clrs);
25313
+ function stripedBox(job, pts, clrs, rotate, renderer, context) {
25314
+ const { segs, error } = parseSegs(clrs, context);
25147
25315
  if (error === 1 || error === 2) return error;
25148
25316
  const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
25149
25317
  const lastx = p[1].x;
@@ -25301,6 +25469,27 @@ function escapeXmlText(s) {
25301
25469
  return gvXmlEscape(s, FLAGS_TEXT);
25302
25470
  }
25303
25471
 
25472
+ // src/gvc/device-transform.ts
25473
+ function transformPoint(p, job) {
25474
+ if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
25475
+ return p;
25476
+ }
25477
+ const sx = job.zoom * job.devscale.x;
25478
+ const sy = job.zoom * job.devscale.y;
25479
+ const tx = job.translation.x;
25480
+ const ty = job.translation.y;
25481
+ return applyScale(p, tx, ty, sx, sy);
25482
+ }
25483
+ function applyScale(p, tx, ty, sx, sy) {
25484
+ const x = (p.x + tx) * sx;
25485
+ const y = (p.y + ty) * sy;
25486
+ return buildPoint(x, y);
25487
+ }
25488
+ function buildPoint(x, y) {
25489
+ const pt = { x, y };
25490
+ return pt;
25491
+ }
25492
+
25304
25493
  // src/gvc/device-cluster.ts
25305
25494
  function applyClusterGradient(obj, fill) {
25306
25495
  obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
@@ -25348,6 +25537,7 @@ function applyClusterObjState(sg, job) {
25348
25537
  const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
25349
25538
  if (job.obj === null) return false;
25350
25539
  const obj = job.obj;
25540
+ gvrenderSetStyle(checkClusterStyleTokens(styleTokens(clusterStyle(sg))));
25351
25541
  return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
25352
25542
  const filled = applyClusterFill(obj, fillRes);
25353
25543
  applyClusterPenState(obj, sg);
@@ -25355,17 +25545,47 @@ function applyClusterObjState(sg, job) {
25355
25545
  return filled;
25356
25546
  });
25357
25547
  }
25358
- function stripedClusterColors(sg) {
25548
+ function isStripedCluster(sg) {
25549
+ const flags = parseStyleFlags(clusterStyle(sg));
25550
+ return flags.striped && !flags.rounded;
25551
+ }
25552
+ function stripedFillSpec(sg) {
25359
25553
  const flags = parseStyleFlags(clusterStyle(sg));
25360
- if (!flags.striped || flags.rounded) return [];
25361
25554
  const color = clusterAttr(sg, "color") ?? "";
25362
25555
  let fill = clusterAttr(sg, "fillcolor") || color;
25363
25556
  const bg = clusterAttr(sg, "bgcolor") ?? "";
25364
25557
  if ((!flags.filled || fill === "") && bg !== "") fill = bg;
25365
- const { segs, error } = parseSegs(fill === "" ? "lightgrey" : fill);
25558
+ return fill === "" ? "lightgrey" : fill;
25559
+ }
25560
+ function stripedClusterColors(sg) {
25561
+ if (!isStripedCluster(sg)) return [];
25562
+ const { segs, error } = parseSegs(stripedFillSpec(sg), () => `in cluster ${sg.name}`);
25366
25563
  if (error === 1 || error === 2) return [];
25367
25564
  return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
25368
25565
  }
25566
+ function renderStripedClusterBox(sg, renderer, job) {
25567
+ withColorScheme(clusterAttr(sg, "colorscheme"), () => {
25568
+ const { ll, ur } = sg.info.bb;
25569
+ const af = [
25570
+ { x: ll.x, y: ll.y },
25571
+ { x: ur.x, y: ll.y },
25572
+ { x: ur.x, y: ur.y },
25573
+ { x: ll.x, y: ur.y }
25574
+ ].map((p) => transformPoint(p, job));
25575
+ const obj = job.obj;
25576
+ const savedFill = obj?.fill;
25577
+ if (obj !== null && savedFill !== void 0) obj.fill = 1 /* Solid */;
25578
+ stripedBox(job, af, stripedFillSpec(sg), false, renderer, () => `in cluster ${sg.name}`);
25579
+ if (obj !== null && savedFill !== void 0) obj.fill = savedFill;
25580
+ const rawPts = [
25581
+ { x: ll.x, y: ll.y },
25582
+ { x: ll.x, y: ur.y },
25583
+ { x: ur.x, y: ur.y },
25584
+ { x: ur.x, y: ll.y }
25585
+ ];
25586
+ renderer.polygon(rawPts.map((p) => transformPoint(p, job)), false, job);
25587
+ });
25588
+ }
25369
25589
  function applyClusterFill(obj, fillRes) {
25370
25590
  if (fillRes.kind === "none") {
25371
25591
  obj.fill = 0 /* None */;
@@ -25431,7 +25651,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
25431
25651
  const pf = ring.map(
25432
25652
  (v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
25433
25653
  );
25434
- wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
25654
+ wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer, () => `in node ${ctx.nodeName}`);
25435
25655
  renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
25436
25656
  } else {
25437
25657
  renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
@@ -25440,7 +25660,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
25440
25660
  }
25441
25661
  function renderStripedRing(ring, coord, ctx) {
25442
25662
  const af = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job));
25443
- stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer);
25663
+ stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer, () => `in node ${ctx.nodeName}`);
25444
25664
  renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
25445
25665
  }
25446
25666
  function renderPolyRing(ring, coord, filled, j, ctx) {
@@ -25566,6 +25786,10 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
25566
25786
  function applyNodeStyle(obj, n, job) {
25567
25787
  const styleAttr = nodeAttr(n, n.root, "style");
25568
25788
  const colorAttr = nodeAttr(n, n.root, "color");
25789
+ if (!isPointNode(n)) {
25790
+ const shape = n.info.shape;
25791
+ gvrenderSetStyle(checkStyleTokens(styleTokens(styleAttr), shape?.polygon ?? null));
25792
+ }
25569
25793
  const penwidth = nodeAttr(n, n.root, "penwidth");
25570
25794
  if (n.info.shape?.kind === 2 /* SH_RECORD */) {
25571
25795
  applyPenState(obj, styleAttr, colorAttr, penwidth);
@@ -25577,7 +25801,7 @@ function applyNodeStyle(obj, n, job) {
25577
25801
  }
25578
25802
  function prepareDrawPoly(poly, filled, obj) {
25579
25803
  if (poly.peripheries !== 0 || !filled) return poly;
25580
- obj.penColor = { type: "string", s: "transparent" };
25804
+ obj.penColor = resolveRenderColor("transparent");
25581
25805
  return { ...poly, peripheries: 1 };
25582
25806
  }
25583
25807
  function vertexScale(n, poly) {
@@ -25607,6 +25831,7 @@ function resolveNodeDrawCtx(job, n) {
25607
25831
  job,
25608
25832
  style: styleFlags,
25609
25833
  fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
25834
+ nodeName: n.name,
25610
25835
  ...specialCornerFlags(drawPoly.option, styleFlags)
25611
25836
  };
25612
25837
  return { poly: drawPoly, coord, filled, ringCtx };
@@ -25915,7 +26140,7 @@ function findCharset(g) {
25915
26140
  }
25916
26141
  if (p === "big-5" || p === "big5") return CHAR_BIG5;
25917
26142
  if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
25918
- agwarningf(`Unsupported charset "${raw}" - assuming utf-8`, "error");
26143
+ agwarningf(`Unsupported charset "${raw}" - assuming utf-8`);
25919
26144
  return CHAR_UTF8;
25920
26145
  }
25921
26146
  function maptoken(p, names, vals) {
@@ -26133,7 +26358,7 @@ function portToTbl(tbl, id) {
26133
26358
  }
26134
26359
 
26135
26360
  // src/common/compass-port.ts
26136
- function isBox(n) {
26361
+ function isBox2(n) {
26137
26362
  return n.info.shape?.polygon === P_BOX;
26138
26363
  }
26139
26364
  function gdRankdir(n) {
@@ -26324,7 +26549,7 @@ function compassPort(n, args, pp) {
26324
26549
  const { bp, compass, sides: sides2 } = args;
26325
26550
  const { b, p, defined: defBp } = compassBbox(n, bp);
26326
26551
  const dir = compassDirection(compass, b, p, sides2);
26327
- if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
26552
+ if (bp === null && !isBox2(n)) applyIctxt(n, dir, b, p);
26328
26553
  const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
26329
26554
  applyDir(pp, bp, dir, gdRankdir(n), defFinal);
26330
26555
  return dir.rv;
@@ -27606,7 +27831,7 @@ function emitParallelEdgePaths(e, job, colorList) {
27606
27831
  const spl = e.info.spl;
27607
27832
  const numc = (colorList.match(/:/g) ?? []).length;
27608
27833
  const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
27609
- const colors = parseSegs(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR4);
27834
+ const colors = parseSegsSilent(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR4);
27610
27835
  emitColorPasses(segData, colors, job);
27611
27836
  return {
27612
27837
  headColor: colors[0] ?? DEFAULT_COLOR4,
@@ -28438,25 +28663,14 @@ function walkNodesAndEdges(g, renderer, job, info) {
28438
28663
  }
28439
28664
  }
28440
28665
 
28441
- // src/gvc/device-transform.ts
28442
- function transformPoint(p, job) {
28443
- if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
28444
- return p;
28445
- }
28446
- const sx = job.zoom * job.devscale.x;
28447
- const sy = job.zoom * job.devscale.y;
28448
- const tx = job.translation.x;
28449
- const ty = job.translation.y;
28450
- return applyScale(p, tx, ty, sx, sy);
28451
- }
28452
- function applyScale(p, tx, ty, sx, sy) {
28453
- const x = (p.x + tx) * sx;
28454
- const y = (p.y + ty) * sy;
28455
- return buildPoint(x, y);
28456
- }
28457
- function buildPoint(x, y) {
28458
- const pt = { x, y };
28459
- return pt;
28666
+ // src/gvc/first-layer.ts
28667
+ var NATIVE_LANGNAME = /* @__PURE__ */ new Map([
28668
+ ["cmapx-np", "cmapx_np"],
28669
+ ["imap-np", "imap_np"]
28670
+ ]);
28671
+ function warnLayersUnsupported(format, numLayers, doesLayers) {
28672
+ if (numLayers <= 1 || doesLayers) return;
28673
+ agwarningf(`layers not supported in ${NATIVE_LANGNAME.get(format) ?? format} output`);
28460
28674
  }
28461
28675
 
28462
28676
  // src/gvc/device-labels.ts
@@ -28601,6 +28815,7 @@ function setEdgePen(e, job) {
28601
28815
  obj.pen = resolvePenType(flags);
28602
28816
  obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
28603
28817
  obj.rawStyle = styleTokens(e.attrs.get("style"));
28818
+ if (e.info.spl !== void 0) gvrenderSetStyle(obj.rawStyle);
28604
28819
  }
28605
28820
  function renderEdge(e, renderer, job) {
28606
28821
  emitEdgeComments(e, renderer, job);
@@ -28616,6 +28831,8 @@ function renderEdge(e, renderer, job) {
28616
28831
  withColorScheme(e.attrs.get("colorscheme"), () => {
28617
28832
  renderer.beginEdge(e, job);
28618
28833
  reportEdgeColors(e);
28834
+ const styles = styleTokens(e.attrs.get("style"));
28835
+ for (let i = edgeStyleResets(e, styles); i > 0; i--) gvrenderSetStyle(styles);
28619
28836
  reportEdgeLabelColors(e);
28620
28837
  renderer.endEdge(e, job);
28621
28838
  });
@@ -28629,6 +28846,10 @@ function renderGraphLabel(g, renderer, job) {
28629
28846
  }
28630
28847
  function renderClusterBox(sg, filled, renderer, job) {
28631
28848
  const { ll, ur } = sg.info.bb;
28849
+ if (isStripedCluster(sg)) {
28850
+ renderStripedClusterBox(sg, renderer, job);
28851
+ return;
28852
+ }
28632
28853
  if (parseStyleFlags(clusterStyle(sg)).rounded) {
28633
28854
  const af = [{ x: ll.x, y: ll.y }, { x: ur.x, y: ll.y }, { x: ur.x, y: ur.y }, { x: ll.x, y: ur.y }];
28634
28855
  emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer, job });
@@ -28652,7 +28873,7 @@ function renderOneCluster(sg, renderer, job) {
28652
28873
  resolveObjAnchor(sg, labelTextOf2(sg.info.label), svgClusterId(sg, job), job.obj);
28653
28874
  }
28654
28875
  const anchored = beginAnchorIf(renderer, job);
28655
- if ((clusterPeripheries(sg) !== 0 || filled) && job.obj?.pen !== 0 /* None */) {
28876
+ if ((clusterPeripheries(sg) !== 0 || filled || isStripedCluster(sg)) && job.obj?.pen !== 0 /* None */) {
28656
28877
  renderClusterBox(sg, filled, renderer, job);
28657
28878
  }
28658
28879
  renderClusterLabel(sg, renderer, job);
@@ -28682,6 +28903,7 @@ function renderGraph(g, job, renderer) {
28682
28903
  job.numLayers = layered ? info.numLayers : 1;
28683
28904
  job.layerIDs = info.layerIDs;
28684
28905
  renderer.beginGraph(g, job);
28906
+ warnLayersUnsupported(job.format, info.numLayers, renderer.beginLayer !== void 0);
28685
28907
  for (let ln = 1; ln <= job.numLayers; ln++) {
28686
28908
  job.layerNum = ln;
28687
28909
  if (layered) renderer.beginLayer(info.layerIDs[ln], job);
@@ -30021,7 +30243,7 @@ function fillRankVlist(g, r, root) {
30021
30243
  rankArr[r].v = rootRank.v;
30022
30244
  rankArr[r].vStart = lead.info.order ?? 0;
30023
30245
  const maxi = computeMaxi(g, r);
30024
- if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`, "error");
30246
+ if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`);
30025
30247
  rankArr[r].n = maxi + 1;
30026
30248
  return 0;
30027
30249
  }
@@ -32840,7 +33062,7 @@ function routeSplinesInternal(pp, polyline) {
32840
33062
  ];
32841
33063
  const pl = shortestPath(poly, eps);
32842
33064
  if (pl === null) {
32843
- agerrLineOn("warn", "in routesplines, Pshortestpath failed");
33065
+ agerrorf("in routesplines, Pshortestpath failed");
32844
33066
  return null;
32845
33067
  }
32846
33068
  emitDump("S3_POLY", dumpNames, () => ({
@@ -34846,9 +35068,9 @@ function writePortlabelPos(l, pe, pf, angleStr, distanceStr) {
34846
35068
  const angleDeg = lateDouble(angleStr, PORT_LABEL_ANGLE, -180);
34847
35069
  const angle = Math.atan2(pf.y - pe.y, pf.x - pe.x) + RADIANS(angleDeg);
34848
35070
  const distMult = lateDouble(distanceStr || void 0, 1, 0);
34849
- const dist4 = PORT_LABEL_DISTANCE * distMult;
34850
- l.pos.x = pe.x + dist4 * Math.cos(angle);
34851
- l.pos.y = pe.y + dist4 * Math.sin(angle);
35071
+ const dist5 = PORT_LABEL_DISTANCE * distMult;
35072
+ l.pos.x = pe.x + dist5 * Math.cos(angle);
35073
+ l.pos.y = pe.y + dist5 * Math.sin(angle);
34852
35074
  l.set = true;
34853
35075
  }
34854
35076
  function updateBB(g, l) {
@@ -35250,7 +35472,7 @@ function translateDrawing(g) {
35250
35472
  if (e.tail !== v) continue;
35251
35473
  if (e.info.spl === void 0) {
35252
35474
  if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
35253
- agerrLineOn("warn", `lost ${e.tail.name} ${e.head.name} edge`);
35475
+ agerrorf(`lost ${e.tail.name} ${e.head.name} edge`);
35254
35476
  }
35255
35477
  continue;
35256
35478
  }
@@ -36013,9 +36235,14 @@ function nodeInsideFn2(box) {
36013
36235
  function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
36014
36236
  const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
36015
36237
  const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
36016
- const arrowTip = step2[3];
36238
+ const startp = 0;
36239
+ let endp = 0;
36240
+ const arrowTip = step2[endp + 3];
36017
36241
  const elen = normalArrowLen(penwidth);
36018
- const clipped = arrowEndClip(step2, arrowTip, elen);
36242
+ if (endp > startp && distFused(step2[endp], step2[endp + 3]) < elen) {
36243
+ endp -= 3;
36244
+ }
36245
+ const clipped = arrowEndClip(step2.slice(endp, endp + 4), arrowTip, elen);
36019
36246
  const arrowDir = normalizeVec({
36020
36247
  x: clipped[3].x - arrowTip.x,
36021
36248
  y: clipped[3].y - arrowTip.y
@@ -38554,8 +38781,7 @@ function ensureDummyNodes(sg, gstart) {
38554
38781
  }
38555
38782
  function orthoEdges(g, useLbls, clipAndInstall2) {
38556
38783
  if (useLbls) {
38557
- agerrLineOn(
38558
- "warn",
38784
+ agwarningf(
38559
38785
  "Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
38560
38786
  );
38561
38787
  useLbls = false;
@@ -38690,7 +38916,7 @@ function dispatchOrthoEdges(g, useLbls) {
38690
38916
  }
38691
38917
 
38692
38918
  // src/common/arrows-geometry.ts
38693
- function dist(a, b) {
38919
+ function dist3(a, b) {
38694
38920
  return Math.hypot(a.x - b.x, a.y - b.y);
38695
38921
  }
38696
38922
 
@@ -38794,7 +39020,7 @@ function getCycleCentroid(g, edge) {
38794
39020
  }
38795
39021
  function bend(spl, centroid) {
38796
39022
  const midpt = midPointf(spl[0], spl[3]);
38797
- const distVal = dist(spl[3], spl[0]);
39023
+ const distVal = dist3(spl[3], spl[0]);
38798
39024
  const r = distVal / 5;
38799
39025
  const vX = centroid.x - midpt.x;
38800
39026
  const vY = centroid.y - midpt.y;
@@ -39407,7 +39633,7 @@ function arrowEndClipIdx(state3, endp) {
39407
39633
  const elen = arrowClipLength(edgeArrowName(e, "head"), edgeArrowsize(e), edgePenwidthAttr(e));
39408
39634
  bez.eflag = bez.eflag || 1;
39409
39635
  bez.ep = { ...bez.list[endp + 3] };
39410
- if (endp > state3.starti && dist(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
39636
+ if (endp > state3.starti && distFused(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
39411
39637
  const seg2 = [bez.list[endp], bez.list[endp + 1], bez.list[endp + 2], bez.list[endp + 3]];
39412
39638
  const clipped = arrowEndClip(seg2, bez.ep, elen);
39413
39639
  for (let k = 0; k < 4; k++) bez.list[endp + k] = clipped[k];
@@ -39418,7 +39644,7 @@ function arrowStartClipIdx(state3, startp, endp) {
39418
39644
  const slen = arrowClipLength(edgeArrowName(e, "tail"), edgeArrowsize(e), edgePenwidthAttr(e));
39419
39645
  bez.sflag = bez.sflag || 1;
39420
39646
  bez.sp = { ...bez.list[startp] };
39421
- if (endp > startp && dist(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
39647
+ if (endp > startp && distFused(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
39422
39648
  const seg2 = [bez.list[startp], bez.list[startp + 1], bez.list[startp + 2], bez.list[startp + 3]];
39423
39649
  const clipped = tailArrowEndClip(seg2, bez.sp, slen);
39424
39650
  for (let k = 0; k < 4; k++) bez.list[startp + k] = clipped[k];
@@ -40687,120 +40913,522 @@ var DOT_LAYOUT_ENGINE = {
40687
40913
  };
40688
40914
 
40689
40915
  // src/layout/neato/dijkstra.ts
40690
- function heapPush(heap, dist4, idx) {
40691
- let pos = heap.length;
40692
- heap.push(idx);
40693
- while (pos > 0) {
40694
- const parent2 = pos - 1 >> 1;
40695
- if (dist4[heap[parent2]] <= dist4[heap[pos]]) break;
40696
- const tmp = heap[parent2];
40697
- heap[parent2] = heap[pos];
40698
- heap[pos] = tmp;
40699
- pos = parent2;
40700
- }
40701
- }
40702
- function heapSiftDown2(heap, dist4) {
40703
- let pos = 0;
40916
+ var FLT_MAX = 34028234663852886e22;
40917
+ function greaterPriorityF(h, i, j, dist5) {
40918
+ return dist5[h.data[i]] < dist5[h.data[j]];
40919
+ }
40920
+ function heapifyF(h, start, dist5) {
40921
+ let i = start;
40704
40922
  for (; ; ) {
40705
- const l = 2 * pos + 1;
40706
- const r = 2 * pos + 2;
40707
- let smallest = pos;
40708
- if (l < heap.length && dist4[heap[l]] < dist4[heap[smallest]]) smallest = l;
40709
- if (r < heap.length && dist4[heap[r]] < dist4[heap[smallest]]) smallest = r;
40710
- if (smallest === pos) break;
40711
- const tmp = heap[smallest];
40712
- heap[smallest] = heap[pos];
40713
- heap[pos] = tmp;
40714
- pos = smallest;
40715
- }
40716
- }
40717
- function heapPop(heap, dist4) {
40718
- const top = heap[0];
40719
- const last = heap.pop();
40720
- if (heap.length === 0) return top;
40721
- heap[0] = last;
40722
- heapSiftDown2(heap, dist4);
40723
- return top;
40724
- }
40725
- function heapBuildExcluding(src, n, dist4) {
40726
- const heap = [];
40923
+ const l = ngLeft(i);
40924
+ const r = ngRight(i);
40925
+ let largest = ngInsideHeap(h, l) && greaterPriorityF(h, l, i, dist5) ? l : i;
40926
+ if (ngInsideHeap(h, r) && greaterPriorityF(h, r, largest, dist5)) largest = r;
40927
+ if (largest === i) break;
40928
+ ngExchange(h, largest, i);
40929
+ i = largest;
40930
+ }
40931
+ }
40932
+ function initHeapF(startVertex, dist5, n) {
40933
+ const h = {
40934
+ data: new Array(Math.max(n - 1, 0)).fill(0),
40935
+ heapSize: n - 1,
40936
+ index: new Int32Array(n)
40937
+ };
40938
+ let count = 0;
40727
40939
  for (let i = 0; i < n; i++) {
40728
- if (i !== src) heapPush(heap, dist4, i);
40940
+ if (i !== startVertex) {
40941
+ h.data[count] = i;
40942
+ h.index[i] = count;
40943
+ count++;
40944
+ }
40729
40945
  }
40730
- return heap;
40946
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapifyF(h, j, dist5);
40947
+ return h;
40948
+ }
40949
+ function extractMaxF(h, dist5) {
40950
+ if (h.heapSize === 0) return -1;
40951
+ const max = h.data[0];
40952
+ h.data[0] = h.data[h.heapSize - 1];
40953
+ h.index[h.data[0]] = 0;
40954
+ h.heapSize--;
40955
+ heapifyF(h, 0, dist5);
40956
+ return max;
40957
+ }
40958
+ function increaseKeyF(h, increasedVertex, newDist, dist5) {
40959
+ if (dist5[increasedVertex] <= newDist) return;
40960
+ let i = h.index[increasedVertex];
40961
+ dist5[increasedVertex] = newDist;
40962
+ while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
40963
+ ngAssign(h, i, ngParent(i));
40964
+ i = ngParent(i);
40965
+ }
40966
+ h.data[i] = increasedVertex;
40967
+ h.index[increasedVertex] = i;
40968
+ }
40969
+ function dijkstra(vertex, graph, n, dist5) {
40970
+ for (let i = 0; i < n; i++) dist5[i] = FLT_MAX;
40971
+ dist5[vertex] = 0;
40972
+ const vd = graph[vertex];
40973
+ for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = vd.ewgts[i];
40974
+ const h = initHeapF(vertex, dist5, n);
40975
+ for (let closest = extractMaxF(h, dist5); closest >= 0; closest = extractMaxF(h, dist5)) {
40976
+ const closestDist = dist5[closest];
40977
+ if (closestDist === FLT_MAX) break;
40978
+ const cd = graph[closest];
40979
+ for (let i = 1; i < cd.nedges; i++) {
40980
+ increaseKeyF(h, cd.edges[i], Math.fround(closestDist + Math.fround(cd.ewgts[i])), dist5);
40981
+ }
40982
+ }
40983
+ }
40984
+ var MAX_DIST = 2147483647;
40985
+ function ngLeft(i) {
40986
+ return 2 * i;
40987
+ }
40988
+ function ngRight(i) {
40989
+ return 2 * i + 1;
40990
+ }
40991
+ function ngParent(i) {
40992
+ return Math.trunc(i / 2);
40993
+ }
40994
+ function ngInsideHeap(h, i) {
40995
+ return i < h.heapSize;
40996
+ }
40997
+ function ngGreaterPriority(h, i, j, dist5) {
40998
+ return dist5[h.data[i]] < dist5[h.data[j]];
40999
+ }
41000
+ function ngAssign(h, i, j) {
41001
+ h.data[i] = h.data[j];
41002
+ h.index[h.data[i]] = i;
40731
41003
  }
40732
- function dijkstraInitDist(src, graph, n, dist4) {
40733
- for (let i = 0; i < n; i++) dist4[i] = Infinity;
40734
- dist4[src] = 0;
40735
- const v = graph[src];
40736
- for (let i = 1; i < v.nedges; i++) dist4[v.edges[i]] = v.ewgts[i];
41004
+ function ngExchange(h, i, j) {
41005
+ const t = h.data[i];
41006
+ h.data[i] = h.data[j];
41007
+ h.data[j] = t;
41008
+ h.index[h.data[i]] = i;
41009
+ h.index[h.data[j]] = j;
40737
41010
  }
40738
- function dijkstraRelax(closest, closestDist, graph, dist4, heap) {
40739
- const cv = graph[closest];
40740
- for (let i = 1; i < cv.nedges; i++) {
40741
- const nb = cv.edges[i];
40742
- const nd = closestDist + cv.ewgts[i];
40743
- if (nd < dist4[nb]) {
40744
- dist4[nb] = nd;
40745
- heapPush(heap, dist4, nb);
41011
+ function ngHeapify(h, start, dist5) {
41012
+ let i = start;
41013
+ for (; ; ) {
41014
+ const l = ngLeft(i);
41015
+ const r = ngRight(i);
41016
+ let largest = ngInsideHeap(h, l) && ngGreaterPriority(h, l, i, dist5) ? l : i;
41017
+ if (ngInsideHeap(h, r) && ngGreaterPriority(h, r, largest, dist5)) largest = r;
41018
+ if (largest === i) break;
41019
+ ngExchange(h, largest, i);
41020
+ i = largest;
41021
+ }
41022
+ }
41023
+ function ngInitHeap(startVertex, dist5, n) {
41024
+ const h = {
41025
+ data: new Array(Math.max(n - 1, 0)).fill(0),
41026
+ heapSize: n - 1,
41027
+ index: new Int32Array(n)
41028
+ };
41029
+ let count = 0;
41030
+ for (let i = 0; i < n; i++) {
41031
+ if (i !== startVertex) {
41032
+ h.data[count] = i;
41033
+ h.index[i] = count;
41034
+ count++;
40746
41035
  }
40747
41036
  }
41037
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) ngHeapify(h, j, dist5);
41038
+ return h;
41039
+ }
41040
+ function ngExtractMax(h, dist5) {
41041
+ if (h.heapSize === 0) return -1;
41042
+ const max = h.data[0];
41043
+ h.data[0] = h.data[h.heapSize - 1];
41044
+ h.index[h.data[0]] = 0;
41045
+ h.heapSize--;
41046
+ ngHeapify(h, 0, dist5);
41047
+ return max;
40748
41048
  }
40749
- function dijkstra(src, graph, n, dist4) {
40750
- dijkstraInitDist(src, graph, n, dist4);
40751
- const heap = heapBuildExcluding(src, n, dist4);
40752
- while (heap.length > 0) {
40753
- const closest = heapPop(heap, dist4);
40754
- const closestDist = dist4[closest];
40755
- if (!isFinite(closestDist)) break;
40756
- dijkstraRelax(closest, closestDist, graph, dist4, heap);
41049
+ function ngIncreaseKey(h, increasedVertex, newDist, dist5) {
41050
+ if (dist5[increasedVertex] <= newDist) return;
41051
+ let i = h.index[increasedVertex];
41052
+ dist5[increasedVertex] = newDist;
41053
+ while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
41054
+ ngAssign(h, i, ngParent(i));
41055
+ i = ngParent(i);
41056
+ }
41057
+ h.data[i] = increasedVertex;
41058
+ h.index[increasedVertex] = i;
41059
+ }
41060
+ function toDistType(w) {
41061
+ return Math.trunc(Math.fround(w));
41062
+ }
41063
+ function ngdijkstra(vertex, graph, n, dist5) {
41064
+ let prevClosestDist = MAX_DIST;
41065
+ for (let i = 0; i < n; i++) dist5[i] = MAX_DIST;
41066
+ dist5[vertex] = 0;
41067
+ const vd = graph[vertex];
41068
+ for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = toDistType(vd.ewgts[i]);
41069
+ const h = ngInitHeap(vertex, dist5, n);
41070
+ for (let closest = ngExtractMax(h, dist5); closest >= 0; closest = ngExtractMax(h, dist5)) {
41071
+ const closestDist = dist5[closest];
41072
+ if (closestDist === MAX_DIST) break;
41073
+ const cd = graph[closest];
41074
+ for (let i = 1; i < cd.nedges; i++) {
41075
+ ngIncreaseKey(h, cd.edges[i], closestDist + toDistType(cd.ewgts[i]) | 0, dist5);
41076
+ }
41077
+ prevClosestDist = closestDist;
41078
+ }
41079
+ for (let i = 0; i < n; i++) {
41080
+ if (dist5[i] === MAX_DIST) {
41081
+ dist5[i] = MAX_DIST - prevClosestDist < 10 ? MAX_DIST : prevClosestDist + 10;
41082
+ }
40757
41083
  }
40758
41084
  }
40759
41085
 
40760
41086
  // src/layout/neato/bfs.ts
40761
- function bfsInit(src, n, dist4) {
40762
- for (let i = 0; i < n; i++) dist4[i] = -1;
40763
- dist4[src] = 0;
41087
+ function bfsInit(src, n, dist5) {
41088
+ for (let i = 0; i < n; i++) dist5[i] = -1;
41089
+ dist5[src] = 0;
40764
41090
  return [src];
40765
41091
  }
40766
- function bfsFixDisconnected(n, dist4, closestDist) {
41092
+ function bfsFixDisconnected(n, dist5, closestDist) {
40767
41093
  for (let i = 0; i < n; i++) {
40768
- if (dist4[i] < 0) dist4[i] = closestDist + 10;
41094
+ if (dist5[i] < 0) dist5[i] = closestDist + 10;
40769
41095
  }
40770
41096
  }
40771
- function bfsVisitNeighbors(vertex, graph, dist4, queue) {
41097
+ function bfsVisitNeighbors(vertex, graph, dist5, queue) {
40772
41098
  const vd = graph[vertex];
40773
- const d = dist4[vertex];
41099
+ const d = dist5[vertex];
40774
41100
  const unit = graph[0].ewgts.length === 0;
40775
41101
  for (let i = 1; i < vd.nedges; i++) {
40776
41102
  const nb = vd.edges[i];
40777
- if (dist4[nb] < 0) {
40778
- dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
41103
+ if (dist5[nb] < 0) {
41104
+ dist5[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
40779
41105
  queue.push(nb);
40780
41106
  }
40781
41107
  }
40782
41108
  return d;
40783
41109
  }
40784
- function bfs(src, graph, n, dist4) {
40785
- const queue = bfsInit(src, n, dist4);
41110
+ function bfs(src, graph, n, dist5) {
41111
+ const queue = bfsInit(src, n, dist5);
40786
41112
  let closestDist = 0;
40787
41113
  let head = 0;
40788
41114
  while (head < queue.length) {
40789
41115
  const vertex = queue[head++];
40790
- closestDist = bfsVisitNeighbors(vertex, graph, dist4, queue);
41116
+ closestDist = bfsVisitNeighbors(vertex, graph, dist5, queue);
41117
+ }
41118
+ bfsFixDisconnected(n, dist5, closestDist);
41119
+ }
41120
+ function packedIndex(i, j, n) {
41121
+ return i * (2 * n - i - 1) / 2 + j;
41122
+ }
41123
+ function computeWeightedApspPacked(graph, n) {
41124
+ const result = new Float32Array(n * (n + 1) / 2);
41125
+ const di = new Float32Array(n);
41126
+ for (let i = 0; i < n; i++) {
41127
+ dijkstra(i, graph, n, di);
41128
+ for (let j = i; j < n; j++) result[packedIndex(i, j, n)] = di[j];
40791
41129
  }
40792
- bfsFixDisconnected(n, dist4, closestDist);
41130
+ return result;
41131
+ }
41132
+
41133
+ // src/common/crand.ts
41134
+ var C_RAND_MAX = 2147483647;
41135
+ var UNSEEDED_STATE2 = 1;
41136
+ var state2 = UNSEEDED_STATE2;
41137
+ registerRenderState(() => {
41138
+ state2 = UNSEEDED_STATE2;
41139
+ });
41140
+ function csrand(seed) {
41141
+ state2 = seed;
41142
+ }
41143
+ function crand() {
41144
+ state2 = state2 * 16807 % 2147483647;
41145
+ return state2;
41146
+ }
41147
+ function cdrand() {
41148
+ return crand() / C_RAND_MAX;
41149
+ }
41150
+ function gvRandom(bound) {
41151
+ const discardThreshold = C_RAND_MAX - 2147483648 % bound;
41152
+ let r;
41153
+ do {
41154
+ r = crand();
41155
+ } while (r > discardThreshold);
41156
+ return r % bound;
41157
+ }
41158
+ function gvPermutation(bound) {
41159
+ if (bound <= 0) return [];
41160
+ const p = [];
41161
+ for (let i = 0; i < bound; i++) p.push(i);
41162
+ for (let i = bound - 1; i > 0; --i) {
41163
+ const j = gvRandom(i + 1);
41164
+ const t = p[i];
41165
+ p[i] = p[j];
41166
+ p[j] = t;
41167
+ }
41168
+ return p;
41169
+ }
41170
+
41171
+ // src/layout/neato/matrix-ops.ts
41172
+ var fr = Math.fround;
41173
+ function fma2(a, b, c) {
41174
+ const p = a * b;
41175
+ return Number.isFinite(p) && Number.isFinite(c) ? fma(a, b, c) : p + c;
41176
+ }
41177
+ function orthog1(n, vec) {
41178
+ let sum = 0;
41179
+ for (let i = 0; i < n; i++) sum += vec[i];
41180
+ sum /= n;
41181
+ for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
41182
+ }
41183
+ function orthog1f(n, vec) {
41184
+ let sum = fr(0);
41185
+ for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
41186
+ sum = fr(sum / n);
41187
+ for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
41188
+ }
41189
+ function rightMultWithVectorFF(m, n, vector, result) {
41190
+ for (let i = 0; i < n; i++) result[i] = 0;
41191
+ let index = 0;
41192
+ for (let i = 0; i < n; i++) {
41193
+ const vi = vector[i];
41194
+ let res = fr(m[index++] * vi);
41195
+ for (let j = i + 1; j < n; j++, index++) {
41196
+ res = fr(res + fr(m[index] * vector[j]));
41197
+ result[j] = result[j] + fr(m[index] * vi);
41198
+ }
41199
+ result[i] = result[i] + res;
41200
+ }
41201
+ }
41202
+ function vectorsSubtractionF(n, v1, v2, result) {
41203
+ for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
41204
+ }
41205
+ function vectorsMultAdditionF(n, v1, alpha, v2) {
41206
+ const a = fr(alpha);
41207
+ for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
41208
+ }
41209
+ function vectorsInnerProductF(n, v1, v2) {
41210
+ let result = 0;
41211
+ for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
41212
+ return result;
41213
+ }
41214
+ function copyVectorF(n, src, dst) {
41215
+ for (let i = 0; i < n; i++) dst[i] = src[i];
41216
+ }
41217
+ function maxAbsF(n, vec) {
41218
+ let max = fr(-1e30);
41219
+ for (let i = 0; i < n; i++) {
41220
+ const a = fr(Math.abs(vec[i]));
41221
+ if (a > max) max = a;
41222
+ }
41223
+ return max;
41224
+ }
41225
+ function squareVec(n, vec) {
41226
+ for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
41227
+ }
41228
+ function invertVec(n, vec) {
41229
+ for (let i = 0; i < n; i++) {
41230
+ if (vec[i] !== 0) vec[i] = 1 / vec[i];
41231
+ }
41232
+ }
41233
+ function sqrtVecF(n, source, target) {
41234
+ for (let i = 0; i < n; i++) {
41235
+ if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
41236
+ }
41237
+ }
41238
+ function invertSqrtVec(n, vec) {
41239
+ for (let i = 0; i < n; i++) {
41240
+ if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
41241
+ }
41242
+ }
41243
+ var BLOCK_NONE = 1;
41244
+ function innerProduct(n, v1, v2, block) {
41245
+ let result = 0;
41246
+ const blocked = block === BLOCK_NONE ? 0 : n - n % block;
41247
+ let i = 0;
41248
+ for (; i < blocked; i++) result += v1[i] * v2[i];
41249
+ for (; i < n; i++) result = fma2(v1[i], v2[i], result);
41250
+ return result;
41251
+ }
41252
+ function scadd(vec1, end, fac, vec2) {
41253
+ for (let i = 0; i <= end; i++) vec1[i] = fma2(fac, vec2[i], vec1[i]);
41254
+ }
41255
+ function norm(vec, end, block) {
41256
+ return Math.sqrt(innerProduct(end + 1, vec, vec, block));
41257
+ }
41258
+ function vectorsScalarMult(n, vector, alpha, result) {
41259
+ for (let i = 0; i < n; i++) result[i] = vector[i] * alpha;
41260
+ }
41261
+ function copyVector(n, source, dest) {
41262
+ for (let i = 0; i < n; i++) dest[i] = source[i];
41263
+ }
41264
+ function vectorsAddition(n, v1, v2, result) {
41265
+ for (let i = 0; i < n; i++) result[i] = v1[i] + v2[i];
41266
+ }
41267
+ function vectorsSubtraction(n, v1, v2, result) {
41268
+ for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
41269
+ }
41270
+ function maxAbs(n, vector) {
41271
+ let maxVal = -1e50;
41272
+ for (let i = 0; i < n; i++) {
41273
+ const a = Math.abs(vector[i]);
41274
+ if (a > maxVal) maxVal = a;
41275
+ }
41276
+ return maxVal;
41277
+ }
41278
+ function rightMultWithVectorF(matrix, n, vector, result, block) {
41279
+ const blocked = block === BLOCK_NONE ? 0 : n - n % block;
41280
+ for (let i = 0; i < n; i++) {
41281
+ const row = matrix[i];
41282
+ let res = 0;
41283
+ let j = 0;
41284
+ for (; j < blocked; j++) res += row[j] * vector[j];
41285
+ for (; j < n; j++) res = fma2(row[j], vector[j], res);
41286
+ result[i] = res;
41287
+ }
41288
+ }
41289
+ function rightMultWithVector(matrix, n, vector, result) {
41290
+ for (let i = 0; i < n; i++) {
41291
+ let res = 0;
41292
+ const row = matrix[i];
41293
+ for (let j = 0; j < row.nedges; j++) res = fma2(row.ewgts[j], vector[row.edges[j]], res);
41294
+ result[i] = res;
41295
+ }
41296
+ }
41297
+ var RANGE = 500;
41298
+ function initVecOrth1(n, vec) {
41299
+ for (let i = 0; i < n; i++) vec[i] = crand() % RANGE;
41300
+ orthog1(n, vec);
41301
+ }
41302
+
41303
+ // src/layout/neato/conjgrad.ts
41304
+ var BLOCK_INITIAL_RR = 4;
41305
+ var BLOCK_P_AP = 8;
41306
+ function cgNextDirection(n, w, alpha, rR) {
41307
+ vectorsScalarMult(n, w.Ap, alpha, w.Ap);
41308
+ vectorsSubtraction(n, w.r, w.Ap, w.r);
41309
+ const rRNew = innerProduct(n, w.r, w.r, BLOCK_NONE);
41310
+ if (rR === 0) {
41311
+ agerrorf("conjugate_gradient: unexpected length 0 vector\n");
41312
+ return null;
41313
+ }
41314
+ const beta = rRNew / rR;
41315
+ vectorsScalarMult(n, w.p, beta, w.p);
41316
+ vectorsAddition(n, w.r, w.p, w.p);
41317
+ return rRNew;
41318
+ }
41319
+ function cgStart(A3, x, b, n) {
41320
+ const w = {
41321
+ r: new Float64Array(n),
41322
+ p: new Float64Array(n),
41323
+ Ap: new Float64Array(n),
41324
+ alphap: new Float64Array(n)
41325
+ };
41326
+ const Ax = new Float64Array(n);
41327
+ const orthB = Float64Array.from(b.subarray(0, n));
41328
+ orthog1(n, orthB);
41329
+ orthog1(n, x);
41330
+ rightMultWithVector(A3, n, x, Ax);
41331
+ vectorsSubtraction(n, orthB, Ax, w.r);
41332
+ w.p.set(w.r.subarray(0, n));
41333
+ return w;
41334
+ }
41335
+ function conjugateGradient(A3, x, b, n, tol, maxIterations) {
41336
+ const w = cgStart(A3, x, b, n);
41337
+ let rR = innerProduct(n, w.r, w.r, BLOCK_INITIAL_RR);
41338
+ for (let i = 0; i < maxIterations && maxAbs(n, w.r) > tol; i++) {
41339
+ rightMultWithVector(A3, n, w.p, w.Ap);
41340
+ const pAp = innerProduct(n, w.p, w.Ap, BLOCK_P_AP);
41341
+ if (pAp === 0) break;
41342
+ const alpha = rR / pAp;
41343
+ vectorsScalarMult(n, w.p, alpha, w.alphap);
41344
+ vectorsAddition(n, x, w.alphap, x);
41345
+ if (i < maxIterations - 1) {
41346
+ const next = cgNextDirection(n, w, alpha, rR);
41347
+ if (next === null) return 1;
41348
+ rR = next;
41349
+ }
41350
+ }
41351
+ return 0;
41352
+ }
41353
+ var CGF_BLOCK_AX = 4;
41354
+ var CGF_BLOCK_AP = 4;
41355
+ var CGF_BLOCK_INITIAL_RR = 4;
41356
+ var CGF_BLOCK_P_AP = 8;
41357
+ function cgfInit(A3, x, b, n, ortho1) {
41358
+ const orthB = new Float64Array(n);
41359
+ copyVector(n, b, orthB);
41360
+ if (ortho1) {
41361
+ orthog1(n, orthB);
41362
+ orthog1(n, x);
41363
+ }
41364
+ const Ax = new Float64Array(n);
41365
+ rightMultWithVectorF(A3, n, x, Ax, CGF_BLOCK_AX);
41366
+ const r = new Float64Array(n);
41367
+ vectorsSubtraction(n, orthB, Ax, r);
41368
+ const p = new Float64Array(n);
41369
+ copyVector(n, r, p);
41370
+ return {
41371
+ r,
41372
+ p,
41373
+ Ap: new Float64Array(n),
41374
+ alphap: new Float64Array(n),
41375
+ rr: innerProduct(n, r, r, CGF_BLOCK_INITIAL_RR)
41376
+ };
41377
+ }
41378
+ function cgfUpdate(n, alpha, st) {
41379
+ vectorsScalarMult(n, st.Ap, alpha, st.Ap);
41380
+ vectorsSubtraction(n, st.r, st.Ap, st.r);
41381
+ const rrNew = innerProduct(n, st.r, st.r, BLOCK_NONE);
41382
+ if (st.rr === 0) {
41383
+ agerrorf("conjugate_gradient: unexpected length 0 vector\n");
41384
+ return 1;
41385
+ }
41386
+ const beta = rrNew / st.rr;
41387
+ st.rr = rrNew;
41388
+ vectorsScalarMult(n, st.p, beta, st.p);
41389
+ vectorsAddition(n, st.r, st.p, st.p);
41390
+ return 0;
41391
+ }
41392
+ function conjugateGradientF(A3, x, b, n, opts) {
41393
+ const { tol, maxIterations, ortho1 } = opts;
41394
+ const st = cgfInit(A3, x, b, n, ortho1);
41395
+ for (let i = 0; i < maxIterations && maxAbs(n, st.r) > tol; i++) {
41396
+ rightMultWithVectorF(A3, n, st.p, st.Ap, CGF_BLOCK_AP);
41397
+ const pAp = innerProduct(n, st.p, st.Ap, CGF_BLOCK_P_AP);
41398
+ if (pAp === 0) break;
41399
+ const alpha = st.rr / pAp;
41400
+ vectorsScalarMult(n, st.p, alpha, st.alphap);
41401
+ vectorsAddition(n, x, st.alphap, x);
41402
+ if (i < maxIterations - 1 && cgfUpdate(n, alpha, st) === 1) return 1;
41403
+ }
41404
+ return 0;
40793
41405
  }
40794
41406
 
40795
41407
  // src/layout/neato/stress.ts
41408
+ var TOLERANCE_CG = 1e-3;
40796
41409
  var DFLT_ITERATIONS = 200;
41410
+ var OPT_SMART_INIT = 4;
41411
+ function mdsModel(graph, nG) {
41412
+ if (graph[0].ewgts.length === 0) return null;
41413
+ const Dij = computeWeightedApspPacked(graph, nG);
41414
+ let shift = 0;
41415
+ for (let i = 0; i < nG; i++) {
41416
+ shift += i;
41417
+ for (let e = 1; e < graph[i].nedges; e++) {
41418
+ const j = graph[i].edges[e];
41419
+ if (j < i) continue;
41420
+ Dij[i * nG + j - shift] = graph[i].ewgts[e];
41421
+ }
41422
+ }
41423
+ return Dij;
41424
+ }
40797
41425
 
40798
41426
  // src/layout/neato/sgd-dijkstra.ts
40799
- var FLT_MAX = 34028234663852886e22;
41427
+ var FLT_MAX2 = 34028234663852886e22;
40800
41428
  var left = (i) => 2 * i;
40801
41429
  var right = (i) => 2 * i + 1;
40802
41430
  var parent = (i) => Math.trunc(i / 2);
40803
- var greaterPriority = (h, i, j, dist4) => dist4[h.data[i]] < dist4[h.data[j]];
41431
+ var greaterPriority = (h, i, j, dist5) => dist5[h.data[i]] < dist5[h.data[j]];
40804
41432
  function exchange2(h, i, j) {
40805
41433
  const t = h.data[i];
40806
41434
  h.data[i] = h.data[j];
@@ -40808,19 +41436,19 @@ function exchange2(h, i, j) {
40808
41436
  h.index[h.data[i]] = i;
40809
41437
  h.index[h.data[j]] = j;
40810
41438
  }
40811
- function heapify(h, start, dist4) {
41439
+ function heapify(h, start, dist5) {
40812
41440
  let i = start;
40813
41441
  for (; ; ) {
40814
41442
  const l = left(i);
40815
41443
  const r = right(i);
40816
- let largest = l < h.heapSize && greaterPriority(h, l, i, dist4) ? l : i;
40817
- if (r < h.heapSize && greaterPriority(h, r, largest, dist4)) largest = r;
41444
+ let largest = l < h.heapSize && greaterPriority(h, l, i, dist5) ? l : i;
41445
+ if (r < h.heapSize && greaterPriority(h, r, largest, dist5)) largest = r;
40818
41446
  if (largest === i) break;
40819
41447
  exchange2(h, largest, i);
40820
41448
  i = largest;
40821
41449
  }
40822
41450
  }
40823
- function initHeap(startVertex, dist4, n) {
41451
+ function initHeap(startVertex, dist5, n) {
40824
41452
  const h = {
40825
41453
  data: new Int32Array(Math.max(n - 1, 0)),
40826
41454
  heapSize: n - 1,
@@ -40832,23 +41460,23 @@ function initHeap(startVertex, dist4, n) {
40832
41460
  h.data[count] = i;
40833
41461
  h.index[i] = count++;
40834
41462
  }
40835
- for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist4);
41463
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist5);
40836
41464
  return h;
40837
41465
  }
40838
- function extractMax(h, dist4) {
41466
+ function extractMax(h, dist5) {
40839
41467
  if (h.heapSize === 0) return -1;
40840
41468
  const max = h.data[0];
40841
41469
  h.data[0] = h.data[h.heapSize - 1];
40842
41470
  h.index[h.data[0]] = 0;
40843
41471
  h.heapSize--;
40844
- heapify(h, 0, dist4);
41472
+ heapify(h, 0, dist5);
40845
41473
  return max;
40846
41474
  }
40847
- function increaseKey(h, v, newDist, dist4) {
40848
- if (dist4[v] <= newDist) return;
40849
- dist4[v] = newDist;
41475
+ function increaseKey(h, v, newDist, dist5) {
41476
+ if (dist5[v] <= newDist) return;
41477
+ dist5[v] = newDist;
40850
41478
  let i = h.index[v];
40851
- while (i > 0 && dist4[h.data[parent(i)]] > newDist) {
41479
+ while (i > 0 && dist5[h.data[parent(i)]] > newDist) {
40852
41480
  h.data[i] = h.data[parent(i)];
40853
41481
  h.index[h.data[i]] = i;
40854
41482
  i = parent(i);
@@ -40857,7 +41485,7 @@ function increaseKey(h, v, newDist, dist4) {
40857
41485
  h.index[v] = i;
40858
41486
  }
40859
41487
  function dijkstraSgd(graph, source, terms) {
40860
- const dists = new Float32Array(graph.n).fill(FLT_MAX);
41488
+ const dists = new Float32Array(graph.n).fill(FLT_MAX2);
40861
41489
  dists[source] = 0;
40862
41490
  for (let i = graph.sources[source]; i < graph.sources[source + 1]; i++) {
40863
41491
  dists[graph.targets[i]] = graph.weights[i];
@@ -40866,7 +41494,7 @@ function dijkstraSgd(graph, source, terms) {
40866
41494
  let offset = 0;
40867
41495
  for (let closest = extractMax(h, dists); closest >= 0; closest = extractMax(h, dists)) {
40868
41496
  const d = dists[closest];
40869
- if (d === FLT_MAX) break;
41497
+ if (d === FLT_MAX2) break;
40870
41498
  if (graph.pinneds[closest] || closest < source) {
40871
41499
  terms[offset++] = { i: source, j: closest, d, w: Math.fround(1 / Math.fround(d * d)) };
40872
41500
  }
@@ -40885,7 +41513,7 @@ function lenattr(ep, g) {
40885
41513
  const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
40886
41514
  const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
40887
41515
  if (Number.isNaN(len) || len < 0 || len === 0) {
40888
- agerrLineOn("warn", `bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
41516
+ agwarningf(`bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
40889
41517
  return DEFAULT_EDGE_LEN;
40890
41518
  }
40891
41519
  return len;
@@ -41049,12 +41677,11 @@ function neatoMode(g) {
41049
41677
  if (str === void 0 || str === "") return MODE_MAJOR;
41050
41678
  const mode = modeByName().get(str);
41051
41679
  if (mode !== void 0) return mode;
41052
- agerrLineOn("warn", `Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
41680
+ agwarningf(`Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
41053
41681
  return MODE_MAJOR;
41054
41682
  }
41055
41683
  function checkMode(g, mode) {
41056
- const value = g.root.attrs.get("mode") || (mode === MODE_HIER ? "hier" : "ipsep");
41057
- if (mode === MODE_HIER) unsupported("mode", value, "hierarchical stress majorization");
41684
+ const value = g.root.attrs.get("mode") || "ipsep";
41058
41685
  if (mode === MODE_IPSEP && ipsepHasConstraints(g)) {
41059
41686
  unsupported("mode", value, "constrained (ipsep) majorization");
41060
41687
  }
@@ -41407,10 +42034,10 @@ function solve(a, b, c, n) {
41407
42034
  }
41408
42035
 
41409
42036
  // src/layout/neato/kk-paths.ts
41410
- function newPathState(n, dist4, adj, initialDist2) {
42037
+ function newPathState(n, dist5, adj, initialDist2) {
41411
42038
  return {
41412
42039
  n,
41413
- dist: dist4,
42040
+ dist: dist5,
41414
42041
  adj,
41415
42042
  initialDist: initialDist2,
41416
42043
  heap: new Int32Array(n + 1),
@@ -41488,10 +42115,10 @@ function s1(s, src) {
41488
42115
  function shortestPath2(s) {
41489
42116
  for (let v = 0; v < s.n; v++) s1(s, v);
41490
42117
  }
41491
- function mdsModel(dist4, n, edges) {
42118
+ function mdsModel2(dist5, n, edges) {
41492
42119
  for (const { tailSeq: i, headSeq: j, len } of edges) {
41493
42120
  if (i === j) continue;
41494
- for (const k of [i * n + j, j * n + i]) if (k < dist4.length) dist4[k] = len;
42121
+ for (const k of [i * n + j, j * n + i]) if (k < dist5.length) dist5[k] = len;
41495
42122
  }
41496
42123
  }
41497
42124
 
@@ -41584,12 +42211,12 @@ function initialPositions2(g, st) {
41584
42211
  }
41585
42212
  }
41586
42213
  function distvec(p0, p1, del) {
41587
- let dist4 = 0;
42214
+ let dist5 = 0;
41588
42215
  for (let k = 0; k < NDIM; k++) {
41589
42216
  del[k] = p0[k] - p1[k];
41590
- dist4 += del[k] * del[k];
42217
+ dist5 += del[k] * del[k];
41591
42218
  }
41592
- return Math.sqrt(dist4);
42219
+ return Math.sqrt(dist5);
41593
42220
  }
41594
42221
  function springFactors(g) {
41595
42222
  const byEnds = /* @__PURE__ */ new Map();
@@ -41606,9 +42233,9 @@ function fillRow(st, i, del) {
41606
42233
  const vi = st.nodes[i];
41607
42234
  for (let j = 0; j < st.n; j++) {
41608
42235
  if (i === j) continue;
41609
- const dist4 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
42236
+ const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
41610
42237
  for (let k = 0; k < NDIM; k++) {
41611
- const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist4);
42238
+ const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist5);
41612
42239
  st.t[(i * st.n + j) * NDIM + k] = v;
41613
42240
  st.sumT[i * NDIM + k] += v;
41614
42241
  }
@@ -41637,9 +42264,9 @@ function updateArrays(st, i) {
41637
42264
  for (let k = 0; k < NDIM; k++) st.sumT[i * NDIM + k] = 0;
41638
42265
  for (let j = 0; j < n; j++) {
41639
42266
  if (i === j) continue;
41640
- const dist4 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
42267
+ const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
41641
42268
  for (let k = 0; k < NDIM; k++) {
41642
- const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist4);
42269
+ const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist5);
41643
42270
  st.t[(i * n + j) * NDIM + k] = tij;
41644
42271
  st.sumT[i * NDIM + k] += tij;
41645
42272
  const old = st.t[(j * n + i) * NDIM + k];
@@ -41706,7 +42333,7 @@ function moveNode(st, m) {
41706
42333
  function solveModel(g, st) {
41707
42334
  for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
41708
42335
  if (st.move === st.maxIter) {
41709
- agerrLineOn("warn", `Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
42336
+ agwarningf(`Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
41710
42337
  }
41711
42338
  }
41712
42339
  function mdsEdges(g, nodes, lens) {
@@ -41719,84 +42346,852 @@ function kkNeato(g, nG, model) {
41719
42346
  if (nG < 2 || maxIter < 0) return;
41720
42347
  const { st, adj, ini, lens } = scanGraphMode(g, maxIter);
41721
42348
  shortestPath2(newPathState(st.n, st.dist, adj, ini));
41722
- if (model === MODEL_MDS2) mdsModel(st.dist, st.n, mdsEdges(g, st.nodes, lens));
42349
+ if (model === MODEL_MDS2) mdsModel2(st.dist, st.n, mdsEdges(g, st.nodes, lens));
41723
42350
  initialPositions2(g, st);
41724
42351
  diffeqModel(g, st);
41725
42352
  solveModel(g, st);
41726
42353
  }
41727
42354
 
41728
- // src/layout/neato/matrix-ops.ts
41729
- var fr = Math.fround;
41730
- function orthog1(n, vec) {
41731
- let sum = 0;
41732
- for (let i = 0; i < n; i++) sum += vec[i];
41733
- sum /= n;
41734
- for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
42355
+ // src/layout/neato/make-graph-data.ts
42356
+ var MODE_IPSEP2 = 3;
42357
+ var EDIST_IN = 1;
42358
+ var EDIST_OUT = -1;
42359
+ var EDIST_NONE = 0;
42360
+ function graphHasLen(g) {
42361
+ for (const e of g.edges) {
42362
+ if (e.attrs.has("len")) return true;
42363
+ }
42364
+ return false;
41735
42365
  }
41736
- function orthog1f(n, vec) {
41737
- let sum = fr(0);
41738
- for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
41739
- sum = fr(sum / n);
41740
- for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
42366
+ var edistsOf = (v) => v.edists;
42367
+ function reverseBackEdge(graph, i, e, mode) {
42368
+ const node = graph[i];
42369
+ const j = node.edges[e];
42370
+ edistsOf(node)[e] = mode === MODE_IPSEP2 ? EDIST_OUT : EDIST_IN;
42371
+ const target = graph[j];
42372
+ let f = 1;
42373
+ while (f < target.nedges && target.edges[f] !== i) f++;
42374
+ if (f >= target.nedges) throw new Error(`neato: edge ${i}-${j} has no reverse entry`);
42375
+ edistsOf(target)[f] = EDIST_OUT;
42376
+ }
42377
+ function dfsCycle(graph, start, st) {
42378
+ const { mode, mark, onstack } = st;
42379
+ const stack = [{ i: start, e: 1 }];
42380
+ mark[start] = 1;
42381
+ onstack[start] = 1;
42382
+ for (let frame = stack.at(-1); frame !== void 0; frame = stack.at(-1)) {
42383
+ const { i } = frame;
42384
+ const node = graph[i];
42385
+ if (frame.e >= node.nedges) {
42386
+ onstack[i] = 0;
42387
+ stack.pop();
42388
+ continue;
42389
+ }
42390
+ const e = frame.e++;
42391
+ if (edistsOf(node)[e] === EDIST_IN) continue;
42392
+ const j = node.edges[e];
42393
+ if (onstack[j]) {
42394
+ reverseBackEdge(graph, i, e, mode);
42395
+ } else if (!mark[j]) {
42396
+ mark[j] = 1;
42397
+ onstack[j] = 1;
42398
+ stack.push({ i: j, e: 1 });
42399
+ }
42400
+ }
41741
42401
  }
41742
- function rightMultWithVectorFF(m, n, vector, result) {
42402
+ function acyclic2(graph, nv, mode) {
42403
+ const st = { mode, mark: new Uint8Array(nv), onstack: new Uint8Array(nv) };
42404
+ for (let i = 0; i < nv; i++) {
42405
+ if (st.mark[i]) continue;
42406
+ dfsCycle(graph, i, st);
42407
+ }
42408
+ }
42409
+ function edgeDist2(dir, np, head) {
42410
+ if (dir !== void 0 && dir.startsWith("none")) return EDIST_NONE;
42411
+ return np === head ? EDIST_IN : EDIST_OUT;
42412
+ }
42413
+ function addNeighbours(g, np, entry, o) {
42414
+ const seen2 = /* @__PURE__ */ new Map();
42415
+ for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
42416
+ if (ep.head === ep.tail) continue;
42417
+ const vp = ep.tail === np ? ep.head : ep.tail;
42418
+ const vid = vp.info.id;
42419
+ const dist5 = o.haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
42420
+ const idx = seen2.get(vid);
42421
+ if (idx !== void 0) {
42422
+ if (o.haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist5);
42423
+ continue;
42424
+ }
42425
+ seen2.set(vid, entry.nedges);
42426
+ entry.edges.push(vid);
42427
+ if (o.haveLen || o.haveDir) entry.ewgts.push(dist5);
42428
+ if (o.haveDir) edistsOf(entry).push(edgeDist2(ep.attrs.get("dir"), np, ep.head));
42429
+ entry.nedges++;
42430
+ }
42431
+ }
42432
+ function makeGraphDataC(g, nodeList, haveLen, haveDir, mode = -1) {
42433
+ const vtx = nodeList.map((_, i) => ({
42434
+ nedges: 1,
42435
+ edges: [i],
42436
+ ewgts: haveLen || haveDir ? [0] : [],
42437
+ ...haveDir ? { edists: [0] } : {}
42438
+ }));
42439
+ for (const np of nodeList) addNeighbours(g, np, vtx[np.info.id], { haveLen, haveDir });
42440
+ if (haveDir) acyclic2(vtx, nodeList.length, mode);
42441
+ return vtx;
42442
+ }
42443
+
42444
+ // src/layout/neato/kkutils.ts
42445
+ function compareKeys(a, b) {
42446
+ if (a < b) return -1;
42447
+ if (a > b) return 1;
42448
+ return 0;
42449
+ }
42450
+ function gvSortByPlace(place, ordering, first, count) {
42451
+ const slice = Array.from(ordering.subarray(first, first + count));
42452
+ gvQsort(slice, (x, y) => compareKeys(place[x], place[y]));
42453
+ for (let i = 0; i < count; i++) ordering[first + i] = slice[i];
42454
+ }
42455
+ function quicksortPlace(place, ordering, size) {
42456
+ gvSortByPlace(place, ordering, 0, size);
42457
+ }
42458
+ function quicksortPlacef(place, ordering, first, last) {
42459
+ if (first < last) {
42460
+ gvSortByPlace(place, ordering, first, last - first + 1);
42461
+ }
42462
+ }
42463
+ function computeApspDijkstra(graph, n) {
42464
+ const dij = [];
42465
+ for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
42466
+ for (let i = 0; i < n; i++) ngdijkstra(i, graph, n, dij[i]);
42467
+ return dij;
42468
+ }
42469
+ function computeApspSimple(graph, n) {
42470
+ const dij = [];
42471
+ for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
42472
+ for (let i = 0; i < n; i++) bfs(i, graph, n, dij[i]);
42473
+ return dij;
42474
+ }
42475
+ function computeApsp(graph, n) {
42476
+ return graph[0].ewgts.length > 0 ? computeApspDijkstra(graph, n) : computeApspSimple(graph, n);
42477
+ }
42478
+
42479
+ // src/layout/neato/quad-prog-solve.ts
42480
+ var fr2 = Math.fround;
42481
+ var TOLERANCE = fr2(0.01);
42482
+ var BOUND = 1e9;
42483
+ var BLOCK_EPSILON = 1e-9;
42484
+ var NO_SPLIT = -1;
42485
+ var BITS = new DataView(new ArrayBuffer(8));
42486
+ function oddNeighbour(s, awayFromZero) {
42487
+ BITS.setFloat64(0, s);
42488
+ const hi = BITS.getUint32(0);
42489
+ const lo = BITS.getUint32(4);
42490
+ if (awayFromZero) {
42491
+ BITS.setUint32(4, lo + 1);
42492
+ } else if (lo === 0) {
42493
+ BITS.setUint32(0, hi - 1);
42494
+ BITS.setUint32(4, 4294967295);
42495
+ } else {
42496
+ BITS.setUint32(4, lo - 1);
42497
+ }
42498
+ return BITS.getFloat64(0);
42499
+ }
42500
+ function fmaf(a, b, c) {
42501
+ const p = a * b;
42502
+ const s = p + c;
42503
+ const bv = s - p;
42504
+ const err = p - (s - bv) + (c - bv);
42505
+ if (err === 0 || !Number.isFinite(s)) return fr2(s);
42506
+ BITS.setFloat64(0, s);
42507
+ if ((BITS.getUint32(4) & 1) !== 0) return fr2(s);
42508
+ return fr2(oddNeighbour(s, err > 0 === s > 0));
42509
+ }
42510
+ function blockPlaceNumerator(blockDeg, desPlaceBlock, negLapTimesDesired, toBlockConnectivity, curPlace) {
42511
+ const t = fmaf(blockDeg, desPlaceBlock, negLapTimesDesired);
42512
+ return fmaf(toBlockConnectivity, curPlace, t);
42513
+ }
42514
+ function equals(a, b) {
42515
+ return Math.abs(fr2(a - b)) < TOLERANCE;
42516
+ }
42517
+ function fminf(a, b) {
42518
+ if (Number.isNaN(a)) return b;
42519
+ if (Number.isNaN(b)) return a;
42520
+ return a < b ? a : b;
42521
+ }
42522
+ function fmaxf(a, b) {
42523
+ if (Number.isNaN(a)) return b;
42524
+ if (Number.isNaN(b)) return a;
42525
+ return a > b ? a : b;
42526
+ }
42527
+ function unpackMatrix(packedMat, n) {
42528
+ const flat = new Float32Array(n * n);
42529
+ const mat = new Array(n);
42530
+ for (let i = 0; i < n; i++) mat[i] = flat.subarray(i * n, (i + 1) * n);
42531
+ for (let i = 0, k = 0; i < n; i++) {
42532
+ for (let j = i; j < n; j++, k++) {
42533
+ mat[j][i] = mat[i][j] = packedMat[k];
42534
+ }
42535
+ }
42536
+ return mat;
42537
+ }
42538
+ function ensureMonotonicOrderingWithGaps(place, n, ordering, levels, numLevels, levelsGap) {
42539
+ let lowerBound = fr2(-1e9);
42540
+ let level = -1;
42541
+ let maxInLevel = 0;
42542
+ for (let i = 0; i < n; i++) {
42543
+ if (i >= maxInLevel) {
42544
+ level++;
42545
+ maxInLevel = level === numLevels ? n : levels[level];
42546
+ lowerBound = i > 0 ? fr2(place[ordering[i - 1]] + levelsGap) : fr2(-1e9);
42547
+ quicksortPlacef(place, ordering, i, maxInLevel - 1);
42548
+ }
42549
+ const node = ordering[i];
42550
+ if (place[node] < lowerBound) place[node] = lowerBound;
42551
+ }
42552
+ }
42553
+ function computeNodeLevels(e) {
42554
+ const lev = new Int32Array(e.n);
42555
+ let level = -1;
42556
+ let maxInLevel = 0;
42557
+ for (let i = 0; i < e.n; i++) {
42558
+ if (i >= maxInLevel) {
42559
+ level++;
42560
+ maxInLevel = level === e.numLevels ? e.n : e.levels[level];
42561
+ }
42562
+ lev[e.ordering[i]] = level;
42563
+ }
42564
+ return lev;
42565
+ }
42566
+ function growBlock(c, left2, curPlace) {
42567
+ const { place, lev, levelsGap, e } = c;
42568
+ const gap = e.fArray4;
42569
+ let targetPlace = curPlace;
42570
+ gap[e.ordering[left2]] = 0;
42571
+ let right2;
42572
+ for (right2 = left2 + 1; right2 < e.n; right2++) {
42573
+ if (lev[right2] > lev[right2 - 1]) {
42574
+ targetPlace = fr2(targetPlace + levelsGap);
42575
+ }
42576
+ const node = e.ordering[right2];
42577
+ if (Math.abs(fr2(place[node] - targetPlace)) > BLOCK_EPSILON) break;
42578
+ gap[node] = fr2(place[node] - curPlace);
42579
+ }
42580
+ return right2;
42581
+ }
42582
+ function computeDesiredPlaces(c, left2, right2) {
42583
+ const { e, place, b } = c;
42584
+ for (let i = left2; i < right2; i++) {
42585
+ const node = e.ordering[i];
42586
+ let newPlaceI = -b[node];
42587
+ const lapNode = e.A[node];
42588
+ for (let j = 0; j < e.n; j++) {
42589
+ if (j === node) continue;
42590
+ newPlaceI = fmaf(lapNode[j], place[j], newPlaceI);
42591
+ }
42592
+ e.fArray1[node] = fr2(fr2(newPlaceI / -lapNode[node]) - e.fArray4[node]);
42593
+ }
42594
+ }
42595
+ function collectWhere(c, from, to, test) {
42596
+ for (let j = from; j < to; j++) {
42597
+ const node = c.e.ordering[j];
42598
+ if (test(c.e.fArray1[node])) c.block.push(node);
42599
+ }
42600
+ }
42601
+ function orderBlockByLevels(c, left2, right2, curPlace) {
42602
+ const { e } = c;
42603
+ c.block.length = 0;
42604
+ let firstNextLevel = 0;
42605
+ for (let i = left2; i < right2; i = firstNextLevel) {
42606
+ const level = c.lev[e.ordering[i]];
42607
+ firstNextLevel = level === e.numLevels ? right2 : Math.min(right2, e.levels[level]);
42608
+ collectWhere(c, i, firstNextLevel, (d) => d < curPlace);
42609
+ collectWhere(c, i, firstNextLevel, (d) => d === curPlace);
42610
+ collectWhere(c, i, firstNextLevel, (d) => d > curPlace);
42611
+ }
42612
+ }
42613
+ function computePrefixDesiredPlaces(c, curPlace) {
42614
+ const { e, block } = c;
42615
+ let desPlaceBlock = 0;
42616
+ let blockDeg = 0;
42617
+ for (let i = 0; i < block.length; i++) {
42618
+ const node = block[i];
42619
+ let toBlockConnectivity = 0;
42620
+ const lapNode = e.A[node];
42621
+ for (let j = 0; j < i; j++) {
42622
+ toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
42623
+ }
42624
+ toBlockConnectivity = fr2(toBlockConnectivity * 2);
42625
+ const num2 = blockPlaceNumerator(
42626
+ blockDeg,
42627
+ desPlaceBlock,
42628
+ fr2(-lapNode[node] * e.fArray1[node]),
42629
+ toBlockConnectivity,
42630
+ curPlace
42631
+ );
42632
+ desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
42633
+ e.fArray2[i] = desPlaceBlock;
42634
+ blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
42635
+ }
42636
+ if (e.n >= 0 && block.length === e.n) {
42637
+ e.fArray2[e.n - 1] = curPlace;
42638
+ }
42639
+ }
42640
+ function computeSuffixDesiredPlaces(c, curPlace) {
42641
+ const { e, block } = c;
42642
+ let desPlaceBlock = 0;
42643
+ let blockDeg = 0;
42644
+ for (let i = block.length - 1; i >= 0; i--) {
42645
+ const node = block[i];
42646
+ let toBlockConnectivity = 0;
42647
+ const lapNode = e.A[node];
42648
+ for (let j = i + 1; j < block.length; j++) {
42649
+ toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
42650
+ }
42651
+ toBlockConnectivity = fr2(toBlockConnectivity * 2);
42652
+ const num2 = blockPlaceNumerator(
42653
+ blockDeg,
42654
+ desPlaceBlock,
42655
+ fr2(-lapNode[node] * e.fArray1[node]),
42656
+ toBlockConnectivity,
42657
+ curPlace
42658
+ );
42659
+ desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
42660
+ e.fArray3[i] = desPlaceBlock;
42661
+ blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
42662
+ }
42663
+ if (e.n >= 0 && block.length === e.n) {
42664
+ e.fArray3[0] = curPlace;
42665
+ }
42666
+ }
42667
+ var LIMITED = new Float64Array(2);
42668
+ function limitMoves(prefix, suffix, curPlace) {
42669
+ if (suffix < prefix) {
42670
+ if (suffix < curPlace) {
42671
+ if (prefix > curPlace) prefix = curPlace;
42672
+ suffix = prefix;
42673
+ } else if (prefix > curPlace) {
42674
+ prefix = suffix;
42675
+ }
42676
+ }
42677
+ LIMITED[0] = prefix;
42678
+ LIMITED[1] = suffix;
42679
+ }
42680
+ function findBestSplit(c, curPlace) {
42681
+ const { e, block } = c;
42682
+ let bestI = NO_SPLIT;
42683
+ let maxMovement = 0;
42684
+ for (let i = 0; i < block.length; i++) {
42685
+ const suffixDesPlace = e.fArray3[i];
42686
+ const prefixDesPlace = i > 0 ? e.fArray2[i - 1] : suffixDesPlace;
42687
+ limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
42688
+ const movement = (block.length - i) * Math.abs(fr2(LIMITED[1] - curPlace)) + i * Math.abs(fr2(LIMITED[0] - curPlace));
42689
+ if (movement > maxMovement) {
42690
+ maxMovement = movement;
42691
+ bestI = i;
42692
+ }
42693
+ }
42694
+ return bestI;
42695
+ }
42696
+ function computeUpperBound(c, right2) {
42697
+ const { e, place, lev, levelsGap, block } = c;
42698
+ if (right2 >= e.n) return BOUND;
42699
+ const lastGap = e.fArray4[block[block.length - 1]];
42700
+ const nextPlace = place[e.ordering[right2]];
42701
+ if (lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
42702
+ return fr2(fr2(nextPlace - levelsGap) - lastGap);
42703
+ }
42704
+ return fr2(nextPlace - lastGap);
42705
+ }
42706
+ function nextLowerBound(c, right2) {
42707
+ const { e, place, lev, levelsGap, block } = c;
42708
+ const last = place[block[block.length - 1]];
42709
+ if (right2 < e.n && lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
42710
+ return fr2(last + levelsGap);
42711
+ }
42712
+ return last;
42713
+ }
42714
+ function moveSplitBlock(c, bestI, left2, right2, curPlace) {
42715
+ const { e, place, block } = c;
42716
+ let suffixDesPlace = e.fArray3[bestI];
42717
+ let prefixDesPlace = bestI > 0 ? e.fArray2[bestI - 1] : suffixDesPlace;
42718
+ suffixDesPlace = fminf(suffixDesPlace, computeUpperBound(c, right2));
42719
+ prefixDesPlace = fmaxf(prefixDesPlace, c.lowerBound);
42720
+ limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
42721
+ prefixDesPlace = LIMITED[0];
42722
+ suffixDesPlace = LIMITED[1];
42723
+ for (let i = 0; i < bestI; i++) {
42724
+ place[block[i]] = fr2(prefixDesPlace + e.fArray4[block[i]]);
42725
+ }
42726
+ for (let i = bestI; i < block.length; i++) {
42727
+ place[block[i]] = fr2(suffixDesPlace + e.fArray4[block[i]]);
42728
+ }
42729
+ c.lowerBound = nextLowerBound(c, right2);
42730
+ for (let i = left2; i < right2; i++) e.ordering[i] = block[i - left2];
42731
+ c.converged = c.converged && equals(prefixDesPlace, curPlace) && equals(suffixDesPlace, curPlace);
42732
+ }
42733
+ function processBlock(c, left2) {
42734
+ const curPlace = c.place[c.e.ordering[left2]];
42735
+ const right2 = growBlock(c, left2, curPlace);
42736
+ computeDesiredPlaces(c, left2, right2);
42737
+ orderBlockByLevels(c, left2, right2, curPlace);
42738
+ computePrefixDesiredPlaces(c, curPlace);
42739
+ computeSuffixDesiredPlaces(c, curPlace);
42740
+ const bestI = findBestSplit(c, curPlace);
42741
+ if (bestI !== NO_SPLIT) {
42742
+ moveSplitBlock(c, bestI, left2, right2, curPlace);
42743
+ } else {
42744
+ c.lowerBound = nextLowerBound(c, right2);
42745
+ }
42746
+ return right2;
42747
+ }
42748
+ function constrainedMajorizationNewWithGaps(e, b, coords, curAxis, maxIterations, levelsGap) {
42749
+ const place = coords[curAxis];
42750
+ if (maxIterations <= 0) return;
42751
+ const gap = fr2(levelsGap);
42752
+ ensureMonotonicOrderingWithGaps(place, e.n, e.ordering, e.levels, e.numLevels, gap);
42753
+ const c = {
42754
+ e,
42755
+ place,
42756
+ b,
42757
+ lev: computeNodeLevels(e),
42758
+ levelsGap: gap,
42759
+ block: [],
42760
+ lowerBound: fr2(-BOUND),
42761
+ converged: false
42762
+ };
42763
+ for (let counter = 0; counter < maxIterations && !c.converged; counter++) {
42764
+ c.converged = true;
42765
+ c.lowerBound = fr2(-BOUND);
42766
+ for (let left2 = 0, right2; left2 < e.n; left2 = right2) {
42767
+ right2 = processBlock(c, left2);
42768
+ }
42769
+ orthog1f(e.n, place);
42770
+ }
42771
+ }
42772
+ function initConstrainedMajorization(packedMat, n, ordering, levels, numLevels) {
42773
+ return {
42774
+ A: unpackMatrix(packedMat, n),
42775
+ n,
42776
+ fArray1: new Float32Array(n),
42777
+ fArray2: new Float32Array(n),
42778
+ fArray3: new Float32Array(n),
42779
+ fArray4: new Float32Array(n),
42780
+ ordering,
42781
+ levels,
42782
+ numLevels
42783
+ };
42784
+ }
42785
+
42786
+ // src/layout/neato/conjgrad-mkernel.ts
42787
+ var fr3 = Math.fround;
42788
+ var RIGHT_MULT_BLOCK = 16;
42789
+ var ZERO_LENGTH_MESSAGE = "conjugate_gradient: unexpected length 0 vector\n";
42790
+ function rightMultWithVectorFFFused(m, n, vector, result) {
41743
42791
  for (let i = 0; i < n; i++) result[i] = 0;
41744
42792
  let index = 0;
41745
42793
  for (let i = 0; i < n; i++) {
41746
42794
  const vi = vector[i];
41747
- let res = fr(m[index++] * vi);
42795
+ let res = fmaf(m[index++], vi, 0);
42796
+ const len = n - i - 1;
42797
+ const blockEnd = i + 1 + (len - len % RIGHT_MULT_BLOCK);
41748
42798
  for (let j = i + 1; j < n; j++, index++) {
41749
- res = fr(res + fr(m[index] * vector[j]));
41750
- result[j] = result[j] + fr(m[index] * vi);
42799
+ const mij = m[index];
42800
+ res = j < blockEnd ? fr3(res + fr3(mij * vector[j])) : fmaf(mij, vector[j], res);
42801
+ result[j] = fmaf(mij, vi, result[j]);
41751
42802
  }
41752
42803
  result[i] = result[i] + res;
41753
42804
  }
41754
42805
  }
41755
- function vectorsSubtractionF(n, v1, v2, result) {
41756
- for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
42806
+ function vectorsMultAdditionFused(n, v1, alpha, v2) {
42807
+ for (let i = 0; i < n; i++) v1[i] = fmaf(alpha, v2[i], v1[i]);
41757
42808
  }
41758
- function vectorsMultAdditionF(n, v1, alpha, v2) {
41759
- const a = fr(alpha);
41760
- for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
42809
+ var CgStep = { CONTINUE: 0, STOP: 1, ERROR: 2 };
42810
+ function initialState(A3, x, b, n) {
42811
+ const Ax = new Float32Array(n);
42812
+ const st = { n, r: new Float32Array(n), p: new Float32Array(n), Ap: new Float32Array(n), rR: 0 };
42813
+ orthog1f(n, x);
42814
+ orthog1f(n, b);
42815
+ rightMultWithVectorFFFused(A3, n, x, Ax);
42816
+ orthog1f(n, Ax);
42817
+ vectorsSubtractionF(n, b, Ax, st.r);
42818
+ copyVectorF(n, st.r, st.p);
42819
+ st.rR = vectorsInnerProductF(n, st.r, st.r);
42820
+ return st;
41761
42821
  }
41762
- function vectorsInnerProductF(n, v1, v2) {
41763
- let result = 0;
41764
- for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
41765
- return result;
42822
+ function cgIteration(A3, x, st, last) {
42823
+ const { n, r, p, Ap } = st;
42824
+ orthog1f(n, p);
42825
+ orthog1f(n, x);
42826
+ orthog1f(n, r);
42827
+ rightMultWithVectorFFFused(A3, n, p, Ap);
42828
+ orthog1f(n, Ap);
42829
+ const pAp = vectorsInnerProductF(n, p, Ap);
42830
+ if (pAp === 0) return CgStep.STOP;
42831
+ const alpha = st.rR / pAp;
42832
+ vectorsMultAdditionFused(n, x, fr3(alpha), p);
42833
+ if (last) return CgStep.CONTINUE;
42834
+ vectorsMultAdditionFused(n, r, fr3(-alpha), Ap);
42835
+ const rRNew = vectorsInnerProductF(n, r, r);
42836
+ if (st.rR === 0) {
42837
+ agerrorf(ZERO_LENGTH_MESSAGE);
42838
+ return CgStep.ERROR;
42839
+ }
42840
+ const beta = fr3(rRNew / st.rR);
42841
+ st.rR = rRNew;
42842
+ for (let j = 0; j < n; j++) p[j] = fmaf(beta, p[j], r[j]);
42843
+ return CgStep.CONTINUE;
42844
+ }
42845
+ function conjugateGradientMkernelFused(A3, x, b, n, o) {
42846
+ const st = initialState(A3, x, b, n);
42847
+ for (let i = 0; i < o.maxIterations && maxAbsF(n, st.r) > o.tol; i++) {
42848
+ const step = cgIteration(A3, x, st, i >= o.maxIterations - 1);
42849
+ if (step === CgStep.STOP) break;
42850
+ if (step === CgStep.ERROR) return 1;
42851
+ }
42852
+ return 0;
41766
42853
  }
41767
- function copyVectorF(n, src, dst) {
41768
- for (let i = 0; i < n; i++) dst[i] = src[i];
42854
+
42855
+ // src/layout/neato/opt-arrangement.ts
42856
+ var HIERARCHY_CG_TOL = 1e-3;
42857
+ function constructB(graph, n, b) {
42858
+ for (let i = 0; i < n; i++) {
42859
+ if (graph[0].edists == null) continue;
42860
+ let bI = 0;
42861
+ const node = graph[i];
42862
+ for (let j = 1; j < node.nedges; j++) {
42863
+ bI += Math.fround(Math.fround(node.ewgts[j]) * node.edists[j]);
42864
+ }
42865
+ b[i] = bI;
42866
+ }
41769
42867
  }
41770
- function maxAbsF(n, vec) {
41771
- let max = fr(-1e30);
42868
+ function setUniformWeights(graph, n) {
42869
+ const old = [];
41772
42870
  for (let i = 0; i < n; i++) {
41773
- const a = fr(Math.abs(vec[i]));
41774
- if (a > max) max = a;
42871
+ const node = graph[i];
42872
+ old.push(node.ewgts);
42873
+ const weights = new Array(node.nedges).fill(1);
42874
+ weights[0] = -(node.nedges - 1);
42875
+ node.ewgts = weights;
41775
42876
  }
41776
- return max;
42877
+ return old;
41777
42878
  }
41778
- function squareVec(n, vec) {
41779
- for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
42879
+ function computeYCoords(graph, n, yCoords, maxIterations) {
42880
+ let rv = 0;
42881
+ const b = new Float64Array(n);
42882
+ constructB(graph, n, b);
42883
+ initVecOrth1(n, yCoords);
42884
+ const oldEwgts = setUniformWeights(graph, n);
42885
+ if (conjugateGradient(graph, yCoords, b, n, HIERARCHY_CG_TOL, maxIterations) < 0) {
42886
+ rv = 1;
42887
+ }
42888
+ for (let i = 0; i < n; i++) graph[i].ewgts = oldEwgts[i];
42889
+ return rv;
41780
42890
  }
41781
- function invertVec(n, vec) {
42891
+
42892
+ // src/layout/neato/compute-hierarchy.ts
42893
+ function countLevels(y, ordering, n, tol) {
42894
+ let numLevels = 0;
42895
+ for (let i = 1; i < n; i++) {
42896
+ if (y[ordering[i]] - y[ordering[i - 1]] > tol) numLevels++;
42897
+ }
42898
+ return numLevels;
42899
+ }
42900
+ function fillLevels(y, ordering, n, tol, numLevels) {
42901
+ if (numLevels === 0) {
42902
+ const levels2 = new Int32Array(1);
42903
+ levels2[0] = n;
42904
+ return levels2;
42905
+ }
42906
+ const levels = new Int32Array(numLevels);
42907
+ let count = 0;
42908
+ for (let i = 1; i < n; i++) {
42909
+ if (y[ordering[i]] - y[ordering[i - 1]] > tol) levels[count++] = i;
42910
+ }
42911
+ return levels;
42912
+ }
42913
+ function computeHierarchy(graph, n, absTol, relTol, given) {
42914
+ let y;
42915
+ if (given) {
42916
+ y = given;
42917
+ } else {
42918
+ y = new Float64Array(n);
42919
+ if (computeYCoords(graph, n, y, n)) return null;
42920
+ }
42921
+ const ordering = new Int32Array(n);
42922
+ for (let i = 0; i < n; i++) ordering[i] = i;
42923
+ quicksortPlace(y, ordering, n);
42924
+ const hierarchySpan = y[ordering[n - 1]] - y[ordering[0]];
42925
+ const relative = relTol * hierarchySpan / (n - 1);
42926
+ const tol = absTol > relative ? absTol : relative;
42927
+ const numLevels = countLevels(y, ordering, n, tol);
42928
+ return { ordering, levels: fillLevels(y, ordering, n, tol, numLevels), numLevels };
42929
+ }
42930
+
42931
+ // src/layout/neato/smart-ini-x.ts
42932
+ var fr4 = Math.fround;
42933
+ var SCALE_FACTOR = 256;
42934
+ var DBL_EPSILON = 2220446049250313e-31;
42935
+ var POWER_LENGTH_FLOOR = 1e-10;
42936
+ var BLOCK_STANDARDIZE_NORM = 4;
42937
+ var BLOCK_MAT_MULT_ROW = 4;
42938
+ var BLOCK_MAT_MULT_ORTHOG = 8;
42939
+ var BLOCK_GUESS_ORTHOG = 8;
42940
+ var BLOCK_GUESS_LEN = BLOCK_NONE;
42941
+ var BLOCK_LOOP_LEN = BLOCK_NONE;
42942
+ var BLOCK_ANGLE = 8;
42943
+ var BLOCK_UNIFORM_SUMS = 4;
42944
+ var BLOCK_AVGS = 4;
42945
+ function standardize(orthog, nvtxs) {
42946
+ let avg = 0;
42947
+ for (let i = 0; i < nvtxs; i++) avg += orthog[i];
42948
+ avg /= nvtxs;
42949
+ for (let i = 0; i < nvtxs; i++) orthog[i] = orthog[i] - avg;
42950
+ const len = norm(orthog, nvtxs - 1, BLOCK_STANDARDIZE_NORM);
42951
+ if (Math.abs(len) < DBL_EPSILON) return;
42952
+ vectorsScalarMult(nvtxs, orthog, 1 / len, orthog);
42953
+ }
42954
+ function matMultVecOrthog(mat, dim, vec, result, orthog) {
42955
+ const blocked = dim - dim % BLOCK_MAT_MULT_ROW;
42956
+ for (let i = 0; i < dim; i++) {
42957
+ const row = mat[i];
42958
+ let sum = 0;
42959
+ let j = 0;
42960
+ for (; j < blocked; j++) sum += row[j] * vec[j];
42961
+ for (; j < dim; j++) sum = fma2(row[j], vec[j], sum);
42962
+ result[i] = sum;
42963
+ }
42964
+ const alpha = -innerProduct(dim, result, orthog, BLOCK_MAT_MULT_ORTHOG);
42965
+ scadd(result, dim - 1, alpha, orthog);
42966
+ }
42967
+ function orthogonalizeAgainstEigs(p, vec, count, block) {
42968
+ for (let j = 0; j < count; j++) {
42969
+ const alpha = -innerProduct(p.n, p.eigs[j], vec, block);
42970
+ scadd(vec, p.n - 1, alpha, p.eigs[j]);
42971
+ }
42972
+ }
42973
+ function chooseStartVector(p, i) {
42974
+ const curr = p.eigs[i];
42975
+ for (; ; ) {
42976
+ for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
42977
+ const alpha = -innerProduct(p.n, p.orthog, curr, BLOCK_GUESS_ORTHOG);
42978
+ scadd(curr, p.n - 1, alpha, p.orthog);
42979
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
42980
+ const len = norm(curr, p.n - 1, BLOCK_GUESS_LEN);
42981
+ if (len < POWER_LENGTH_FLOOR) continue;
42982
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
42983
+ return;
42984
+ }
42985
+ }
42986
+ function iterateEigenvector(p, i, tol, work) {
42987
+ const curr = p.eigs[i];
42988
+ for (; ; ) {
42989
+ copyVector(p.n, curr, work.last);
42990
+ matMultVecOrthog(p.mat, p.n, curr, work.tmp, p.orthog);
42991
+ copyVector(p.n, work.tmp, curr);
42992
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
42993
+ const len = norm(curr, p.n - 1, BLOCK_LOOP_LEN);
42994
+ if (len < POWER_LENGTH_FLOOR) {
42995
+ return { nullSpace: true, eval: 0 };
42996
+ }
42997
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
42998
+ const angle = innerProduct(p.n, curr, work.last, BLOCK_ANGLE);
42999
+ if (!(Math.abs(angle) < tol)) {
43000
+ return { nullSpace: false, eval: angle * len };
43001
+ }
43002
+ }
43003
+ }
43004
+ function fillNullSpaceEigenvectors(p, from, neigs) {
43005
+ for (let i = from; i < neigs; i++) {
43006
+ const curr = p.eigs[i];
43007
+ for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
43008
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
43009
+ const len = norm(curr, p.n - 1, BLOCK_NONE);
43010
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
43011
+ p.evals[i] = 0;
43012
+ }
43013
+ }
43014
+ function sortEigenvectors(p, neigs, tmp) {
43015
+ for (let i = 0; i < neigs - 1; i++) {
43016
+ let largestIndex = i;
43017
+ let largestEval = p.evals[largestIndex];
43018
+ for (let j = i + 1; j < neigs; j++) {
43019
+ if (largestEval < p.evals[j]) {
43020
+ largestIndex = j;
43021
+ largestEval = p.evals[largestIndex];
43022
+ }
43023
+ }
43024
+ if (largestIndex !== i) {
43025
+ copyVector(p.n, p.eigs[i], tmp);
43026
+ copyVector(p.n, p.eigs[largestIndex], p.eigs[i]);
43027
+ copyVector(p.n, tmp, p.eigs[largestIndex]);
43028
+ p.evals[largestIndex] = p.evals[i];
43029
+ p.evals[i] = largestEval;
43030
+ }
43031
+ }
43032
+ }
43033
+ function powerIterationOrthog(p, neigsIn, pIterationThreshold) {
43034
+ const work = { tmp: new Float64Array(p.n), last: new Float64Array(p.n) };
43035
+ const tol = 1 - pIterationThreshold;
43036
+ const neigs = neigsIn >= p.n ? p.n : neigsIn;
43037
+ let i = 0;
43038
+ for (; i < neigs; i++) {
43039
+ chooseStartVector(p, i);
43040
+ const res = iterateEigenvector(p, i, tol, work);
43041
+ if (res.nullSpace) break;
43042
+ p.evals[i] = res.eval;
43043
+ }
43044
+ fillNullSpaceEigenvectors(p, i, neigs);
43045
+ sortEigenvectors(p, neigs, work.tmp);
43046
+ }
43047
+ function computeAvgs(Dij, n) {
43048
+ const rowAvg = new Float32Array(n);
43049
+ let sum = 0;
43050
+ const blocked = n - n % BLOCK_AVGS;
41782
43051
  for (let i = 0; i < n; i++) {
41783
- if (vec[i] !== 0) vec[i] = 1 / vec[i];
43052
+ let sumRow = 0;
43053
+ const row = Dij[i];
43054
+ let j = 0;
43055
+ for (; j < blocked; j++) {
43056
+ sum += row[j] * row[j];
43057
+ sumRow += row[j] * row[j];
43058
+ }
43059
+ for (; j < n; j++) {
43060
+ sum = fma2(row[j], row[j], sum);
43061
+ sumRow = fma2(row[j], row[j], sumRow);
43062
+ }
43063
+ rowAvg[i] = fr4(fr4(sumRow) / n);
41784
43064
  }
43065
+ return { rowAvg, allAvg: fr4(fr4(sum) / (n * n)) };
41785
43066
  }
41786
- function sqrtVecF(n, source, target) {
43067
+ function computeBij(Dij, n) {
43068
+ const Bij = [];
43069
+ for (let i = 0; i < n; i++) Bij.push(new Float32Array(n));
43070
+ const { rowAvg, allAvg } = computeAvgs(Dij, n);
41787
43071
  for (let i = 0; i < n; i++) {
41788
- if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
43072
+ for (let j = 0; j <= i; j++) {
43073
+ const fD = fr4(Dij[i][j]);
43074
+ const t = fr4(fma2(-fD, fD, rowAvg[i]));
43075
+ Bij[i][j] = fr4(fr4(t + rowAvg[j]) - allAvg);
43076
+ Bij[j][i] = Bij[i][j];
43077
+ }
43078
+ }
43079
+ return Bij;
43080
+ }
43081
+ function cmdsOrthog(n, dim, eigs, tol, input) {
43082
+ const { orthog, Dij } = input;
43083
+ const Bij = computeBij(Dij, n);
43084
+ const evals = new Float64Array(dim);
43085
+ const orthogAux = Float64Array.from(orthog.subarray(0, n));
43086
+ standardize(orthogAux, n);
43087
+ powerIterationOrthog({ mat: Bij, n, eigs, evals, orthog: orthogAux }, dim, tol);
43088
+ for (let i = 0; i < dim; i++) {
43089
+ for (let j = 0; j < n; j++) eigs[i][j] = eigs[i][j] * Math.sqrt(Math.abs(evals[i]));
41789
43090
  }
41790
43091
  }
41791
- function invertSqrtVec(n, vec) {
43092
+ function scaleGivenCoords(Dij, n, x) {
43093
+ let sum1 = 0;
43094
+ let sum2 = 0;
43095
+ for (let i = 1; i < n; i++) {
43096
+ const blocked = i - i % BLOCK_UNIFORM_SUMS;
43097
+ for (let j = 0; j < i; j++) {
43098
+ const d = Dij[i][j];
43099
+ const f = Math.abs(x[i] - x[j]);
43100
+ const t1 = 1 / d;
43101
+ const t2 = 1 / Math.imul(d, d) * f;
43102
+ if (j < blocked) {
43103
+ sum1 += t1 * f;
43104
+ sum2 += t2 * f;
43105
+ } else {
43106
+ sum1 = fma2(t1, f, sum1);
43107
+ sum2 = fma2(t2, f, sum2);
43108
+ }
43109
+ }
43110
+ }
43111
+ const uniLength = Math.abs(sum2) === Infinity ? 0 : sum1 / sum2;
43112
+ for (let i = 0; i < n; i++) x[i] = x[i] * uniLength;
43113
+ return uniLength;
43114
+ }
43115
+ function computeLaplacian(Dij, n) {
43116
+ const lap = [];
41792
43117
  for (let i = 0; i < n; i++) {
41793
- if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
43118
+ const row = new Float32Array(n);
43119
+ let degree = fr4(0);
43120
+ for (let j = 0; j < n; j++) {
43121
+ if (j === i) continue;
43122
+ const w = fr4(fr4(-1) / fr4(fr4(Dij[i][j]) * fr4(Dij[i][j])));
43123
+ row[j] = w;
43124
+ degree = fr4(degree - w);
43125
+ }
43126
+ row[i] = degree;
43127
+ lap.push(row);
43128
+ }
43129
+ return lap;
43130
+ }
43131
+ function computeResidualDistances(Dij, n, x) {
43132
+ for (let i = 1; i < n; i++) {
43133
+ const posI = x[i];
43134
+ for (let j = 0; j < i; j++) {
43135
+ const t = posI - x[j];
43136
+ const d = Dij[i][j];
43137
+ const diff = fma2(d, d, -(t * t));
43138
+ const v = diff > 0 ? Math.sqrt(diff) : 0;
43139
+ Dij[i][j] = v;
43140
+ Dij[j][i] = v;
43141
+ }
43142
+ }
43143
+ }
43144
+ function balanceOf(i, n, y, ctx) {
43145
+ const posI = y[i];
43146
+ let b = 0;
43147
+ for (let j = 0; j < n; j++) {
43148
+ if (j === i) continue;
43149
+ const term = fr4(fr4(ctx.Dij[i][j]) * -ctx.lap[i][j]);
43150
+ if (posI >= y[j]) b += term;
43151
+ else b -= term;
41794
43152
  }
43153
+ return b;
43154
+ }
43155
+ function solveBalanced(ctx, n, y, balance, convTol) {
43156
+ let converged = false;
43157
+ for (let iterations2 = 0; iterations2 < 200 && !converged; iterations2++) {
43158
+ if (conjugateGradientF(ctx.lap, y, balance, n, { tol: convTol, maxIterations: n, ortho1: true }) < 0) return 1;
43159
+ converged = true;
43160
+ for (let i = 0; i < n; i++) {
43161
+ const b = balanceOf(i, n, y, ctx);
43162
+ if (b !== balance[i] && Math.abs(1 - b / balance[i]) > 1e-5) {
43163
+ converged = false;
43164
+ balance[i] = b;
43165
+ }
43166
+ }
43167
+ }
43168
+ return 0;
43169
+ }
43170
+ function imdsGivenDim(graph, n, givenCoords, newCoords, conjTol) {
43171
+ const x = givenCoords;
43172
+ const y = newCoords;
43173
+ const Dij = computeApsp(graph, n);
43174
+ for (let i = 0; i < n; i++) {
43175
+ for (let j = 0; j < n; j++) Dij[i][j] = Dij[i][j] * SCALE_FACTOR;
43176
+ }
43177
+ const uniLength = scaleGivenCoords(Dij, n, x);
43178
+ cmdsOrthog(n, 1, [y], conjTol, { orthog: x, Dij });
43179
+ const lap = computeLaplacian(Dij, n);
43180
+ computeResidualDistances(Dij, n, x);
43181
+ const ctx = { Dij, lap };
43182
+ const balance = new Float64Array(n);
43183
+ for (let i = 0; i < n; i++) balance[i] = balanceOf(i, n, y, ctx);
43184
+ if (solveBalanced(ctx, n, y, balance, conjTol) === 1) return 1;
43185
+ for (let i = 0; !(Math.abs(uniLength) < DBL_EPSILON) && i < n; i++) {
43186
+ x[i] = x[i] / uniLength;
43187
+ y[i] = y[i] / uniLength;
43188
+ }
43189
+ return 0;
41795
43190
  }
41796
43191
 
41797
43192
  // src/layout/neato/stress-kernel.ts
41798
- var fr2 = Math.fround;
41799
- var TOLERANCE_CG = 1e-3;
43193
+ var fr5 = Math.fround;
43194
+ var TOLERANCE_CG2 = 1e-3;
41800
43195
  var OPT_EXP_FLAG = 2;
41801
43196
  function computeApspPacked2(graph, n) {
41802
43197
  const Dij = new Float32Array(n * (n + 1) / 2);
@@ -41856,9 +43251,9 @@ function cgStep(st, last) {
41856
43251
  vectorsMultAdditionF(n, st.r, -alpha, st.Ap);
41857
43252
  const rRNew = vectorsInnerProductF(n, st.r, st.r);
41858
43253
  if (st.rR === 0) return false;
41859
- const betaF = fr2(rRNew / st.rR);
43254
+ const betaF = fr5(rRNew / st.rR);
41860
43255
  st.rR = rRNew;
41861
- for (let j = 0; j < n; j++) st.p[j] = fr2(betaF * st.p[j]) + st.r[j];
43256
+ for (let j = 0; j < n; j++) st.p[j] = fr5(betaF * st.p[j]) + st.r[j];
41862
43257
  }
41863
43258
  return true;
41864
43259
  }
@@ -41920,8 +43315,8 @@ function buildLap1(lap1, lap2, coords, shape) {
41920
43315
  for (let k = 0; k < dim; k++) {
41921
43316
  const ck = coords[k];
41922
43317
  for (let x = 0; x < len; x++) {
41923
- const tmp = fr2(ck[i] + fr2(-1 * ck[i + 1 + x]));
41924
- distAccumulator[x] = distAccumulator[x] + fr2(tmp * tmp);
43318
+ const tmp = fr5(ck[i] + fr5(-1 * ck[i + 1 + x]));
43319
+ distAccumulator[x] = distAccumulator[x] + fr5(tmp * tmp);
41925
43320
  }
41926
43321
  }
41927
43322
  invertSqrtVec(len, distAccumulator);
@@ -41933,7 +43328,7 @@ function buildLap1(lap1, lap2, coords, shape) {
41933
43328
  let degree = 0;
41934
43329
  if (exp === 2) {
41935
43330
  for (let j = 0; j < len; j++, count++) {
41936
- const val2 = lap1[count] = fr2(lap1[count] * distAccumulator[j]);
43331
+ const val2 = lap1[count] = fr5(lap1[count] * distAccumulator[j]);
41937
43332
  degree += val2;
41938
43333
  degrees[i + j + 1] = degrees[i + j + 1] - val2;
41939
43334
  }
@@ -41967,10 +43362,10 @@ function computeStress(st) {
41967
43362
  }
41968
43363
  function solveAxis(st, k, havePinned, nodes) {
41969
43364
  if (!havePinned) {
41970
- return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG, st.n);
43365
+ return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG2, st.n);
41971
43366
  }
41972
43367
  copyVectorF(st.n, st.coords[k], st.tmpCoords);
41973
- const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG, st.n);
43368
+ const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG2, st.n);
41974
43369
  if (rc < 0) return rc;
41975
43370
  for (let i = 0; i < st.n; i++) {
41976
43371
  if (!isFixed(nodes[i])) st.coords[k][i] = st.tmpCoords[i];
@@ -41986,10 +43381,10 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
41986
43381
  const coords = [];
41987
43382
  for (let i = 0; i < dim; i++) {
41988
43383
  const c = new Float32Array(n);
41989
- for (let j = 0; j < n; j++) c[j] = fr2(dCoords[i][j]);
43384
+ for (let j = 0; j < n; j++) c[j] = fr5(dCoords[i][j]);
41990
43385
  coords.push(c);
41991
43386
  }
41992
- const constantTerm = fr2(n * (n - 1) / 2);
43387
+ const constantTerm = fr5(n * (n - 1) / 2);
41993
43388
  const lap2 = Dij;
41994
43389
  buildLap2(lap2, n, exp);
41995
43390
  const lapLength = n * (n + 1) / 2;
@@ -42024,6 +43419,261 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
42024
43419
  return iterations;
42025
43420
  }
42026
43421
 
43422
+ // src/layout/neato/constrained-majorization.ts
43423
+ var fr6 = Math.fround;
43424
+ var LOCAL_CONSTR_MAJOR_ITERATIONS = 15;
43425
+ var LEVELS_SEP_TOL = 0.1;
43426
+ var ABS_TOL = 0.01;
43427
+ var SUBSPACE_ITERATIONS = 15;
43428
+ var FLT_MAX3 = 34028234663852886e22;
43429
+ var DBL_MAX = Number.MAX_VALUE;
43430
+ var MIN_LEVELS = 1;
43431
+ var Y_AXIS = 1;
43432
+ function unsupported2(what) {
43433
+ throw new RenderError(`hierarchical stress majorization: ${what} is not supported yet`, "UNSUPPORTED_FEATURE");
43434
+ }
43435
+ function modelDistances(graph, n, model) {
43436
+ if (model === MODEL_SUBSET) unsupported2("the subset distance model");
43437
+ if (model === MODEL_CIRCUIT) unsupported2("the circuit distance model");
43438
+ return model === MODEL_MDS2 ? mdsModel(graph, n) : null;
43439
+ }
43440
+ function unconstrainedMajorization(graph, n, dCoords, nodes, o) {
43441
+ if (o.maxi < 0) return 0;
43442
+ const weighted = (graph[0]?.ewgts.length ?? 0) > 0;
43443
+ const Dij = modelDistances(graph, n, o.model) ?? (weighted ? computeWeightedApspPacked2(graph, n) : computeApspPacked2(graph, n));
43444
+ if ((o.opts & OPT_SMART_INIT) !== 0 && n > 1) unsupported2("the smart initial layout");
43445
+ return stressMajorizationKDMkernel(Dij, n, dCoords, nodes, {
43446
+ dim: o.dim,
43447
+ opts: o.opts,
43448
+ maxi: o.maxi,
43449
+ epsilon: o.epsilon
43450
+ });
43451
+ }
43452
+ function hasDirectionality(graph, n) {
43453
+ if (!graph[0]?.edists) return false;
43454
+ let directionalityExist = false;
43455
+ for (let i = 0; i < n; i++) {
43456
+ const edists = graph[i].edists;
43457
+ for (let j = 1; j < graph[i].nedges; j++) {
43458
+ directionalityExist ||= edists[j] !== 0;
43459
+ }
43460
+ }
43461
+ return directionalityExist;
43462
+ }
43463
+ function separateLevels(y, h, n, levelsGap) {
43464
+ const { ordering, levels, numLevels } = h;
43465
+ let displacement = 0;
43466
+ for (let i = 0; i < numLevels; i++) {
43467
+ const shortfall = levelsGap - (y[ordering[levels[i]]] + displacement - y[ordering[levels[i] - 1]]);
43468
+ displacement += 0 > shortfall ? 0 : shortfall;
43469
+ const stop = i < numLevels - 1 ? levels[i + 1] : n;
43470
+ for (let j = levels[i]; j < stop; j++) y[ordering[j]] += displacement;
43471
+ }
43472
+ }
43473
+ function smartInitLayers(graph, n, dCoords, nodes, o) {
43474
+ const { dim } = o;
43475
+ if (dim > 2) {
43476
+ const sub = { dim: dim - 1, opts: o.opts, model: o.model, maxi: SUBSPACE_ITERATIONS, epsilon: o.epsilon };
43477
+ if (unconstrainedMajorization(graph, n, dCoords.slice(1), nodes, sub) < 0) return -1;
43478
+ dCoords[dim - 1].set(dCoords[1].subarray(0, n));
43479
+ }
43480
+ const x = dCoords[0];
43481
+ const y = dCoords[1];
43482
+ if (computeYCoords(graph, n, y, n)) return -1;
43483
+ const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, y);
43484
+ if (h === null) return -1;
43485
+ if (h.numLevels < MIN_LEVELS) {
43486
+ return unconstrainedMajorization(graph, n, dCoords, nodes, o);
43487
+ }
43488
+ if (o.levelsGap > 0) separateLevels(y, h, n, o.levelsGap);
43489
+ if (dim === 2 && imdsGivenDim(graph, n, y, x, o.epsilon)) return -1;
43490
+ return h;
43491
+ }
43492
+ function plainInitLayers(graph, n, dCoords, nodes, dim) {
43493
+ initLayout(n, dim, dCoords, nodes);
43494
+ const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, null);
43495
+ return h === null ? -1 : h;
43496
+ }
43497
+ function distanceKD(coords, dim, i, j) {
43498
+ let sum = 0;
43499
+ for (let k = 0; k < dim; k++) {
43500
+ const d = coords[k][i] - coords[k][j];
43501
+ sum = fma2(d, d, sum);
43502
+ }
43503
+ return Math.sqrt(sum);
43504
+ }
43505
+ function scaleDownLayout(dCoords, n, dim) {
43506
+ let max = 1;
43507
+ for (let i = 0; i < dim; i++) {
43508
+ for (let j = 0; j < n; j++) {
43509
+ const a = Math.abs(dCoords[i][j]);
43510
+ if (a > max) max = a;
43511
+ }
43512
+ }
43513
+ for (let i = 0; i < dim; i++) {
43514
+ for (let j = 0; j < n; j++) dCoords[i][j] *= 10 / max;
43515
+ }
43516
+ }
43517
+ function scaleDistances(Dij, dCoords, n, dim) {
43518
+ const length = n + Math.trunc(n * (n - 1) / 2);
43519
+ const sum1 = Math.trunc(n * (n - 1) / 2);
43520
+ let sum2 = 0;
43521
+ for (let count = 0, i = 0; i < n - 1; i++) {
43522
+ count++;
43523
+ for (let j = i + 1; j < n; j++, count++) {
43524
+ sum2 += distanceKD(dCoords, dim, i, j) / Dij[count];
43525
+ }
43526
+ }
43527
+ const scaleRatio = fr6(sum2 / sum1);
43528
+ for (let i = 0; i < length; i++) Dij[i] = Dij[i] * scaleRatio;
43529
+ }
43530
+ function centerLayout(dCoords, n, dim) {
43531
+ for (let i = 0; i < dim; i++) orthog1(n, dCoords[i]);
43532
+ const y0 = dCoords[Y_AXIS][0];
43533
+ for (let i = 0; i < n; i++) dCoords[Y_AXIS][i] -= y0;
43534
+ }
43535
+ function negatedDegrees(lap2, n) {
43536
+ const degrees = new Float64Array(n);
43537
+ for (let i = 0, count = 0; i < n - 1; i++) {
43538
+ let degree = 0;
43539
+ count++;
43540
+ for (let j = 1; j < n - i; j++, count++) {
43541
+ const val2 = lap2[count];
43542
+ degree += val2;
43543
+ degrees[i + j] -= val2;
43544
+ }
43545
+ degrees[i] -= degree;
43546
+ }
43547
+ return degrees;
43548
+ }
43549
+ function buildLap22(lap2, n) {
43550
+ const lapLength = n + Math.trunc(n * (n - 1) / 2);
43551
+ squareVec(lapLength, lap2);
43552
+ invertVec(lapLength, lap2);
43553
+ const degrees = negatedDegrees(lap2, n);
43554
+ for (let step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
43555
+ lap2[count] = degrees[i];
43556
+ }
43557
+ }
43558
+ function inverseDistances(st, i, len) {
43559
+ const { coords, tmpCoords, distAccumulator } = st;
43560
+ distAccumulator.fill(0, 0, st.n);
43561
+ for (let k = 0; k < st.dim; k++) {
43562
+ const ck = coords[k];
43563
+ for (let j = 0; j < len; j++) tmpCoords[j] = ck[i] - ck[i + 1 + j];
43564
+ for (let j = 0; j < len; j++) tmpCoords[j] = tmpCoords[j] * tmpCoords[j];
43565
+ for (let j = 0; j < len; j++) distAccumulator[j] = tmpCoords[j] + distAccumulator[j];
43566
+ }
43567
+ invertSqrtVec(len, distAccumulator);
43568
+ for (let j = 0; j < len; j++) {
43569
+ if (distAccumulator[j] >= FLT_MAX3 || distAccumulator[j] < 0) distAccumulator[j] = 0;
43570
+ }
43571
+ }
43572
+ function buildLap12(st) {
43573
+ const { n, lap1, lap2, degrees, distAccumulator } = st;
43574
+ degrees.fill(0);
43575
+ sqrtVecF(n + Math.trunc(n * (n - 1) / 2), lap2, lap1);
43576
+ let count = 0;
43577
+ for (let i = 0; i < n - 1; i++) {
43578
+ const len = n - i - 1;
43579
+ inverseDistances(st, i, len);
43580
+ count++;
43581
+ let degree = 0;
43582
+ for (let j = 0; j < len; j++, count++) {
43583
+ const val2 = fr6(lap1[count] * distAccumulator[j]);
43584
+ lap1[count] = val2;
43585
+ degree += val2;
43586
+ degrees[i + j + 1] -= val2;
43587
+ }
43588
+ degrees[i] -= degree;
43589
+ }
43590
+ for (let step = n, count2 = 0, i = 0; i < n; i++, count2 += step, step--) {
43591
+ lap1[count2] = degrees[i];
43592
+ }
43593
+ }
43594
+ function computeNewStress(st, constantTerm) {
43595
+ const { n, dim, lap1, lap2, coords, b, tmpCoords } = st;
43596
+ for (let k = 0; k < dim; k++) rightMultWithVectorFFFused(lap1, n, coords[k], b[k]);
43597
+ let newStress = 0;
43598
+ for (let k = 0; k < dim; k++) newStress += vectorsInnerProductF(n, coords[k], b[k]);
43599
+ newStress *= 2;
43600
+ newStress += constantTerm;
43601
+ for (let k = 0; k < dim; k++) {
43602
+ rightMultWithVectorFFFused(lap2, n, coords[k], tmpCoords);
43603
+ newStress -= vectorsInnerProductF(n, coords[k], tmpCoords);
43604
+ }
43605
+ return newStress;
43606
+ }
43607
+ function solveAxes(st, ctx) {
43608
+ for (let k = 0; k < st.dim; k++) {
43609
+ if (k === Y_AXIS) {
43610
+ constrainedMajorizationNewWithGaps(
43611
+ ctx.cMajEnv,
43612
+ st.b[k],
43613
+ st.coords,
43614
+ k,
43615
+ LOCAL_CONSTR_MAJOR_ITERATIONS,
43616
+ ctx.levelsGap
43617
+ );
43618
+ } else if (conjugateGradientMkernelFused(st.lap2, st.coords[k], st.b[k], st.n, { tol: TOLERANCE_CG, maxIterations: st.n })) {
43619
+ return true;
43620
+ }
43621
+ }
43622
+ return false;
43623
+ }
43624
+ function majorize(st, ctx, dCoords) {
43625
+ const constantTerm = Math.trunc(st.n * (st.n - 1) / 2);
43626
+ let oldStress = DBL_MAX;
43627
+ let iterations = 0;
43628
+ for (let converged = false; iterations < ctx.maxi && !converged; iterations++) {
43629
+ buildLap12(st);
43630
+ const newStress = computeNewStress(st, constantTerm);
43631
+ converged = Math.abs(newStress - oldStress) / Math.abs(oldStress + 1e-10) < ctx.epsilon;
43632
+ converged ||= iterations > 1 && newStress > oldStress;
43633
+ oldStress = newStress;
43634
+ if (solveAxes(st, ctx)) return -1;
43635
+ }
43636
+ for (let i = 0; i < st.dim; i++) {
43637
+ for (let j = 0; j < st.n; j++) dCoords[i][j] = st.coords[i][j];
43638
+ }
43639
+ return iterations;
43640
+ }
43641
+ function toFloatCoords(dCoords, n, dim) {
43642
+ const coords = [];
43643
+ for (let i = 0; i < dim; i++) coords.push(Float32Array.from(dCoords[i].subarray(0, n)));
43644
+ return coords;
43645
+ }
43646
+ function newLoopState(lap2, coords, n) {
43647
+ const dim = coords.length;
43648
+ return {
43649
+ n,
43650
+ dim,
43651
+ lap2,
43652
+ coords,
43653
+ lap1: new Float32Array(n + Math.trunc(n * (n - 1) / 2)),
43654
+ b: Array.from({ length: dim }, () => new Float32Array(n)),
43655
+ tmpCoords: new Float32Array(n),
43656
+ distAccumulator: new Float32Array(n),
43657
+ degrees: new Float64Array(n)
43658
+ };
43659
+ }
43660
+ function stressMajorizationWithHierarchy(graph, n, dCoords, nodes, o) {
43661
+ if (!hasDirectionality(graph, n)) return unconstrainedMajorization(graph, n, dCoords, nodes, o);
43662
+ const smartIni = (o.opts & OPT_SMART_INIT) !== 0;
43663
+ const layers = smartIni ? smartInitLayers(graph, n, dCoords, nodes, o) : plainInitLayers(graph, n, dCoords, nodes, o.dim);
43664
+ if (typeof layers === "number") return layers;
43665
+ if (n === 1) return 0;
43666
+ if (o.maxi === 0) return 0;
43667
+ const Dij = modelDistances(graph, n, o.model) ?? computeApspPacked2(graph, n);
43668
+ if (!smartIni) scaleDownLayout(dCoords, n, o.dim);
43669
+ if (o.levelsGap > 0) scaleDistances(Dij, dCoords, n, o.dim);
43670
+ centerLayout(dCoords, n, o.dim);
43671
+ const st = newLoopState(Dij, toFloatCoords(dCoords, n, o.dim), n);
43672
+ buildLap22(Dij, n);
43673
+ const cMajEnv = initConstrainedMajorization(Dij, n, layers.ordering, layers.levels, layers.numLevels);
43674
+ return majorize(st, { cMajEnv, levelsGap: o.levelsGap, maxi: o.maxi, epsilon: o.epsilon }, dCoords);
43675
+ }
43676
+
42027
43677
  // src/common/utils-inputscale.ts
42028
43678
  var POINTS_PER_INCH3 = 72;
42029
43679
  function getInputscale(g) {
@@ -42210,61 +43860,47 @@ function neatoMaxIter(maxiter, mode, n) {
42210
43860
  if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
42211
43861
  return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
42212
43862
  }
42213
- function runMajorization(g, mode, model) {
42214
- void model;
42215
- const nodeList = assignNodeIds2(g);
43863
+ var levelsGapOf = (g) => lateDouble(g.root.attrs.get("levelsgap"), 0, -Number.MAX_VALUE);
43864
+ function solveStress(c, vtx, dCoords, nodeList) {
43865
+ const { g, mode, model, haveLen, opts } = c;
42216
43866
  const n = nodeList.length;
42217
- const haveLen = graphHasLen(g);
42218
- const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
42219
- checkStart(g);
42220
43867
  const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
42221
43868
  const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
43869
+ if (mode === MODE_HIER) {
43870
+ return stressMajorizationWithHierarchy(vtx, n, dCoords, nodeList, {
43871
+ dim: DFLT_DIM,
43872
+ opts,
43873
+ model,
43874
+ maxi,
43875
+ epsilon,
43876
+ levelsGap: levelsGapOf(g)
43877
+ });
43878
+ }
42222
43879
  const weighted = haveLen && mode !== MODE_IPSEP;
42223
43880
  const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
42224
- const dCoords = [new Float64Array(n), new Float64Array(n)];
42225
- stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
43881
+ return stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
42226
43882
  dim: DFLT_DIM,
42227
- opts: OPT_EXP_FLAG,
43883
+ opts,
42228
43884
  maxi,
42229
43885
  epsilon
42230
43886
  });
42231
- for (let i = 0; i < n; i++) {
42232
- nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
42233
- }
42234
43887
  }
42235
- function graphHasLen(g) {
42236
- for (const e of g.edges) {
42237
- if (e.attrs.has("len")) return true;
43888
+ function runMajorization(g, mode, model) {
43889
+ const nodeList = assignNodeIds2(g);
43890
+ const n = nodeList.length;
43891
+ const haveLen = graphHasLen(g);
43892
+ const init = checkStart(g, n, mode === MODE_HIER ? INIT_SELF : INIT_RANDOM);
43893
+ const opts = init === INIT_SELF ? OPT_EXP_FLAG | OPT_SMART_INIT : OPT_EXP_FLAG;
43894
+ const haveDir = mode === MODE_HIER || mode === MODE_IPSEP;
43895
+ const vtx = makeGraphDataC(g, nodeList, haveLen, haveDir, mode);
43896
+ const dCoords = [new Float64Array(n), new Float64Array(n)];
43897
+ if (solveStress({ g, mode, model, haveLen, opts }, vtx, dCoords, nodeList) < 0) {
43898
+ agerr("prev", "layout aborted");
43899
+ return;
42238
43900
  }
42239
- return false;
42240
- }
42241
- function makeGraphDataC(g, nodeList, haveLen, haveDir) {
42242
- const vtx = nodeList.map((_, i) => ({
42243
- nedges: 1,
42244
- edges: [i],
42245
- ewgts: haveLen || haveDir ? [0] : []
42246
- }));
42247
- for (const np of nodeList) {
42248
- const i = np.info.id;
42249
- const entry = vtx[i];
42250
- const seen2 = /* @__PURE__ */ new Map();
42251
- for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
42252
- if (ep.head === ep.tail) continue;
42253
- const vp = ep.tail === np ? ep.head : ep.tail;
42254
- const vid = vp.info.id;
42255
- const dist4 = haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
42256
- const idx = seen2.get(vid);
42257
- if (idx !== void 0) {
42258
- if (haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist4);
42259
- continue;
42260
- }
42261
- seen2.set(vid, entry.nedges);
42262
- entry.edges.push(vid);
42263
- if (haveLen || haveDir) entry.ewgts.push(dist4);
42264
- entry.nedges++;
42265
- }
43901
+ for (let i = 0; i < n; i++) {
43902
+ nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
42266
43903
  }
42267
- return vtx;
42268
43904
  }
42269
43905
  function solveModel2(g, mode, model) {
42270
43906
  if (g.nodes.size < 2) return;
@@ -42456,6 +44092,25 @@ function esepFactor(g) {
42456
44092
  return { x: SEPFACT * DFLT_MARGIN, y: SEPFACT * DFLT_MARGIN, doAdd: true };
42457
44093
  }
42458
44094
 
44095
+ // src/common/libm-trig.ts
44096
+ var OCTAGON_TRIG = /* @__PURE__ */ new Map([
44097
+ [-0.39269908169872414, [0.9238795325112867, -0.3826834323650898]],
44098
+ [0.39269908169872414, [0.9238795325112867, 0.3826834323650898]],
44099
+ [1.1780972450961724, [0.38268343236508984, 0.9238795325112867]],
44100
+ [1.9634954084936207, [-0.3826834323650897, 0.9238795325112867]],
44101
+ [2.748893571891069, [-0.9238795325112867, 0.3826834323650899]],
44102
+ [3.5342917352885173, [-0.9238795325112868, -0.38268343236508967]],
44103
+ [4.319689898685965, [-0.38268343236509034, -0.9238795325112865]],
44104
+ [5.105088062083414, [0.38268343236509, -0.9238795325112866]],
44105
+ [5.890486225480862, [0.9238795325112865, -0.3826834323650904]]
44106
+ ]);
44107
+ function libmCos(x) {
44108
+ return OCTAGON_TRIG.get(x)?.[0] ?? Math.cos(x);
44109
+ }
44110
+ function libmSin(x) {
44111
+ return OCTAGON_TRIG.get(x)?.[1] ?? Math.sin(x);
44112
+ }
44113
+
42459
44114
  // src/layout/neato/delaunay.ts
42460
44115
  var ICCERRBOUND_A = (10 + 96 * 2 ** -53) * 2 ** -53;
42461
44116
  function ulpExp(v) {
@@ -42624,6 +44279,32 @@ function delaunayTri(xv, yv, n) {
42624
44279
  return edges;
42625
44280
  }
42626
44281
 
44282
+ // src/layout/neato/gts-triangle.ts
44283
+ var SQRT3 = 1.73205080757;
44284
+ function gtsTriangleEnclosing(px, py, n, scale) {
44285
+ let xmin = px[0];
44286
+ let xmax = px[0];
44287
+ let ymin = py[0];
44288
+ let ymax = py[0];
44289
+ for (let i = 1; i < n; i++) {
44290
+ if (px[i] > xmax) xmax = px[i];
44291
+ else if (px[i] < xmin) xmin = px[i];
44292
+ if (py[i] > ymax) ymax = py[i];
44293
+ else if (py[i] < ymin) ymin = py[i];
44294
+ }
44295
+ const xo = (xmax + xmin) / 2;
44296
+ const yo = (ymax + ymin) / 2;
44297
+ const dx = xmax - xo;
44298
+ const dy = ymax - yo;
44299
+ let r = scale * Math.sqrt(fma(dx, dx, dy * dy));
44300
+ if (r === 0) r = scale;
44301
+ return [
44302
+ [fma(r, SQRT3, xo), yo - r],
44303
+ [xo, fma(r, 2, yo)],
44304
+ [fma(-r, SQRT3, xo), yo - r]
44305
+ ];
44306
+ }
44307
+
42627
44308
  // src/layout/neato/cdt-surface.ts
42628
44309
  var pairKey = (u, v) => u < v ? u * 1048576 + v : v * 1048576 + u;
42629
44310
  var Cdt = class {
@@ -43134,27 +44815,15 @@ var Cdt = class {
43134
44815
  return { nfaces: kept.length, faces, neigh };
43135
44816
  }
43136
44817
  };
43137
- var SQRT3 = 1.7320508075688772;
43138
44818
  function mkSurface(x, y, n, segs, nsegs) {
43139
44819
  const px = x.slice(0, n);
43140
44820
  const py = y.slice(0, n);
43141
- let xmin = px[0];
43142
- let xmax = px[0];
43143
- let ymin = py[0];
43144
- let ymax = py[0];
43145
- for (let i = 1; i < n; i++) {
43146
- if (px[i] > xmax) xmax = px[i];
43147
- else if (px[i] < xmin) xmin = px[i];
43148
- if (py[i] > ymax) ymax = py[i];
43149
- else if (py[i] < ymin) ymin = py[i];
43150
- }
43151
- const xo = (xmax + xmin) / 2;
43152
- const yo = (ymax + ymin) / 2;
43153
- let r = 100 * Math.hypot(xmax - xo, ymax - yo);
43154
- if (r === 0) r = 100;
43155
44821
  const s0 = n;
43156
- px.push(xo + r * SQRT3, xo, xo - r * SQRT3);
43157
- py.push(yo - r, yo + 2 * r, yo - r);
44822
+ const enc = gtsTriangleEnclosing(px, py, n, 100);
44823
+ for (const [ex, ey] of enc) {
44824
+ px.push(ex);
44825
+ py.push(ey);
44826
+ }
43158
44827
  const cdt = new Cdt(px, py);
43159
44828
  const cons = [];
43160
44829
  for (let k = 0; k < nsegs; k++) {
@@ -43201,9 +44870,9 @@ function sharedEdge(faces, p3, q3) {
43201
44870
  return { i: p1, j: p2 };
43202
44871
  }
43203
44872
  function addTriEdge(g, t, h, seg2) {
43204
- const dist4 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
44873
+ const dist5 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
43205
44874
  const idx = g.edges.length;
43206
- g.edges.push({ t, h, seg: seg2, dist: dist4 });
44875
+ g.edges.push({ t, h, seg: seg2, dist: dist5 });
43207
44876
  g.nodes[t].edges.push(idx);
43208
44877
  g.nodes[h].edges.push(idx);
43209
44878
  }
@@ -44007,8 +45676,8 @@ function ellipseTangentSlope(a, b, p) {
44007
45676
  function circumscribedCorner(a, b, i, nsides) {
44008
45677
  const angle0 = 2 * Math.PI * (i - 0.5) / nsides;
44009
45678
  const angle1 = 2 * Math.PI * (i + 0.5) / nsides;
44010
- const p0 = { x: a * Math.cos(angle0), y: b * Math.sin(angle0) };
44011
- const p1 = { x: a * Math.cos(angle1), y: b * Math.sin(angle1) };
45679
+ const p0 = { x: a * libmCos(angle0), y: b * libmSin(angle0) };
45680
+ const p1 = { x: a * libmCos(angle1), y: b * libmSin(angle1) };
44012
45681
  const m0 = ellipseTangentSlope(a, b, p0);
44013
45682
  const m1 = ellipseTangentSlope(a, b, p1);
44014
45683
  const x = (fms(p1.x, m1, fma(m0, p0.x, -p0.y)) + p1.y) / (m0 - m1);
@@ -46344,52 +48013,14 @@ function armPow(x, y) {
46344
48013
  return expInline(ehi, elo, signBias);
46345
48014
  }
46346
48015
 
46347
- // src/common/crand.ts
46348
- var C_RAND_MAX = 2147483647;
46349
- var UNSEEDED_STATE2 = 1;
46350
- var state2 = UNSEEDED_STATE2;
46351
- registerRenderState(() => {
46352
- state2 = UNSEEDED_STATE2;
46353
- });
46354
- function csrand(seed) {
46355
- state2 = seed;
46356
- }
46357
- function crand() {
46358
- state2 = state2 * 16807 % 2147483647;
46359
- return state2;
46360
- }
46361
- function cdrand() {
46362
- return crand() / C_RAND_MAX;
46363
- }
46364
- function gvRandom(bound) {
46365
- const discardThreshold = C_RAND_MAX - 2147483648 % bound;
46366
- let r;
46367
- do {
46368
- r = crand();
46369
- } while (r > discardThreshold);
46370
- return r % bound;
46371
- }
46372
- function gvPermutation(bound) {
46373
- if (bound <= 0) return [];
46374
- const p = [];
46375
- for (let i = 0; i < bound; i++) p.push(i);
46376
- for (let i = bound - 1; i > 0; --i) {
46377
- const j = gvRandom(i + 1);
46378
- const t = p[i];
46379
- p[i] = p[j];
46380
- p[j] = t;
46381
- }
46382
- return p;
46383
- }
46384
-
46385
48016
  // src/layout/sfdp/quadtree.ts
46386
48017
  function pointDistance(p1, o1, p2, o2, dim) {
46387
- let dist4 = 0;
48018
+ let dist5 = 0;
46388
48019
  for (let i = 0; i < dim; i++) {
46389
48020
  const d = p1[o1 + i] - p2[o2 + i];
46390
- dist4 = fma(d, d, dist4);
48021
+ dist5 = fma(d, d, dist5);
46391
48022
  }
46392
- return Math.sqrt(dist4);
48023
+ return Math.sqrt(dist5);
46393
48024
  }
46394
48025
  function quadTreeNew(dim, center, width2, maxLevel) {
46395
48026
  return {
@@ -46524,8 +48155,8 @@ function getSupernodesInternal(qt, bh, pt, ptOff, nodeid, out) {
46524
48155
  l = l.next;
46525
48156
  }
46526
48157
  if (qt.qts !== null) {
46527
- const dist4 = pointDistance(qt.center, 0, pt, ptOff, dim);
46528
- if (qt.width < bh * dist4) {
48158
+ const dist5 = pointDistance(qt.center, 0, pt, ptOff, dim);
48159
+ if (qt.width < bh * dist5) {
46529
48160
  for (let i = 0; i < dim; i++) {
46530
48161
  out.center[dim * out.nsuper + i] = qt.average[i];
46531
48162
  }
@@ -46623,12 +48254,12 @@ function onedOptimizerTrain(opt, work) {
46623
48254
  else optHill(opt, i);
46624
48255
  }
46625
48256
  function distance(x, dim, i, j) {
46626
- let dist4 = 0;
48257
+ let dist5 = 0;
46627
48258
  for (let k = 0; k < dim; k++) {
46628
48259
  const d = x[i * dim + k] - x[j * dim + k];
46629
- dist4 = fma(d, d, dist4);
48260
+ dist5 = fma(d, d, dist5);
46630
48261
  }
46631
- return Math.sqrt(dist4);
48262
+ return Math.sqrt(dist5);
46632
48263
  }
46633
48264
  function distanceCropped(x, dim, i, j) {
46634
48265
  return Math.max(distance(x, dim, i, j), MINDIST);
@@ -46636,16 +48267,16 @@ function distanceCropped(x, dim, i, j) {
46636
48267
  function gatherLeaves(A3, p, checked, x, dim) {
46637
48268
  const { ia, ja } = A3;
46638
48269
  const leaves = [];
46639
- let dist4 = 0;
48270
+ let dist5 = 0;
46640
48271
  for (let j = ia[p]; j < ia[p + 1]; j++) {
46641
48272
  const c = ja[j];
46642
48273
  if (ia[c + 1] - ia[c] === 1) {
46643
48274
  checked[c] = true;
46644
- dist4 += distance(x, dim, p, c);
48275
+ dist5 += distance(x, dim, p, c);
46645
48276
  leaves.push(c);
46646
48277
  }
46647
48278
  }
46648
- return { leaves, avgDist: dist4 / leaves.length };
48279
+ return { leaves, avgDist: dist5 / leaves.length };
46649
48280
  }
46650
48281
  function beautifyLeaves(dim, A3, x) {
46651
48282
  const { ia, ja, m } = A3;
@@ -46668,7 +48299,7 @@ function beautifyLeaves(dim, A3, x) {
46668
48299
  }
46669
48300
  }
46670
48301
  function averageEdgeLength(A3, dim, coord) {
46671
- let dist4 = 0;
48302
+ let dist5 = 0;
46672
48303
  const { ia, ja } = A3;
46673
48304
  if (ia[A3.m] === 0) return 1;
46674
48305
  for (let i = 0; i < A3.m; i++) {
@@ -46678,10 +48309,10 @@ function averageEdgeLength(A3, dim, coord) {
46678
48309
  const dd = coord[dim * i + k] - coord[dim * ja[j]];
46679
48310
  d = fma(dd, dd, d);
46680
48311
  }
46681
- dist4 += Math.sqrt(d);
48312
+ dist5 += Math.sqrt(d);
46682
48313
  }
46683
48314
  }
46684
- return dist4 / ia[A3.m];
48315
+ return dist5 / ia[A3.m];
46685
48316
  }
46686
48317
  function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
46687
48318
  if (!adaptiveCooling) return COOL * step;
@@ -46692,18 +48323,18 @@ function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
46692
48323
  }
46693
48324
  return 0.99 * step / COOL;
46694
48325
  }
46695
- function repulsivePow(dist4, p) {
46696
- return armPow(dist4, 1 - p);
48326
+ function repulsivePow(dist5, p) {
48327
+ return armPow(dist5, 1 - p);
46697
48328
  }
46698
48329
  function attractiveForce(ctx, i) {
46699
48330
  const { A: A3, x, dim, fp, f } = ctx;
46700
48331
  const { ia, ja } = A3;
46701
48332
  for (let j = ia[i]; j < ia[i + 1]; j++) {
46702
48333
  if (ja[j] === i) continue;
46703
- const dist4 = distance(x, dim, i, ja[j]);
48334
+ const dist5 = distance(x, dim, i, ja[j]);
46704
48335
  for (let k = 0; k < dim; k++) {
46705
48336
  const t = fp.CRK * (x[i * dim + k] - x[ja[j] * dim + k]);
46706
- f[k] = fma(-t, dist4, f[k]);
48337
+ f[k] = fma(-t, dist5, f[k]);
46707
48338
  }
46708
48339
  }
46709
48340
  }
@@ -46711,9 +48342,9 @@ function repulsiveForceDirect(ctx, i) {
46711
48342
  const { x, dim, n, fp, f } = ctx;
46712
48343
  for (let j = 0; j < n; j++) {
46713
48344
  if (j === i) continue;
46714
- const dist4 = distanceCropped(x, dim, i, j);
48345
+ const dist5 = distanceCropped(x, dim, i, j);
46715
48346
  for (let k = 0; k < dim; k++) {
46716
- f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist4, fp.p);
48347
+ f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist5, fp.p);
46717
48348
  }
46718
48349
  }
46719
48350
  }
@@ -46723,9 +48354,9 @@ function repulsiveForceQT(ctx, qt, i, acc) {
46723
48354
  acc.countsAvg += counts;
46724
48355
  acc.nsuperAvg += nsuper;
46725
48356
  for (let j = 0; j < nsuper; j++) {
46726
- const dist4 = Math.max(distances[j], MINDIST);
48357
+ const dist5 = Math.max(distances[j], MINDIST);
46727
48358
  for (let k = 0; k < dim; k++) {
46728
- f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist4, fp.p);
48359
+ f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist5, fp.p);
46729
48360
  }
46730
48361
  }
46731
48362
  }
@@ -46981,7 +48612,7 @@ function diagPreconNew(A3) {
46981
48612
  }
46982
48613
  return diag;
46983
48614
  }
46984
- function conjugateGradient(A3, precon, n, x, rhs, tol, maxit) {
48615
+ function conjugateGradient2(A3, precon, n, x, rhs, tol, maxit) {
46985
48616
  let rho = 0;
46986
48617
  let rhoOld = 1;
46987
48618
  let iter = 0;
@@ -47022,7 +48653,7 @@ function smSolve(A3, dim, x0, rhs, tol, maxit) {
47022
48653
  x[i] = x0[i * dim + k];
47023
48654
  b[i] = rhs[i * dim + k];
47024
48655
  }
47025
- res += conjugateGradient(A3, precond, n, x, b, tol, maxit);
48656
+ res += conjugateGradient2(A3, precond, n, x, b, tol, maxit);
47026
48657
  for (let i = 0; i < n; i++) {
47027
48658
  rhs[i * dim + k] = x[i];
47028
48659
  }
@@ -47376,7 +49007,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
47376
49007
  for (let j = ia[i]; j < ia[i + 1]; j++) {
47377
49008
  const jj = ja[j];
47378
49009
  if (jj === i) continue;
47379
- const dist4 = distance(x, dim, i, jj);
49010
+ const dist5 = distance(x, dim, i, jj);
47380
49011
  const dx = Math.abs(x[i * dim] - x[jj * dim]);
47381
49012
  const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
47382
49013
  const wx = width2[i * dim] + width2[jj * dim];
@@ -47399,9 +49030,9 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
47399
49030
  t = Math.min(expandmax, t);
47400
49031
  t = Math.max(expandmin, t);
47401
49032
  if (t > 1) {
47402
- idealDistance[j] = t * dist4;
49033
+ idealDistance[j] = t * dist5;
47403
49034
  } else {
47404
- idealDistance[j] = -t * dist4;
49035
+ idealDistance[j] = -t * dist5;
47405
49036
  }
47406
49037
  }
47407
49038
  }
@@ -47496,9 +49127,9 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
47496
49127
  w[j] = -1 / d[j] / d[j];
47497
49128
  d[j] = -d[j];
47498
49129
  }
47499
- const dist4 = d[j];
49130
+ const dist5 = d[j];
47500
49131
  diagW += w[j];
47501
- d[j] = w[j] * dist4;
49132
+ d[j] = w[j] * dist5;
47502
49133
  diagD += d[j];
47503
49134
  }
47504
49135
  w[jdiag] = -diagW;
@@ -47509,11 +49140,11 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
47509
49140
  function totalDistance(m, dim, x, y) {
47510
49141
  let total = 0;
47511
49142
  for (let i = 0; i < m; i++) {
47512
- let dist4 = 0;
49143
+ let dist5 = 0;
47513
49144
  for (let j = 0; j < dim; j++) {
47514
- dist4 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
49145
+ dist5 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
47515
49146
  }
47516
- total += Math.sqrt(dist4);
49147
+ total += Math.sqrt(dist5);
47517
49148
  }
47518
49149
  return total;
47519
49150
  }
@@ -47546,18 +49177,18 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
47546
49177
  idiag = j;
47547
49178
  continue;
47548
49179
  }
47549
- let dist4 = distance(x, dim, i, jd[j]);
49180
+ let dist5 = distance(x, dim, i, jd[j]);
47550
49181
  if (d[j] === 0) {
47551
49182
  dd[j] = 0;
47552
49183
  } else {
47553
- if (dist4 === 0) {
49184
+ if (dist5 === 0) {
47554
49185
  const dij = d[j] / Lw.a[j];
47555
49186
  for (let k = 0; k < dim; k++) {
47556
49187
  x[jd[j] * dim + k] += 1e-4 * (cdrand() + 1e-4) * dij;
47557
49188
  }
47558
- dist4 = distance(x, dim, i, jd[j]);
49189
+ dist5 = distance(x, dim, i, jd[j]);
47559
49190
  }
47560
- dd[j] = d[j] / dist4;
49191
+ dd[j] = d[j] / dist5;
47561
49192
  }
47562
49193
  diag += dd[j];
47563
49194
  }
@@ -47576,9 +49207,9 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
47576
49207
  return diff;
47577
49208
  }
47578
49209
  function scaleToEdgeLength(dim, A3, x, avgLabelSize) {
47579
- let dist4 = averageEdgeLength(A3, dim, x);
47580
- dist4 = avgLabelSize / Math.max(dist4, MACHINEACC);
47581
- for (let i = 0; i < dim * A3.m; i++) x[i] *= dist4;
49210
+ let dist5 = averageEdgeLength(A3, dim, x);
49211
+ dist5 = avgLabelSize / Math.max(dist5, MACHINEACC);
49212
+ for (let i = 0; i < dim * A3.m; i++) x[i] *= dist5;
47582
49213
  }
47583
49214
  function removeOverlapPrism(dim, A3, x, labelSizes, ntry, initialScaling, doShrinking) {
47584
49215
  if (!labelSizes) return;
@@ -47945,7 +49576,7 @@ function makeHasEdge(g) {
47945
49576
  }
47946
49577
  return (a, b) => pairs.get(a)?.has(b) === true || undirected && pairs.get(b)?.has(a) === true;
47947
49578
  }
47948
- function mkNConstraintG(g, list, intersect, dist4) {
49579
+ function mkNConstraintG(g, list, intersect, dist5) {
47949
49580
  const cg = newCg();
47950
49581
  const flat = flatten(list);
47951
49582
  let lastn;
@@ -47962,7 +49593,7 @@ function mkNConstraintG(g, list, intersect, dist4) {
47962
49593
  const nxp = flat[j];
47963
49594
  if (!intersect(p, nxp)) continue;
47964
49595
  const e = cgEdge(cg, cnodeOf(p), cnodeOf(nxp));
47965
- e.info.minlen = dist4(p.bb, nxp.bb);
49596
+ e.info.minlen = dist5(p.bb, nxp.bb);
47966
49597
  e.info.weight = hasEdge(p.np, nxp.np) ? 100 : 1;
47967
49598
  created.push(e);
47968
49599
  }
@@ -48009,12 +49640,12 @@ function buildVisibility(flat, intersect) {
48009
49640
  }
48010
49641
  return vg;
48011
49642
  }
48012
- function mapGraphs(vg, flat, cg, dist4) {
49643
+ function mapGraphs(vg, flat, cg, dist5) {
48013
49644
  for (let i = 0; i < flat.length; i++) {
48014
49645
  const tp = flat[i];
48015
49646
  for (const j of vg[i]) {
48016
49647
  const hp = flat[j];
48017
- const delta2 = dist4(tp.bb, hp.bb);
49648
+ const delta2 = dist5(tp.bb, hp.bb);
48018
49649
  const ce = cgEdge(cg, cnodeOf(tp), cnodeOf(hp));
48019
49650
  ce.info.weight = 1;
48020
49651
  if ((ce.info.minlen ?? 0) < delta2) {
@@ -48024,15 +49655,15 @@ function mapGraphs(vg, flat, cg, dist4) {
48024
49655
  }
48025
49656
  }
48026
49657
  }
48027
- function mkConstraintG(list, intersect, dist4) {
49658
+ function mkConstraintG(list, intersect, dist5) {
48028
49659
  const cg = newCg();
48029
49660
  const flat = flatten(list);
48030
49661
  buildChain(cg, flat);
48031
- mapGraphs(buildVisibility(flat, intersect), flat, cg, dist4);
49662
+ mapGraphs(buildVisibility(flat, intersect), flat, cg, dist5);
48032
49663
  return cg;
48033
49664
  }
48034
- function buildConstraintGraph(g, list, ifn, dist4, ortho) {
48035
- return ortho ? mkConstraintG(list, ifn, dist4) : mkNConstraintG(g, list, ifn, dist4);
49665
+ function buildConstraintGraph(g, list, ifn, dist5, ortho) {
49666
+ return ortho ? mkConstraintG(list, ifn, dist5) : mkNConstraintG(g, list, ifn, dist5);
48036
49667
  }
48037
49668
  function newItems() {
48038
49669
  return new DtBag((p) => p.val, cmpitem);
@@ -48173,7 +49804,7 @@ function inflatePts(verts, xmargin, ymargin) {
48173
49804
  v.y *= ymargin;
48174
49805
  }
48175
49806
  }
48176
- function isBox2(verts) {
49807
+ function isBox3(verts) {
48177
49808
  if (verts.length !== 4) return false;
48178
49809
  const [v0, v1, v2, v3] = verts;
48179
49810
  if (v0.y === v1.y) {
@@ -48233,7 +49864,7 @@ function clusterVerts(n, xmargin, ymargin) {
48233
49864
  function polyKind(n, poly, verts) {
48234
49865
  const name = shapeName(n);
48235
49866
  if (name === "box") return POLY_BOX;
48236
- if (name === "polygon" && isBox2(verts)) return POLY_BOX;
49867
+ if (name === "polygon" && isBox3(verts)) return POLY_BOX;
48237
49868
  if (poly.sides < 3 && poly.regular) return POLY_CIRCLE;
48238
49869
  return 0;
48239
49870
  }
@@ -48741,7 +50372,7 @@ function heapSiftUp(h, i) {
48741
50372
  i = parent2;
48742
50373
  }
48743
50374
  }
48744
- function heapSiftDown3(h, i) {
50375
+ function heapSiftDown2(h, i) {
48745
50376
  const n = h.length;
48746
50377
  for (; ; ) {
48747
50378
  let smallest = i;
@@ -48758,7 +50389,7 @@ function heapSiftDown3(h, i) {
48758
50389
  }
48759
50390
  function makeHeap(h) {
48760
50391
  for (let i = (h.length >> 1) - 1; i >= 0; i--) {
48761
- heapSiftDown3(h, i);
50392
+ heapSiftDown2(h, i);
48762
50393
  }
48763
50394
  }
48764
50395
  function heapFindMin(h) {
@@ -48767,7 +50398,7 @@ function heapFindMin(h) {
48767
50398
  function heapDeleteMin(h) {
48768
50399
  h[0] = h[h.length - 1];
48769
50400
  h.pop();
48770
- if (h.length > 0) heapSiftDown3(h, 0);
50401
+ if (h.length > 0) heapSiftDown2(h, 0);
48771
50402
  }
48772
50403
  function heapInsert(h, c) {
48773
50404
  h.push(c);
@@ -48851,27 +50482,27 @@ var Block = class _Block {
48851
50482
  * @see lib/vpsc/block.cpp: Block::merge(Block* b, Constraint* c)
48852
50483
  */
48853
50484
  mergeTwoArg(b, c) {
48854
- const dist4 = c.right.offset - c.left.offset - c.gap;
50485
+ const dist5 = c.right.offset - c.left.offset - c.gap;
48855
50486
  let l = c.left.block;
48856
50487
  let r = c.right.block;
48857
50488
  if (this.vars.length < b.vars.length) {
48858
- r.mergeInto(l, c, dist4);
50489
+ r.mergeInto(l, c, dist5);
48859
50490
  } else {
48860
- l.mergeInto(r, c, -dist4);
50491
+ l.mergeInto(r, c, -dist5);
48861
50492
  }
48862
50493
  }
48863
50494
  /**
48864
50495
  * Merge block b into this across constraint c by dist.
48865
50496
  * @see lib/vpsc/block.cpp: Block::merge(Block *b, Constraint *c, double dist)
48866
50497
  */
48867
- mergeInto(b, c, dist4) {
50498
+ mergeInto(b, c, dist5) {
48868
50499
  c.active = true;
48869
- this.wposn += b.wposn - dist4 * b.weight;
50500
+ this.wposn += b.wposn - dist5 * b.weight;
48870
50501
  this.weight += b.weight;
48871
50502
  this.posn = this.wposn / this.weight;
48872
50503
  for (const v of b.vars) {
48873
50504
  v.block = this;
48874
- v.offset += dist4;
50505
+ v.offset += dist5;
48875
50506
  this.vars.push(v);
48876
50507
  }
48877
50508
  b.deleted = true;
@@ -49160,13 +50791,13 @@ var Blocks = class {
49160
50791
  r.deleteMinInConstraint();
49161
50792
  let l = c.left.block;
49162
50793
  if (l.in.length === 0) l.setUpInConstraints();
49163
- let dist4 = c.right.offset - c.left.offset - c.gap;
50794
+ let dist5 = c.right.offset - c.left.offset - c.gap;
49164
50795
  if (r.vars.length < l.vars.length) {
49165
- dist4 = -dist4;
50796
+ dist5 = -dist5;
49166
50797
  [l, r] = [r, l];
49167
50798
  }
49168
50799
  this.timeCtr.value++;
49169
- r.mergeInto(l, c, dist4);
50800
+ r.mergeInto(l, c, dist5);
49170
50801
  r.mergeIn(l);
49171
50802
  r.timeStamp = this.timeCtr.value;
49172
50803
  this.removeBlock(l);
@@ -49184,12 +50815,12 @@ var Blocks = class {
49184
50815
  l.deleteMinOutConstraint();
49185
50816
  let r = c.right.block;
49186
50817
  r.setUpOutConstraints();
49187
- let dist4 = c.left.offset + c.gap - c.right.offset;
50818
+ let dist5 = c.left.offset + c.gap - c.right.offset;
49188
50819
  if (l.vars.length > r.vars.length) {
49189
- dist4 = -dist4;
50820
+ dist5 = -dist5;
49190
50821
  [l, r] = [r, l];
49191
50822
  }
49192
- l.mergeInto(r, c, dist4);
50823
+ l.mergeInto(r, c, dist5);
49193
50824
  l.mergeOut(r);
49194
50825
  this.removeBlock(r);
49195
50826
  c = l.findMinOutConstraint();
@@ -49705,7 +51336,7 @@ function warnUnrecognizedOverlap(flag) {
49705
51336
  const s = flag.toLowerCase();
49706
51337
  if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
49707
51338
  if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
49708
- agerrLineOn("warn", `Unrecognized overlap value "${flag}" - using false`);
51339
+ agwarningf(`Unrecognized overlap value "${flag}" - using false`);
49709
51340
  }
49710
51341
  function getAdjustMode(flag) {
49711
51342
  warnUnrecognizedOverlap(flag);
@@ -49738,7 +51369,7 @@ function adjustLate(g, am) {
49738
51369
  case AM_VPSC:
49739
51370
  return vpscAdjust(g);
49740
51371
  default:
49741
- agerrLineOn("warn", `Unhandled adjust option ${am.print}`);
51372
+ agwarningf(`Unhandled adjust option ${am.print}`);
49742
51373
  return 0;
49743
51374
  }
49744
51375
  }
@@ -50712,20 +52343,20 @@ function coincidentDelta() {
50712
52343
  } while (xdelta === 0 && ydelta === 0);
50713
52344
  return { xdelta, ydelta };
50714
52345
  }
50715
- function doRep(p, q, xdelta, ydelta, dist4) {
52346
+ function doRep(p, q, xdelta, ydelta, dist5) {
50716
52347
  let force;
50717
- if (!(dist4 > 0)) {
52348
+ if (!(dist5 > 0)) {
50718
52349
  const d = coincidentDelta();
50719
52350
  xdelta = d.xdelta;
50720
52351
  ydelta = d.ydelta;
50721
- dist4 = libmHypot(xdelta, ydelta);
52352
+ dist5 = libmHypot(xdelta, ydelta);
50722
52353
  }
50723
- if (dist4 > fdpParms.Mlimit) {
52354
+ if (dist5 > fdpParms.Mlimit) {
50724
52355
  force = 0;
50725
52356
  } else if (parms.useNew) {
50726
- force = parms.K * parms.K / (dist4 * dist4 * dist4);
52357
+ force = parms.K * parms.K / (dist5 * dist5 * dist5);
50727
52358
  } else {
50728
- force = parms.K * parms.K / (dist4 * dist4);
52359
+ force = parms.K * parms.K / (dist5 * dist5);
50729
52360
  }
50730
52361
  if (isPort(p) && isPort(q)) force *= 10;
50731
52362
  const dq = disp(q);
@@ -50747,8 +52378,8 @@ function doNeighbor(grid2, i, j, nodes) {
50747
52378
  for (const q of cellp.nodes) {
50748
52379
  const xdelta = q.info.pos[0] - p.info.pos[0];
50749
52380
  const ydelta = q.info.pos[1] - p.info.pos[1];
50750
- const dist4 = libmHypot(xdelta, ydelta);
50751
- if (dist4 < parms.Cell) doRep(p, q, xdelta, ydelta, dist4);
52381
+ const dist5 = libmHypot(xdelta, ydelta);
52382
+ if (dist5 < parms.Cell) doRep(p, q, xdelta, ydelta, dist5);
50752
52383
  }
50753
52384
  }
50754
52385
  }
@@ -50780,12 +52411,12 @@ function applyAttr(p, q, e) {
50780
52411
  ydelta = d.ydelta;
50781
52412
  dist22 = fma(xdelta, xdelta, ydelta * ydelta);
50782
52413
  }
50783
- const dist4 = Math.sqrt(dist22);
52414
+ const dist5 = Math.sqrt(dist22);
50784
52415
  let force;
50785
52416
  if (parms.useNew) {
50786
- force = (e.info.factor ?? 1) * (dist4 - (e.info.dist ?? 1)) / dist4;
52417
+ force = (e.info.factor ?? 1) * (dist5 - (e.info.dist ?? 1)) / dist5;
50787
52418
  } else {
50788
- force = (e.info.factor ?? 1) * dist4 / (e.info.dist ?? 1);
52419
+ force = (e.info.factor ?? 1) * dist5 / (e.info.dist ?? 1);
50789
52420
  }
50790
52421
  const dq = disp(q);
50791
52422
  const dp = disp(p);
@@ -50960,16 +52591,16 @@ function cntOverlaps(g) {
50960
52591
  function applyRep2(p, q, rs) {
50961
52592
  let xdelta = q.info.pos[0] - p.info.pos[0];
50962
52593
  let ydelta = q.info.pos[1] - p.info.pos[1];
50963
- let dist4 = libmHypot(xdelta, ydelta);
50964
- if (!(dist4 > 0)) {
52594
+ let dist5 = libmHypot(xdelta, ydelta);
52595
+ if (!(dist5 > 0)) {
50965
52596
  const d = coincidentDelta();
50966
52597
  xdelta = d.xdelta;
50967
52598
  ydelta = d.ydelta;
50968
- dist4 = libmHypot(xdelta, ydelta);
52599
+ dist5 = libmHypot(xdelta, ydelta);
50969
52600
  }
50970
52601
  const ov = overlap4(p, q) ? 1 : 0;
50971
- let force = ov ? rs.ov / (dist4 * dist4) : rs.nonov / (dist4 * dist4);
50972
- if (dist4 > fdpParms.Mlimit) force = 0;
52602
+ let force = ov ? rs.ov / (dist5 * dist5) : rs.nonov / (dist5 * dist5);
52603
+ if (dist5 > fdpParms.Mlimit) force = 0;
50973
52604
  const dq = disp(q);
50974
52605
  const dp = disp(p);
50975
52606
  dq[0] = fma(xdelta, force, dq[0]);
@@ -50982,10 +52613,10 @@ function applyAttr2(p, q) {
50982
52613
  if (overlap4(p, q)) return;
50983
52614
  const xdelta = q.info.pos[0] - p.info.pos[0];
50984
52615
  const ydelta = q.info.pos[1] - p.info.pos[1];
50985
- const dist4 = libmHypot(xdelta, ydelta);
52616
+ const dist5 = libmHypot(xdelta, ydelta);
50986
52617
  const din = rad(p) + rad(q);
50987
- const dout = dist4 - din;
50988
- const force = dout * dout / ((xParams.K + din) * dist4);
52618
+ const dout = dist5 - din;
52619
+ const force = dout * dout / ((xParams.K + din) * dist5);
50989
52620
  const dq = disp(q);
50990
52621
  const dp = disp(p);
50991
52622
  dq[0] = fms(xdelta, force, dq[0]);
@@ -52140,9 +53771,9 @@ function pcpRotate(n, dim, x) {
52140
53771
  axis[0] = -(-y[0] + y[3] - Math.sqrt(radicand)) / (2 * y[1]);
52141
53772
  axis[1] = 1;
52142
53773
  }
52143
- const dist4 = Math.sqrt(fma(axis[0], axis[0], 1));
52144
- axis[0] = axis[0] / dist4;
52145
- axis[1] = axis[1] / dist4;
53774
+ const dist5 = Math.sqrt(fma(axis[0], axis[0], 1));
53775
+ axis[0] = axis[0] / dist5;
53776
+ axis[1] = axis[1] / dist5;
52146
53777
  for (let i = 0; i < n; i++) {
52147
53778
  const x0 = fma(x[dim * i], axis[0], x[dim * i + 1] * axis[1]);
52148
53779
  const x1 = fma(-x[dim * i], axis[1], x[dim * i + 1] * axis[0]);
@@ -52555,10 +54186,10 @@ function buildSpanTree(nodes, edges) {
52555
54186
  }
52556
54187
  return map;
52557
54188
  }
52558
- function measureDist(leaf, anc, dist4, change) {
54189
+ function measureDist(leaf, anc, dist5, change) {
52559
54190
  const p = anc.tparent;
52560
54191
  if (!p) return;
52561
- const d = dist4 + 1;
54192
+ const d = dist5 + 1;
52562
54193
  if (p.distone === 0) {
52563
54194
  p.leafone = leaf;
52564
54195
  p.distone = d;
@@ -54058,11 +55689,11 @@ var DEFAULT_COLOR5 = "black";
54058
55689
  var PENWIDTH_NORMAL4 = 1;
54059
55690
  var PENWIDTH_THRESHOLD4 = 5e-3;
54060
55691
  var EPS3 = 1e-5;
54061
- function dist3(a, b) {
55692
+ function dist4(a, b) {
54062
55693
  return Math.sqrt(dist2(a, b));
54063
55694
  }
54064
55695
  function approxLen(list, off) {
54065
- return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
55696
+ return dist4(list[off], list[off + 1]) + dist4(list[off + 1], list[off + 2]) + dist4(list[off + 2], list[off + 3]);
54066
55697
  }
54067
55698
  function splitCubic(v, t) {
54068
55699
  const left2 = [];
@@ -54141,7 +55772,7 @@ function drawSplitSpline(list, segs, job) {
54141
55772
  return endColor;
54142
55773
  }
54143
55774
  function emitSplitEdgePaths(e, job, colorList) {
54144
- const segs = parseSegs(colorList).segs;
55775
+ const segs = parseSegs(colorList, edgeSegsContext(e)).segs;
54145
55776
  const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
54146
55777
  const spl = e.info.spl;
54147
55778
  let endColor = firstColor2;
@@ -54162,8 +55793,8 @@ var forfunc = (cur, total, init) => (1 - cur / total) * init / 2;
54162
55793
  var revfunc = (cur, total, init) => cur / total * init / 2;
54163
55794
  var nonefunc = (_cur, _total, init) => init / 2;
54164
55795
  var bothfunc = (cur, total, init) => {
54165
- const fr3 = cur / total;
54166
- return fr3 <= 0.5 ? fr3 * init : (1 - fr3) * init;
55796
+ const fr7 = cur / total;
55797
+ return fr7 <= 0.5 ? fr7 * init : (1 - fr7) * init;
54167
55798
  };
54168
55799
  function taperfun(dir, directed) {
54169
55800
  if (dir === "forward") return forfunc;
@@ -55597,7 +57228,7 @@ var DotWriterBase = class {
55597
57228
 
55598
57229
  // src/render/dot/edge-draw.ts
55599
57230
  var DEFAULT_COLOR6 = "black";
55600
- var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
57231
+ var DEFAULT_LINE_STYLE2 = ["solid", "setlinewidth(1)"];
55601
57232
  function emitArrowOp(buf, op, pen) {
55602
57233
  switch (op.kind) {
55603
57234
  case "polygon":
@@ -55632,8 +57263,9 @@ var EdgeDrawBase = class extends DotWriterBase {
55632
57263
  */
55633
57264
  attachmentPolyline(pts, pencolor, job) {
55634
57265
  const obj = job.obj;
57266
+ gvrenderSetStyle(DEFAULT_LINE_STYLE2);
55635
57267
  if (obj !== null) {
55636
- obj.rawStyle = [...DEFAULT_LINE_STYLE];
57268
+ obj.rawStyle = [...DEFAULT_LINE_STYLE2];
55637
57269
  obj.pen = 3 /* Solid */;
55638
57270
  obj.penWidth = 1;
55639
57271
  obj.penColor = resolveRenderColor(pencolor.split(":")[0]);
@@ -55687,8 +57319,8 @@ var EdgeDrawBase = class extends DotWriterBase {
55687
57319
  * under that segment's pen. Reuses the same split geometry
55688
57320
  * (splitSplineByColor) as the SVG path. @see lib/common/emit.c:1975 multicolor
55689
57321
  */
55690
- emitSplitSpline(bzList, colorAttr, edraw, job) {
55691
- const segs = parseSegs(colorAttr).segs;
57322
+ emitSplitSpline(bzList, e, colorAttr, edraw, job) {
57323
+ const segs = parseSegs(colorAttr, edgeSegsContext(e)).segs;
55692
57324
  const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
55693
57325
  let endColor = firstColor2;
55694
57326
  for (const bz of bzList) {
@@ -55711,7 +57343,7 @@ var EdgeDrawBase = class extends DotWriterBase {
55711
57343
  const segData = bzList.map(
55712
57344
  (bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
55713
57345
  );
55714
- const colors = parseSegs(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
57346
+ const colors = parseSegsSilent(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
55715
57347
  for (const color of colors) {
55716
57348
  const pen = xdotPenColor(resolveRenderColor(color));
55717
57349
  for (const sd of segData) {
@@ -55867,7 +57499,7 @@ var XdotRenderer = class extends EdgeDrawBase {
55867
57499
  let tailArrowColor;
55868
57500
  let headArrowColor;
55869
57501
  if (numsemi > 0 && numc > 0) {
55870
- const c = this.emitSplitSpline(spl.list, colorAttr, edraw, job);
57502
+ const c = this.emitSplitSpline(spl.list, e, colorAttr, edraw, job);
55871
57503
  tailArrowColor = c.firstColor;
55872
57504
  headArrowColor = c.endColor;
55873
57505
  } else if (edgeIsTapered(e)) {
@@ -56103,72 +57735,6 @@ function svgTaperedEdge(e, job) {
56103
57735
  svgArrowPolygons(e, job);
56104
57736
  }
56105
57737
 
56106
- // src/gvc/image-resolver.ts
56107
- var activeResolver = null;
56108
- function setImageResolver(fn) {
56109
- if (fn !== null && typeof fn !== "function") {
56110
- throw invalidArgType("resolver", "function or null", fn);
56111
- }
56112
- activeResolver = fn;
56113
- }
56114
- var EXT_MIME = {
56115
- png: "image/png",
56116
- jpg: "image/jpeg",
56117
- jpeg: "image/jpeg",
56118
- gif: "image/gif",
56119
- svg: "image/svg+xml",
56120
- webp: "image/webp"
56121
- };
56122
- var FALLBACK_MIME = "application/octet-stream";
56123
- function inferMimeFromSrc(src) {
56124
- const dot = src.lastIndexOf(".");
56125
- if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
56126
- const ext = src.slice(dot + 1).toLowerCase();
56127
- return EXT_MIME[ext] ?? FALLBACK_MIME;
56128
- }
56129
- function findImageBytes(src, resolver) {
56130
- const active = resolver ?? activeResolver;
56131
- if (active === null) return null;
56132
- const result = active(src);
56133
- if (result === null) return null;
56134
- if (result instanceof Uint8Array) {
56135
- return { bytes: result, mime: inferMimeFromSrc(src) };
56136
- }
56137
- return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
56138
- }
56139
- var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56140
- function base64Encode(bytes) {
56141
- const len = bytes.length;
56142
- const out = [];
56143
- let i = 0;
56144
- for (; i + 2 < len; i += 3) {
56145
- const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
56146
- out.push(
56147
- B64_CHARS[n >> 18 & 63],
56148
- B64_CHARS[n >> 12 & 63],
56149
- B64_CHARS[n >> 6 & 63],
56150
- B64_CHARS[n & 63]
56151
- );
56152
- }
56153
- const remaining = len - i;
56154
- if (remaining === 1) {
56155
- const n = bytes[i] << 16;
56156
- out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
56157
- } else if (remaining === 2) {
56158
- const n = bytes[i] << 16 | bytes[i + 1] << 8;
56159
- out.push(
56160
- B64_CHARS[n >> 18 & 63],
56161
- B64_CHARS[n >> 12 & 63],
56162
- B64_CHARS[n >> 6 & 63],
56163
- "="
56164
- );
56165
- }
56166
- return out.join("");
56167
- }
56168
- function toDataUri(bytes, mime) {
56169
- return "data:" + mime + ";base64," + base64Encode(bytes);
56170
- }
56171
-
56172
57738
  // src/render/svg.ts
56173
57739
  function emitMulticolorArrows(e, job, headColor, tailColor) {
56174
57740
  const obj = job.obj;