@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/render.js CHANGED
@@ -1,3 +1,12 @@
1
+ // src/common/render-state.ts
2
+ var resets = [];
3
+ function registerRenderState(reset2) {
4
+ resets.push(reset2);
5
+ }
6
+ function resetRenderState() {
7
+ for (const reset2 of resets) reset2();
8
+ }
9
+
1
10
  // src/errors.ts
2
11
  var FRIENDLY_MESSAGES = {
3
12
  SYNTAX_ERROR: "There is a syntax error in the DOT source.",
@@ -214,6 +223,12 @@ var GvcContext = class {
214
223
  * rendering happens in between and must see the layout state
215
224
  * (e.g. cluster arrays).
216
225
  *
226
+ * Contract (AD-4/AD-8): first resets the C process state (RNG streams,
227
+ * sequence counters, once-only warnings), so each `layout` call behaves
228
+ * as one native run — drive one graph per `layout`. Caller-installed hooks
229
+ * (setTextMeasurer, setImageSizer, setImageResolver, the per-context
230
+ * measurer/sizer/resolver) are configuration and are not reset.
231
+ *
217
232
  * @throws TypeError (ERR_INVALID_ARG_TYPE / ERR_INVALID_ARG_VALUE) for a
218
233
  * bad `g`, or an engine argument that is not registered
219
234
  * @throws RenderError (UNKNOWN_LAYOUT) if the `layout` attribute names no
@@ -224,6 +239,7 @@ var GvcContext = class {
224
239
  * @see lib/gvc/gvlayout.c:gvLayoutJobs
225
240
  */
226
241
  layout(g, engineName) {
242
+ resetRenderState();
227
243
  const selected = this.checkLayoutArgs(g, engineName);
228
244
  const attr2 = g.attrs?.get("layout");
229
245
  let engine = selected;
@@ -5079,15 +5095,6 @@ var ALL_FONT_METRICS = [
5079
5095
  CALIBRI_FAMILY
5080
5096
  ];
5081
5097
 
5082
- // src/common/render-state.ts
5083
- var resets = [];
5084
- function registerRenderState(reset2) {
5085
- resets.push(reset2);
5086
- }
5087
- function resetRenderState() {
5088
- for (const reset2 of resets) reset2();
5089
- }
5090
-
5091
5098
  // src/common/agerr.ts
5092
5099
  var PREFIX_ERROR = "Error";
5093
5100
  var PREFIX_WARNING = "Warning";
@@ -5152,7 +5159,7 @@ function getFamilyMetrics(fontName) {
5152
5159
  if (!warnedFontNames.has(fontName)) {
5153
5160
  warnedFontNames.add(fontName);
5154
5161
  agwarningf(
5155
- `no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
5162
+ `Warning: no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
5156
5163
  );
5157
5164
  }
5158
5165
  return TIMES_FALLBACK;
@@ -5537,6 +5544,17 @@ function createMeasurer() {
5537
5544
  function setAspect(_g) {
5538
5545
  }
5539
5546
 
5547
+ // src/common/attr-get.ts
5548
+ function nodeAttr(n, g, key) {
5549
+ const own = n.attrs.get(key);
5550
+ if (own !== void 0) return own;
5551
+ if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
5552
+ return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
5553
+ }
5554
+ function graphAttrInherited(sg, key) {
5555
+ return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
5556
+ }
5557
+
5540
5558
  // src/common/htmltable-types.ts
5541
5559
  var HtmlParseError = class extends DotEngineError {
5542
5560
  type = "semantic";
@@ -6286,9 +6304,15 @@ function scanCdata(text, p, base, dataOf, tokens) {
6286
6304
  if (end > p) tokens.push({ kind: "cdata", start: base + p, end: base + end, data: dataOf(base + p, base + end) });
6287
6305
  return close < 0 ? -1 : close + CDATA_CLOSE.length;
6288
6306
  }
6307
+ var CONTENT_NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
6289
6308
  function scanText(text, p, base, tokens) {
6290
6309
  const e = text.indexOf("<", p);
6291
6310
  const slice = text.slice(p, e < 0 ? text.length : e);
6311
+ const bad = CONTENT_NON_XML.exec(slice)?.index;
6312
+ if (bad !== void 0) {
6313
+ if (bad > 0) tokens.push({ kind: "text", start: base + p, end: base + p + bad });
6314
+ return { at: p + bad, held: false, invalid: p + bad };
6315
+ }
6292
6316
  const from = e < 0 ? heldRefStart(slice) : void 0;
6293
6317
  const end = from === void 0 ? p + slice.length : p + from;
6294
6318
  if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
@@ -6308,6 +6332,7 @@ function scanContent(text, base, inCdata, dataOf) {
6308
6332
  }
6309
6333
  if (text[p] !== "<") {
6310
6334
  const scanned = scanText(text, p, base, tokens);
6335
+ if (scanned.invalid !== void 0) return { tokens, consumed: scanned.at, invalid: base + scanned.invalid, inCdata: false };
6311
6336
  if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
6312
6337
  p = scanned.at;
6313
6338
  continue;
@@ -7314,11 +7339,79 @@ var parseHtmlLabelRv = (src, stderr) => {
7314
7339
  };
7315
7340
  var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
7316
7341
 
7342
+ // src/gvc/image-resolver.ts
7343
+ var activeResolver = null;
7344
+ var EXT_MIME = {
7345
+ png: "image/png",
7346
+ jpg: "image/jpeg",
7347
+ jpeg: "image/jpeg",
7348
+ gif: "image/gif",
7349
+ svg: "image/svg+xml",
7350
+ webp: "image/webp"
7351
+ };
7352
+ var FALLBACK_MIME = "application/octet-stream";
7353
+ function inferMimeFromSrc(src) {
7354
+ const dot = src.lastIndexOf(".");
7355
+ if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
7356
+ const ext = src.slice(dot + 1).toLowerCase();
7357
+ return EXT_MIME[ext] ?? FALLBACK_MIME;
7358
+ }
7359
+ function findImageBytes(src, resolver) {
7360
+ const active = resolver ?? activeResolver;
7361
+ if (active === null) return null;
7362
+ const result = active(src);
7363
+ if (result === null) return null;
7364
+ if (result instanceof Uint8Array) {
7365
+ return { bytes: result, mime: inferMimeFromSrc(src) };
7366
+ }
7367
+ return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
7368
+ }
7369
+ var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7370
+ function base64Encode(bytes) {
7371
+ const len = bytes.length;
7372
+ const out = [];
7373
+ let i = 0;
7374
+ for (; i + 2 < len; i += 3) {
7375
+ const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
7376
+ out.push(
7377
+ B64_CHARS[n >> 18 & 63],
7378
+ B64_CHARS[n >> 12 & 63],
7379
+ B64_CHARS[n >> 6 & 63],
7380
+ B64_CHARS[n & 63]
7381
+ );
7382
+ }
7383
+ const remaining = len - i;
7384
+ if (remaining === 1) {
7385
+ const n = bytes[i] << 16;
7386
+ out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
7387
+ } else if (remaining === 2) {
7388
+ const n = bytes[i] << 16 | bytes[i + 1] << 8;
7389
+ out.push(
7390
+ B64_CHARS[n >> 18 & 63],
7391
+ B64_CHARS[n >> 12 & 63],
7392
+ B64_CHARS[n >> 6 & 63],
7393
+ "="
7394
+ );
7395
+ }
7396
+ return out.join("");
7397
+ }
7398
+ function toDataUri(bytes, mime) {
7399
+ return "data:" + mime + ";base64," + base64Encode(bytes);
7400
+ }
7401
+
7317
7402
  // src/gvc/usershape.ts
7318
7403
  var activeSizer = null;
7319
7404
  function findImageSize(src) {
7320
7405
  return activeSizer !== null ? activeSizer(src) : null;
7321
7406
  }
7407
+ var STRERROR_ENOENT = "No such file or directory";
7408
+ function imageIsSupplied(name, sizer, resolver) {
7409
+ const size = sizer !== void 0 ? sizer(name) : findImageSize(name);
7410
+ return size !== null || findImageBytes(name, resolver) !== null;
7411
+ }
7412
+ function imageOpenWarning(name) {
7413
+ return `${STRERROR_ENOENT} while opening ${name}`;
7414
+ }
7322
7415
 
7323
7416
  // src/common/pointset.ts
7324
7417
  function cmpPair(a, b) {
@@ -7371,6 +7464,173 @@ var PointSet = class {
7371
7464
  }
7372
7465
  };
7373
7466
 
7467
+ // src/common/emit-types.ts
7468
+ var PS2INCH = 1 / 72;
7469
+ var HTML_BF = 1 << 0;
7470
+ var HTML_IF = 1 << 1;
7471
+ var HTML_UL = 1 << 2;
7472
+ var HTML_SUP = 1 << 3;
7473
+ var HTML_SUB = 1 << 4;
7474
+ var HTML_S = 1 << 5;
7475
+ var HTML_OL = 1 << 6;
7476
+
7477
+ // src/common/htmltable-pos-runs.ts
7478
+ function itemFontFlags(item) {
7479
+ let f = 0;
7480
+ if (item.bold) f |= HTML_BF;
7481
+ if (item.italic) f |= HTML_IF;
7482
+ if (item.underline) f |= HTML_UL;
7483
+ if (item.superscript) f |= HTML_SUP;
7484
+ if (item.subscript) f |= HTML_SUB;
7485
+ if (item.strikethrough) f |= HTML_S;
7486
+ if (item.overline) f |= HTML_OL;
7487
+ return f;
7488
+ }
7489
+ function itemFace(item, finfo) {
7490
+ return {
7491
+ fs: item.fontSize !== void 0 ? item.fontSize : finfo.fontsize,
7492
+ face: item.fontFace !== void 0 ? item.fontFace : finfo.fontname
7493
+ };
7494
+ }
7495
+ function measureItem(item, finfo, measurer) {
7496
+ if (item.text === void 0) return null;
7497
+ const { fs, face } = itemFace(item, finfo);
7498
+ const flags = itemFontFlags(item);
7499
+ const sz = measurer.measure(
7500
+ item.text,
7501
+ face,
7502
+ fs,
7503
+ { bold: !!(flags & HTML_BF), italic: !!(flags & HTML_IF) }
7504
+ );
7505
+ return { w: sz.w, h: sz.h, fs, yoffsetCenterline: sz.yoffsetCenterline, yoffsetLayout: sz.yoffsetLayout };
7506
+ }
7507
+ function newRun() {
7508
+ return { items: [], width: 0, fontSize: 0, height: 0, maxOffset: 0, maxLayout: 0 };
7509
+ }
7510
+ function runLeftX(run, box, centerX) {
7511
+ if (run.just === "left") return box.ll.x;
7512
+ if (run.just === "right") return box.ur.x - run.width;
7513
+ return centerX - run.width / 2;
7514
+ }
7515
+ function accumulateItem(cur, item, m) {
7516
+ cur.items.push(item);
7517
+ cur.width += m.w;
7518
+ cur.fontSize = Math.max(cur.fontSize, m.fs);
7519
+ cur.height = Math.max(cur.height, m.h);
7520
+ cur.maxOffset = Math.max(cur.maxOffset, m.yoffsetCenterline ?? 0.05 * m.fs);
7521
+ cur.maxLayout = Math.max(cur.maxLayout, m.yoffsetLayout ?? 0);
7522
+ }
7523
+ function buildLineRuns(texts, finfo, measurer) {
7524
+ const runs = [];
7525
+ let cur = newRun();
7526
+ const flush = (br) => {
7527
+ if (cur.items.length === 0 && br !== void 0) {
7528
+ const { br: _b, brAlign: _a, ...fontProps } = br;
7529
+ const empty = { text: "", ...fontProps };
7530
+ const m = measureItem(empty, finfo, measurer);
7531
+ if (m !== null) accumulateItem(cur, empty, m);
7532
+ }
7533
+ cur.just = br?.brAlign;
7534
+ runs.push(cur);
7535
+ cur = newRun();
7536
+ };
7537
+ for (const txt of texts) {
7538
+ for (const item of txt.items) {
7539
+ if (item.br) {
7540
+ flush(item);
7541
+ continue;
7542
+ }
7543
+ const m = measureItem(item, finfo, measurer);
7544
+ if (m !== null) accumulateItem(cur, item, m);
7545
+ }
7546
+ if (cur.items.length > 0) flush();
7547
+ }
7548
+ return runs;
7549
+ }
7550
+ function runSimpleKey(run, finfo) {
7551
+ if (run.items.length > 1) return null;
7552
+ const item = run.items[0];
7553
+ if (item === void 0) return void 0;
7554
+ if (itemFontFlags(item) !== 0) return null;
7555
+ return itemFace(item, finfo);
7556
+ }
7557
+ function runsAreSimple(runs, finfo) {
7558
+ let prevFs = -1;
7559
+ let prevFace = null;
7560
+ for (const run of runs) {
7561
+ const key = runSimpleKey(run, finfo);
7562
+ if (key === null) return false;
7563
+ if (key === void 0) continue;
7564
+ if (prevFs < 0) prevFs = key.fs;
7565
+ else if (key.fs !== prevFs) return false;
7566
+ if (prevFace === null) prevFace = key.face;
7567
+ else if (key.face !== prevFace) return false;
7568
+ }
7569
+ return true;
7570
+ }
7571
+ function placeRunItems(run, startX, baseline, finfo, measurer) {
7572
+ const lines = [];
7573
+ let x = startX;
7574
+ for (const item of run.items) {
7575
+ const { fs, face } = itemFace(item, finfo);
7576
+ const flags = itemFontFlags(item);
7577
+ const sz = measurer.measure(
7578
+ item.text,
7579
+ face,
7580
+ fs,
7581
+ { bold: !!(flags & HTML_BF), italic: !!(flags & HTML_IF) }
7582
+ );
7583
+ lines.push({
7584
+ text: item.text,
7585
+ x,
7586
+ baseline,
7587
+ width: sz.w,
7588
+ fontSize: fs,
7589
+ fontName: face,
7590
+ fontColor: item.fontColor ?? finfo.fontcolor,
7591
+ fontFlags: flags
7592
+ });
7593
+ x += sz.w;
7594
+ }
7595
+ return lines;
7596
+ }
7597
+ function placeTextRuns(runs, box, finfo, measurer) {
7598
+ if (runsAreSimple(runs, finfo)) {
7599
+ return placeSimpleRuns(runs, box, finfo, measurer);
7600
+ }
7601
+ return placeComplexRuns(runs, box, finfo, measurer);
7602
+ }
7603
+ function placeSimpleRuns(runs, box, finfo, measurer) {
7604
+ const centerX = (box.ll.x + box.ur.x) / 2;
7605
+ const lines = [];
7606
+ let baseline = box.ur.y;
7607
+ for (let i = 0; i < runs.length; i++) {
7608
+ const run = runs[i];
7609
+ const ascent = run.maxLayout > 0 ? run.maxLayout : freetypeAscent(run.fontSize, finfo.fontname);
7610
+ baseline -= i === 0 ? ascent : run.height;
7611
+ lines.push(...placeRunItems(run, runLeftX(run, box, centerX), baseline, finfo, measurer));
7612
+ }
7613
+ return lines;
7614
+ }
7615
+ function placeComplexRuns(runs, box, finfo, measurer) {
7616
+ const centerX = (box.ll.x + box.ur.x) / 2;
7617
+ const lines = [];
7618
+ let curbline = 0;
7619
+ let ysize = 0;
7620
+ for (let i = 0; i < runs.length; i++) {
7621
+ const run = runs[i];
7622
+ const lfsize = i === 0 ? run.fontSize - run.maxOffset : run.fontSize + ysize - curbline - run.maxOffset;
7623
+ curbline += lfsize;
7624
+ ysize += run.fontSize;
7625
+ const baseline = box.ur.y - curbline;
7626
+ for (const pl of placeRunItems(run, runLeftX(run, box, centerX), baseline, finfo, measurer)) {
7627
+ pl.yoffsetCenterline = 1;
7628
+ lines.push(pl);
7629
+ }
7630
+ }
7631
+ return lines;
7632
+ }
7633
+
7374
7634
  // src/common/htmltable-fontinfo.ts
7375
7635
  var SIZE_SAVEF = { fontsize: 0 };
7376
7636
  var EMIT_SAVEF = { fontsize: 0 };
@@ -7432,87 +7692,33 @@ var findCol = (ps, row, startCol, colspan, rowspan) => {
7432
7692
  return col;
7433
7693
  };
7434
7694
  var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
7435
- var itemFont = (item, env) => ({
7436
- fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
7437
- face: item.fontFace !== void 0 ? item.fontFace : env.fontname
7438
- });
7439
- var measureItem = (item, measurer, env) => {
7440
- const { fs, face } = itemFont(item, env);
7441
- const flags = item.bold === true || item.italic === true ? { bold: item.bold === true, italic: item.italic === true } : void 0;
7442
- return measurer.measure(item.text ?? "", face, fs, flags);
7443
- };
7444
- var splitSizedLines = (texts, measurer, env) => {
7445
- const lines = [];
7446
- let cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
7447
- const accumulate = (item) => {
7448
- const sz = measureItem(item, measurer, env);
7449
- cur.items.push(item);
7450
- cur.width += sz.w;
7451
- cur.mxysize = Math.max(cur.mxysize, sz.h);
7452
- cur.mxfsize = Math.max(cur.mxfsize, itemFont(item, env).fs);
7453
- };
7454
- const flush = (br) => {
7455
- if (cur.items.length === 0 && br !== void 0) {
7456
- const { br: _b, brAlign: _a, ...fontProps } = br;
7457
- accumulate({ text: "", ...fontProps });
7458
- }
7459
- lines.push(cur);
7460
- cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
7461
- };
7462
- for (const txt of texts) {
7463
- for (const item of txt.items) {
7464
- if (item.br) {
7465
- flush(item);
7466
- continue;
7467
- }
7468
- if (item.text === void 0) continue;
7469
- accumulate(item);
7470
- }
7471
- if (cur.items.length > 0) flush();
7472
- }
7473
- return lines;
7474
- };
7475
- var itemHasFlags = (i) => i.bold === true || i.italic === true || i.underline === true || i.strikethrough === true || i.overline === true || i.subscript === true || i.superscript === true;
7476
- var htmlTextIsSimple = (lines, env) => {
7477
- let prevFs = -1;
7478
- let prevFace = null;
7479
- for (const ln of lines) {
7480
- const item = ln.items[0];
7481
- if (ln.items.length > 1 || itemHasFlags(item)) return false;
7482
- const { fs, face } = itemFont(item, env);
7483
- if (prevFs < 0) prevFs = fs;
7484
- else if (fs !== prevFs) return false;
7485
- if (prevFace === null) prevFace = face;
7486
- else if (face !== prevFace) return false;
7487
- }
7488
- return true;
7489
- };
7490
7695
  var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
7491
- const lines = splitSizedLines(texts, measurer, env);
7492
- const simple = htmlTextIsSimple(lines, env);
7696
+ const lines = buildLineRuns(texts, env, measurer);
7697
+ const simple = runsAreSimple(lines, env);
7493
7698
  let w = 0;
7494
7699
  let h = 0;
7495
7700
  for (const ln of lines) {
7496
7701
  w = Math.max(w, ln.width);
7497
- const lsize = simple ? ln.mxysize : ln.mxfsize;
7702
+ const lsize = simple ? ln.height : ln.fontSize;
7498
7703
  h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
7499
7704
  }
7500
- if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].mxysize : DEFAULT_FONTSIZE;
7705
+ if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].height : DEFAULT_FONTSIZE;
7501
7706
  return { w, h };
7502
7707
  };
7503
- var missingImages = /* @__PURE__ */ new WeakSet();
7708
+ var missingImages = { set: /* @__PURE__ */ new WeakSet() };
7504
7709
  var sizeHtmlImg = (img, { imageSizer, stderr }) => {
7505
- if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
7710
+ if (img.width !== void 0 && img.height !== void 0) return missingImages.set.has(img) ? 1 : 0;
7506
7711
  const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
7507
7712
  if (sz !== null) {
7508
7713
  img.width = sz.w;
7509
7714
  img.height = sz.h;
7510
7715
  return 0;
7511
7716
  }
7717
+ if (!imageIsSupplied(img.src, imageSizer)) agerrLine(stderr, `Warning: ${imageOpenWarning(img.src)}`);
7512
7718
  agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
7513
7719
  img.width = 0;
7514
7720
  img.height = 0;
7515
- missingImages.add(img);
7721
+ missingImages.set.add(img);
7516
7722
  return 1;
7517
7723
  };
7518
7724
  var sizeContentItem = (item, measurer, env) => {
@@ -7551,7 +7757,11 @@ var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
7551
7757
  var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
7552
7758
  var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
7553
7759
  var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
7554
- var sizeWarned = /* @__PURE__ */ new WeakSet();
7760
+ var sizeWarned = { set: /* @__PURE__ */ new WeakSet() };
7761
+ registerRenderState(() => {
7762
+ missingImages.set = /* @__PURE__ */ new WeakSet();
7763
+ sizeWarned.set = /* @__PURE__ */ new WeakSet();
7764
+ });
7555
7765
  var fixedCellCheck = (cell2, sz, warn, out) => {
7556
7766
  if (!cell2.fixedsize) return { rv: 0, zero: false };
7557
7767
  if (cell2.width && cell2.height) {
@@ -7573,8 +7783,8 @@ var getCellSize = (cell2, tbl, measurer, env) => {
7573
7783
  }
7574
7784
  let szx = cw + margin;
7575
7785
  let szy = ch + margin;
7576
- const warn = !sizeWarned.has(cell2);
7577
- sizeWarned.add(cell2);
7786
+ const warn = !sizeWarned.set.has(cell2);
7787
+ sizeWarned.set.add(cell2);
7578
7788
  const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
7579
7789
  rv |= fixed.rv;
7580
7790
  if (fixed.zero) {
@@ -7670,8 +7880,8 @@ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
7670
7880
  return { entries, widths, heights, spacing, border: border2, rv };
7671
7881
  };
7672
7882
  var warnFixedTable = (tbl, dims, out) => {
7673
- const warn = !sizeWarned.has(tbl);
7674
- sizeWarned.add(tbl);
7883
+ const warn = !sizeWarned.set.has(tbl);
7884
+ sizeWarned.set.add(tbl);
7675
7885
  if (tbl.fixedsize !== true) return 0;
7676
7886
  if (tbl.width && tbl.height) {
7677
7887
  if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
@@ -7728,173 +7938,6 @@ var INIT_DELTA = 10;
7728
7938
  var LOOP_TRIES = 15;
7729
7939
  var ROUTESPL_FUDGE = 1e-4;
7730
7940
 
7731
- // src/common/emit-types.ts
7732
- var PS2INCH = 1 / 72;
7733
- var HTML_BF = 1 << 0;
7734
- var HTML_IF = 1 << 1;
7735
- var HTML_UL = 1 << 2;
7736
- var HTML_SUP = 1 << 3;
7737
- var HTML_SUB = 1 << 4;
7738
- var HTML_S = 1 << 5;
7739
- var HTML_OL = 1 << 6;
7740
-
7741
- // src/common/htmltable-pos-runs.ts
7742
- function itemFontFlags(item) {
7743
- let f = 0;
7744
- if (item.bold) f |= HTML_BF;
7745
- if (item.italic) f |= HTML_IF;
7746
- if (item.underline) f |= HTML_UL;
7747
- if (item.superscript) f |= HTML_SUP;
7748
- if (item.subscript) f |= HTML_SUB;
7749
- if (item.strikethrough) f |= HTML_S;
7750
- if (item.overline) f |= HTML_OL;
7751
- return f;
7752
- }
7753
- function itemFace(item, finfo) {
7754
- return {
7755
- fs: item.fontSize !== void 0 ? item.fontSize : finfo.fontsize,
7756
- face: item.fontFace !== void 0 ? item.fontFace : finfo.fontname
7757
- };
7758
- }
7759
- function measureItem2(item, finfo, measurer) {
7760
- if (item.text === void 0) return null;
7761
- const { fs, face } = itemFace(item, finfo);
7762
- const flags = itemFontFlags(item);
7763
- const sz = measurer.measure(
7764
- item.text,
7765
- face,
7766
- fs,
7767
- { bold: !!(flags & HTML_BF), italic: !!(flags & HTML_IF) }
7768
- );
7769
- return { w: sz.w, h: sz.h, fs, yoffsetCenterline: sz.yoffsetCenterline, yoffsetLayout: sz.yoffsetLayout };
7770
- }
7771
- function newRun() {
7772
- return { items: [], width: 0, fontSize: 0, height: 0, maxOffset: 0, maxLayout: 0 };
7773
- }
7774
- function runLeftX(run, box, centerX) {
7775
- if (run.just === "left") return box.ll.x;
7776
- if (run.just === "right") return box.ur.x - run.width;
7777
- return centerX - run.width / 2;
7778
- }
7779
- function accumulateItem(cur, item, m) {
7780
- cur.items.push(item);
7781
- cur.width += m.w;
7782
- cur.fontSize = Math.max(cur.fontSize, m.fs);
7783
- cur.height = Math.max(cur.height, m.h);
7784
- cur.maxOffset = Math.max(cur.maxOffset, m.yoffsetCenterline ?? 0.05 * m.fs);
7785
- cur.maxLayout = Math.max(cur.maxLayout, m.yoffsetLayout ?? 0);
7786
- }
7787
- function buildLineRuns(texts, finfo, measurer) {
7788
- const runs = [];
7789
- let cur = newRun();
7790
- const flush = (br) => {
7791
- if (cur.items.length === 0 && br !== void 0) {
7792
- const { br: _b, brAlign: _a, ...fontProps } = br;
7793
- const empty = { text: "", ...fontProps };
7794
- const m = measureItem2(empty, finfo, measurer);
7795
- if (m !== null) accumulateItem(cur, empty, m);
7796
- }
7797
- cur.just = br?.brAlign;
7798
- runs.push(cur);
7799
- cur = newRun();
7800
- };
7801
- for (const txt of texts) {
7802
- for (const item of txt.items) {
7803
- if (item.br) {
7804
- flush(item);
7805
- continue;
7806
- }
7807
- const m = measureItem2(item, finfo, measurer);
7808
- if (m !== null) accumulateItem(cur, item, m);
7809
- }
7810
- if (cur.items.length > 0) flush();
7811
- }
7812
- return runs;
7813
- }
7814
- function runSimpleKey(run, finfo) {
7815
- if (run.items.length > 1) return null;
7816
- const item = run.items[0];
7817
- if (item === void 0) return void 0;
7818
- if (itemFontFlags(item) !== 0) return null;
7819
- return itemFace(item, finfo);
7820
- }
7821
- function runsAreSimple(runs, finfo) {
7822
- let prevFs = -1;
7823
- let prevFace = null;
7824
- for (const run of runs) {
7825
- const key = runSimpleKey(run, finfo);
7826
- if (key === null) return false;
7827
- if (key === void 0) continue;
7828
- if (prevFs < 0) prevFs = key.fs;
7829
- else if (key.fs !== prevFs) return false;
7830
- if (prevFace === null) prevFace = key.face;
7831
- else if (key.face !== prevFace) return false;
7832
- }
7833
- return true;
7834
- }
7835
- function placeRunItems(run, startX, baseline, finfo, measurer) {
7836
- const lines = [];
7837
- let x = startX;
7838
- for (const item of run.items) {
7839
- const { fs, face } = itemFace(item, finfo);
7840
- const flags = itemFontFlags(item);
7841
- const sz = measurer.measure(
7842
- item.text,
7843
- face,
7844
- fs,
7845
- { bold: !!(flags & HTML_BF), italic: !!(flags & HTML_IF) }
7846
- );
7847
- lines.push({
7848
- text: item.text,
7849
- x,
7850
- baseline,
7851
- width: sz.w,
7852
- fontSize: fs,
7853
- fontName: face,
7854
- fontColor: item.fontColor ?? finfo.fontcolor,
7855
- fontFlags: flags
7856
- });
7857
- x += sz.w;
7858
- }
7859
- return lines;
7860
- }
7861
- function placeTextRuns(runs, box, finfo, measurer) {
7862
- if (runsAreSimple(runs, finfo)) {
7863
- return placeSimpleRuns(runs, box, finfo, measurer);
7864
- }
7865
- return placeComplexRuns(runs, box, finfo, measurer);
7866
- }
7867
- function placeSimpleRuns(runs, box, finfo, measurer) {
7868
- const centerX = (box.ll.x + box.ur.x) / 2;
7869
- const lines = [];
7870
- let baseline = box.ur.y;
7871
- for (let i = 0; i < runs.length; i++) {
7872
- const run = runs[i];
7873
- const ascent = run.maxLayout > 0 ? run.maxLayout : freetypeAscent(run.fontSize, finfo.fontname);
7874
- baseline -= i === 0 ? ascent : run.height;
7875
- lines.push(...placeRunItems(run, runLeftX(run, box, centerX), baseline, finfo, measurer));
7876
- }
7877
- return lines;
7878
- }
7879
- function placeComplexRuns(runs, box, finfo, measurer) {
7880
- const centerX = (box.ll.x + box.ur.x) / 2;
7881
- const lines = [];
7882
- let curbline = 0;
7883
- let ysize = 0;
7884
- for (let i = 0; i < runs.length; i++) {
7885
- const run = runs[i];
7886
- const lfsize = i === 0 ? run.fontSize - run.maxOffset : run.fontSize + ysize - curbline - run.maxOffset;
7887
- curbline += lfsize;
7888
- ysize += run.fontSize;
7889
- const baseline = box.ur.y - curbline;
7890
- for (const pl of placeRunItems(run, runLeftX(run, box, centerX), baseline, finfo, measurer)) {
7891
- pl.yoffsetCenterline = 1;
7892
- lines.push(pl);
7893
- }
7894
- }
7895
- return lines;
7896
- }
7897
-
7898
7941
  // src/common/htmltable-pos.ts
7899
7942
  function alignContentBox(box, cell2, w, h) {
7900
7943
  const out = { ll: { ...box.ll }, ur: { ...box.ur } };
@@ -8196,6 +8239,20 @@ function htmlTextLabel(text, finfo, placed, dim) {
8196
8239
  };
8197
8240
  }
8198
8241
 
8242
+ // src/model/lazy-attrs.ts
8243
+ var SharedEmptyAttrs = class extends Map {
8244
+ set(key, _value) {
8245
+ throw new Error(`attrs.set("${key}") on a shared empty map; use ownAttrs()`);
8246
+ }
8247
+ delete(key) {
8248
+ throw new Error(`attrs.delete("${key}") on a shared empty map; use ownAttrs()`);
8249
+ }
8250
+ clear() {
8251
+ throw new Error("attrs.clear() on a shared empty map; use ownAttrs()");
8252
+ }
8253
+ };
8254
+ var EMPTY_ATTRS = new SharedEmptyAttrs();
8255
+
8199
8256
  // src/model/algData.ts
8200
8257
  var THETA_UNSET = 10;
8201
8258
 
@@ -8298,10 +8355,10 @@ var Node = class {
8298
8355
  */
8299
8356
  nodeDefaultsSnapshot;
8300
8357
  /** @see lib/cgraph/node.c:agnode */
8301
- constructor(id, name, root) {
8358
+ constructor(id, name, root, lazyAttrs = false) {
8302
8359
  this.id = id;
8303
8360
  this.name = name;
8304
- this.attrs = /* @__PURE__ */ new Map();
8361
+ this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
8305
8362
  this.info = makeNodeInfo();
8306
8363
  this.root = root;
8307
8364
  }
@@ -8471,12 +8528,12 @@ var Edge = class _Edge {
8471
8528
  */
8472
8529
  info;
8473
8530
  /** @see lib/cgraph/edge.c:agedge */
8474
- constructor(tail, head, name) {
8531
+ constructor(tail, head, name, lazyAttrs = false) {
8475
8532
  this.seq = _Edge._nextSeq++;
8476
8533
  this.tail = tail;
8477
8534
  this.head = head;
8478
8535
  this.name = name;
8479
- this.attrs = /* @__PURE__ */ new Map();
8536
+ this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
8480
8537
  this.info = makeEdgeInfo(makePort(), makePort());
8481
8538
  }
8482
8539
  };
@@ -8728,12 +8785,17 @@ var DEFAULT_FONTNAME = "Times-Roman";
8728
8785
  var DEFAULT_COLOR = "black";
8729
8786
  function getPenColor(obj) {
8730
8787
  if (obj === void 0) return void 0;
8731
- const pc = obj.attrs.get("pencolor");
8788
+ const pc = aggetObj(obj, "pencolor");
8732
8789
  if (pc !== void 0 && pc !== "") return pc;
8733
- const c = obj.attrs.get("color");
8790
+ const c = aggetObj(obj, "color");
8734
8791
  if (c !== void 0 && c !== "") return c;
8735
8792
  return void 0;
8736
8793
  }
8794
+ function aggetObj(obj, key) {
8795
+ if (obj instanceof Node) return nodeAttr(obj, obj.root, key);
8796
+ if (obj instanceof Graph) return graphAttrInherited(obj, key);
8797
+ return obj.attrs.get(key);
8798
+ }
8737
8799
  function rootOf(obj) {
8738
8800
  return obj instanceof Edge ? obj.tail.root : obj.root;
8739
8801
  }
@@ -8900,7 +8962,7 @@ function copyVirtualEdgeInfo(e, orig) {
8900
8962
  e.seq = orig.seq;
8901
8963
  }
8902
8964
  function newVirtualEdge(u, v, orig) {
8903
- const e = new Edge(u, v, "");
8965
+ const e = new Edge(u, v, "", true);
8904
8966
  e.info.edge_type = VIRTUAL;
8905
8967
  if (orig) {
8906
8968
  copyVirtualEdgeInfo(e, orig);
@@ -9001,7 +9063,7 @@ function removeFromRank(g, n) {
9001
9063
  }
9002
9064
  }
9003
9065
  function virtualNode(g) {
9004
- const n = new Node(0, "", g.root);
9066
+ const n = new Node(0, "", g.root, true);
9005
9067
  n.info.node_type = VIRTUAL;
9006
9068
  n.info.lw = 1;
9007
9069
  n.info.rw = 1;
@@ -9313,10 +9375,10 @@ var ARROW_EPSILON = 1e-4;
9313
9375
  var vsub = (p, q) => ({ x: p.x - q.x, y: p.y - q.y });
9314
9376
  var vadd = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
9315
9377
  var vscale = (c, p) => ({ x: c * p.x, y: c * p.y });
9316
- var negUnit = (u, dist4) => {
9378
+ var negUnit = (u, dist5) => {
9317
9379
  if (u.x === 0 && u.y === 0) return { x: 0, y: 0 };
9318
9380
  const h = Math.hypot(u.x, u.y);
9319
- return { x: dist4 * (-u.x / h), y: dist4 * (-u.y / h) };
9381
+ return { x: dist5 * (-u.x / h), y: dist5 * (-u.y / h) };
9320
9382
  };
9321
9383
  var backwardDelta = (u, penwidth) => negUnit(u, penwidth / 2);
9322
9384
  function axialProjection(phiSrc, from, to, sign2) {
@@ -9899,9 +9961,9 @@ function makeEllipseInsideFn(rx, ry, penwidth = DEFAULT_NODEPENWIDTH) {
9899
9961
  return (lx, ly) => lx * lx / (erx * erx) + ly * ly / (ery * ery) < 1;
9900
9962
  }
9901
9963
  function tailArrowEndClip(path4, tailTip, elen) {
9902
- if (elen <= 0) return path4;
9903
- const inside = (lx, ly) => Math.hypot(lx, ly) <= elen;
9904
- return bezierClipNode(path4, tailTip.x, tailTip.y, inside, true);
9964
+ const sp = [path4[3], path4[2], path4[1], tailTip];
9965
+ const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, tailTip) <= elen, false) : sp;
9966
+ return [clipped[3], clipped[2], clipped[1], clipped[0]];
9905
9967
  }
9906
9968
 
9907
9969
  // src/layout/dot/edge-route-geom.ts
@@ -11598,11 +11660,12 @@ function emitHtmlLine(line, pos, renderer, job) {
11598
11660
  }
11599
11661
  function bgFillPaint(ctx) {
11600
11662
  const penWidth = htmlFillPenWidth();
11601
- const spec = parseGradientSpec(ctx.bgcolor);
11663
+ const spec = findHtmlStopColor(ctx.bgcolor);
11602
11664
  if (spec === null) return { fill: ctx.bgcolor, penWidth };
11603
11665
  return {
11604
- fill: spec[0],
11605
- stop: spec[1],
11666
+ fill: spec.fill,
11667
+ stop: spec.stop ?? "black",
11668
+ gradientFrac: spec.frac,
11606
11669
  gradientAngle: ctx.gradientangle ?? 0,
11607
11670
  radial: htmlStyle(ctx.style).radial,
11608
11671
  penWidth
@@ -12032,7 +12095,7 @@ function transformUnitVertex(R2, g, c, bb) {
12032
12095
  const r = libmHypot(D.x, D.y);
12033
12096
  return { x: r * Math.cos(alpha) * bb.x, y: r * Math.sin(alpha) * bb.y };
12034
12097
  }
12035
- function polygonVertices(bb, g, isBox3) {
12098
+ function polygonVertices(bb, g, isBox4) {
12036
12099
  const sectorangle = 2 * Math.PI / g.sides;
12037
12100
  const sidelength = Math.sin(sectorangle / 2);
12038
12101
  const c = {
@@ -12050,7 +12113,7 @@ function polygonVertices(bb, g, isBox3) {
12050
12113
  R2.y = fma(sidelength, Math.sin(angle), R2.y);
12051
12114
  const P = transformUnitVertex(R2, g, c, bb);
12052
12115
  verts.push(P);
12053
- if (isBox3) {
12116
+ if (isBox4) {
12054
12117
  verts.push({ x: -P.x, y: P.y }, { x: -P.x, y: -P.y }, { x: P.x, y: -P.y });
12055
12118
  break;
12056
12119
  }
@@ -12141,14 +12204,14 @@ function starVertexGen(bb) {
12141
12204
  }
12142
12205
  return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
12143
12206
  }
12144
- function polygonBB(bb, minSize, p, sides2, isBox3) {
12207
+ function polygonBB(bb, minSize, p, sides2, isBox4) {
12145
12208
  const geom = {
12146
12209
  sides: sides2,
12147
12210
  orientation: p.orientation,
12148
12211
  distortion: p.distortion,
12149
12212
  skew: p.skew
12150
12213
  };
12151
- const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox3);
12214
+ const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox4);
12152
12215
  const xmax2 = 2 * xmax;
12153
12216
  const ymax2 = 2 * ymax;
12154
12217
  const nbb = { x: Math.max(minSize.x, xmax2), y: Math.max(minSize.y, ymax2) };
@@ -12160,7 +12223,7 @@ function polygonBB(bb, minSize, p, sides2, isBox3) {
12160
12223
  v.x *= scalex;
12161
12224
  v.y *= scaley;
12162
12225
  }
12163
- return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
12226
+ return { ...polygonPeripheryBB(verts, isBox4 ? 4 : sides2, p, nbb), base: nbb };
12164
12227
  }
12165
12228
  function gvNodesize(widthPts, heightPts, flip) {
12166
12229
  if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
@@ -12185,9 +12248,9 @@ function applySizeConstraints(p, bb0, width0, height0) {
12185
12248
  function polySize(p) {
12186
12249
  const init = initialSizePts(p);
12187
12250
  const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
12188
- const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
12251
+ const { sides: sides2, isBox: isBox4 } = effectiveShape(p);
12189
12252
  let bb = { x: dimen.x, y: dimen.y };
12190
- if (isBox3) {
12253
+ if (isBox4) {
12191
12254
  } else if (p.optionShape === STAR) {
12192
12255
  bb = starSize(bb);
12193
12256
  } else if (p.optionShape === CYLINDER) {
@@ -12199,16 +12262,16 @@ function polySize(p) {
12199
12262
  const c = applySizeConstraints(p, bb, init.width, init.height);
12200
12263
  const penwidth = p.penwidth ?? 1;
12201
12264
  const hasOutline = penwidth > 0 || p.peripheries < 1;
12202
- 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);
12265
+ 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);
12203
12266
  const result = assembleResult(p, dimen, grown, c.fixedshape);
12204
- return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
12267
+ return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox4, c.fixedshape) };
12205
12268
  }
12206
- function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
12269
+ function labelSpace(p, dimen, bb, minBb, isBox4, fixedshape) {
12207
12270
  const spacex = dimen.x - p.labelDimen.x;
12208
12271
  let spaceX;
12209
12272
  if (p.nojustify) {
12210
12273
  spaceX = dimen.x - spacex;
12211
- } else if (isBox3) {
12274
+ } else if (isBox4) {
12212
12275
  spaceX = Math.max(dimen.x, bb.x) - spacex;
12213
12276
  } else if (dimen.y < bb.y) {
12214
12277
  spaceX = Math.max(dimen.x, bb.x * Math.sqrt(1 - dimen.y * dimen.y / (bb.y * bb.y))) - spacex;
@@ -12221,8 +12284,8 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
12221
12284
  function effectiveShape(p) {
12222
12285
  let sides2 = p.sides;
12223
12286
  if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
12224
- const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
12225
- return { sides: sides2, isBox: isBox3 };
12287
+ const isBox4 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
12288
+ return { sides: sides2, isBox: isBox4 };
12226
12289
  }
12227
12290
  function labelValign(p) {
12228
12291
  const ll = p.labelloc?.[0];
@@ -12634,12 +12697,6 @@ function drawRecordBox(job, n, ll, ur, filled) {
12634
12697
  var DEFAULT_LW = 27;
12635
12698
  var DEFAULT_RW = 27;
12636
12699
  var DEFAULT_HT = 36;
12637
- function nodeAttr(n, g, key) {
12638
- const own = n.attrs.get(key);
12639
- if (own !== void 0) return own;
12640
- if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
12641
- return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
12642
- }
12643
12700
  function readFontAttrs(n, g) {
12644
12701
  return {
12645
12702
  fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
@@ -12664,17 +12721,27 @@ function buildNodeLabel(n, g, measurer) {
12664
12721
  const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
12665
12722
  n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
12666
12723
  }
12724
+ function warnMissingImage(n, g, shapefile) {
12725
+ if (shapefile !== void 0 && shapefile !== "" && nodeAttr(n, g, "shape") !== "epsf") return;
12726
+ const image = nodeAttr(n, g, "image");
12727
+ if (image === void 0 || image === "") return;
12728
+ const gvc = g.root.info.gvc;
12729
+ if (imageIsSupplied(image, gvc?.imageSizer, gvc?.imageResolver)) return;
12730
+ agwarningf(imageOpenWarning(image));
12731
+ agwarningf(`No or improper image="${image}" for node "${n.name}"`);
12732
+ }
12667
12733
  function polyInit(n, g, measurer) {
12668
12734
  const shapeName2 = nodeAttr(n, g, "shape") ?? "ellipse";
12669
12735
  const shapefile = nodeAttr(n, g, "shapefile");
12670
12736
  n.info.shape = bindShape(shapeName2, shapefile);
12671
12737
  if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
12672
- agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`, "error");
12738
+ agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`);
12673
12739
  }
12674
12740
  if (n.info.shape.kind === 2 /* SH_RECORD */) {
12675
12741
  if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
12676
12742
  return;
12677
12743
  }
12744
+ warnMissingImage(n, g, shapefile);
12678
12745
  buildNodeLabel(n, g, measurer);
12679
12746
  if (n.info.shape_info !== void 0) return;
12680
12747
  const polyDesc = n.info.shape.polygon;
@@ -12682,6 +12749,16 @@ function polyInit(n, g, measurer) {
12682
12749
  }
12683
12750
 
12684
12751
  // src/common/multicolor.ts
12752
+ var parseSegsState = { warned: false };
12753
+ registerRenderState(() => {
12754
+ parseSegsState.warned = false;
12755
+ });
12756
+ function claimWarned() {
12757
+ if (parseSegsState.warned) return false;
12758
+ parseSegsState.warned = true;
12759
+ return true;
12760
+ }
12761
+ var claimNever = () => false;
12685
12762
  var EPS = 1e-5;
12686
12763
  function aeq0(x) {
12687
12764
  return x < EPS && x > -EPS;
@@ -12695,17 +12772,14 @@ function getSegLen(token) {
12695
12772
  const parsed = parseFloat(rest);
12696
12773
  return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
12697
12774
  }
12698
- function appendSeg(token, left2, segs, warnedExceeded) {
12775
+ function appendSeg(token, left2, segs, claim) {
12699
12776
  const { color, v } = getSegLen(token);
12700
12777
  if (v < 0) return null;
12701
12778
  let t = v;
12702
12779
  let rval = 0;
12703
12780
  const del = t - left2;
12704
12781
  if (del > 0) {
12705
- if (!aeq0(del) && !warnedExceeded.v) {
12706
- warnedExceeded.v = true;
12707
- rval = 3;
12708
- }
12782
+ if (!aeq0(del) && claim()) rval = 3;
12709
12783
  t = left2;
12710
12784
  }
12711
12785
  left2 -= t;
@@ -12729,19 +12803,13 @@ function trimTrailing(segs) {
12729
12803
  segs.pop();
12730
12804
  }
12731
12805
  }
12732
- function parseSegs(colorlist) {
12806
+ function scanSegs(colorlist, claim) {
12733
12807
  const segs = [];
12734
12808
  let left2 = 1;
12735
12809
  let rval = 0;
12736
- let badFloatCount = 0;
12737
- const warnedExceeded = { v: false };
12738
12810
  for (const token of colorlist.split(":")) {
12739
- const result = appendSeg(token, left2, segs, warnedExceeded);
12740
- if (result === null) {
12741
- const errCode = badFloatCount === 0 ? 2 : 1;
12742
- badFloatCount++;
12743
- return { segs: [], error: errCode };
12744
- }
12811
+ const result = appendSeg(token, left2, segs, claim);
12812
+ if (result === null) return { segs: [], error: claim() ? 2 : 1 };
12745
12813
  if (result.rval === 3) rval = 3;
12746
12814
  left2 = result.left;
12747
12815
  if (aeq0(left2)) {
@@ -12753,6 +12821,91 @@ function parseSegs(colorlist) {
12753
12821
  trimTrailing(segs);
12754
12822
  return { segs, error: rval };
12755
12823
  }
12824
+ function parseSegs(colorlist, context) {
12825
+ const result = scanSegs(colorlist, claimWarned);
12826
+ if (result.error === 3) {
12827
+ const tail = context === void 0 ? "" : context();
12828
+ agwarningf(`Total size > 1 in "${colorlist}" color spec ${tail}`);
12829
+ } else if (result.error === 2) {
12830
+ agerrorf(`Illegal value in "${colorlist}" color attribute; float expected after ';'`);
12831
+ if (context !== void 0) agerr("prev", context());
12832
+ }
12833
+ return result;
12834
+ }
12835
+ function parseSegsSilent(colorlist) {
12836
+ return scanSegs(colorlist, claimNever);
12837
+ }
12838
+ function edgeSegsContext(e) {
12839
+ return () => {
12840
+ const directed = !e.tail.root.kind.endsWith("undirected");
12841
+ return `in edge ${e.tail.name}${directed ? " -> " : " -- "}${e.head.name}`;
12842
+ };
12843
+ }
12844
+
12845
+ // src/gvc/gvrender-set-style.ts
12846
+ var SUPPORTED_STYLES = /* @__PURE__ */ new Set([
12847
+ "solid",
12848
+ "dashed",
12849
+ "dotted",
12850
+ "invis",
12851
+ "invisible",
12852
+ "bold",
12853
+ "setlinewidth",
12854
+ "filled",
12855
+ "unfilled",
12856
+ "tapered"
12857
+ ]);
12858
+ var BOX_ORIENTATION_TOLERANCE = 0.5;
12859
+ var BOX_ORIENTATION_STEP = 90;
12860
+ var BOX_SIDES = 4;
12861
+ var ELLIPSE_MAX_SIDES = 2;
12862
+ function styleName(token) {
12863
+ const paren = token.indexOf("(");
12864
+ return paren < 0 ? token : token.slice(0, paren);
12865
+ }
12866
+ function gvrenderSetStyle(styles) {
12867
+ if (styles === null) return;
12868
+ for (const token of styles) {
12869
+ const name = styleName(token);
12870
+ if (!SUPPORTED_STYLES.has(name)) {
12871
+ agwarningf(`gvrender_set_style: unsupported style ${name} - ignoring`);
12872
+ }
12873
+ }
12874
+ }
12875
+ function isBox(p) {
12876
+ if (p === null) return false;
12877
+ return p.sides === BOX_SIDES && Math.abs(p.orientation % BOX_ORIENTATION_STEP) < BOX_ORIENTATION_TOLERANCE && p.distortion === 0 && p.skew === 0;
12878
+ }
12879
+ function isEllipse(p) {
12880
+ return p !== null && p.sides <= ELLIPSE_MAX_SIDES;
12881
+ }
12882
+ function checkStyleTokens(styles, shape) {
12883
+ return styles.filter((p) => {
12884
+ if (p === "rounded" || p === "diagonals" || p === "radial") return false;
12885
+ if (p === "striped") return !isBox(shape);
12886
+ if (p === "wedged") return !isEllipse(shape);
12887
+ return true;
12888
+ });
12889
+ }
12890
+ function checkClusterStyleTokens(styles) {
12891
+ return styles.filter((p) => p !== "radial" && p !== "striped" && p !== "rounded");
12892
+ }
12893
+ function countChar(s, ch) {
12894
+ return [...s].filter((c) => c === ch).length;
12895
+ }
12896
+ function multicolorTaken(color) {
12897
+ if (countChar(color, ";") === 0 || countChar(color, ":") === 0) return false;
12898
+ const { error } = parseSegsSilent(color);
12899
+ return error !== 1 && error !== 2;
12900
+ }
12901
+ function edgeStyleResets(e, styles) {
12902
+ const spl = e.info.spl;
12903
+ if (spl === void 0 || spl.size <= 1 || styles.length === 0) return 0;
12904
+ const color = e.attrs.get("color") ?? "";
12905
+ const otherBranch = styles.includes("tapered") || countChar(color, ":") > 0;
12906
+ if (otherBranch && !multicolorTaken(color)) return 0;
12907
+ return spl.list.filter((bz) => bz.sflag !== 0 || bz.eflag !== 0).length;
12908
+ }
12756
12909
 
12757
12910
  // src/util/math.ts
12758
12911
  var INT32_MAX = 2147483647;
@@ -15735,11 +15888,11 @@ var SEG_EPS = 1e-5;
15735
15888
  function reportColorNames(names) {
15736
15889
  for (const name of names) resolveRenderColor(firstColor(name));
15737
15890
  }
15738
- function countChar(s, ch) {
15891
+ function countChar2(s, ch) {
15739
15892
  return s.split(ch).length - 1;
15740
15893
  }
15741
15894
  function multicolorNames(color, arrows) {
15742
- const { segs, error } = parseSegs(color);
15895
+ const { segs, error } = parseSegsSilent(color);
15743
15896
  if (error === 1 || error === 2) return null;
15744
15897
  const out = [];
15745
15898
  const front = segs[0]?.color ?? null;
@@ -15761,9 +15914,9 @@ function taperedNames(color, fillcolor, hasFill) {
15761
15914
  return hasFill ? [pen, fillcolor === "" ? DEFAULT_COLOR2 : fillcolor] : [pen];
15762
15915
  }
15763
15916
  function edgeGraphicsColors(spec) {
15764
- const numc = countChar(spec.color, ":");
15917
+ const numc = countChar2(spec.color, ":");
15765
15918
  let color = spec.color;
15766
- if (countChar(color, ";") > 0 && numc > 0) {
15919
+ if (countChar2(color, ";") > 0 && numc > 0) {
15767
15920
  const multi = multicolorNames(color, spec.arrows);
15768
15921
  if (multi !== null) return multi;
15769
15922
  color = DEFAULT_COLOR2;
@@ -15916,8 +16069,8 @@ function drawWedge(seg2, e, ctx) {
15916
16069
  ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
15917
16070
  return angle1;
15918
16071
  }
15919
- function wedgedEllipse(job, pf, clrs, renderer) {
15920
- const { segs, error } = parseSegs(clrs);
16072
+ function wedgedEllipse(job, pf, clrs, renderer, context) {
16073
+ const { segs, error } = parseSegs(clrs, context);
15921
16074
  if (error === 1 || error === 2) return error;
15922
16075
  const ctrX = (pf[0].x + pf[1].x) / 2;
15923
16076
  const ctrY = (pf[0].y + pf[1].y) / 2;
@@ -15949,8 +16102,8 @@ function drawBand(p, seg2, ctx) {
15949
16102
  ctx.renderer.polygon([...p], true, ctx.job);
15950
16103
  p[0].x = p[3].x = p[1].x;
15951
16104
  }
15952
- function stripedBox(job, pts, clrs, rotate, renderer) {
15953
- const { segs, error } = parseSegs(clrs);
16105
+ function stripedBox(job, pts, clrs, rotate, renderer, context) {
16106
+ const { segs, error } = parseSegs(clrs, context);
15954
16107
  if (error === 1 || error === 2) return error;
15955
16108
  const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
15956
16109
  const lastx = p[1].x;
@@ -16108,6 +16261,27 @@ function escapeXmlText(s) {
16108
16261
  return gvXmlEscape(s, FLAGS_TEXT);
16109
16262
  }
16110
16263
 
16264
+ // src/gvc/device-transform.ts
16265
+ function transformPoint(p, job) {
16266
+ if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
16267
+ return p;
16268
+ }
16269
+ const sx = job.zoom * job.devscale.x;
16270
+ const sy = job.zoom * job.devscale.y;
16271
+ const tx = job.translation.x;
16272
+ const ty = job.translation.y;
16273
+ return applyScale(p, tx, ty, sx, sy);
16274
+ }
16275
+ function applyScale(p, tx, ty, sx, sy) {
16276
+ const x = (p.x + tx) * sx;
16277
+ const y = (p.y + ty) * sy;
16278
+ return buildPoint(x, y);
16279
+ }
16280
+ function buildPoint(x, y) {
16281
+ const pt = { x, y };
16282
+ return pt;
16283
+ }
16284
+
16111
16285
  // src/gvc/device-cluster.ts
16112
16286
  function applyClusterGradient(obj, fill) {
16113
16287
  obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
@@ -16155,6 +16329,7 @@ function applyClusterObjState(sg, job) {
16155
16329
  const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
16156
16330
  if (job.obj === null) return false;
16157
16331
  const obj = job.obj;
16332
+ gvrenderSetStyle(checkClusterStyleTokens(styleTokens2(clusterStyle(sg))));
16158
16333
  return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
16159
16334
  const filled = applyClusterFill(obj, fillRes);
16160
16335
  applyClusterPenState(obj, sg);
@@ -16162,17 +16337,47 @@ function applyClusterObjState(sg, job) {
16162
16337
  return filled;
16163
16338
  });
16164
16339
  }
16165
- function stripedClusterColors(sg) {
16340
+ function isStripedCluster(sg) {
16341
+ const flags = parseStyleFlags(clusterStyle(sg));
16342
+ return flags.striped && !flags.rounded;
16343
+ }
16344
+ function stripedFillSpec(sg) {
16166
16345
  const flags = parseStyleFlags(clusterStyle(sg));
16167
- if (!flags.striped || flags.rounded) return [];
16168
16346
  const color = clusterAttr(sg, "color") ?? "";
16169
16347
  let fill = clusterAttr(sg, "fillcolor") || color;
16170
16348
  const bg = clusterAttr(sg, "bgcolor") ?? "";
16171
16349
  if ((!flags.filled || fill === "") && bg !== "") fill = bg;
16172
- const { segs, error } = parseSegs(fill === "" ? "lightgrey" : fill);
16350
+ return fill === "" ? "lightgrey" : fill;
16351
+ }
16352
+ function stripedClusterColors(sg) {
16353
+ if (!isStripedCluster(sg)) return [];
16354
+ const { segs, error } = parseSegs(stripedFillSpec(sg), () => `in cluster ${sg.name}`);
16173
16355
  if (error === 1 || error === 2) return [];
16174
16356
  return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
16175
16357
  }
16358
+ function renderStripedClusterBox(sg, renderer, job) {
16359
+ withColorScheme(clusterAttr(sg, "colorscheme"), () => {
16360
+ const { ll, ur } = sg.info.bb;
16361
+ const af = [
16362
+ { x: ll.x, y: ll.y },
16363
+ { x: ur.x, y: ll.y },
16364
+ { x: ur.x, y: ur.y },
16365
+ { x: ll.x, y: ur.y }
16366
+ ].map((p) => transformPoint(p, job));
16367
+ const obj = job.obj;
16368
+ const savedFill = obj?.fill;
16369
+ if (obj !== null && savedFill !== void 0) obj.fill = 1 /* Solid */;
16370
+ stripedBox(job, af, stripedFillSpec(sg), false, renderer, () => `in cluster ${sg.name}`);
16371
+ if (obj !== null && savedFill !== void 0) obj.fill = savedFill;
16372
+ const rawPts = [
16373
+ { x: ll.x, y: ll.y },
16374
+ { x: ll.x, y: ur.y },
16375
+ { x: ur.x, y: ur.y },
16376
+ { x: ur.x, y: ll.y }
16377
+ ];
16378
+ renderer.polygon(rawPts.map((p) => transformPoint(p, job)), false, job);
16379
+ });
16380
+ }
16176
16381
  function applyClusterFill(obj, fillRes) {
16177
16382
  if (fillRes.kind === "none") {
16178
16383
  obj.fill = 0 /* None */;
@@ -16238,7 +16443,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
16238
16443
  const pf = ring.map(
16239
16444
  (v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
16240
16445
  );
16241
- wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
16446
+ wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer, () => `in node ${ctx.nodeName}`);
16242
16447
  renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
16243
16448
  } else {
16244
16449
  renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
@@ -16247,7 +16452,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
16247
16452
  }
16248
16453
  function renderStripedRing(ring, coord, ctx) {
16249
16454
  const af = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job));
16250
- stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer);
16455
+ stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer, () => `in node ${ctx.nodeName}`);
16251
16456
  renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
16252
16457
  }
16253
16458
  function renderPolyRing(ring, coord, filled, j, ctx) {
@@ -16373,6 +16578,10 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
16373
16578
  function applyNodeStyle(obj, n, job) {
16374
16579
  const styleAttr = nodeAttr(n, n.root, "style");
16375
16580
  const colorAttr = nodeAttr(n, n.root, "color");
16581
+ if (!isPointNode(n)) {
16582
+ const shape = n.info.shape;
16583
+ gvrenderSetStyle(checkStyleTokens(styleTokens2(styleAttr), shape?.polygon ?? null));
16584
+ }
16376
16585
  const penwidth = nodeAttr(n, n.root, "penwidth");
16377
16586
  if (n.info.shape?.kind === 2 /* SH_RECORD */) {
16378
16587
  applyPenState(obj, styleAttr, colorAttr, penwidth);
@@ -16384,7 +16593,7 @@ function applyNodeStyle(obj, n, job) {
16384
16593
  }
16385
16594
  function prepareDrawPoly(poly, filled, obj) {
16386
16595
  if (poly.peripheries !== 0 || !filled) return poly;
16387
- obj.penColor = { type: "string", s: "transparent" };
16596
+ obj.penColor = resolveRenderColor("transparent");
16388
16597
  return { ...poly, peripheries: 1 };
16389
16598
  }
16390
16599
  function vertexScale(n, poly) {
@@ -16414,6 +16623,7 @@ function resolveNodeDrawCtx(job, n) {
16414
16623
  job,
16415
16624
  style: styleFlags,
16416
16625
  fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
16626
+ nodeName: n.name,
16417
16627
  ...specialCornerFlags(drawPoly.option, styleFlags)
16418
16628
  };
16419
16629
  return { poly: drawPoly, coord, filled, ringCtx };
@@ -17773,7 +17983,7 @@ function pruneForeignClusterNodes(par, clust) {
17773
17983
  }
17774
17984
  function markClusterNode(clust, n, g) {
17775
17985
  if ((n.info.ranktype ?? 0) !== 0) {
17776
- agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`, "error");
17986
+ agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`);
17777
17987
  agDeleteFromCluster(clust, n);
17778
17988
  return;
17779
17989
  }
@@ -18352,7 +18562,7 @@ function findCharset(g) {
18352
18562
  }
18353
18563
  if (p === "big-5" || p === "big5") return CHAR_BIG5;
18354
18564
  if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
18355
- agwarningf(`Unsupported charset "${raw}" - assuming utf-8`, "error");
18565
+ agwarningf(`Unsupported charset "${raw}" - assuming utf-8`);
18356
18566
  return CHAR_UTF8;
18357
18567
  }
18358
18568
  function maptoken(p, names, vals) {
@@ -18570,7 +18780,7 @@ function portToTbl(tbl, id) {
18570
18780
  }
18571
18781
 
18572
18782
  // src/common/compass-port.ts
18573
- function isBox(n) {
18783
+ function isBox2(n) {
18574
18784
  return n.info.shape?.polygon === P_BOX;
18575
18785
  }
18576
18786
  function gdRankdir(n) {
@@ -18761,7 +18971,7 @@ function compassPort(n, args, pp) {
18761
18971
  const { bp, compass, sides: sides2 } = args;
18762
18972
  const { b, p, defined: defBp } = compassBbox(n, bp);
18763
18973
  const dir = compassDirection(compass, b, p, sides2);
18764
- if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
18974
+ if (bp === null && !isBox2(n)) applyIctxt(n, dir, b, p);
18765
18975
  const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
18766
18976
  applyDir(pp, bp, dir, gdRankdir(n), defFinal);
18767
18977
  return dir.rv;
@@ -20043,7 +20253,7 @@ function emitParallelEdgePaths(e, job, colorList) {
20043
20253
  const spl = e.info.spl;
20044
20254
  const numc = (colorList.match(/:/g) ?? []).length;
20045
20255
  const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
20046
- const colors = parseSegs(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR3);
20256
+ const colors = parseSegsSilent(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR3);
20047
20257
  emitColorPasses(segData, colors, job);
20048
20258
  return {
20049
20259
  headColor: colors[0] ?? DEFAULT_COLOR3,
@@ -20875,25 +21085,14 @@ function walkNodesAndEdges(g, renderer, job, info) {
20875
21085
  }
20876
21086
  }
20877
21087
 
20878
- // src/gvc/device-transform.ts
20879
- function transformPoint(p, job) {
20880
- if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
20881
- return p;
20882
- }
20883
- const sx = job.zoom * job.devscale.x;
20884
- const sy = job.zoom * job.devscale.y;
20885
- const tx = job.translation.x;
20886
- const ty = job.translation.y;
20887
- return applyScale(p, tx, ty, sx, sy);
20888
- }
20889
- function applyScale(p, tx, ty, sx, sy) {
20890
- const x = (p.x + tx) * sx;
20891
- const y = (p.y + ty) * sy;
20892
- return buildPoint(x, y);
20893
- }
20894
- function buildPoint(x, y) {
20895
- const pt = { x, y };
20896
- return pt;
21088
+ // src/gvc/first-layer.ts
21089
+ var NATIVE_LANGNAME = /* @__PURE__ */ new Map([
21090
+ ["cmapx-np", "cmapx_np"],
21091
+ ["imap-np", "imap_np"]
21092
+ ]);
21093
+ function warnLayersUnsupported(format, numLayers, doesLayers) {
21094
+ if (numLayers <= 1 || doesLayers) return;
21095
+ agwarningf(`layers not supported in ${NATIVE_LANGNAME.get(format) ?? format} output`);
20897
21096
  }
20898
21097
 
20899
21098
  // src/gvc/device-labels.ts
@@ -21038,6 +21237,7 @@ function setEdgePen(e, job) {
21038
21237
  obj.pen = resolvePenType(flags);
21039
21238
  obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
21040
21239
  obj.rawStyle = styleTokens2(e.attrs.get("style"));
21240
+ if (e.info.spl !== void 0) gvrenderSetStyle(obj.rawStyle);
21041
21241
  }
21042
21242
  function renderEdge(e, renderer, job) {
21043
21243
  emitEdgeComments(e, renderer, job);
@@ -21053,6 +21253,8 @@ function renderEdge(e, renderer, job) {
21053
21253
  withColorScheme(e.attrs.get("colorscheme"), () => {
21054
21254
  renderer.beginEdge(e, job);
21055
21255
  reportEdgeColors(e);
21256
+ const styles = styleTokens2(e.attrs.get("style"));
21257
+ for (let i = edgeStyleResets(e, styles); i > 0; i--) gvrenderSetStyle(styles);
21056
21258
  reportEdgeLabelColors(e);
21057
21259
  renderer.endEdge(e, job);
21058
21260
  });
@@ -21066,6 +21268,10 @@ function renderGraphLabel(g, renderer, job) {
21066
21268
  }
21067
21269
  function renderClusterBox(sg, filled, renderer, job) {
21068
21270
  const { ll, ur } = sg.info.bb;
21271
+ if (isStripedCluster(sg)) {
21272
+ renderStripedClusterBox(sg, renderer, job);
21273
+ return;
21274
+ }
21069
21275
  if (parseStyleFlags(clusterStyle(sg)).rounded) {
21070
21276
  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 }];
21071
21277
  emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer, job });
@@ -21089,7 +21295,7 @@ function renderOneCluster(sg, renderer, job) {
21089
21295
  resolveObjAnchor(sg, labelTextOf2(sg.info.label), svgClusterId(sg, job), job.obj);
21090
21296
  }
21091
21297
  const anchored = beginAnchorIf(renderer, job);
21092
- if ((clusterPeripheries(sg) !== 0 || filled) && job.obj?.pen !== 0 /* None */) {
21298
+ if ((clusterPeripheries(sg) !== 0 || filled || isStripedCluster(sg)) && job.obj?.pen !== 0 /* None */) {
21093
21299
  renderClusterBox(sg, filled, renderer, job);
21094
21300
  }
21095
21301
  renderClusterLabel(sg, renderer, job);
@@ -21119,6 +21325,7 @@ function renderGraph(g, job, renderer) {
21119
21325
  job.numLayers = layered ? info.numLayers : 1;
21120
21326
  job.layerIDs = info.layerIDs;
21121
21327
  renderer.beginGraph(g, job);
21328
+ warnLayersUnsupported(job.format, info.numLayers, renderer.beginLayer !== void 0);
21122
21329
  for (let ln = 1; ln <= job.numLayers; ln++) {
21123
21330
  job.layerNum = ln;
21124
21331
  if (layered) renderer.beginLayer(info.layerIDs[ln], job);
@@ -21180,13 +21387,21 @@ function render(ctx, g, format, inlineImages = false) {
21180
21387
  }
21181
21388
 
21182
21389
  // src/common/htmltable-emit-fill.ts
21390
+ var MSG_MANY_COLORS = "More than 2 colors specified for a gradient - ignoring remaining";
21391
+ function findHtmlStopColor(color, silent = false) {
21392
+ const { segs, error } = silent ? parseSegsSilent(color) : parseSegs(color);
21393
+ const first = segs[0];
21394
+ const second = segs[1];
21395
+ if (error !== 0 || first === void 0 || second === void 0 || first.color === null) {
21396
+ return null;
21397
+ }
21398
+ if (segs.length > 2 && !silent) agwarningf(MSG_MANY_COLORS);
21399
+ const frac = first.hasFraction ? first.t : second.hasFraction ? 1 - second.t : 0;
21400
+ return { fill: first.color, stop: second.color, frac };
21401
+ }
21183
21402
  function parseGradientSpec(color) {
21184
- const idx = color.indexOf(":");
21185
- if (idx < 1) return null;
21186
- const c0 = color.slice(0, idx).trim();
21187
- const c1 = color.slice(idx + 1).trim();
21188
- if (c0.length === 0) return null;
21189
- return [c0, c1.length > 0 ? c1 : "black"];
21403
+ const spec = findHtmlStopColor(color, true);
21404
+ return spec === null ? null : [spec.fill, spec.stop ?? "black"];
21190
21405
  }
21191
21406
  var paintObj = {
21192
21407
  parent: null,
@@ -21243,6 +21458,12 @@ function resetHtmlFillPenWidth() {
21243
21458
  htmlFillPen = 1;
21244
21459
  }
21245
21460
  registerRenderState(resetHtmlFillPenWidth);
21461
+ var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
21462
+ function htmlBorderStyle(pen) {
21463
+ if (pen === 1 /* Dashed */) return ["dashed"];
21464
+ if (pen === 2 /* Dotted */) return ["dotted"];
21465
+ return DEFAULT_LINE_STYLE;
21466
+ }
21246
21467
  function penTypeOf(style2) {
21247
21468
  const st = htmlStyle(style2);
21248
21469
  if (st.dashed) return 1 /* Dashed */;
@@ -21250,12 +21471,13 @@ function penTypeOf(style2) {
21250
21471
  return 3 /* Solid */;
21251
21472
  }
21252
21473
  function withHtmlPaint(paint, job, drawFn) {
21253
- paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(paint.fill) : { type: "none" };
21474
+ paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(firstColor(paint.fill)) : { type: "none" };
21254
21475
  paintObj.penColor = paint.pen !== void 0 ? resolveRenderColor(paint.pen) : { type: "string", s: "transparent" };
21255
21476
  applyHtmlFill(paint);
21256
21477
  paintObj.pen = penTypeOf(paint.penStyle);
21257
21478
  paintObj.penWidth = paint.penWidth !== void 0 ? paint.penWidth : 1;
21258
21479
  paintObj.rawStyle = paintObj.pen === 3 /* Solid */ ? ["solid"] : [];
21480
+ gvrenderSetStyle(htmlBorderStyle(paintObj.pen));
21259
21481
  paintObj.emitState = job.obj?.emitState ?? 8 /* NDraw */;
21260
21482
  job.pushObj(paintObj);
21261
21483
  try {
@@ -21269,7 +21491,7 @@ function applyHtmlFill(paint) {
21269
21491
  paintObj.fill = paint.radial === true ? 3 /* Radial */ : 2 /* Linear */;
21270
21492
  paintObj.stopColor = resolveRenderColor(paint.stop);
21271
21493
  paintObj.gradientAngle = paint.gradientAngle ?? 0;
21272
- paintObj.gradientFrac = 0;
21494
+ paintObj.gradientFrac = paint.gradientFrac ?? 0;
21273
21495
  return;
21274
21496
  }
21275
21497
  paintObj.fill = paint.fill !== void 0 ? 1 /* Solid */ : 0 /* None */;
@@ -21572,6 +21794,7 @@ function resolveClusterFillEx(attrs) {
21572
21794
 
21573
21795
  // src/common/splines-clip.ts
21574
21796
  var ARR_NORM = 1;
21797
+ var dist = distFused;
21575
21798
  var SplineClipHelper = class _SplineClipHelper {
21576
21799
  static makeEmptySpl() {
21577
21800
  return { list: [], size: 0, bb: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } } };
@@ -21664,15 +21887,11 @@ var SplineClipHelper = class _SplineClipHelper {
21664
21887
  if (j) return [eflag, sflag];
21665
21888
  return [sflag, eflag];
21666
21889
  }
21667
- /** DIST(p, q). */
21668
- static dist(p, q) {
21669
- return Math.hypot(p.x - q.x, p.y - q.y);
21670
- }
21671
21890
  /** Sphere inside-fn around `tip` with radius `r` for bezierClip. */
21672
21891
  static sphereCtx(tip2, r) {
21673
21892
  return {
21674
21893
  ctx: { nodeCoord: { x: 0, y: 0 }, rw: 0, bp: null },
21675
- fn: (_c, p) => _SplineClipHelper.dist(p, tip2) <= r
21894
+ fn: (_c, p) => dist(p, tip2) <= r
21676
21895
  };
21677
21896
  }
21678
21897
  /**
@@ -21704,7 +21923,7 @@ var SplineClipHelper = class _SplineClipHelper {
21704
21923
  );
21705
21924
  spl.eflag = eflag;
21706
21925
  spl.ep = ps[endp + 3];
21707
- if (endp > startp && _SplineClipHelper.dist(ps[endp], ps[endp + 3]) < elen) {
21926
+ if (endp > startp && dist(ps[endp], ps[endp + 3]) < elen) {
21708
21927
  endp -= 3;
21709
21928
  }
21710
21929
  const sp = [spl.ep, ps[endp + 2], ps[endp + 1], ps[endp]];
@@ -21731,7 +21950,7 @@ var SplineClipHelper = class _SplineClipHelper {
21731
21950
  );
21732
21951
  spl.sflag = sflag;
21733
21952
  spl.sp = ps[startp];
21734
- if (endp > startp && _SplineClipHelper.dist(ps[startp], ps[startp + 3]) < slen) {
21953
+ if (endp > startp && dist(ps[startp], ps[startp + 3]) < slen) {
21735
21954
  startp += 3;
21736
21955
  }
21737
21956
  const sp = [ps[startp + 3], ps[startp + 2], ps[startp + 1], spl.sp];
@@ -21832,7 +22051,7 @@ var SplineClipHelper = class _SplineClipHelper {
21832
22051
  if (sflag && eflag && endp === startp) {
21833
22052
  const p = ps[endp];
21834
22053
  const q = ps[endp + 3];
21835
- const d = _SplineClipHelper.dist(p, q);
22054
+ const d = dist(p, q);
21836
22055
  let hlen = hlen0;
21837
22056
  let tlen = tlen0;
21838
22057
  if (hlen + tlen >= d) {
@@ -21875,7 +22094,7 @@ var SplineClipHelper = class _SplineClipHelper {
21875
22094
  let hlen = hlen0;
21876
22095
  const p = ps[endp];
21877
22096
  const q = ps[endp + 3];
21878
- const maxd = 0.9 * _SplineClipHelper.dist(p, q);
22097
+ const maxd = 0.9 * dist(p, q);
21879
22098
  if (hlen >= maxd) hlen = maxd;
21880
22099
  const r = { x: p.x, y: p.y };
21881
22100
  if (p.y === q.y) {
@@ -21895,7 +22114,7 @@ var SplineClipHelper = class _SplineClipHelper {
21895
22114
  let tlen = tlen0;
21896
22115
  const p = ps[startp];
21897
22116
  const q = ps[startp + 3];
21898
- const maxd = 0.9 * _SplineClipHelper.dist(p, q);
22117
+ const maxd = 0.9 * dist(p, q);
21899
22118
  if (tlen >= maxd) tlen = maxd;
21900
22119
  const r = { x: p.x, y: p.y };
21901
22120
  if (p.y === q.y) {
@@ -22606,9 +22825,6 @@ function readLabelPos(sg) {
22606
22825
  }
22607
22826
  return pos;
22608
22827
  }
22609
- function graphAttrInherited(sg, key) {
22610
- return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
22611
- }
22612
22828
  function readFontParams(sg) {
22613
22829
  return {
22614
22830
  fontsize: parseFloat(graphAttrInherited(sg, "fontsize") ?? "") || DEFAULT_FONTSIZE2,
@@ -24029,13 +24245,13 @@ function dfsNode(Xg, v, frames) {
24029
24245
  frames.push({ v, edges: v.outEdges(Xg).slice(), i: 0 });
24030
24246
  }
24031
24247
  function dfsStep2(Xg, frames) {
24032
- const fr3 = frames[frames.length - 1];
24033
- if (fr3.i < fr3.edges.length) {
24034
- const e = fr3.edges[fr3.i++];
24248
+ const fr7 = frames[frames.length - 1];
24249
+ if (fr7.i < fr7.edges.length) {
24250
+ const e = fr7.edges[fr7.i++];
24035
24251
  if (e.head.info.onstack) reverseEdge2(Xg, e);
24036
24252
  else if (!e.head.info.mark) dfsNode(Xg, e.head, frames);
24037
24253
  } else {
24038
- fr3.v.info.onstack = 0;
24254
+ fr7.v.info.onstack = 0;
24039
24255
  frames.pop();
24040
24256
  }
24041
24257
  }
@@ -25807,7 +26023,7 @@ function fillRankVlist(g, r, root) {
25807
26023
  rankArr[r].v = rootRank.v;
25808
26024
  rankArr[r].vStart = lead.info.order ?? 0;
25809
26025
  const maxi = computeMaxi(g, r);
25810
- if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`, "error");
26026
+ if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`);
25811
26027
  rankArr[r].n = maxi + 1;
25812
26028
  return 0;
25813
26029
  }
@@ -28626,7 +28842,7 @@ function routeSplinesInternal(pp, polyline) {
28626
28842
  ];
28627
28843
  const pl = shortestPath(poly, eps);
28628
28844
  if (pl === null) {
28629
- agerrLineOn("warn", "in routesplines, Pshortestpath failed");
28845
+ agerrorf("in routesplines, Pshortestpath failed");
28630
28846
  return null;
28631
28847
  }
28632
28848
  emitDump("S3_POLY", dumpNames, () => ({
@@ -30632,9 +30848,9 @@ function writePortlabelPos(l, pe, pf, angleStr, distanceStr) {
30632
30848
  const angleDeg = lateDouble(angleStr, PORT_LABEL_ANGLE, -180);
30633
30849
  const angle = Math.atan2(pf.y - pe.y, pf.x - pe.x) + RADIANS(angleDeg);
30634
30850
  const distMult = lateDouble(distanceStr || void 0, 1, 0);
30635
- const dist4 = PORT_LABEL_DISTANCE * distMult;
30636
- l.pos.x = pe.x + dist4 * Math.cos(angle);
30637
- l.pos.y = pe.y + dist4 * Math.sin(angle);
30851
+ const dist5 = PORT_LABEL_DISTANCE * distMult;
30852
+ l.pos.x = pe.x + dist5 * Math.cos(angle);
30853
+ l.pos.y = pe.y + dist5 * Math.sin(angle);
30638
30854
  l.set = true;
30639
30855
  }
30640
30856
  function updateBB(g, l) {
@@ -31036,7 +31252,7 @@ function translateDrawing(g) {
31036
31252
  if (e.tail !== v) continue;
31037
31253
  if (e.info.spl === void 0) {
31038
31254
  if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
31039
- agerrLineOn("warn", `lost ${e.tail.name} ${e.head.name} edge`);
31255
+ agerrorf(`lost ${e.tail.name} ${e.head.name} edge`);
31040
31256
  }
31041
31257
  continue;
31042
31258
  }
@@ -31799,9 +32015,14 @@ function nodeInsideFn2(box) {
31799
32015
  function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
31800
32016
  const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
31801
32017
  const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
31802
- const arrowTip = step2[3];
32018
+ const startp = 0;
32019
+ let endp = 0;
32020
+ const arrowTip = step2[endp + 3];
31803
32021
  const elen = normalArrowLen(penwidth);
31804
- const clipped = arrowEndClip(step2, arrowTip, elen);
32022
+ if (endp > startp && distFused(step2[endp], step2[endp + 3]) < elen) {
32023
+ endp -= 3;
32024
+ }
32025
+ const clipped = arrowEndClip(step2.slice(endp, endp + 4), arrowTip, elen);
31805
32026
  const arrowDir = normalizeVec({
31806
32027
  x: clipped[3].x - arrowTip.x,
31807
32028
  y: clipped[3].y - arrowTip.y
@@ -34340,8 +34561,7 @@ function ensureDummyNodes(sg, gstart) {
34340
34561
  }
34341
34562
  function orthoEdges(g, useLbls, clipAndInstall2) {
34342
34563
  if (useLbls) {
34343
- agerrLineOn(
34344
- "warn",
34564
+ agwarningf(
34345
34565
  "Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
34346
34566
  );
34347
34567
  useLbls = false;
@@ -34476,7 +34696,7 @@ function dispatchOrthoEdges(g, useLbls) {
34476
34696
  }
34477
34697
 
34478
34698
  // src/common/arrows-geometry.ts
34479
- function dist(a, b) {
34699
+ function dist3(a, b) {
34480
34700
  return Math.hypot(a.x - b.x, a.y - b.y);
34481
34701
  }
34482
34702
 
@@ -34580,7 +34800,7 @@ function getCycleCentroid(g, edge) {
34580
34800
  }
34581
34801
  function bend(spl, centroid) {
34582
34802
  const midpt = midPointf(spl[0], spl[3]);
34583
- const distVal = dist(spl[3], spl[0]);
34803
+ const distVal = dist3(spl[3], spl[0]);
34584
34804
  const r = distVal / 5;
34585
34805
  const vX = centroid.x - midpt.x;
34586
34806
  const vY = centroid.y - midpt.y;
@@ -35193,7 +35413,7 @@ function arrowEndClipIdx(state3, endp) {
35193
35413
  const elen = arrowClipLength(edgeArrowName(e, "head"), edgeArrowsize(e), edgePenwidthAttr(e));
35194
35414
  bez.eflag = bez.eflag || 1;
35195
35415
  bez.ep = { ...bez.list[endp + 3] };
35196
- if (endp > state3.starti && dist(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
35416
+ if (endp > state3.starti && distFused(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
35197
35417
  const seg2 = [bez.list[endp], bez.list[endp + 1], bez.list[endp + 2], bez.list[endp + 3]];
35198
35418
  const clipped = arrowEndClip(seg2, bez.ep, elen);
35199
35419
  for (let k = 0; k < 4; k++) bez.list[endp + k] = clipped[k];
@@ -35204,7 +35424,7 @@ function arrowStartClipIdx(state3, startp, endp) {
35204
35424
  const slen = arrowClipLength(edgeArrowName(e, "tail"), edgeArrowsize(e), edgePenwidthAttr(e));
35205
35425
  bez.sflag = bez.sflag || 1;
35206
35426
  bez.sp = { ...bez.list[startp] };
35207
- if (endp > startp && dist(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
35427
+ if (endp > startp && distFused(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
35208
35428
  const seg2 = [bez.list[startp], bez.list[startp + 1], bez.list[startp + 2], bez.list[startp + 3]];
35209
35429
  const clipped = tailArrowEndClip(seg2, bez.sp, slen);
35210
35430
  for (let k = 0; k < 4; k++) bez.list[startp + k] = clipped[k];
@@ -36473,120 +36693,522 @@ var DOT_LAYOUT_ENGINE = {
36473
36693
  };
36474
36694
 
36475
36695
  // src/layout/neato/dijkstra.ts
36476
- function heapPush(heap, dist4, idx) {
36477
- let pos = heap.length;
36478
- heap.push(idx);
36479
- while (pos > 0) {
36480
- const parent2 = pos - 1 >> 1;
36481
- if (dist4[heap[parent2]] <= dist4[heap[pos]]) break;
36482
- const tmp = heap[parent2];
36483
- heap[parent2] = heap[pos];
36484
- heap[pos] = tmp;
36485
- pos = parent2;
36486
- }
36487
- }
36488
- function heapSiftDown2(heap, dist4) {
36489
- let pos = 0;
36696
+ var FLT_MAX = 34028234663852886e22;
36697
+ function greaterPriorityF(h, i, j, dist5) {
36698
+ return dist5[h.data[i]] < dist5[h.data[j]];
36699
+ }
36700
+ function heapifyF(h, start, dist5) {
36701
+ let i = start;
36490
36702
  for (; ; ) {
36491
- const l = 2 * pos + 1;
36492
- const r = 2 * pos + 2;
36493
- let smallest = pos;
36494
- if (l < heap.length && dist4[heap[l]] < dist4[heap[smallest]]) smallest = l;
36495
- if (r < heap.length && dist4[heap[r]] < dist4[heap[smallest]]) smallest = r;
36496
- if (smallest === pos) break;
36497
- const tmp = heap[smallest];
36498
- heap[smallest] = heap[pos];
36499
- heap[pos] = tmp;
36500
- pos = smallest;
36501
- }
36502
- }
36503
- function heapPop(heap, dist4) {
36504
- const top = heap[0];
36505
- const last = heap.pop();
36506
- if (heap.length === 0) return top;
36507
- heap[0] = last;
36508
- heapSiftDown2(heap, dist4);
36509
- return top;
36510
- }
36511
- function heapBuildExcluding(src, n, dist4) {
36512
- const heap = [];
36703
+ const l = ngLeft(i);
36704
+ const r = ngRight(i);
36705
+ let largest = ngInsideHeap(h, l) && greaterPriorityF(h, l, i, dist5) ? l : i;
36706
+ if (ngInsideHeap(h, r) && greaterPriorityF(h, r, largest, dist5)) largest = r;
36707
+ if (largest === i) break;
36708
+ ngExchange(h, largest, i);
36709
+ i = largest;
36710
+ }
36711
+ }
36712
+ function initHeapF(startVertex, dist5, n) {
36713
+ const h = {
36714
+ data: new Array(Math.max(n - 1, 0)).fill(0),
36715
+ heapSize: n - 1,
36716
+ index: new Int32Array(n)
36717
+ };
36718
+ let count = 0;
36513
36719
  for (let i = 0; i < n; i++) {
36514
- if (i !== src) heapPush(heap, dist4, i);
36720
+ if (i !== startVertex) {
36721
+ h.data[count] = i;
36722
+ h.index[i] = count;
36723
+ count++;
36724
+ }
36515
36725
  }
36516
- return heap;
36726
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapifyF(h, j, dist5);
36727
+ return h;
36517
36728
  }
36518
- function dijkstraInitDist(src, graph, n, dist4) {
36519
- for (let i = 0; i < n; i++) dist4[i] = Infinity;
36520
- dist4[src] = 0;
36521
- const v = graph[src];
36522
- for (let i = 1; i < v.nedges; i++) dist4[v.edges[i]] = v.ewgts[i];
36729
+ function extractMaxF(h, dist5) {
36730
+ if (h.heapSize === 0) return -1;
36731
+ const max = h.data[0];
36732
+ h.data[0] = h.data[h.heapSize - 1];
36733
+ h.index[h.data[0]] = 0;
36734
+ h.heapSize--;
36735
+ heapifyF(h, 0, dist5);
36736
+ return max;
36523
36737
  }
36524
- function dijkstraRelax(closest, closestDist, graph, dist4, heap) {
36525
- const cv = graph[closest];
36526
- for (let i = 1; i < cv.nedges; i++) {
36527
- const nb = cv.edges[i];
36528
- const nd = closestDist + cv.ewgts[i];
36529
- if (nd < dist4[nb]) {
36530
- dist4[nb] = nd;
36531
- heapPush(heap, dist4, nb);
36738
+ function increaseKeyF(h, increasedVertex, newDist, dist5) {
36739
+ if (dist5[increasedVertex] <= newDist) return;
36740
+ let i = h.index[increasedVertex];
36741
+ dist5[increasedVertex] = newDist;
36742
+ while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
36743
+ ngAssign(h, i, ngParent(i));
36744
+ i = ngParent(i);
36745
+ }
36746
+ h.data[i] = increasedVertex;
36747
+ h.index[increasedVertex] = i;
36748
+ }
36749
+ function dijkstra(vertex, graph, n, dist5) {
36750
+ for (let i = 0; i < n; i++) dist5[i] = FLT_MAX;
36751
+ dist5[vertex] = 0;
36752
+ const vd = graph[vertex];
36753
+ for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = vd.ewgts[i];
36754
+ const h = initHeapF(vertex, dist5, n);
36755
+ for (let closest = extractMaxF(h, dist5); closest >= 0; closest = extractMaxF(h, dist5)) {
36756
+ const closestDist = dist5[closest];
36757
+ if (closestDist === FLT_MAX) break;
36758
+ const cd = graph[closest];
36759
+ for (let i = 1; i < cd.nedges; i++) {
36760
+ increaseKeyF(h, cd.edges[i], Math.fround(closestDist + Math.fround(cd.ewgts[i])), dist5);
36532
36761
  }
36533
36762
  }
36534
36763
  }
36535
- function dijkstra(src, graph, n, dist4) {
36536
- dijkstraInitDist(src, graph, n, dist4);
36537
- const heap = heapBuildExcluding(src, n, dist4);
36538
- while (heap.length > 0) {
36539
- const closest = heapPop(heap, dist4);
36540
- const closestDist = dist4[closest];
36541
- if (!isFinite(closestDist)) break;
36542
- dijkstraRelax(closest, closestDist, graph, dist4, heap);
36764
+ var MAX_DIST = 2147483647;
36765
+ function ngLeft(i) {
36766
+ return 2 * i;
36767
+ }
36768
+ function ngRight(i) {
36769
+ return 2 * i + 1;
36770
+ }
36771
+ function ngParent(i) {
36772
+ return Math.trunc(i / 2);
36773
+ }
36774
+ function ngInsideHeap(h, i) {
36775
+ return i < h.heapSize;
36776
+ }
36777
+ function ngGreaterPriority(h, i, j, dist5) {
36778
+ return dist5[h.data[i]] < dist5[h.data[j]];
36779
+ }
36780
+ function ngAssign(h, i, j) {
36781
+ h.data[i] = h.data[j];
36782
+ h.index[h.data[i]] = i;
36783
+ }
36784
+ function ngExchange(h, i, j) {
36785
+ const t = h.data[i];
36786
+ h.data[i] = h.data[j];
36787
+ h.data[j] = t;
36788
+ h.index[h.data[i]] = i;
36789
+ h.index[h.data[j]] = j;
36790
+ }
36791
+ function ngHeapify(h, start, dist5) {
36792
+ let i = start;
36793
+ for (; ; ) {
36794
+ const l = ngLeft(i);
36795
+ const r = ngRight(i);
36796
+ let largest = ngInsideHeap(h, l) && ngGreaterPriority(h, l, i, dist5) ? l : i;
36797
+ if (ngInsideHeap(h, r) && ngGreaterPriority(h, r, largest, dist5)) largest = r;
36798
+ if (largest === i) break;
36799
+ ngExchange(h, largest, i);
36800
+ i = largest;
36801
+ }
36802
+ }
36803
+ function ngInitHeap(startVertex, dist5, n) {
36804
+ const h = {
36805
+ data: new Array(Math.max(n - 1, 0)).fill(0),
36806
+ heapSize: n - 1,
36807
+ index: new Int32Array(n)
36808
+ };
36809
+ let count = 0;
36810
+ for (let i = 0; i < n; i++) {
36811
+ if (i !== startVertex) {
36812
+ h.data[count] = i;
36813
+ h.index[i] = count;
36814
+ count++;
36815
+ }
36816
+ }
36817
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) ngHeapify(h, j, dist5);
36818
+ return h;
36819
+ }
36820
+ function ngExtractMax(h, dist5) {
36821
+ if (h.heapSize === 0) return -1;
36822
+ const max = h.data[0];
36823
+ h.data[0] = h.data[h.heapSize - 1];
36824
+ h.index[h.data[0]] = 0;
36825
+ h.heapSize--;
36826
+ ngHeapify(h, 0, dist5);
36827
+ return max;
36828
+ }
36829
+ function ngIncreaseKey(h, increasedVertex, newDist, dist5) {
36830
+ if (dist5[increasedVertex] <= newDist) return;
36831
+ let i = h.index[increasedVertex];
36832
+ dist5[increasedVertex] = newDist;
36833
+ while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
36834
+ ngAssign(h, i, ngParent(i));
36835
+ i = ngParent(i);
36836
+ }
36837
+ h.data[i] = increasedVertex;
36838
+ h.index[increasedVertex] = i;
36839
+ }
36840
+ function toDistType(w) {
36841
+ return Math.trunc(Math.fround(w));
36842
+ }
36843
+ function ngdijkstra(vertex, graph, n, dist5) {
36844
+ let prevClosestDist = MAX_DIST;
36845
+ for (let i = 0; i < n; i++) dist5[i] = MAX_DIST;
36846
+ dist5[vertex] = 0;
36847
+ const vd = graph[vertex];
36848
+ for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = toDistType(vd.ewgts[i]);
36849
+ const h = ngInitHeap(vertex, dist5, n);
36850
+ for (let closest = ngExtractMax(h, dist5); closest >= 0; closest = ngExtractMax(h, dist5)) {
36851
+ const closestDist = dist5[closest];
36852
+ if (closestDist === MAX_DIST) break;
36853
+ const cd = graph[closest];
36854
+ for (let i = 1; i < cd.nedges; i++) {
36855
+ ngIncreaseKey(h, cd.edges[i], closestDist + toDistType(cd.ewgts[i]) | 0, dist5);
36856
+ }
36857
+ prevClosestDist = closestDist;
36858
+ }
36859
+ for (let i = 0; i < n; i++) {
36860
+ if (dist5[i] === MAX_DIST) {
36861
+ dist5[i] = MAX_DIST - prevClosestDist < 10 ? MAX_DIST : prevClosestDist + 10;
36862
+ }
36543
36863
  }
36544
36864
  }
36545
36865
 
36546
36866
  // src/layout/neato/bfs.ts
36547
- function bfsInit(src, n, dist4) {
36548
- for (let i = 0; i < n; i++) dist4[i] = -1;
36549
- dist4[src] = 0;
36867
+ function bfsInit(src, n, dist5) {
36868
+ for (let i = 0; i < n; i++) dist5[i] = -1;
36869
+ dist5[src] = 0;
36550
36870
  return [src];
36551
36871
  }
36552
- function bfsFixDisconnected(n, dist4, closestDist) {
36872
+ function bfsFixDisconnected(n, dist5, closestDist) {
36553
36873
  for (let i = 0; i < n; i++) {
36554
- if (dist4[i] < 0) dist4[i] = closestDist + 10;
36874
+ if (dist5[i] < 0) dist5[i] = closestDist + 10;
36555
36875
  }
36556
36876
  }
36557
- function bfsVisitNeighbors(vertex, graph, dist4, queue) {
36877
+ function bfsVisitNeighbors(vertex, graph, dist5, queue) {
36558
36878
  const vd = graph[vertex];
36559
- const d = dist4[vertex];
36879
+ const d = dist5[vertex];
36560
36880
  const unit = graph[0].ewgts.length === 0;
36561
36881
  for (let i = 1; i < vd.nedges; i++) {
36562
36882
  const nb = vd.edges[i];
36563
- if (dist4[nb] < 0) {
36564
- dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
36883
+ if (dist5[nb] < 0) {
36884
+ dist5[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
36565
36885
  queue.push(nb);
36566
36886
  }
36567
36887
  }
36568
36888
  return d;
36569
36889
  }
36570
- function bfs(src, graph, n, dist4) {
36571
- const queue = bfsInit(src, n, dist4);
36890
+ function bfs(src, graph, n, dist5) {
36891
+ const queue = bfsInit(src, n, dist5);
36572
36892
  let closestDist = 0;
36573
36893
  let head = 0;
36574
36894
  while (head < queue.length) {
36575
36895
  const vertex = queue[head++];
36576
- closestDist = bfsVisitNeighbors(vertex, graph, dist4, queue);
36896
+ closestDist = bfsVisitNeighbors(vertex, graph, dist5, queue);
36897
+ }
36898
+ bfsFixDisconnected(n, dist5, closestDist);
36899
+ }
36900
+ function packedIndex(i, j, n) {
36901
+ return i * (2 * n - i - 1) / 2 + j;
36902
+ }
36903
+ function computeWeightedApspPacked(graph, n) {
36904
+ const result = new Float32Array(n * (n + 1) / 2);
36905
+ const di = new Float32Array(n);
36906
+ for (let i = 0; i < n; i++) {
36907
+ dijkstra(i, graph, n, di);
36908
+ for (let j = i; j < n; j++) result[packedIndex(i, j, n)] = di[j];
36909
+ }
36910
+ return result;
36911
+ }
36912
+
36913
+ // src/common/crand.ts
36914
+ var C_RAND_MAX = 2147483647;
36915
+ var UNSEEDED_STATE2 = 1;
36916
+ var state2 = UNSEEDED_STATE2;
36917
+ registerRenderState(() => {
36918
+ state2 = UNSEEDED_STATE2;
36919
+ });
36920
+ function csrand(seed) {
36921
+ state2 = seed;
36922
+ }
36923
+ function crand() {
36924
+ state2 = state2 * 16807 % 2147483647;
36925
+ return state2;
36926
+ }
36927
+ function cdrand() {
36928
+ return crand() / C_RAND_MAX;
36929
+ }
36930
+ function gvRandom(bound) {
36931
+ const discardThreshold = C_RAND_MAX - 2147483648 % bound;
36932
+ let r;
36933
+ do {
36934
+ r = crand();
36935
+ } while (r > discardThreshold);
36936
+ return r % bound;
36937
+ }
36938
+ function gvPermutation(bound) {
36939
+ if (bound <= 0) return [];
36940
+ const p = [];
36941
+ for (let i = 0; i < bound; i++) p.push(i);
36942
+ for (let i = bound - 1; i > 0; --i) {
36943
+ const j = gvRandom(i + 1);
36944
+ const t = p[i];
36945
+ p[i] = p[j];
36946
+ p[j] = t;
36577
36947
  }
36578
- bfsFixDisconnected(n, dist4, closestDist);
36948
+ return p;
36949
+ }
36950
+
36951
+ // src/layout/neato/matrix-ops.ts
36952
+ var fr = Math.fround;
36953
+ function fma2(a, b, c) {
36954
+ const p = a * b;
36955
+ return Number.isFinite(p) && Number.isFinite(c) ? fma(a, b, c) : p + c;
36956
+ }
36957
+ function orthog1(n, vec) {
36958
+ let sum = 0;
36959
+ for (let i = 0; i < n; i++) sum += vec[i];
36960
+ sum /= n;
36961
+ for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
36962
+ }
36963
+ function orthog1f(n, vec) {
36964
+ let sum = fr(0);
36965
+ for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
36966
+ sum = fr(sum / n);
36967
+ for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
36968
+ }
36969
+ function rightMultWithVectorFF(m, n, vector, result) {
36970
+ for (let i = 0; i < n; i++) result[i] = 0;
36971
+ let index = 0;
36972
+ for (let i = 0; i < n; i++) {
36973
+ const vi = vector[i];
36974
+ let res = fr(m[index++] * vi);
36975
+ for (let j = i + 1; j < n; j++, index++) {
36976
+ res = fr(res + fr(m[index] * vector[j]));
36977
+ result[j] = result[j] + fr(m[index] * vi);
36978
+ }
36979
+ result[i] = result[i] + res;
36980
+ }
36981
+ }
36982
+ function vectorsSubtractionF(n, v1, v2, result) {
36983
+ for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
36984
+ }
36985
+ function vectorsMultAdditionF(n, v1, alpha, v2) {
36986
+ const a = fr(alpha);
36987
+ for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
36988
+ }
36989
+ function vectorsInnerProductF(n, v1, v2) {
36990
+ let result = 0;
36991
+ for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
36992
+ return result;
36993
+ }
36994
+ function copyVectorF(n, src, dst) {
36995
+ for (let i = 0; i < n; i++) dst[i] = src[i];
36996
+ }
36997
+ function maxAbsF(n, vec) {
36998
+ let max = fr(-1e30);
36999
+ for (let i = 0; i < n; i++) {
37000
+ const a = fr(Math.abs(vec[i]));
37001
+ if (a > max) max = a;
37002
+ }
37003
+ return max;
37004
+ }
37005
+ function squareVec(n, vec) {
37006
+ for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
37007
+ }
37008
+ function invertVec(n, vec) {
37009
+ for (let i = 0; i < n; i++) {
37010
+ if (vec[i] !== 0) vec[i] = 1 / vec[i];
37011
+ }
37012
+ }
37013
+ function sqrtVecF(n, source, target) {
37014
+ for (let i = 0; i < n; i++) {
37015
+ if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
37016
+ }
37017
+ }
37018
+ function invertSqrtVec(n, vec) {
37019
+ for (let i = 0; i < n; i++) {
37020
+ if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
37021
+ }
37022
+ }
37023
+ var BLOCK_NONE = 1;
37024
+ function innerProduct(n, v1, v2, block) {
37025
+ let result = 0;
37026
+ const blocked = block === BLOCK_NONE ? 0 : n - n % block;
37027
+ let i = 0;
37028
+ for (; i < blocked; i++) result += v1[i] * v2[i];
37029
+ for (; i < n; i++) result = fma2(v1[i], v2[i], result);
37030
+ return result;
37031
+ }
37032
+ function scadd(vec1, end, fac, vec2) {
37033
+ for (let i = 0; i <= end; i++) vec1[i] = fma2(fac, vec2[i], vec1[i]);
37034
+ }
37035
+ function norm(vec, end, block) {
37036
+ return Math.sqrt(innerProduct(end + 1, vec, vec, block));
37037
+ }
37038
+ function vectorsScalarMult(n, vector, alpha, result) {
37039
+ for (let i = 0; i < n; i++) result[i] = vector[i] * alpha;
37040
+ }
37041
+ function copyVector(n, source, dest) {
37042
+ for (let i = 0; i < n; i++) dest[i] = source[i];
37043
+ }
37044
+ function vectorsAddition(n, v1, v2, result) {
37045
+ for (let i = 0; i < n; i++) result[i] = v1[i] + v2[i];
37046
+ }
37047
+ function vectorsSubtraction(n, v1, v2, result) {
37048
+ for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
37049
+ }
37050
+ function maxAbs(n, vector) {
37051
+ let maxVal = -1e50;
37052
+ for (let i = 0; i < n; i++) {
37053
+ const a = Math.abs(vector[i]);
37054
+ if (a > maxVal) maxVal = a;
37055
+ }
37056
+ return maxVal;
37057
+ }
37058
+ function rightMultWithVectorF(matrix, n, vector, result, block) {
37059
+ const blocked = block === BLOCK_NONE ? 0 : n - n % block;
37060
+ for (let i = 0; i < n; i++) {
37061
+ const row = matrix[i];
37062
+ let res = 0;
37063
+ let j = 0;
37064
+ for (; j < blocked; j++) res += row[j] * vector[j];
37065
+ for (; j < n; j++) res = fma2(row[j], vector[j], res);
37066
+ result[i] = res;
37067
+ }
37068
+ }
37069
+ function rightMultWithVector(matrix, n, vector, result) {
37070
+ for (let i = 0; i < n; i++) {
37071
+ let res = 0;
37072
+ const row = matrix[i];
37073
+ for (let j = 0; j < row.nedges; j++) res = fma2(row.ewgts[j], vector[row.edges[j]], res);
37074
+ result[i] = res;
37075
+ }
37076
+ }
37077
+ var RANGE = 500;
37078
+ function initVecOrth1(n, vec) {
37079
+ for (let i = 0; i < n; i++) vec[i] = crand() % RANGE;
37080
+ orthog1(n, vec);
37081
+ }
37082
+
37083
+ // src/layout/neato/conjgrad.ts
37084
+ var BLOCK_INITIAL_RR = 4;
37085
+ var BLOCK_P_AP = 8;
37086
+ function cgNextDirection(n, w, alpha, rR) {
37087
+ vectorsScalarMult(n, w.Ap, alpha, w.Ap);
37088
+ vectorsSubtraction(n, w.r, w.Ap, w.r);
37089
+ const rRNew = innerProduct(n, w.r, w.r, BLOCK_NONE);
37090
+ if (rR === 0) {
37091
+ agerrorf("conjugate_gradient: unexpected length 0 vector\n");
37092
+ return null;
37093
+ }
37094
+ const beta = rRNew / rR;
37095
+ vectorsScalarMult(n, w.p, beta, w.p);
37096
+ vectorsAddition(n, w.r, w.p, w.p);
37097
+ return rRNew;
37098
+ }
37099
+ function cgStart(A3, x, b, n) {
37100
+ const w = {
37101
+ r: new Float64Array(n),
37102
+ p: new Float64Array(n),
37103
+ Ap: new Float64Array(n),
37104
+ alphap: new Float64Array(n)
37105
+ };
37106
+ const Ax = new Float64Array(n);
37107
+ const orthB = Float64Array.from(b.subarray(0, n));
37108
+ orthog1(n, orthB);
37109
+ orthog1(n, x);
37110
+ rightMultWithVector(A3, n, x, Ax);
37111
+ vectorsSubtraction(n, orthB, Ax, w.r);
37112
+ w.p.set(w.r.subarray(0, n));
37113
+ return w;
37114
+ }
37115
+ function conjugateGradient(A3, x, b, n, tol, maxIterations) {
37116
+ const w = cgStart(A3, x, b, n);
37117
+ let rR = innerProduct(n, w.r, w.r, BLOCK_INITIAL_RR);
37118
+ for (let i = 0; i < maxIterations && maxAbs(n, w.r) > tol; i++) {
37119
+ rightMultWithVector(A3, n, w.p, w.Ap);
37120
+ const pAp = innerProduct(n, w.p, w.Ap, BLOCK_P_AP);
37121
+ if (pAp === 0) break;
37122
+ const alpha = rR / pAp;
37123
+ vectorsScalarMult(n, w.p, alpha, w.alphap);
37124
+ vectorsAddition(n, x, w.alphap, x);
37125
+ if (i < maxIterations - 1) {
37126
+ const next = cgNextDirection(n, w, alpha, rR);
37127
+ if (next === null) return 1;
37128
+ rR = next;
37129
+ }
37130
+ }
37131
+ return 0;
37132
+ }
37133
+ var CGF_BLOCK_AX = 4;
37134
+ var CGF_BLOCK_AP = 4;
37135
+ var CGF_BLOCK_INITIAL_RR = 4;
37136
+ var CGF_BLOCK_P_AP = 8;
37137
+ function cgfInit(A3, x, b, n, ortho1) {
37138
+ const orthB = new Float64Array(n);
37139
+ copyVector(n, b, orthB);
37140
+ if (ortho1) {
37141
+ orthog1(n, orthB);
37142
+ orthog1(n, x);
37143
+ }
37144
+ const Ax = new Float64Array(n);
37145
+ rightMultWithVectorF(A3, n, x, Ax, CGF_BLOCK_AX);
37146
+ const r = new Float64Array(n);
37147
+ vectorsSubtraction(n, orthB, Ax, r);
37148
+ const p = new Float64Array(n);
37149
+ copyVector(n, r, p);
37150
+ return {
37151
+ r,
37152
+ p,
37153
+ Ap: new Float64Array(n),
37154
+ alphap: new Float64Array(n),
37155
+ rr: innerProduct(n, r, r, CGF_BLOCK_INITIAL_RR)
37156
+ };
37157
+ }
37158
+ function cgfUpdate(n, alpha, st) {
37159
+ vectorsScalarMult(n, st.Ap, alpha, st.Ap);
37160
+ vectorsSubtraction(n, st.r, st.Ap, st.r);
37161
+ const rrNew = innerProduct(n, st.r, st.r, BLOCK_NONE);
37162
+ if (st.rr === 0) {
37163
+ agerrorf("conjugate_gradient: unexpected length 0 vector\n");
37164
+ return 1;
37165
+ }
37166
+ const beta = rrNew / st.rr;
37167
+ st.rr = rrNew;
37168
+ vectorsScalarMult(n, st.p, beta, st.p);
37169
+ vectorsAddition(n, st.r, st.p, st.p);
37170
+ return 0;
37171
+ }
37172
+ function conjugateGradientF(A3, x, b, n, opts) {
37173
+ const { tol, maxIterations, ortho1 } = opts;
37174
+ const st = cgfInit(A3, x, b, n, ortho1);
37175
+ for (let i = 0; i < maxIterations && maxAbs(n, st.r) > tol; i++) {
37176
+ rightMultWithVectorF(A3, n, st.p, st.Ap, CGF_BLOCK_AP);
37177
+ const pAp = innerProduct(n, st.p, st.Ap, CGF_BLOCK_P_AP);
37178
+ if (pAp === 0) break;
37179
+ const alpha = st.rr / pAp;
37180
+ vectorsScalarMult(n, st.p, alpha, st.alphap);
37181
+ vectorsAddition(n, x, st.alphap, x);
37182
+ if (i < maxIterations - 1 && cgfUpdate(n, alpha, st) === 1) return 1;
37183
+ }
37184
+ return 0;
36579
37185
  }
36580
37186
 
36581
37187
  // src/layout/neato/stress.ts
37188
+ var TOLERANCE_CG = 1e-3;
36582
37189
  var DFLT_ITERATIONS = 200;
37190
+ var OPT_SMART_INIT = 4;
37191
+ function mdsModel(graph, nG) {
37192
+ if (graph[0].ewgts.length === 0) return null;
37193
+ const Dij = computeWeightedApspPacked(graph, nG);
37194
+ let shift = 0;
37195
+ for (let i = 0; i < nG; i++) {
37196
+ shift += i;
37197
+ for (let e = 1; e < graph[i].nedges; e++) {
37198
+ const j = graph[i].edges[e];
37199
+ if (j < i) continue;
37200
+ Dij[i * nG + j - shift] = graph[i].ewgts[e];
37201
+ }
37202
+ }
37203
+ return Dij;
37204
+ }
36583
37205
 
36584
37206
  // src/layout/neato/sgd-dijkstra.ts
36585
- var FLT_MAX = 34028234663852886e22;
37207
+ var FLT_MAX2 = 34028234663852886e22;
36586
37208
  var left = (i) => 2 * i;
36587
37209
  var right = (i) => 2 * i + 1;
36588
37210
  var parent = (i) => Math.trunc(i / 2);
36589
- var greaterPriority = (h, i, j, dist4) => dist4[h.data[i]] < dist4[h.data[j]];
37211
+ var greaterPriority = (h, i, j, dist5) => dist5[h.data[i]] < dist5[h.data[j]];
36590
37212
  function exchange2(h, i, j) {
36591
37213
  const t = h.data[i];
36592
37214
  h.data[i] = h.data[j];
@@ -36594,19 +37216,19 @@ function exchange2(h, i, j) {
36594
37216
  h.index[h.data[i]] = i;
36595
37217
  h.index[h.data[j]] = j;
36596
37218
  }
36597
- function heapify(h, start, dist4) {
37219
+ function heapify(h, start, dist5) {
36598
37220
  let i = start;
36599
37221
  for (; ; ) {
36600
37222
  const l = left(i);
36601
37223
  const r = right(i);
36602
- let largest = l < h.heapSize && greaterPriority(h, l, i, dist4) ? l : i;
36603
- if (r < h.heapSize && greaterPriority(h, r, largest, dist4)) largest = r;
37224
+ let largest = l < h.heapSize && greaterPriority(h, l, i, dist5) ? l : i;
37225
+ if (r < h.heapSize && greaterPriority(h, r, largest, dist5)) largest = r;
36604
37226
  if (largest === i) break;
36605
37227
  exchange2(h, largest, i);
36606
37228
  i = largest;
36607
37229
  }
36608
37230
  }
36609
- function initHeap(startVertex, dist4, n) {
37231
+ function initHeap(startVertex, dist5, n) {
36610
37232
  const h = {
36611
37233
  data: new Int32Array(Math.max(n - 1, 0)),
36612
37234
  heapSize: n - 1,
@@ -36618,23 +37240,23 @@ function initHeap(startVertex, dist4, n) {
36618
37240
  h.data[count] = i;
36619
37241
  h.index[i] = count++;
36620
37242
  }
36621
- for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist4);
37243
+ for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist5);
36622
37244
  return h;
36623
37245
  }
36624
- function extractMax(h, dist4) {
37246
+ function extractMax(h, dist5) {
36625
37247
  if (h.heapSize === 0) return -1;
36626
37248
  const max = h.data[0];
36627
37249
  h.data[0] = h.data[h.heapSize - 1];
36628
37250
  h.index[h.data[0]] = 0;
36629
37251
  h.heapSize--;
36630
- heapify(h, 0, dist4);
37252
+ heapify(h, 0, dist5);
36631
37253
  return max;
36632
37254
  }
36633
- function increaseKey(h, v, newDist, dist4) {
36634
- if (dist4[v] <= newDist) return;
36635
- dist4[v] = newDist;
37255
+ function increaseKey(h, v, newDist, dist5) {
37256
+ if (dist5[v] <= newDist) return;
37257
+ dist5[v] = newDist;
36636
37258
  let i = h.index[v];
36637
- while (i > 0 && dist4[h.data[parent(i)]] > newDist) {
37259
+ while (i > 0 && dist5[h.data[parent(i)]] > newDist) {
36638
37260
  h.data[i] = h.data[parent(i)];
36639
37261
  h.index[h.data[i]] = i;
36640
37262
  i = parent(i);
@@ -36643,7 +37265,7 @@ function increaseKey(h, v, newDist, dist4) {
36643
37265
  h.index[v] = i;
36644
37266
  }
36645
37267
  function dijkstraSgd(graph, source, terms) {
36646
- const dists = new Float32Array(graph.n).fill(FLT_MAX);
37268
+ const dists = new Float32Array(graph.n).fill(FLT_MAX2);
36647
37269
  dists[source] = 0;
36648
37270
  for (let i = graph.sources[source]; i < graph.sources[source + 1]; i++) {
36649
37271
  dists[graph.targets[i]] = graph.weights[i];
@@ -36652,7 +37274,7 @@ function dijkstraSgd(graph, source, terms) {
36652
37274
  let offset = 0;
36653
37275
  for (let closest = extractMax(h, dists); closest >= 0; closest = extractMax(h, dists)) {
36654
37276
  const d = dists[closest];
36655
- if (d === FLT_MAX) break;
37277
+ if (d === FLT_MAX2) break;
36656
37278
  if (graph.pinneds[closest] || closest < source) {
36657
37279
  terms[offset++] = { i: source, j: closest, d, w: Math.fround(1 / Math.fround(d * d)) };
36658
37280
  }
@@ -36671,7 +37293,7 @@ function lenattr(ep, g) {
36671
37293
  const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
36672
37294
  const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
36673
37295
  if (Number.isNaN(len) || len < 0 || len === 0) {
36674
- agerrLineOn("warn", `bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
37296
+ agwarningf(`bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
36675
37297
  return DEFAULT_EDGE_LEN;
36676
37298
  }
36677
37299
  return len;
@@ -36835,12 +37457,11 @@ function neatoMode(g) {
36835
37457
  if (str === void 0 || str === "") return MODE_MAJOR;
36836
37458
  const mode = modeByName().get(str);
36837
37459
  if (mode !== void 0) return mode;
36838
- agerrLineOn("warn", `Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
37460
+ agwarningf(`Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
36839
37461
  return MODE_MAJOR;
36840
37462
  }
36841
37463
  function checkMode(g, mode) {
36842
- const value = g.root.attrs.get("mode") || (mode === MODE_HIER ? "hier" : "ipsep");
36843
- if (mode === MODE_HIER) unsupported("mode", value, "hierarchical stress majorization");
37464
+ const value = g.root.attrs.get("mode") || "ipsep";
36844
37465
  if (mode === MODE_IPSEP && ipsepHasConstraints(g)) {
36845
37466
  unsupported("mode", value, "constrained (ipsep) majorization");
36846
37467
  }
@@ -37193,10 +37814,10 @@ function solve(a, b, c, n) {
37193
37814
  }
37194
37815
 
37195
37816
  // src/layout/neato/kk-paths.ts
37196
- function newPathState(n, dist4, adj, initialDist2) {
37817
+ function newPathState(n, dist5, adj, initialDist2) {
37197
37818
  return {
37198
37819
  n,
37199
- dist: dist4,
37820
+ dist: dist5,
37200
37821
  adj,
37201
37822
  initialDist: initialDist2,
37202
37823
  heap: new Int32Array(n + 1),
@@ -37274,10 +37895,10 @@ function s1(s, src) {
37274
37895
  function shortestPath2(s) {
37275
37896
  for (let v = 0; v < s.n; v++) s1(s, v);
37276
37897
  }
37277
- function mdsModel(dist4, n, edges) {
37898
+ function mdsModel2(dist5, n, edges) {
37278
37899
  for (const { tailSeq: i, headSeq: j, len } of edges) {
37279
37900
  if (i === j) continue;
37280
- for (const k of [i * n + j, j * n + i]) if (k < dist4.length) dist4[k] = len;
37901
+ for (const k of [i * n + j, j * n + i]) if (k < dist5.length) dist5[k] = len;
37281
37902
  }
37282
37903
  }
37283
37904
 
@@ -37370,12 +37991,12 @@ function initialPositions2(g, st) {
37370
37991
  }
37371
37992
  }
37372
37993
  function distvec(p0, p1, del) {
37373
- let dist4 = 0;
37994
+ let dist5 = 0;
37374
37995
  for (let k = 0; k < NDIM; k++) {
37375
37996
  del[k] = p0[k] - p1[k];
37376
- dist4 += del[k] * del[k];
37997
+ dist5 += del[k] * del[k];
37377
37998
  }
37378
- return Math.sqrt(dist4);
37999
+ return Math.sqrt(dist5);
37379
38000
  }
37380
38001
  function springFactors(g) {
37381
38002
  const byEnds = /* @__PURE__ */ new Map();
@@ -37392,9 +38013,9 @@ function fillRow(st, i, del) {
37392
38013
  const vi = st.nodes[i];
37393
38014
  for (let j = 0; j < st.n; j++) {
37394
38015
  if (i === j) continue;
37395
- const dist4 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
38016
+ const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
37396
38017
  for (let k = 0; k < NDIM; k++) {
37397
- const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist4);
38018
+ const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist5);
37398
38019
  st.t[(i * st.n + j) * NDIM + k] = v;
37399
38020
  st.sumT[i * NDIM + k] += v;
37400
38021
  }
@@ -37423,9 +38044,9 @@ function updateArrays(st, i) {
37423
38044
  for (let k = 0; k < NDIM; k++) st.sumT[i * NDIM + k] = 0;
37424
38045
  for (let j = 0; j < n; j++) {
37425
38046
  if (i === j) continue;
37426
- const dist4 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
38047
+ const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
37427
38048
  for (let k = 0; k < NDIM; k++) {
37428
- const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist4);
38049
+ const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist5);
37429
38050
  st.t[(i * n + j) * NDIM + k] = tij;
37430
38051
  st.sumT[i * NDIM + k] += tij;
37431
38052
  const old = st.t[(j * n + i) * NDIM + k];
@@ -37492,7 +38113,7 @@ function moveNode(st, m) {
37492
38113
  function solveModel(g, st) {
37493
38114
  for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
37494
38115
  if (st.move === st.maxIter) {
37495
- agerrLineOn("warn", `Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
38116
+ agwarningf(`Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
37496
38117
  }
37497
38118
  }
37498
38119
  function mdsEdges(g, nodes, lens) {
@@ -37505,84 +38126,852 @@ function kkNeato(g, nG, model) {
37505
38126
  if (nG < 2 || maxIter < 0) return;
37506
38127
  const { st, adj, ini, lens } = scanGraphMode(g, maxIter);
37507
38128
  shortestPath2(newPathState(st.n, st.dist, adj, ini));
37508
- if (model === MODEL_MDS2) mdsModel(st.dist, st.n, mdsEdges(g, st.nodes, lens));
38129
+ if (model === MODEL_MDS2) mdsModel2(st.dist, st.n, mdsEdges(g, st.nodes, lens));
37509
38130
  initialPositions2(g, st);
37510
38131
  diffeqModel(g, st);
37511
38132
  solveModel(g, st);
37512
38133
  }
37513
38134
 
37514
- // src/layout/neato/matrix-ops.ts
37515
- var fr = Math.fround;
37516
- function orthog1(n, vec) {
37517
- let sum = 0;
37518
- for (let i = 0; i < n; i++) sum += vec[i];
37519
- sum /= n;
37520
- for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
38135
+ // src/layout/neato/make-graph-data.ts
38136
+ var MODE_IPSEP2 = 3;
38137
+ var EDIST_IN = 1;
38138
+ var EDIST_OUT = -1;
38139
+ var EDIST_NONE = 0;
38140
+ function graphHasLen(g) {
38141
+ for (const e of g.edges) {
38142
+ if (e.attrs.has("len")) return true;
38143
+ }
38144
+ return false;
37521
38145
  }
37522
- function orthog1f(n, vec) {
37523
- let sum = fr(0);
37524
- for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
37525
- sum = fr(sum / n);
37526
- for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
38146
+ var edistsOf = (v) => v.edists;
38147
+ function reverseBackEdge(graph, i, e, mode) {
38148
+ const node = graph[i];
38149
+ const j = node.edges[e];
38150
+ edistsOf(node)[e] = mode === MODE_IPSEP2 ? EDIST_OUT : EDIST_IN;
38151
+ const target = graph[j];
38152
+ let f = 1;
38153
+ while (f < target.nedges && target.edges[f] !== i) f++;
38154
+ if (f >= target.nedges) throw new Error(`neato: edge ${i}-${j} has no reverse entry`);
38155
+ edistsOf(target)[f] = EDIST_OUT;
38156
+ }
38157
+ function dfsCycle(graph, start, st) {
38158
+ const { mode, mark, onstack } = st;
38159
+ const stack = [{ i: start, e: 1 }];
38160
+ mark[start] = 1;
38161
+ onstack[start] = 1;
38162
+ for (let frame = stack.at(-1); frame !== void 0; frame = stack.at(-1)) {
38163
+ const { i } = frame;
38164
+ const node = graph[i];
38165
+ if (frame.e >= node.nedges) {
38166
+ onstack[i] = 0;
38167
+ stack.pop();
38168
+ continue;
38169
+ }
38170
+ const e = frame.e++;
38171
+ if (edistsOf(node)[e] === EDIST_IN) continue;
38172
+ const j = node.edges[e];
38173
+ if (onstack[j]) {
38174
+ reverseBackEdge(graph, i, e, mode);
38175
+ } else if (!mark[j]) {
38176
+ mark[j] = 1;
38177
+ onstack[j] = 1;
38178
+ stack.push({ i: j, e: 1 });
38179
+ }
38180
+ }
37527
38181
  }
37528
- function rightMultWithVectorFF(m, n, vector, result) {
38182
+ function acyclic2(graph, nv, mode) {
38183
+ const st = { mode, mark: new Uint8Array(nv), onstack: new Uint8Array(nv) };
38184
+ for (let i = 0; i < nv; i++) {
38185
+ if (st.mark[i]) continue;
38186
+ dfsCycle(graph, i, st);
38187
+ }
38188
+ }
38189
+ function edgeDist2(dir, np, head) {
38190
+ if (dir !== void 0 && dir.startsWith("none")) return EDIST_NONE;
38191
+ return np === head ? EDIST_IN : EDIST_OUT;
38192
+ }
38193
+ function addNeighbours(g, np, entry, o) {
38194
+ const seen2 = /* @__PURE__ */ new Map();
38195
+ for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
38196
+ if (ep.head === ep.tail) continue;
38197
+ const vp = ep.tail === np ? ep.head : ep.tail;
38198
+ const vid = vp.info.id;
38199
+ const dist5 = o.haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
38200
+ const idx = seen2.get(vid);
38201
+ if (idx !== void 0) {
38202
+ if (o.haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist5);
38203
+ continue;
38204
+ }
38205
+ seen2.set(vid, entry.nedges);
38206
+ entry.edges.push(vid);
38207
+ if (o.haveLen || o.haveDir) entry.ewgts.push(dist5);
38208
+ if (o.haveDir) edistsOf(entry).push(edgeDist2(ep.attrs.get("dir"), np, ep.head));
38209
+ entry.nedges++;
38210
+ }
38211
+ }
38212
+ function makeGraphDataC(g, nodeList, haveLen, haveDir, mode = -1) {
38213
+ const vtx = nodeList.map((_, i) => ({
38214
+ nedges: 1,
38215
+ edges: [i],
38216
+ ewgts: haveLen || haveDir ? [0] : [],
38217
+ ...haveDir ? { edists: [0] } : {}
38218
+ }));
38219
+ for (const np of nodeList) addNeighbours(g, np, vtx[np.info.id], { haveLen, haveDir });
38220
+ if (haveDir) acyclic2(vtx, nodeList.length, mode);
38221
+ return vtx;
38222
+ }
38223
+
38224
+ // src/layout/neato/kkutils.ts
38225
+ function compareKeys(a, b) {
38226
+ if (a < b) return -1;
38227
+ if (a > b) return 1;
38228
+ return 0;
38229
+ }
38230
+ function gvSortByPlace(place, ordering, first, count) {
38231
+ const slice = Array.from(ordering.subarray(first, first + count));
38232
+ gvQsort(slice, (x, y) => compareKeys(place[x], place[y]));
38233
+ for (let i = 0; i < count; i++) ordering[first + i] = slice[i];
38234
+ }
38235
+ function quicksortPlace(place, ordering, size) {
38236
+ gvSortByPlace(place, ordering, 0, size);
38237
+ }
38238
+ function quicksortPlacef(place, ordering, first, last) {
38239
+ if (first < last) {
38240
+ gvSortByPlace(place, ordering, first, last - first + 1);
38241
+ }
38242
+ }
38243
+ function computeApspDijkstra(graph, n) {
38244
+ const dij = [];
38245
+ for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
38246
+ for (let i = 0; i < n; i++) ngdijkstra(i, graph, n, dij[i]);
38247
+ return dij;
38248
+ }
38249
+ function computeApspSimple(graph, n) {
38250
+ const dij = [];
38251
+ for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
38252
+ for (let i = 0; i < n; i++) bfs(i, graph, n, dij[i]);
38253
+ return dij;
38254
+ }
38255
+ function computeApsp(graph, n) {
38256
+ return graph[0].ewgts.length > 0 ? computeApspDijkstra(graph, n) : computeApspSimple(graph, n);
38257
+ }
38258
+
38259
+ // src/layout/neato/quad-prog-solve.ts
38260
+ var fr2 = Math.fround;
38261
+ var TOLERANCE = fr2(0.01);
38262
+ var BOUND = 1e9;
38263
+ var BLOCK_EPSILON = 1e-9;
38264
+ var NO_SPLIT = -1;
38265
+ var BITS = new DataView(new ArrayBuffer(8));
38266
+ function oddNeighbour(s, awayFromZero) {
38267
+ BITS.setFloat64(0, s);
38268
+ const hi = BITS.getUint32(0);
38269
+ const lo = BITS.getUint32(4);
38270
+ if (awayFromZero) {
38271
+ BITS.setUint32(4, lo + 1);
38272
+ } else if (lo === 0) {
38273
+ BITS.setUint32(0, hi - 1);
38274
+ BITS.setUint32(4, 4294967295);
38275
+ } else {
38276
+ BITS.setUint32(4, lo - 1);
38277
+ }
38278
+ return BITS.getFloat64(0);
38279
+ }
38280
+ function fmaf(a, b, c) {
38281
+ const p = a * b;
38282
+ const s = p + c;
38283
+ const bv = s - p;
38284
+ const err = p - (s - bv) + (c - bv);
38285
+ if (err === 0 || !Number.isFinite(s)) return fr2(s);
38286
+ BITS.setFloat64(0, s);
38287
+ if ((BITS.getUint32(4) & 1) !== 0) return fr2(s);
38288
+ return fr2(oddNeighbour(s, err > 0 === s > 0));
38289
+ }
38290
+ function blockPlaceNumerator(blockDeg, desPlaceBlock, negLapTimesDesired, toBlockConnectivity, curPlace) {
38291
+ const t = fmaf(blockDeg, desPlaceBlock, negLapTimesDesired);
38292
+ return fmaf(toBlockConnectivity, curPlace, t);
38293
+ }
38294
+ function equals(a, b) {
38295
+ return Math.abs(fr2(a - b)) < TOLERANCE;
38296
+ }
38297
+ function fminf(a, b) {
38298
+ if (Number.isNaN(a)) return b;
38299
+ if (Number.isNaN(b)) return a;
38300
+ return a < b ? a : b;
38301
+ }
38302
+ function fmaxf(a, b) {
38303
+ if (Number.isNaN(a)) return b;
38304
+ if (Number.isNaN(b)) return a;
38305
+ return a > b ? a : b;
38306
+ }
38307
+ function unpackMatrix(packedMat, n) {
38308
+ const flat = new Float32Array(n * n);
38309
+ const mat = new Array(n);
38310
+ for (let i = 0; i < n; i++) mat[i] = flat.subarray(i * n, (i + 1) * n);
38311
+ for (let i = 0, k = 0; i < n; i++) {
38312
+ for (let j = i; j < n; j++, k++) {
38313
+ mat[j][i] = mat[i][j] = packedMat[k];
38314
+ }
38315
+ }
38316
+ return mat;
38317
+ }
38318
+ function ensureMonotonicOrderingWithGaps(place, n, ordering, levels, numLevels, levelsGap) {
38319
+ let lowerBound = fr2(-1e9);
38320
+ let level = -1;
38321
+ let maxInLevel = 0;
38322
+ for (let i = 0; i < n; i++) {
38323
+ if (i >= maxInLevel) {
38324
+ level++;
38325
+ maxInLevel = level === numLevels ? n : levels[level];
38326
+ lowerBound = i > 0 ? fr2(place[ordering[i - 1]] + levelsGap) : fr2(-1e9);
38327
+ quicksortPlacef(place, ordering, i, maxInLevel - 1);
38328
+ }
38329
+ const node = ordering[i];
38330
+ if (place[node] < lowerBound) place[node] = lowerBound;
38331
+ }
38332
+ }
38333
+ function computeNodeLevels(e) {
38334
+ const lev = new Int32Array(e.n);
38335
+ let level = -1;
38336
+ let maxInLevel = 0;
38337
+ for (let i = 0; i < e.n; i++) {
38338
+ if (i >= maxInLevel) {
38339
+ level++;
38340
+ maxInLevel = level === e.numLevels ? e.n : e.levels[level];
38341
+ }
38342
+ lev[e.ordering[i]] = level;
38343
+ }
38344
+ return lev;
38345
+ }
38346
+ function growBlock(c, left2, curPlace) {
38347
+ const { place, lev, levelsGap, e } = c;
38348
+ const gap = e.fArray4;
38349
+ let targetPlace = curPlace;
38350
+ gap[e.ordering[left2]] = 0;
38351
+ let right2;
38352
+ for (right2 = left2 + 1; right2 < e.n; right2++) {
38353
+ if (lev[right2] > lev[right2 - 1]) {
38354
+ targetPlace = fr2(targetPlace + levelsGap);
38355
+ }
38356
+ const node = e.ordering[right2];
38357
+ if (Math.abs(fr2(place[node] - targetPlace)) > BLOCK_EPSILON) break;
38358
+ gap[node] = fr2(place[node] - curPlace);
38359
+ }
38360
+ return right2;
38361
+ }
38362
+ function computeDesiredPlaces(c, left2, right2) {
38363
+ const { e, place, b } = c;
38364
+ for (let i = left2; i < right2; i++) {
38365
+ const node = e.ordering[i];
38366
+ let newPlaceI = -b[node];
38367
+ const lapNode = e.A[node];
38368
+ for (let j = 0; j < e.n; j++) {
38369
+ if (j === node) continue;
38370
+ newPlaceI = fmaf(lapNode[j], place[j], newPlaceI);
38371
+ }
38372
+ e.fArray1[node] = fr2(fr2(newPlaceI / -lapNode[node]) - e.fArray4[node]);
38373
+ }
38374
+ }
38375
+ function collectWhere(c, from, to, test) {
38376
+ for (let j = from; j < to; j++) {
38377
+ const node = c.e.ordering[j];
38378
+ if (test(c.e.fArray1[node])) c.block.push(node);
38379
+ }
38380
+ }
38381
+ function orderBlockByLevels(c, left2, right2, curPlace) {
38382
+ const { e } = c;
38383
+ c.block.length = 0;
38384
+ let firstNextLevel = 0;
38385
+ for (let i = left2; i < right2; i = firstNextLevel) {
38386
+ const level = c.lev[e.ordering[i]];
38387
+ firstNextLevel = level === e.numLevels ? right2 : Math.min(right2, e.levels[level]);
38388
+ collectWhere(c, i, firstNextLevel, (d) => d < curPlace);
38389
+ collectWhere(c, i, firstNextLevel, (d) => d === curPlace);
38390
+ collectWhere(c, i, firstNextLevel, (d) => d > curPlace);
38391
+ }
38392
+ }
38393
+ function computePrefixDesiredPlaces(c, curPlace) {
38394
+ const { e, block } = c;
38395
+ let desPlaceBlock = 0;
38396
+ let blockDeg = 0;
38397
+ for (let i = 0; i < block.length; i++) {
38398
+ const node = block[i];
38399
+ let toBlockConnectivity = 0;
38400
+ const lapNode = e.A[node];
38401
+ for (let j = 0; j < i; j++) {
38402
+ toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
38403
+ }
38404
+ toBlockConnectivity = fr2(toBlockConnectivity * 2);
38405
+ const num2 = blockPlaceNumerator(
38406
+ blockDeg,
38407
+ desPlaceBlock,
38408
+ fr2(-lapNode[node] * e.fArray1[node]),
38409
+ toBlockConnectivity,
38410
+ curPlace
38411
+ );
38412
+ desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
38413
+ e.fArray2[i] = desPlaceBlock;
38414
+ blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
38415
+ }
38416
+ if (e.n >= 0 && block.length === e.n) {
38417
+ e.fArray2[e.n - 1] = curPlace;
38418
+ }
38419
+ }
38420
+ function computeSuffixDesiredPlaces(c, curPlace) {
38421
+ const { e, block } = c;
38422
+ let desPlaceBlock = 0;
38423
+ let blockDeg = 0;
38424
+ for (let i = block.length - 1; i >= 0; i--) {
38425
+ const node = block[i];
38426
+ let toBlockConnectivity = 0;
38427
+ const lapNode = e.A[node];
38428
+ for (let j = i + 1; j < block.length; j++) {
38429
+ toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
38430
+ }
38431
+ toBlockConnectivity = fr2(toBlockConnectivity * 2);
38432
+ const num2 = blockPlaceNumerator(
38433
+ blockDeg,
38434
+ desPlaceBlock,
38435
+ fr2(-lapNode[node] * e.fArray1[node]),
38436
+ toBlockConnectivity,
38437
+ curPlace
38438
+ );
38439
+ desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
38440
+ e.fArray3[i] = desPlaceBlock;
38441
+ blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
38442
+ }
38443
+ if (e.n >= 0 && block.length === e.n) {
38444
+ e.fArray3[0] = curPlace;
38445
+ }
38446
+ }
38447
+ var LIMITED = new Float64Array(2);
38448
+ function limitMoves(prefix, suffix, curPlace) {
38449
+ if (suffix < prefix) {
38450
+ if (suffix < curPlace) {
38451
+ if (prefix > curPlace) prefix = curPlace;
38452
+ suffix = prefix;
38453
+ } else if (prefix > curPlace) {
38454
+ prefix = suffix;
38455
+ }
38456
+ }
38457
+ LIMITED[0] = prefix;
38458
+ LIMITED[1] = suffix;
38459
+ }
38460
+ function findBestSplit(c, curPlace) {
38461
+ const { e, block } = c;
38462
+ let bestI = NO_SPLIT;
38463
+ let maxMovement = 0;
38464
+ for (let i = 0; i < block.length; i++) {
38465
+ const suffixDesPlace = e.fArray3[i];
38466
+ const prefixDesPlace = i > 0 ? e.fArray2[i - 1] : suffixDesPlace;
38467
+ limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
38468
+ const movement = (block.length - i) * Math.abs(fr2(LIMITED[1] - curPlace)) + i * Math.abs(fr2(LIMITED[0] - curPlace));
38469
+ if (movement > maxMovement) {
38470
+ maxMovement = movement;
38471
+ bestI = i;
38472
+ }
38473
+ }
38474
+ return bestI;
38475
+ }
38476
+ function computeUpperBound(c, right2) {
38477
+ const { e, place, lev, levelsGap, block } = c;
38478
+ if (right2 >= e.n) return BOUND;
38479
+ const lastGap = e.fArray4[block[block.length - 1]];
38480
+ const nextPlace = place[e.ordering[right2]];
38481
+ if (lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
38482
+ return fr2(fr2(nextPlace - levelsGap) - lastGap);
38483
+ }
38484
+ return fr2(nextPlace - lastGap);
38485
+ }
38486
+ function nextLowerBound(c, right2) {
38487
+ const { e, place, lev, levelsGap, block } = c;
38488
+ const last = place[block[block.length - 1]];
38489
+ if (right2 < e.n && lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
38490
+ return fr2(last + levelsGap);
38491
+ }
38492
+ return last;
38493
+ }
38494
+ function moveSplitBlock(c, bestI, left2, right2, curPlace) {
38495
+ const { e, place, block } = c;
38496
+ let suffixDesPlace = e.fArray3[bestI];
38497
+ let prefixDesPlace = bestI > 0 ? e.fArray2[bestI - 1] : suffixDesPlace;
38498
+ suffixDesPlace = fminf(suffixDesPlace, computeUpperBound(c, right2));
38499
+ prefixDesPlace = fmaxf(prefixDesPlace, c.lowerBound);
38500
+ limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
38501
+ prefixDesPlace = LIMITED[0];
38502
+ suffixDesPlace = LIMITED[1];
38503
+ for (let i = 0; i < bestI; i++) {
38504
+ place[block[i]] = fr2(prefixDesPlace + e.fArray4[block[i]]);
38505
+ }
38506
+ for (let i = bestI; i < block.length; i++) {
38507
+ place[block[i]] = fr2(suffixDesPlace + e.fArray4[block[i]]);
38508
+ }
38509
+ c.lowerBound = nextLowerBound(c, right2);
38510
+ for (let i = left2; i < right2; i++) e.ordering[i] = block[i - left2];
38511
+ c.converged = c.converged && equals(prefixDesPlace, curPlace) && equals(suffixDesPlace, curPlace);
38512
+ }
38513
+ function processBlock(c, left2) {
38514
+ const curPlace = c.place[c.e.ordering[left2]];
38515
+ const right2 = growBlock(c, left2, curPlace);
38516
+ computeDesiredPlaces(c, left2, right2);
38517
+ orderBlockByLevels(c, left2, right2, curPlace);
38518
+ computePrefixDesiredPlaces(c, curPlace);
38519
+ computeSuffixDesiredPlaces(c, curPlace);
38520
+ const bestI = findBestSplit(c, curPlace);
38521
+ if (bestI !== NO_SPLIT) {
38522
+ moveSplitBlock(c, bestI, left2, right2, curPlace);
38523
+ } else {
38524
+ c.lowerBound = nextLowerBound(c, right2);
38525
+ }
38526
+ return right2;
38527
+ }
38528
+ function constrainedMajorizationNewWithGaps(e, b, coords, curAxis, maxIterations, levelsGap) {
38529
+ const place = coords[curAxis];
38530
+ if (maxIterations <= 0) return;
38531
+ const gap = fr2(levelsGap);
38532
+ ensureMonotonicOrderingWithGaps(place, e.n, e.ordering, e.levels, e.numLevels, gap);
38533
+ const c = {
38534
+ e,
38535
+ place,
38536
+ b,
38537
+ lev: computeNodeLevels(e),
38538
+ levelsGap: gap,
38539
+ block: [],
38540
+ lowerBound: fr2(-BOUND),
38541
+ converged: false
38542
+ };
38543
+ for (let counter = 0; counter < maxIterations && !c.converged; counter++) {
38544
+ c.converged = true;
38545
+ c.lowerBound = fr2(-BOUND);
38546
+ for (let left2 = 0, right2; left2 < e.n; left2 = right2) {
38547
+ right2 = processBlock(c, left2);
38548
+ }
38549
+ orthog1f(e.n, place);
38550
+ }
38551
+ }
38552
+ function initConstrainedMajorization(packedMat, n, ordering, levels, numLevels) {
38553
+ return {
38554
+ A: unpackMatrix(packedMat, n),
38555
+ n,
38556
+ fArray1: new Float32Array(n),
38557
+ fArray2: new Float32Array(n),
38558
+ fArray3: new Float32Array(n),
38559
+ fArray4: new Float32Array(n),
38560
+ ordering,
38561
+ levels,
38562
+ numLevels
38563
+ };
38564
+ }
38565
+
38566
+ // src/layout/neato/conjgrad-mkernel.ts
38567
+ var fr3 = Math.fround;
38568
+ var RIGHT_MULT_BLOCK = 16;
38569
+ var ZERO_LENGTH_MESSAGE = "conjugate_gradient: unexpected length 0 vector\n";
38570
+ function rightMultWithVectorFFFused(m, n, vector, result) {
37529
38571
  for (let i = 0; i < n; i++) result[i] = 0;
37530
38572
  let index = 0;
37531
38573
  for (let i = 0; i < n; i++) {
37532
38574
  const vi = vector[i];
37533
- let res = fr(m[index++] * vi);
38575
+ let res = fmaf(m[index++], vi, 0);
38576
+ const len = n - i - 1;
38577
+ const blockEnd = i + 1 + (len - len % RIGHT_MULT_BLOCK);
37534
38578
  for (let j = i + 1; j < n; j++, index++) {
37535
- res = fr(res + fr(m[index] * vector[j]));
37536
- result[j] = result[j] + fr(m[index] * vi);
38579
+ const mij = m[index];
38580
+ res = j < blockEnd ? fr3(res + fr3(mij * vector[j])) : fmaf(mij, vector[j], res);
38581
+ result[j] = fmaf(mij, vi, result[j]);
37537
38582
  }
37538
38583
  result[i] = result[i] + res;
37539
38584
  }
37540
38585
  }
37541
- function vectorsSubtractionF(n, v1, v2, result) {
37542
- for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
38586
+ function vectorsMultAdditionFused(n, v1, alpha, v2) {
38587
+ for (let i = 0; i < n; i++) v1[i] = fmaf(alpha, v2[i], v1[i]);
37543
38588
  }
37544
- function vectorsMultAdditionF(n, v1, alpha, v2) {
37545
- const a = fr(alpha);
37546
- for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
38589
+ var CgStep = { CONTINUE: 0, STOP: 1, ERROR: 2 };
38590
+ function initialState(A3, x, b, n) {
38591
+ const Ax = new Float32Array(n);
38592
+ const st = { n, r: new Float32Array(n), p: new Float32Array(n), Ap: new Float32Array(n), rR: 0 };
38593
+ orthog1f(n, x);
38594
+ orthog1f(n, b);
38595
+ rightMultWithVectorFFFused(A3, n, x, Ax);
38596
+ orthog1f(n, Ax);
38597
+ vectorsSubtractionF(n, b, Ax, st.r);
38598
+ copyVectorF(n, st.r, st.p);
38599
+ st.rR = vectorsInnerProductF(n, st.r, st.r);
38600
+ return st;
37547
38601
  }
37548
- function vectorsInnerProductF(n, v1, v2) {
37549
- let result = 0;
37550
- for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
37551
- return result;
38602
+ function cgIteration(A3, x, st, last) {
38603
+ const { n, r, p, Ap } = st;
38604
+ orthog1f(n, p);
38605
+ orthog1f(n, x);
38606
+ orthog1f(n, r);
38607
+ rightMultWithVectorFFFused(A3, n, p, Ap);
38608
+ orthog1f(n, Ap);
38609
+ const pAp = vectorsInnerProductF(n, p, Ap);
38610
+ if (pAp === 0) return CgStep.STOP;
38611
+ const alpha = st.rR / pAp;
38612
+ vectorsMultAdditionFused(n, x, fr3(alpha), p);
38613
+ if (last) return CgStep.CONTINUE;
38614
+ vectorsMultAdditionFused(n, r, fr3(-alpha), Ap);
38615
+ const rRNew = vectorsInnerProductF(n, r, r);
38616
+ if (st.rR === 0) {
38617
+ agerrorf(ZERO_LENGTH_MESSAGE);
38618
+ return CgStep.ERROR;
38619
+ }
38620
+ const beta = fr3(rRNew / st.rR);
38621
+ st.rR = rRNew;
38622
+ for (let j = 0; j < n; j++) p[j] = fmaf(beta, p[j], r[j]);
38623
+ return CgStep.CONTINUE;
38624
+ }
38625
+ function conjugateGradientMkernelFused(A3, x, b, n, o) {
38626
+ const st = initialState(A3, x, b, n);
38627
+ for (let i = 0; i < o.maxIterations && maxAbsF(n, st.r) > o.tol; i++) {
38628
+ const step = cgIteration(A3, x, st, i >= o.maxIterations - 1);
38629
+ if (step === CgStep.STOP) break;
38630
+ if (step === CgStep.ERROR) return 1;
38631
+ }
38632
+ return 0;
37552
38633
  }
37553
- function copyVectorF(n, src, dst) {
37554
- for (let i = 0; i < n; i++) dst[i] = src[i];
38634
+
38635
+ // src/layout/neato/opt-arrangement.ts
38636
+ var HIERARCHY_CG_TOL = 1e-3;
38637
+ function constructB(graph, n, b) {
38638
+ for (let i = 0; i < n; i++) {
38639
+ if (graph[0].edists == null) continue;
38640
+ let bI = 0;
38641
+ const node = graph[i];
38642
+ for (let j = 1; j < node.nedges; j++) {
38643
+ bI += Math.fround(Math.fround(node.ewgts[j]) * node.edists[j]);
38644
+ }
38645
+ b[i] = bI;
38646
+ }
37555
38647
  }
37556
- function maxAbsF(n, vec) {
37557
- let max = fr(-1e30);
38648
+ function setUniformWeights(graph, n) {
38649
+ const old = [];
37558
38650
  for (let i = 0; i < n; i++) {
37559
- const a = fr(Math.abs(vec[i]));
37560
- if (a > max) max = a;
38651
+ const node = graph[i];
38652
+ old.push(node.ewgts);
38653
+ const weights = new Array(node.nedges).fill(1);
38654
+ weights[0] = -(node.nedges - 1);
38655
+ node.ewgts = weights;
37561
38656
  }
37562
- return max;
38657
+ return old;
37563
38658
  }
37564
- function squareVec(n, vec) {
37565
- for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
38659
+ function computeYCoords(graph, n, yCoords, maxIterations) {
38660
+ let rv = 0;
38661
+ const b = new Float64Array(n);
38662
+ constructB(graph, n, b);
38663
+ initVecOrth1(n, yCoords);
38664
+ const oldEwgts = setUniformWeights(graph, n);
38665
+ if (conjugateGradient(graph, yCoords, b, n, HIERARCHY_CG_TOL, maxIterations) < 0) {
38666
+ rv = 1;
38667
+ }
38668
+ for (let i = 0; i < n; i++) graph[i].ewgts = oldEwgts[i];
38669
+ return rv;
37566
38670
  }
37567
- function invertVec(n, vec) {
38671
+
38672
+ // src/layout/neato/compute-hierarchy.ts
38673
+ function countLevels(y, ordering, n, tol) {
38674
+ let numLevels = 0;
38675
+ for (let i = 1; i < n; i++) {
38676
+ if (y[ordering[i]] - y[ordering[i - 1]] > tol) numLevels++;
38677
+ }
38678
+ return numLevels;
38679
+ }
38680
+ function fillLevels(y, ordering, n, tol, numLevels) {
38681
+ if (numLevels === 0) {
38682
+ const levels2 = new Int32Array(1);
38683
+ levels2[0] = n;
38684
+ return levels2;
38685
+ }
38686
+ const levels = new Int32Array(numLevels);
38687
+ let count = 0;
38688
+ for (let i = 1; i < n; i++) {
38689
+ if (y[ordering[i]] - y[ordering[i - 1]] > tol) levels[count++] = i;
38690
+ }
38691
+ return levels;
38692
+ }
38693
+ function computeHierarchy(graph, n, absTol, relTol, given) {
38694
+ let y;
38695
+ if (given) {
38696
+ y = given;
38697
+ } else {
38698
+ y = new Float64Array(n);
38699
+ if (computeYCoords(graph, n, y, n)) return null;
38700
+ }
38701
+ const ordering = new Int32Array(n);
38702
+ for (let i = 0; i < n; i++) ordering[i] = i;
38703
+ quicksortPlace(y, ordering, n);
38704
+ const hierarchySpan = y[ordering[n - 1]] - y[ordering[0]];
38705
+ const relative = relTol * hierarchySpan / (n - 1);
38706
+ const tol = absTol > relative ? absTol : relative;
38707
+ const numLevels = countLevels(y, ordering, n, tol);
38708
+ return { ordering, levels: fillLevels(y, ordering, n, tol, numLevels), numLevels };
38709
+ }
38710
+
38711
+ // src/layout/neato/smart-ini-x.ts
38712
+ var fr4 = Math.fround;
38713
+ var SCALE_FACTOR = 256;
38714
+ var DBL_EPSILON = 2220446049250313e-31;
38715
+ var POWER_LENGTH_FLOOR = 1e-10;
38716
+ var BLOCK_STANDARDIZE_NORM = 4;
38717
+ var BLOCK_MAT_MULT_ROW = 4;
38718
+ var BLOCK_MAT_MULT_ORTHOG = 8;
38719
+ var BLOCK_GUESS_ORTHOG = 8;
38720
+ var BLOCK_GUESS_LEN = BLOCK_NONE;
38721
+ var BLOCK_LOOP_LEN = BLOCK_NONE;
38722
+ var BLOCK_ANGLE = 8;
38723
+ var BLOCK_UNIFORM_SUMS = 4;
38724
+ var BLOCK_AVGS = 4;
38725
+ function standardize(orthog, nvtxs) {
38726
+ let avg = 0;
38727
+ for (let i = 0; i < nvtxs; i++) avg += orthog[i];
38728
+ avg /= nvtxs;
38729
+ for (let i = 0; i < nvtxs; i++) orthog[i] = orthog[i] - avg;
38730
+ const len = norm(orthog, nvtxs - 1, BLOCK_STANDARDIZE_NORM);
38731
+ if (Math.abs(len) < DBL_EPSILON) return;
38732
+ vectorsScalarMult(nvtxs, orthog, 1 / len, orthog);
38733
+ }
38734
+ function matMultVecOrthog(mat, dim, vec, result, orthog) {
38735
+ const blocked = dim - dim % BLOCK_MAT_MULT_ROW;
38736
+ for (let i = 0; i < dim; i++) {
38737
+ const row = mat[i];
38738
+ let sum = 0;
38739
+ let j = 0;
38740
+ for (; j < blocked; j++) sum += row[j] * vec[j];
38741
+ for (; j < dim; j++) sum = fma2(row[j], vec[j], sum);
38742
+ result[i] = sum;
38743
+ }
38744
+ const alpha = -innerProduct(dim, result, orthog, BLOCK_MAT_MULT_ORTHOG);
38745
+ scadd(result, dim - 1, alpha, orthog);
38746
+ }
38747
+ function orthogonalizeAgainstEigs(p, vec, count, block) {
38748
+ for (let j = 0; j < count; j++) {
38749
+ const alpha = -innerProduct(p.n, p.eigs[j], vec, block);
38750
+ scadd(vec, p.n - 1, alpha, p.eigs[j]);
38751
+ }
38752
+ }
38753
+ function chooseStartVector(p, i) {
38754
+ const curr = p.eigs[i];
38755
+ for (; ; ) {
38756
+ for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
38757
+ const alpha = -innerProduct(p.n, p.orthog, curr, BLOCK_GUESS_ORTHOG);
38758
+ scadd(curr, p.n - 1, alpha, p.orthog);
38759
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
38760
+ const len = norm(curr, p.n - 1, BLOCK_GUESS_LEN);
38761
+ if (len < POWER_LENGTH_FLOOR) continue;
38762
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
38763
+ return;
38764
+ }
38765
+ }
38766
+ function iterateEigenvector(p, i, tol, work) {
38767
+ const curr = p.eigs[i];
38768
+ for (; ; ) {
38769
+ copyVector(p.n, curr, work.last);
38770
+ matMultVecOrthog(p.mat, p.n, curr, work.tmp, p.orthog);
38771
+ copyVector(p.n, work.tmp, curr);
38772
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
38773
+ const len = norm(curr, p.n - 1, BLOCK_LOOP_LEN);
38774
+ if (len < POWER_LENGTH_FLOOR) {
38775
+ return { nullSpace: true, eval: 0 };
38776
+ }
38777
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
38778
+ const angle = innerProduct(p.n, curr, work.last, BLOCK_ANGLE);
38779
+ if (!(Math.abs(angle) < tol)) {
38780
+ return { nullSpace: false, eval: angle * len };
38781
+ }
38782
+ }
38783
+ }
38784
+ function fillNullSpaceEigenvectors(p, from, neigs) {
38785
+ for (let i = from; i < neigs; i++) {
38786
+ const curr = p.eigs[i];
38787
+ for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
38788
+ orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
38789
+ const len = norm(curr, p.n - 1, BLOCK_NONE);
38790
+ vectorsScalarMult(p.n, curr, 1 / len, curr);
38791
+ p.evals[i] = 0;
38792
+ }
38793
+ }
38794
+ function sortEigenvectors(p, neigs, tmp) {
38795
+ for (let i = 0; i < neigs - 1; i++) {
38796
+ let largestIndex = i;
38797
+ let largestEval = p.evals[largestIndex];
38798
+ for (let j = i + 1; j < neigs; j++) {
38799
+ if (largestEval < p.evals[j]) {
38800
+ largestIndex = j;
38801
+ largestEval = p.evals[largestIndex];
38802
+ }
38803
+ }
38804
+ if (largestIndex !== i) {
38805
+ copyVector(p.n, p.eigs[i], tmp);
38806
+ copyVector(p.n, p.eigs[largestIndex], p.eigs[i]);
38807
+ copyVector(p.n, tmp, p.eigs[largestIndex]);
38808
+ p.evals[largestIndex] = p.evals[i];
38809
+ p.evals[i] = largestEval;
38810
+ }
38811
+ }
38812
+ }
38813
+ function powerIterationOrthog(p, neigsIn, pIterationThreshold) {
38814
+ const work = { tmp: new Float64Array(p.n), last: new Float64Array(p.n) };
38815
+ const tol = 1 - pIterationThreshold;
38816
+ const neigs = neigsIn >= p.n ? p.n : neigsIn;
38817
+ let i = 0;
38818
+ for (; i < neigs; i++) {
38819
+ chooseStartVector(p, i);
38820
+ const res = iterateEigenvector(p, i, tol, work);
38821
+ if (res.nullSpace) break;
38822
+ p.evals[i] = res.eval;
38823
+ }
38824
+ fillNullSpaceEigenvectors(p, i, neigs);
38825
+ sortEigenvectors(p, neigs, work.tmp);
38826
+ }
38827
+ function computeAvgs(Dij, n) {
38828
+ const rowAvg = new Float32Array(n);
38829
+ let sum = 0;
38830
+ const blocked = n - n % BLOCK_AVGS;
37568
38831
  for (let i = 0; i < n; i++) {
37569
- if (vec[i] !== 0) vec[i] = 1 / vec[i];
38832
+ let sumRow = 0;
38833
+ const row = Dij[i];
38834
+ let j = 0;
38835
+ for (; j < blocked; j++) {
38836
+ sum += row[j] * row[j];
38837
+ sumRow += row[j] * row[j];
38838
+ }
38839
+ for (; j < n; j++) {
38840
+ sum = fma2(row[j], row[j], sum);
38841
+ sumRow = fma2(row[j], row[j], sumRow);
38842
+ }
38843
+ rowAvg[i] = fr4(fr4(sumRow) / n);
37570
38844
  }
38845
+ return { rowAvg, allAvg: fr4(fr4(sum) / (n * n)) };
37571
38846
  }
37572
- function sqrtVecF(n, source, target) {
38847
+ function computeBij(Dij, n) {
38848
+ const Bij = [];
38849
+ for (let i = 0; i < n; i++) Bij.push(new Float32Array(n));
38850
+ const { rowAvg, allAvg } = computeAvgs(Dij, n);
37573
38851
  for (let i = 0; i < n; i++) {
37574
- if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
38852
+ for (let j = 0; j <= i; j++) {
38853
+ const fD = fr4(Dij[i][j]);
38854
+ const t = fr4(fma2(-fD, fD, rowAvg[i]));
38855
+ Bij[i][j] = fr4(fr4(t + rowAvg[j]) - allAvg);
38856
+ Bij[j][i] = Bij[i][j];
38857
+ }
38858
+ }
38859
+ return Bij;
38860
+ }
38861
+ function cmdsOrthog(n, dim, eigs, tol, input) {
38862
+ const { orthog, Dij } = input;
38863
+ const Bij = computeBij(Dij, n);
38864
+ const evals = new Float64Array(dim);
38865
+ const orthogAux = Float64Array.from(orthog.subarray(0, n));
38866
+ standardize(orthogAux, n);
38867
+ powerIterationOrthog({ mat: Bij, n, eigs, evals, orthog: orthogAux }, dim, tol);
38868
+ for (let i = 0; i < dim; i++) {
38869
+ for (let j = 0; j < n; j++) eigs[i][j] = eigs[i][j] * Math.sqrt(Math.abs(evals[i]));
37575
38870
  }
37576
38871
  }
37577
- function invertSqrtVec(n, vec) {
38872
+ function scaleGivenCoords(Dij, n, x) {
38873
+ let sum1 = 0;
38874
+ let sum2 = 0;
38875
+ for (let i = 1; i < n; i++) {
38876
+ const blocked = i - i % BLOCK_UNIFORM_SUMS;
38877
+ for (let j = 0; j < i; j++) {
38878
+ const d = Dij[i][j];
38879
+ const f = Math.abs(x[i] - x[j]);
38880
+ const t1 = 1 / d;
38881
+ const t2 = 1 / Math.imul(d, d) * f;
38882
+ if (j < blocked) {
38883
+ sum1 += t1 * f;
38884
+ sum2 += t2 * f;
38885
+ } else {
38886
+ sum1 = fma2(t1, f, sum1);
38887
+ sum2 = fma2(t2, f, sum2);
38888
+ }
38889
+ }
38890
+ }
38891
+ const uniLength = Math.abs(sum2) === Infinity ? 0 : sum1 / sum2;
38892
+ for (let i = 0; i < n; i++) x[i] = x[i] * uniLength;
38893
+ return uniLength;
38894
+ }
38895
+ function computeLaplacian(Dij, n) {
38896
+ const lap = [];
37578
38897
  for (let i = 0; i < n; i++) {
37579
- if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
38898
+ const row = new Float32Array(n);
38899
+ let degree = fr4(0);
38900
+ for (let j = 0; j < n; j++) {
38901
+ if (j === i) continue;
38902
+ const w = fr4(fr4(-1) / fr4(fr4(Dij[i][j]) * fr4(Dij[i][j])));
38903
+ row[j] = w;
38904
+ degree = fr4(degree - w);
38905
+ }
38906
+ row[i] = degree;
38907
+ lap.push(row);
38908
+ }
38909
+ return lap;
38910
+ }
38911
+ function computeResidualDistances(Dij, n, x) {
38912
+ for (let i = 1; i < n; i++) {
38913
+ const posI = x[i];
38914
+ for (let j = 0; j < i; j++) {
38915
+ const t = posI - x[j];
38916
+ const d = Dij[i][j];
38917
+ const diff = fma2(d, d, -(t * t));
38918
+ const v = diff > 0 ? Math.sqrt(diff) : 0;
38919
+ Dij[i][j] = v;
38920
+ Dij[j][i] = v;
38921
+ }
38922
+ }
38923
+ }
38924
+ function balanceOf(i, n, y, ctx) {
38925
+ const posI = y[i];
38926
+ let b = 0;
38927
+ for (let j = 0; j < n; j++) {
38928
+ if (j === i) continue;
38929
+ const term = fr4(fr4(ctx.Dij[i][j]) * -ctx.lap[i][j]);
38930
+ if (posI >= y[j]) b += term;
38931
+ else b -= term;
37580
38932
  }
38933
+ return b;
38934
+ }
38935
+ function solveBalanced(ctx, n, y, balance, convTol) {
38936
+ let converged = false;
38937
+ for (let iterations2 = 0; iterations2 < 200 && !converged; iterations2++) {
38938
+ if (conjugateGradientF(ctx.lap, y, balance, n, { tol: convTol, maxIterations: n, ortho1: true }) < 0) return 1;
38939
+ converged = true;
38940
+ for (let i = 0; i < n; i++) {
38941
+ const b = balanceOf(i, n, y, ctx);
38942
+ if (b !== balance[i] && Math.abs(1 - b / balance[i]) > 1e-5) {
38943
+ converged = false;
38944
+ balance[i] = b;
38945
+ }
38946
+ }
38947
+ }
38948
+ return 0;
38949
+ }
38950
+ function imdsGivenDim(graph, n, givenCoords, newCoords, conjTol) {
38951
+ const x = givenCoords;
38952
+ const y = newCoords;
38953
+ const Dij = computeApsp(graph, n);
38954
+ for (let i = 0; i < n; i++) {
38955
+ for (let j = 0; j < n; j++) Dij[i][j] = Dij[i][j] * SCALE_FACTOR;
38956
+ }
38957
+ const uniLength = scaleGivenCoords(Dij, n, x);
38958
+ cmdsOrthog(n, 1, [y], conjTol, { orthog: x, Dij });
38959
+ const lap = computeLaplacian(Dij, n);
38960
+ computeResidualDistances(Dij, n, x);
38961
+ const ctx = { Dij, lap };
38962
+ const balance = new Float64Array(n);
38963
+ for (let i = 0; i < n; i++) balance[i] = balanceOf(i, n, y, ctx);
38964
+ if (solveBalanced(ctx, n, y, balance, conjTol) === 1) return 1;
38965
+ for (let i = 0; !(Math.abs(uniLength) < DBL_EPSILON) && i < n; i++) {
38966
+ x[i] = x[i] / uniLength;
38967
+ y[i] = y[i] / uniLength;
38968
+ }
38969
+ return 0;
37581
38970
  }
37582
38971
 
37583
38972
  // src/layout/neato/stress-kernel.ts
37584
- var fr2 = Math.fround;
37585
- var TOLERANCE_CG = 1e-3;
38973
+ var fr5 = Math.fround;
38974
+ var TOLERANCE_CG2 = 1e-3;
37586
38975
  var OPT_EXP_FLAG = 2;
37587
38976
  function computeApspPacked2(graph, n) {
37588
38977
  const Dij = new Float32Array(n * (n + 1) / 2);
@@ -37642,9 +39031,9 @@ function cgStep(st, last) {
37642
39031
  vectorsMultAdditionF(n, st.r, -alpha, st.Ap);
37643
39032
  const rRNew = vectorsInnerProductF(n, st.r, st.r);
37644
39033
  if (st.rR === 0) return false;
37645
- const betaF = fr2(rRNew / st.rR);
39034
+ const betaF = fr5(rRNew / st.rR);
37646
39035
  st.rR = rRNew;
37647
- for (let j = 0; j < n; j++) st.p[j] = fr2(betaF * st.p[j]) + st.r[j];
39036
+ for (let j = 0; j < n; j++) st.p[j] = fr5(betaF * st.p[j]) + st.r[j];
37648
39037
  }
37649
39038
  return true;
37650
39039
  }
@@ -37706,8 +39095,8 @@ function buildLap1(lap1, lap2, coords, shape) {
37706
39095
  for (let k = 0; k < dim; k++) {
37707
39096
  const ck = coords[k];
37708
39097
  for (let x = 0; x < len; x++) {
37709
- const tmp = fr2(ck[i] + fr2(-1 * ck[i + 1 + x]));
37710
- distAccumulator[x] = distAccumulator[x] + fr2(tmp * tmp);
39098
+ const tmp = fr5(ck[i] + fr5(-1 * ck[i + 1 + x]));
39099
+ distAccumulator[x] = distAccumulator[x] + fr5(tmp * tmp);
37711
39100
  }
37712
39101
  }
37713
39102
  invertSqrtVec(len, distAccumulator);
@@ -37719,7 +39108,7 @@ function buildLap1(lap1, lap2, coords, shape) {
37719
39108
  let degree = 0;
37720
39109
  if (exp === 2) {
37721
39110
  for (let j = 0; j < len; j++, count++) {
37722
- const val2 = lap1[count] = fr2(lap1[count] * distAccumulator[j]);
39111
+ const val2 = lap1[count] = fr5(lap1[count] * distAccumulator[j]);
37723
39112
  degree += val2;
37724
39113
  degrees[i + j + 1] = degrees[i + j + 1] - val2;
37725
39114
  }
@@ -37753,10 +39142,10 @@ function computeStress(st) {
37753
39142
  }
37754
39143
  function solveAxis(st, k, havePinned, nodes) {
37755
39144
  if (!havePinned) {
37756
- return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG, st.n);
39145
+ return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG2, st.n);
37757
39146
  }
37758
39147
  copyVectorF(st.n, st.coords[k], st.tmpCoords);
37759
- const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG, st.n);
39148
+ const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG2, st.n);
37760
39149
  if (rc < 0) return rc;
37761
39150
  for (let i = 0; i < st.n; i++) {
37762
39151
  if (!isFixed(nodes[i])) st.coords[k][i] = st.tmpCoords[i];
@@ -37772,10 +39161,10 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
37772
39161
  const coords = [];
37773
39162
  for (let i = 0; i < dim; i++) {
37774
39163
  const c = new Float32Array(n);
37775
- for (let j = 0; j < n; j++) c[j] = fr2(dCoords[i][j]);
39164
+ for (let j = 0; j < n; j++) c[j] = fr5(dCoords[i][j]);
37776
39165
  coords.push(c);
37777
39166
  }
37778
- const constantTerm = fr2(n * (n - 1) / 2);
39167
+ const constantTerm = fr5(n * (n - 1) / 2);
37779
39168
  const lap2 = Dij;
37780
39169
  buildLap2(lap2, n, exp);
37781
39170
  const lapLength = n * (n + 1) / 2;
@@ -37810,6 +39199,261 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
37810
39199
  return iterations;
37811
39200
  }
37812
39201
 
39202
+ // src/layout/neato/constrained-majorization.ts
39203
+ var fr6 = Math.fround;
39204
+ var LOCAL_CONSTR_MAJOR_ITERATIONS = 15;
39205
+ var LEVELS_SEP_TOL = 0.1;
39206
+ var ABS_TOL = 0.01;
39207
+ var SUBSPACE_ITERATIONS = 15;
39208
+ var FLT_MAX3 = 34028234663852886e22;
39209
+ var DBL_MAX = Number.MAX_VALUE;
39210
+ var MIN_LEVELS = 1;
39211
+ var Y_AXIS = 1;
39212
+ function unsupported2(what) {
39213
+ throw new RenderError(`hierarchical stress majorization: ${what} is not supported yet`, "UNSUPPORTED_FEATURE");
39214
+ }
39215
+ function modelDistances(graph, n, model) {
39216
+ if (model === MODEL_SUBSET) unsupported2("the subset distance model");
39217
+ if (model === MODEL_CIRCUIT) unsupported2("the circuit distance model");
39218
+ return model === MODEL_MDS2 ? mdsModel(graph, n) : null;
39219
+ }
39220
+ function unconstrainedMajorization(graph, n, dCoords, nodes, o) {
39221
+ if (o.maxi < 0) return 0;
39222
+ const weighted = (graph[0]?.ewgts.length ?? 0) > 0;
39223
+ const Dij = modelDistances(graph, n, o.model) ?? (weighted ? computeWeightedApspPacked2(graph, n) : computeApspPacked2(graph, n));
39224
+ if ((o.opts & OPT_SMART_INIT) !== 0 && n > 1) unsupported2("the smart initial layout");
39225
+ return stressMajorizationKDMkernel(Dij, n, dCoords, nodes, {
39226
+ dim: o.dim,
39227
+ opts: o.opts,
39228
+ maxi: o.maxi,
39229
+ epsilon: o.epsilon
39230
+ });
39231
+ }
39232
+ function hasDirectionality(graph, n) {
39233
+ if (!graph[0]?.edists) return false;
39234
+ let directionalityExist = false;
39235
+ for (let i = 0; i < n; i++) {
39236
+ const edists = graph[i].edists;
39237
+ for (let j = 1; j < graph[i].nedges; j++) {
39238
+ directionalityExist ||= edists[j] !== 0;
39239
+ }
39240
+ }
39241
+ return directionalityExist;
39242
+ }
39243
+ function separateLevels(y, h, n, levelsGap) {
39244
+ const { ordering, levels, numLevels } = h;
39245
+ let displacement = 0;
39246
+ for (let i = 0; i < numLevels; i++) {
39247
+ const shortfall = levelsGap - (y[ordering[levels[i]]] + displacement - y[ordering[levels[i] - 1]]);
39248
+ displacement += 0 > shortfall ? 0 : shortfall;
39249
+ const stop = i < numLevels - 1 ? levels[i + 1] : n;
39250
+ for (let j = levels[i]; j < stop; j++) y[ordering[j]] += displacement;
39251
+ }
39252
+ }
39253
+ function smartInitLayers(graph, n, dCoords, nodes, o) {
39254
+ const { dim } = o;
39255
+ if (dim > 2) {
39256
+ const sub = { dim: dim - 1, opts: o.opts, model: o.model, maxi: SUBSPACE_ITERATIONS, epsilon: o.epsilon };
39257
+ if (unconstrainedMajorization(graph, n, dCoords.slice(1), nodes, sub) < 0) return -1;
39258
+ dCoords[dim - 1].set(dCoords[1].subarray(0, n));
39259
+ }
39260
+ const x = dCoords[0];
39261
+ const y = dCoords[1];
39262
+ if (computeYCoords(graph, n, y, n)) return -1;
39263
+ const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, y);
39264
+ if (h === null) return -1;
39265
+ if (h.numLevels < MIN_LEVELS) {
39266
+ return unconstrainedMajorization(graph, n, dCoords, nodes, o);
39267
+ }
39268
+ if (o.levelsGap > 0) separateLevels(y, h, n, o.levelsGap);
39269
+ if (dim === 2 && imdsGivenDim(graph, n, y, x, o.epsilon)) return -1;
39270
+ return h;
39271
+ }
39272
+ function plainInitLayers(graph, n, dCoords, nodes, dim) {
39273
+ initLayout(n, dim, dCoords, nodes);
39274
+ const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, null);
39275
+ return h === null ? -1 : h;
39276
+ }
39277
+ function distanceKD(coords, dim, i, j) {
39278
+ let sum = 0;
39279
+ for (let k = 0; k < dim; k++) {
39280
+ const d = coords[k][i] - coords[k][j];
39281
+ sum = fma2(d, d, sum);
39282
+ }
39283
+ return Math.sqrt(sum);
39284
+ }
39285
+ function scaleDownLayout(dCoords, n, dim) {
39286
+ let max = 1;
39287
+ for (let i = 0; i < dim; i++) {
39288
+ for (let j = 0; j < n; j++) {
39289
+ const a = Math.abs(dCoords[i][j]);
39290
+ if (a > max) max = a;
39291
+ }
39292
+ }
39293
+ for (let i = 0; i < dim; i++) {
39294
+ for (let j = 0; j < n; j++) dCoords[i][j] *= 10 / max;
39295
+ }
39296
+ }
39297
+ function scaleDistances(Dij, dCoords, n, dim) {
39298
+ const length = n + Math.trunc(n * (n - 1) / 2);
39299
+ const sum1 = Math.trunc(n * (n - 1) / 2);
39300
+ let sum2 = 0;
39301
+ for (let count = 0, i = 0; i < n - 1; i++) {
39302
+ count++;
39303
+ for (let j = i + 1; j < n; j++, count++) {
39304
+ sum2 += distanceKD(dCoords, dim, i, j) / Dij[count];
39305
+ }
39306
+ }
39307
+ const scaleRatio = fr6(sum2 / sum1);
39308
+ for (let i = 0; i < length; i++) Dij[i] = Dij[i] * scaleRatio;
39309
+ }
39310
+ function centerLayout(dCoords, n, dim) {
39311
+ for (let i = 0; i < dim; i++) orthog1(n, dCoords[i]);
39312
+ const y0 = dCoords[Y_AXIS][0];
39313
+ for (let i = 0; i < n; i++) dCoords[Y_AXIS][i] -= y0;
39314
+ }
39315
+ function negatedDegrees(lap2, n) {
39316
+ const degrees = new Float64Array(n);
39317
+ for (let i = 0, count = 0; i < n - 1; i++) {
39318
+ let degree = 0;
39319
+ count++;
39320
+ for (let j = 1; j < n - i; j++, count++) {
39321
+ const val2 = lap2[count];
39322
+ degree += val2;
39323
+ degrees[i + j] -= val2;
39324
+ }
39325
+ degrees[i] -= degree;
39326
+ }
39327
+ return degrees;
39328
+ }
39329
+ function buildLap22(lap2, n) {
39330
+ const lapLength = n + Math.trunc(n * (n - 1) / 2);
39331
+ squareVec(lapLength, lap2);
39332
+ invertVec(lapLength, lap2);
39333
+ const degrees = negatedDegrees(lap2, n);
39334
+ for (let step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
39335
+ lap2[count] = degrees[i];
39336
+ }
39337
+ }
39338
+ function inverseDistances(st, i, len) {
39339
+ const { coords, tmpCoords, distAccumulator } = st;
39340
+ distAccumulator.fill(0, 0, st.n);
39341
+ for (let k = 0; k < st.dim; k++) {
39342
+ const ck = coords[k];
39343
+ for (let j = 0; j < len; j++) tmpCoords[j] = ck[i] - ck[i + 1 + j];
39344
+ for (let j = 0; j < len; j++) tmpCoords[j] = tmpCoords[j] * tmpCoords[j];
39345
+ for (let j = 0; j < len; j++) distAccumulator[j] = tmpCoords[j] + distAccumulator[j];
39346
+ }
39347
+ invertSqrtVec(len, distAccumulator);
39348
+ for (let j = 0; j < len; j++) {
39349
+ if (distAccumulator[j] >= FLT_MAX3 || distAccumulator[j] < 0) distAccumulator[j] = 0;
39350
+ }
39351
+ }
39352
+ function buildLap12(st) {
39353
+ const { n, lap1, lap2, degrees, distAccumulator } = st;
39354
+ degrees.fill(0);
39355
+ sqrtVecF(n + Math.trunc(n * (n - 1) / 2), lap2, lap1);
39356
+ let count = 0;
39357
+ for (let i = 0; i < n - 1; i++) {
39358
+ const len = n - i - 1;
39359
+ inverseDistances(st, i, len);
39360
+ count++;
39361
+ let degree = 0;
39362
+ for (let j = 0; j < len; j++, count++) {
39363
+ const val2 = fr6(lap1[count] * distAccumulator[j]);
39364
+ lap1[count] = val2;
39365
+ degree += val2;
39366
+ degrees[i + j + 1] -= val2;
39367
+ }
39368
+ degrees[i] -= degree;
39369
+ }
39370
+ for (let step = n, count2 = 0, i = 0; i < n; i++, count2 += step, step--) {
39371
+ lap1[count2] = degrees[i];
39372
+ }
39373
+ }
39374
+ function computeNewStress(st, constantTerm) {
39375
+ const { n, dim, lap1, lap2, coords, b, tmpCoords } = st;
39376
+ for (let k = 0; k < dim; k++) rightMultWithVectorFFFused(lap1, n, coords[k], b[k]);
39377
+ let newStress = 0;
39378
+ for (let k = 0; k < dim; k++) newStress += vectorsInnerProductF(n, coords[k], b[k]);
39379
+ newStress *= 2;
39380
+ newStress += constantTerm;
39381
+ for (let k = 0; k < dim; k++) {
39382
+ rightMultWithVectorFFFused(lap2, n, coords[k], tmpCoords);
39383
+ newStress -= vectorsInnerProductF(n, coords[k], tmpCoords);
39384
+ }
39385
+ return newStress;
39386
+ }
39387
+ function solveAxes(st, ctx) {
39388
+ for (let k = 0; k < st.dim; k++) {
39389
+ if (k === Y_AXIS) {
39390
+ constrainedMajorizationNewWithGaps(
39391
+ ctx.cMajEnv,
39392
+ st.b[k],
39393
+ st.coords,
39394
+ k,
39395
+ LOCAL_CONSTR_MAJOR_ITERATIONS,
39396
+ ctx.levelsGap
39397
+ );
39398
+ } else if (conjugateGradientMkernelFused(st.lap2, st.coords[k], st.b[k], st.n, { tol: TOLERANCE_CG, maxIterations: st.n })) {
39399
+ return true;
39400
+ }
39401
+ }
39402
+ return false;
39403
+ }
39404
+ function majorize(st, ctx, dCoords) {
39405
+ const constantTerm = Math.trunc(st.n * (st.n - 1) / 2);
39406
+ let oldStress = DBL_MAX;
39407
+ let iterations = 0;
39408
+ for (let converged = false; iterations < ctx.maxi && !converged; iterations++) {
39409
+ buildLap12(st);
39410
+ const newStress = computeNewStress(st, constantTerm);
39411
+ converged = Math.abs(newStress - oldStress) / Math.abs(oldStress + 1e-10) < ctx.epsilon;
39412
+ converged ||= iterations > 1 && newStress > oldStress;
39413
+ oldStress = newStress;
39414
+ if (solveAxes(st, ctx)) return -1;
39415
+ }
39416
+ for (let i = 0; i < st.dim; i++) {
39417
+ for (let j = 0; j < st.n; j++) dCoords[i][j] = st.coords[i][j];
39418
+ }
39419
+ return iterations;
39420
+ }
39421
+ function toFloatCoords(dCoords, n, dim) {
39422
+ const coords = [];
39423
+ for (let i = 0; i < dim; i++) coords.push(Float32Array.from(dCoords[i].subarray(0, n)));
39424
+ return coords;
39425
+ }
39426
+ function newLoopState(lap2, coords, n) {
39427
+ const dim = coords.length;
39428
+ return {
39429
+ n,
39430
+ dim,
39431
+ lap2,
39432
+ coords,
39433
+ lap1: new Float32Array(n + Math.trunc(n * (n - 1) / 2)),
39434
+ b: Array.from({ length: dim }, () => new Float32Array(n)),
39435
+ tmpCoords: new Float32Array(n),
39436
+ distAccumulator: new Float32Array(n),
39437
+ degrees: new Float64Array(n)
39438
+ };
39439
+ }
39440
+ function stressMajorizationWithHierarchy(graph, n, dCoords, nodes, o) {
39441
+ if (!hasDirectionality(graph, n)) return unconstrainedMajorization(graph, n, dCoords, nodes, o);
39442
+ const smartIni = (o.opts & OPT_SMART_INIT) !== 0;
39443
+ const layers = smartIni ? smartInitLayers(graph, n, dCoords, nodes, o) : plainInitLayers(graph, n, dCoords, nodes, o.dim);
39444
+ if (typeof layers === "number") return layers;
39445
+ if (n === 1) return 0;
39446
+ if (o.maxi === 0) return 0;
39447
+ const Dij = modelDistances(graph, n, o.model) ?? computeApspPacked2(graph, n);
39448
+ if (!smartIni) scaleDownLayout(dCoords, n, o.dim);
39449
+ if (o.levelsGap > 0) scaleDistances(Dij, dCoords, n, o.dim);
39450
+ centerLayout(dCoords, n, o.dim);
39451
+ const st = newLoopState(Dij, toFloatCoords(dCoords, n, o.dim), n);
39452
+ buildLap22(Dij, n);
39453
+ const cMajEnv = initConstrainedMajorization(Dij, n, layers.ordering, layers.levels, layers.numLevels);
39454
+ return majorize(st, { cMajEnv, levelsGap: o.levelsGap, maxi: o.maxi, epsilon: o.epsilon }, dCoords);
39455
+ }
39456
+
37813
39457
  // src/common/utils-inputscale.ts
37814
39458
  var POINTS_PER_INCH3 = 72;
37815
39459
  function getInputscale(g) {
@@ -37996,61 +39640,47 @@ function neatoMaxIter(maxiter, mode, n) {
37996
39640
  if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
37997
39641
  return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
37998
39642
  }
37999
- function runMajorization(g, mode, model) {
38000
- void model;
38001
- const nodeList = assignNodeIds2(g);
39643
+ var levelsGapOf = (g) => lateDouble(g.root.attrs.get("levelsgap"), 0, -Number.MAX_VALUE);
39644
+ function solveStress(c, vtx, dCoords, nodeList) {
39645
+ const { g, mode, model, haveLen, opts } = c;
38002
39646
  const n = nodeList.length;
38003
- const haveLen = graphHasLen(g);
38004
- const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
38005
- checkStart(g);
38006
39647
  const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
38007
39648
  const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
39649
+ if (mode === MODE_HIER) {
39650
+ return stressMajorizationWithHierarchy(vtx, n, dCoords, nodeList, {
39651
+ dim: DFLT_DIM,
39652
+ opts,
39653
+ model,
39654
+ maxi,
39655
+ epsilon,
39656
+ levelsGap: levelsGapOf(g)
39657
+ });
39658
+ }
38008
39659
  const weighted = haveLen && mode !== MODE_IPSEP;
38009
39660
  const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
38010
- const dCoords = [new Float64Array(n), new Float64Array(n)];
38011
- stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
39661
+ return stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
38012
39662
  dim: DFLT_DIM,
38013
- opts: OPT_EXP_FLAG,
39663
+ opts,
38014
39664
  maxi,
38015
39665
  epsilon
38016
39666
  });
38017
- for (let i = 0; i < n; i++) {
38018
- nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
38019
- }
38020
39667
  }
38021
- function graphHasLen(g) {
38022
- for (const e of g.edges) {
38023
- if (e.attrs.has("len")) return true;
39668
+ function runMajorization(g, mode, model) {
39669
+ const nodeList = assignNodeIds2(g);
39670
+ const n = nodeList.length;
39671
+ const haveLen = graphHasLen(g);
39672
+ const init = checkStart(g, n, mode === MODE_HIER ? INIT_SELF : INIT_RANDOM);
39673
+ const opts = init === INIT_SELF ? OPT_EXP_FLAG | OPT_SMART_INIT : OPT_EXP_FLAG;
39674
+ const haveDir = mode === MODE_HIER || mode === MODE_IPSEP;
39675
+ const vtx = makeGraphDataC(g, nodeList, haveLen, haveDir, mode);
39676
+ const dCoords = [new Float64Array(n), new Float64Array(n)];
39677
+ if (solveStress({ g, mode, model, haveLen, opts }, vtx, dCoords, nodeList) < 0) {
39678
+ agerr("prev", "layout aborted");
39679
+ return;
38024
39680
  }
38025
- return false;
38026
- }
38027
- function makeGraphDataC(g, nodeList, haveLen, haveDir) {
38028
- const vtx = nodeList.map((_, i) => ({
38029
- nedges: 1,
38030
- edges: [i],
38031
- ewgts: haveLen || haveDir ? [0] : []
38032
- }));
38033
- for (const np of nodeList) {
38034
- const i = np.info.id;
38035
- const entry = vtx[i];
38036
- const seen2 = /* @__PURE__ */ new Map();
38037
- for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
38038
- if (ep.head === ep.tail) continue;
38039
- const vp = ep.tail === np ? ep.head : ep.tail;
38040
- const vid = vp.info.id;
38041
- const dist4 = haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
38042
- const idx = seen2.get(vid);
38043
- if (idx !== void 0) {
38044
- if (haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist4);
38045
- continue;
38046
- }
38047
- seen2.set(vid, entry.nedges);
38048
- entry.edges.push(vid);
38049
- if (haveLen || haveDir) entry.ewgts.push(dist4);
38050
- entry.nedges++;
38051
- }
39681
+ for (let i = 0; i < n; i++) {
39682
+ nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
38052
39683
  }
38053
- return vtx;
38054
39684
  }
38055
39685
  function solveModel2(g, mode, model) {
38056
39686
  if (g.nodes.size < 2) return;
@@ -38242,6 +39872,25 @@ function esepFactor(g) {
38242
39872
  return { x: SEPFACT * DFLT_MARGIN, y: SEPFACT * DFLT_MARGIN, doAdd: true };
38243
39873
  }
38244
39874
 
39875
+ // src/common/libm-trig.ts
39876
+ var OCTAGON_TRIG = /* @__PURE__ */ new Map([
39877
+ [-0.39269908169872414, [0.9238795325112867, -0.3826834323650898]],
39878
+ [0.39269908169872414, [0.9238795325112867, 0.3826834323650898]],
39879
+ [1.1780972450961724, [0.38268343236508984, 0.9238795325112867]],
39880
+ [1.9634954084936207, [-0.3826834323650897, 0.9238795325112867]],
39881
+ [2.748893571891069, [-0.9238795325112867, 0.3826834323650899]],
39882
+ [3.5342917352885173, [-0.9238795325112868, -0.38268343236508967]],
39883
+ [4.319689898685965, [-0.38268343236509034, -0.9238795325112865]],
39884
+ [5.105088062083414, [0.38268343236509, -0.9238795325112866]],
39885
+ [5.890486225480862, [0.9238795325112865, -0.3826834323650904]]
39886
+ ]);
39887
+ function libmCos(x) {
39888
+ return OCTAGON_TRIG.get(x)?.[0] ?? Math.cos(x);
39889
+ }
39890
+ function libmSin(x) {
39891
+ return OCTAGON_TRIG.get(x)?.[1] ?? Math.sin(x);
39892
+ }
39893
+
38245
39894
  // src/layout/neato/delaunay.ts
38246
39895
  var ICCERRBOUND_A = (10 + 96 * 2 ** -53) * 2 ** -53;
38247
39896
  function ulpExp(v) {
@@ -38410,6 +40059,32 @@ function delaunayTri(xv, yv, n) {
38410
40059
  return edges;
38411
40060
  }
38412
40061
 
40062
+ // src/layout/neato/gts-triangle.ts
40063
+ var SQRT3 = 1.73205080757;
40064
+ function gtsTriangleEnclosing(px, py, n, scale) {
40065
+ let xmin = px[0];
40066
+ let xmax = px[0];
40067
+ let ymin = py[0];
40068
+ let ymax = py[0];
40069
+ for (let i = 1; i < n; i++) {
40070
+ if (px[i] > xmax) xmax = px[i];
40071
+ else if (px[i] < xmin) xmin = px[i];
40072
+ if (py[i] > ymax) ymax = py[i];
40073
+ else if (py[i] < ymin) ymin = py[i];
40074
+ }
40075
+ const xo = (xmax + xmin) / 2;
40076
+ const yo = (ymax + ymin) / 2;
40077
+ const dx = xmax - xo;
40078
+ const dy = ymax - yo;
40079
+ let r = scale * Math.sqrt(fma(dx, dx, dy * dy));
40080
+ if (r === 0) r = scale;
40081
+ return [
40082
+ [fma(r, SQRT3, xo), yo - r],
40083
+ [xo, fma(r, 2, yo)],
40084
+ [fma(-r, SQRT3, xo), yo - r]
40085
+ ];
40086
+ }
40087
+
38413
40088
  // src/layout/neato/cdt-surface.ts
38414
40089
  var pairKey = (u, v) => u < v ? u * 1048576 + v : v * 1048576 + u;
38415
40090
  var Cdt = class {
@@ -38920,27 +40595,15 @@ var Cdt = class {
38920
40595
  return { nfaces: kept.length, faces, neigh };
38921
40596
  }
38922
40597
  };
38923
- var SQRT3 = 1.7320508075688772;
38924
40598
  function mkSurface(x, y, n, segs, nsegs) {
38925
40599
  const px = x.slice(0, n);
38926
40600
  const py = y.slice(0, n);
38927
- let xmin = px[0];
38928
- let xmax = px[0];
38929
- let ymin = py[0];
38930
- let ymax = py[0];
38931
- for (let i = 1; i < n; i++) {
38932
- if (px[i] > xmax) xmax = px[i];
38933
- else if (px[i] < xmin) xmin = px[i];
38934
- if (py[i] > ymax) ymax = py[i];
38935
- else if (py[i] < ymin) ymin = py[i];
38936
- }
38937
- const xo = (xmax + xmin) / 2;
38938
- const yo = (ymax + ymin) / 2;
38939
- let r = 100 * Math.hypot(xmax - xo, ymax - yo);
38940
- if (r === 0) r = 100;
38941
40601
  const s0 = n;
38942
- px.push(xo + r * SQRT3, xo, xo - r * SQRT3);
38943
- py.push(yo - r, yo + 2 * r, yo - r);
40602
+ const enc = gtsTriangleEnclosing(px, py, n, 100);
40603
+ for (const [ex, ey] of enc) {
40604
+ px.push(ex);
40605
+ py.push(ey);
40606
+ }
38944
40607
  const cdt = new Cdt(px, py);
38945
40608
  const cons = [];
38946
40609
  for (let k = 0; k < nsegs; k++) {
@@ -38987,9 +40650,9 @@ function sharedEdge(faces, p3, q3) {
38987
40650
  return { i: p1, j: p2 };
38988
40651
  }
38989
40652
  function addTriEdge(g, t, h, seg2) {
38990
- const dist4 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
40653
+ const dist5 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
38991
40654
  const idx = g.edges.length;
38992
- g.edges.push({ t, h, seg: seg2, dist: dist4 });
40655
+ g.edges.push({ t, h, seg: seg2, dist: dist5 });
38993
40656
  g.nodes[t].edges.push(idx);
38994
40657
  g.nodes[h].edges.push(idx);
38995
40658
  }
@@ -39793,8 +41456,8 @@ function ellipseTangentSlope(a, b, p) {
39793
41456
  function circumscribedCorner(a, b, i, nsides) {
39794
41457
  const angle0 = 2 * Math.PI * (i - 0.5) / nsides;
39795
41458
  const angle1 = 2 * Math.PI * (i + 0.5) / nsides;
39796
- const p0 = { x: a * Math.cos(angle0), y: b * Math.sin(angle0) };
39797
- const p1 = { x: a * Math.cos(angle1), y: b * Math.sin(angle1) };
41459
+ const p0 = { x: a * libmCos(angle0), y: b * libmSin(angle0) };
41460
+ const p1 = { x: a * libmCos(angle1), y: b * libmSin(angle1) };
39798
41461
  const m0 = ellipseTangentSlope(a, b, p0);
39799
41462
  const m1 = ellipseTangentSlope(a, b, p1);
39800
41463
  const x = (fms(p1.x, m1, fma(m0, p0.x, -p0.y)) + p1.y) / (m0 - m1);
@@ -42130,52 +43793,14 @@ function armPow(x, y) {
42130
43793
  return expInline(ehi, elo, signBias);
42131
43794
  }
42132
43795
 
42133
- // src/common/crand.ts
42134
- var C_RAND_MAX = 2147483647;
42135
- var UNSEEDED_STATE2 = 1;
42136
- var state2 = UNSEEDED_STATE2;
42137
- registerRenderState(() => {
42138
- state2 = UNSEEDED_STATE2;
42139
- });
42140
- function csrand(seed) {
42141
- state2 = seed;
42142
- }
42143
- function crand() {
42144
- state2 = state2 * 16807 % 2147483647;
42145
- return state2;
42146
- }
42147
- function cdrand() {
42148
- return crand() / C_RAND_MAX;
42149
- }
42150
- function gvRandom(bound) {
42151
- const discardThreshold = C_RAND_MAX - 2147483648 % bound;
42152
- let r;
42153
- do {
42154
- r = crand();
42155
- } while (r > discardThreshold);
42156
- return r % bound;
42157
- }
42158
- function gvPermutation(bound) {
42159
- if (bound <= 0) return [];
42160
- const p = [];
42161
- for (let i = 0; i < bound; i++) p.push(i);
42162
- for (let i = bound - 1; i > 0; --i) {
42163
- const j = gvRandom(i + 1);
42164
- const t = p[i];
42165
- p[i] = p[j];
42166
- p[j] = t;
42167
- }
42168
- return p;
42169
- }
42170
-
42171
43796
  // src/layout/sfdp/quadtree.ts
42172
43797
  function pointDistance(p1, o1, p2, o2, dim) {
42173
- let dist4 = 0;
43798
+ let dist5 = 0;
42174
43799
  for (let i = 0; i < dim; i++) {
42175
43800
  const d = p1[o1 + i] - p2[o2 + i];
42176
- dist4 = fma(d, d, dist4);
43801
+ dist5 = fma(d, d, dist5);
42177
43802
  }
42178
- return Math.sqrt(dist4);
43803
+ return Math.sqrt(dist5);
42179
43804
  }
42180
43805
  function quadTreeNew(dim, center, width2, maxLevel) {
42181
43806
  return {
@@ -42310,8 +43935,8 @@ function getSupernodesInternal(qt, bh, pt, ptOff, nodeid, out) {
42310
43935
  l = l.next;
42311
43936
  }
42312
43937
  if (qt.qts !== null) {
42313
- const dist4 = pointDistance(qt.center, 0, pt, ptOff, dim);
42314
- if (qt.width < bh * dist4) {
43938
+ const dist5 = pointDistance(qt.center, 0, pt, ptOff, dim);
43939
+ if (qt.width < bh * dist5) {
42315
43940
  for (let i = 0; i < dim; i++) {
42316
43941
  out.center[dim * out.nsuper + i] = qt.average[i];
42317
43942
  }
@@ -42409,12 +44034,12 @@ function onedOptimizerTrain(opt, work) {
42409
44034
  else optHill(opt, i);
42410
44035
  }
42411
44036
  function distance(x, dim, i, j) {
42412
- let dist4 = 0;
44037
+ let dist5 = 0;
42413
44038
  for (let k = 0; k < dim; k++) {
42414
44039
  const d = x[i * dim + k] - x[j * dim + k];
42415
- dist4 = fma(d, d, dist4);
44040
+ dist5 = fma(d, d, dist5);
42416
44041
  }
42417
- return Math.sqrt(dist4);
44042
+ return Math.sqrt(dist5);
42418
44043
  }
42419
44044
  function distanceCropped(x, dim, i, j) {
42420
44045
  return Math.max(distance(x, dim, i, j), MINDIST);
@@ -42422,16 +44047,16 @@ function distanceCropped(x, dim, i, j) {
42422
44047
  function gatherLeaves(A3, p, checked, x, dim) {
42423
44048
  const { ia, ja } = A3;
42424
44049
  const leaves = [];
42425
- let dist4 = 0;
44050
+ let dist5 = 0;
42426
44051
  for (let j = ia[p]; j < ia[p + 1]; j++) {
42427
44052
  const c = ja[j];
42428
44053
  if (ia[c + 1] - ia[c] === 1) {
42429
44054
  checked[c] = true;
42430
- dist4 += distance(x, dim, p, c);
44055
+ dist5 += distance(x, dim, p, c);
42431
44056
  leaves.push(c);
42432
44057
  }
42433
44058
  }
42434
- return { leaves, avgDist: dist4 / leaves.length };
44059
+ return { leaves, avgDist: dist5 / leaves.length };
42435
44060
  }
42436
44061
  function beautifyLeaves(dim, A3, x) {
42437
44062
  const { ia, ja, m } = A3;
@@ -42454,7 +44079,7 @@ function beautifyLeaves(dim, A3, x) {
42454
44079
  }
42455
44080
  }
42456
44081
  function averageEdgeLength(A3, dim, coord) {
42457
- let dist4 = 0;
44082
+ let dist5 = 0;
42458
44083
  const { ia, ja } = A3;
42459
44084
  if (ia[A3.m] === 0) return 1;
42460
44085
  for (let i = 0; i < A3.m; i++) {
@@ -42464,10 +44089,10 @@ function averageEdgeLength(A3, dim, coord) {
42464
44089
  const dd = coord[dim * i + k] - coord[dim * ja[j]];
42465
44090
  d = fma(dd, dd, d);
42466
44091
  }
42467
- dist4 += Math.sqrt(d);
44092
+ dist5 += Math.sqrt(d);
42468
44093
  }
42469
44094
  }
42470
- return dist4 / ia[A3.m];
44095
+ return dist5 / ia[A3.m];
42471
44096
  }
42472
44097
  function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
42473
44098
  if (!adaptiveCooling) return COOL * step;
@@ -42478,18 +44103,18 @@ function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
42478
44103
  }
42479
44104
  return 0.99 * step / COOL;
42480
44105
  }
42481
- function repulsivePow(dist4, p) {
42482
- return armPow(dist4, 1 - p);
44106
+ function repulsivePow(dist5, p) {
44107
+ return armPow(dist5, 1 - p);
42483
44108
  }
42484
44109
  function attractiveForce(ctx, i) {
42485
44110
  const { A: A3, x, dim, fp, f } = ctx;
42486
44111
  const { ia, ja } = A3;
42487
44112
  for (let j = ia[i]; j < ia[i + 1]; j++) {
42488
44113
  if (ja[j] === i) continue;
42489
- const dist4 = distance(x, dim, i, ja[j]);
44114
+ const dist5 = distance(x, dim, i, ja[j]);
42490
44115
  for (let k = 0; k < dim; k++) {
42491
44116
  const t = fp.CRK * (x[i * dim + k] - x[ja[j] * dim + k]);
42492
- f[k] = fma(-t, dist4, f[k]);
44117
+ f[k] = fma(-t, dist5, f[k]);
42493
44118
  }
42494
44119
  }
42495
44120
  }
@@ -42497,9 +44122,9 @@ function repulsiveForceDirect(ctx, i) {
42497
44122
  const { x, dim, n, fp, f } = ctx;
42498
44123
  for (let j = 0; j < n; j++) {
42499
44124
  if (j === i) continue;
42500
- const dist4 = distanceCropped(x, dim, i, j);
44125
+ const dist5 = distanceCropped(x, dim, i, j);
42501
44126
  for (let k = 0; k < dim; k++) {
42502
- f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist4, fp.p);
44127
+ f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist5, fp.p);
42503
44128
  }
42504
44129
  }
42505
44130
  }
@@ -42509,9 +44134,9 @@ function repulsiveForceQT(ctx, qt, i, acc) {
42509
44134
  acc.countsAvg += counts;
42510
44135
  acc.nsuperAvg += nsuper;
42511
44136
  for (let j = 0; j < nsuper; j++) {
42512
- const dist4 = Math.max(distances[j], MINDIST);
44137
+ const dist5 = Math.max(distances[j], MINDIST);
42513
44138
  for (let k = 0; k < dim; k++) {
42514
- f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist4, fp.p);
44139
+ f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist5, fp.p);
42515
44140
  }
42516
44141
  }
42517
44142
  }
@@ -42767,7 +44392,7 @@ function diagPreconNew(A3) {
42767
44392
  }
42768
44393
  return diag;
42769
44394
  }
42770
- function conjugateGradient(A3, precon, n, x, rhs, tol, maxit) {
44395
+ function conjugateGradient2(A3, precon, n, x, rhs, tol, maxit) {
42771
44396
  let rho = 0;
42772
44397
  let rhoOld = 1;
42773
44398
  let iter = 0;
@@ -42808,7 +44433,7 @@ function smSolve(A3, dim, x0, rhs, tol, maxit) {
42808
44433
  x[i] = x0[i * dim + k];
42809
44434
  b[i] = rhs[i * dim + k];
42810
44435
  }
42811
- res += conjugateGradient(A3, precond, n, x, b, tol, maxit);
44436
+ res += conjugateGradient2(A3, precond, n, x, b, tol, maxit);
42812
44437
  for (let i = 0; i < n; i++) {
42813
44438
  rhs[i * dim + k] = x[i];
42814
44439
  }
@@ -43162,7 +44787,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
43162
44787
  for (let j = ia[i]; j < ia[i + 1]; j++) {
43163
44788
  const jj = ja[j];
43164
44789
  if (jj === i) continue;
43165
- const dist4 = distance(x, dim, i, jj);
44790
+ const dist5 = distance(x, dim, i, jj);
43166
44791
  const dx = Math.abs(x[i * dim] - x[jj * dim]);
43167
44792
  const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
43168
44793
  const wx = width2[i * dim] + width2[jj * dim];
@@ -43185,9 +44810,9 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
43185
44810
  t = Math.min(expandmax, t);
43186
44811
  t = Math.max(expandmin, t);
43187
44812
  if (t > 1) {
43188
- idealDistance[j] = t * dist4;
44813
+ idealDistance[j] = t * dist5;
43189
44814
  } else {
43190
- idealDistance[j] = -t * dist4;
44815
+ idealDistance[j] = -t * dist5;
43191
44816
  }
43192
44817
  }
43193
44818
  }
@@ -43282,9 +44907,9 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
43282
44907
  w[j] = -1 / d[j] / d[j];
43283
44908
  d[j] = -d[j];
43284
44909
  }
43285
- const dist4 = d[j];
44910
+ const dist5 = d[j];
43286
44911
  diagW += w[j];
43287
- d[j] = w[j] * dist4;
44912
+ d[j] = w[j] * dist5;
43288
44913
  diagD += d[j];
43289
44914
  }
43290
44915
  w[jdiag] = -diagW;
@@ -43295,11 +44920,11 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
43295
44920
  function totalDistance(m, dim, x, y) {
43296
44921
  let total = 0;
43297
44922
  for (let i = 0; i < m; i++) {
43298
- let dist4 = 0;
44923
+ let dist5 = 0;
43299
44924
  for (let j = 0; j < dim; j++) {
43300
- dist4 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
44925
+ dist5 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
43301
44926
  }
43302
- total += Math.sqrt(dist4);
44927
+ total += Math.sqrt(dist5);
43303
44928
  }
43304
44929
  return total;
43305
44930
  }
@@ -43332,18 +44957,18 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
43332
44957
  idiag = j;
43333
44958
  continue;
43334
44959
  }
43335
- let dist4 = distance(x, dim, i, jd[j]);
44960
+ let dist5 = distance(x, dim, i, jd[j]);
43336
44961
  if (d[j] === 0) {
43337
44962
  dd[j] = 0;
43338
44963
  } else {
43339
- if (dist4 === 0) {
44964
+ if (dist5 === 0) {
43340
44965
  const dij = d[j] / Lw.a[j];
43341
44966
  for (let k = 0; k < dim; k++) {
43342
44967
  x[jd[j] * dim + k] += 1e-4 * (cdrand() + 1e-4) * dij;
43343
44968
  }
43344
- dist4 = distance(x, dim, i, jd[j]);
44969
+ dist5 = distance(x, dim, i, jd[j]);
43345
44970
  }
43346
- dd[j] = d[j] / dist4;
44971
+ dd[j] = d[j] / dist5;
43347
44972
  }
43348
44973
  diag += dd[j];
43349
44974
  }
@@ -43362,9 +44987,9 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
43362
44987
  return diff;
43363
44988
  }
43364
44989
  function scaleToEdgeLength(dim, A3, x, avgLabelSize) {
43365
- let dist4 = averageEdgeLength(A3, dim, x);
43366
- dist4 = avgLabelSize / Math.max(dist4, MACHINEACC);
43367
- for (let i = 0; i < dim * A3.m; i++) x[i] *= dist4;
44990
+ let dist5 = averageEdgeLength(A3, dim, x);
44991
+ dist5 = avgLabelSize / Math.max(dist5, MACHINEACC);
44992
+ for (let i = 0; i < dim * A3.m; i++) x[i] *= dist5;
43368
44993
  }
43369
44994
  function removeOverlapPrism(dim, A3, x, labelSizes, ntry, initialScaling, doShrinking) {
43370
44995
  if (!labelSizes) return;
@@ -43731,7 +45356,7 @@ function makeHasEdge(g) {
43731
45356
  }
43732
45357
  return (a, b) => pairs.get(a)?.has(b) === true || undirected && pairs.get(b)?.has(a) === true;
43733
45358
  }
43734
- function mkNConstraintG(g, list, intersect, dist4) {
45359
+ function mkNConstraintG(g, list, intersect, dist5) {
43735
45360
  const cg = newCg();
43736
45361
  const flat = flatten(list);
43737
45362
  let lastn;
@@ -43748,7 +45373,7 @@ function mkNConstraintG(g, list, intersect, dist4) {
43748
45373
  const nxp = flat[j];
43749
45374
  if (!intersect(p, nxp)) continue;
43750
45375
  const e = cgEdge(cg, cnodeOf(p), cnodeOf(nxp));
43751
- e.info.minlen = dist4(p.bb, nxp.bb);
45376
+ e.info.minlen = dist5(p.bb, nxp.bb);
43752
45377
  e.info.weight = hasEdge(p.np, nxp.np) ? 100 : 1;
43753
45378
  created.push(e);
43754
45379
  }
@@ -43795,12 +45420,12 @@ function buildVisibility(flat, intersect) {
43795
45420
  }
43796
45421
  return vg;
43797
45422
  }
43798
- function mapGraphs(vg, flat, cg, dist4) {
45423
+ function mapGraphs(vg, flat, cg, dist5) {
43799
45424
  for (let i = 0; i < flat.length; i++) {
43800
45425
  const tp = flat[i];
43801
45426
  for (const j of vg[i]) {
43802
45427
  const hp = flat[j];
43803
- const delta2 = dist4(tp.bb, hp.bb);
45428
+ const delta2 = dist5(tp.bb, hp.bb);
43804
45429
  const ce = cgEdge(cg, cnodeOf(tp), cnodeOf(hp));
43805
45430
  ce.info.weight = 1;
43806
45431
  if ((ce.info.minlen ?? 0) < delta2) {
@@ -43810,15 +45435,15 @@ function mapGraphs(vg, flat, cg, dist4) {
43810
45435
  }
43811
45436
  }
43812
45437
  }
43813
- function mkConstraintG(list, intersect, dist4) {
45438
+ function mkConstraintG(list, intersect, dist5) {
43814
45439
  const cg = newCg();
43815
45440
  const flat = flatten(list);
43816
45441
  buildChain(cg, flat);
43817
- mapGraphs(buildVisibility(flat, intersect), flat, cg, dist4);
45442
+ mapGraphs(buildVisibility(flat, intersect), flat, cg, dist5);
43818
45443
  return cg;
43819
45444
  }
43820
- function buildConstraintGraph(g, list, ifn, dist4, ortho) {
43821
- return ortho ? mkConstraintG(list, ifn, dist4) : mkNConstraintG(g, list, ifn, dist4);
45445
+ function buildConstraintGraph(g, list, ifn, dist5, ortho) {
45446
+ return ortho ? mkConstraintG(list, ifn, dist5) : mkNConstraintG(g, list, ifn, dist5);
43822
45447
  }
43823
45448
  function newItems() {
43824
45449
  return new DtBag((p) => p.val, cmpitem);
@@ -43959,7 +45584,7 @@ function inflatePts(verts, xmargin, ymargin) {
43959
45584
  v.y *= ymargin;
43960
45585
  }
43961
45586
  }
43962
- function isBox2(verts) {
45587
+ function isBox3(verts) {
43963
45588
  if (verts.length !== 4) return false;
43964
45589
  const [v0, v1, v2, v3] = verts;
43965
45590
  if (v0.y === v1.y) {
@@ -44019,7 +45644,7 @@ function clusterVerts(n, xmargin, ymargin) {
44019
45644
  function polyKind(n, poly, verts) {
44020
45645
  const name = shapeName(n);
44021
45646
  if (name === "box") return POLY_BOX;
44022
- if (name === "polygon" && isBox2(verts)) return POLY_BOX;
45647
+ if (name === "polygon" && isBox3(verts)) return POLY_BOX;
44023
45648
  if (poly.sides < 3 && poly.regular) return POLY_CIRCLE;
44024
45649
  return 0;
44025
45650
  }
@@ -44527,7 +46152,7 @@ function heapSiftUp(h, i) {
44527
46152
  i = parent2;
44528
46153
  }
44529
46154
  }
44530
- function heapSiftDown3(h, i) {
46155
+ function heapSiftDown2(h, i) {
44531
46156
  const n = h.length;
44532
46157
  for (; ; ) {
44533
46158
  let smallest = i;
@@ -44544,7 +46169,7 @@ function heapSiftDown3(h, i) {
44544
46169
  }
44545
46170
  function makeHeap(h) {
44546
46171
  for (let i = (h.length >> 1) - 1; i >= 0; i--) {
44547
- heapSiftDown3(h, i);
46172
+ heapSiftDown2(h, i);
44548
46173
  }
44549
46174
  }
44550
46175
  function heapFindMin(h) {
@@ -44553,7 +46178,7 @@ function heapFindMin(h) {
44553
46178
  function heapDeleteMin(h) {
44554
46179
  h[0] = h[h.length - 1];
44555
46180
  h.pop();
44556
- if (h.length > 0) heapSiftDown3(h, 0);
46181
+ if (h.length > 0) heapSiftDown2(h, 0);
44557
46182
  }
44558
46183
  function heapInsert(h, c) {
44559
46184
  h.push(c);
@@ -44637,27 +46262,27 @@ var Block = class _Block {
44637
46262
  * @see lib/vpsc/block.cpp: Block::merge(Block* b, Constraint* c)
44638
46263
  */
44639
46264
  mergeTwoArg(b, c) {
44640
- const dist4 = c.right.offset - c.left.offset - c.gap;
46265
+ const dist5 = c.right.offset - c.left.offset - c.gap;
44641
46266
  let l = c.left.block;
44642
46267
  let r = c.right.block;
44643
46268
  if (this.vars.length < b.vars.length) {
44644
- r.mergeInto(l, c, dist4);
46269
+ r.mergeInto(l, c, dist5);
44645
46270
  } else {
44646
- l.mergeInto(r, c, -dist4);
46271
+ l.mergeInto(r, c, -dist5);
44647
46272
  }
44648
46273
  }
44649
46274
  /**
44650
46275
  * Merge block b into this across constraint c by dist.
44651
46276
  * @see lib/vpsc/block.cpp: Block::merge(Block *b, Constraint *c, double dist)
44652
46277
  */
44653
- mergeInto(b, c, dist4) {
46278
+ mergeInto(b, c, dist5) {
44654
46279
  c.active = true;
44655
- this.wposn += b.wposn - dist4 * b.weight;
46280
+ this.wposn += b.wposn - dist5 * b.weight;
44656
46281
  this.weight += b.weight;
44657
46282
  this.posn = this.wposn / this.weight;
44658
46283
  for (const v of b.vars) {
44659
46284
  v.block = this;
44660
- v.offset += dist4;
46285
+ v.offset += dist5;
44661
46286
  this.vars.push(v);
44662
46287
  }
44663
46288
  b.deleted = true;
@@ -44946,13 +46571,13 @@ var Blocks = class {
44946
46571
  r.deleteMinInConstraint();
44947
46572
  let l = c.left.block;
44948
46573
  if (l.in.length === 0) l.setUpInConstraints();
44949
- let dist4 = c.right.offset - c.left.offset - c.gap;
46574
+ let dist5 = c.right.offset - c.left.offset - c.gap;
44950
46575
  if (r.vars.length < l.vars.length) {
44951
- dist4 = -dist4;
46576
+ dist5 = -dist5;
44952
46577
  [l, r] = [r, l];
44953
46578
  }
44954
46579
  this.timeCtr.value++;
44955
- r.mergeInto(l, c, dist4);
46580
+ r.mergeInto(l, c, dist5);
44956
46581
  r.mergeIn(l);
44957
46582
  r.timeStamp = this.timeCtr.value;
44958
46583
  this.removeBlock(l);
@@ -44970,12 +46595,12 @@ var Blocks = class {
44970
46595
  l.deleteMinOutConstraint();
44971
46596
  let r = c.right.block;
44972
46597
  r.setUpOutConstraints();
44973
- let dist4 = c.left.offset + c.gap - c.right.offset;
46598
+ let dist5 = c.left.offset + c.gap - c.right.offset;
44974
46599
  if (l.vars.length > r.vars.length) {
44975
- dist4 = -dist4;
46600
+ dist5 = -dist5;
44976
46601
  [l, r] = [r, l];
44977
46602
  }
44978
- l.mergeInto(r, c, dist4);
46603
+ l.mergeInto(r, c, dist5);
44979
46604
  l.mergeOut(r);
44980
46605
  this.removeBlock(r);
44981
46606
  c = l.findMinOutConstraint();
@@ -45491,7 +47116,7 @@ function warnUnrecognizedOverlap(flag) {
45491
47116
  const s = flag.toLowerCase();
45492
47117
  if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
45493
47118
  if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
45494
- agerrLineOn("warn", `Unrecognized overlap value "${flag}" - using false`);
47119
+ agwarningf(`Unrecognized overlap value "${flag}" - using false`);
45495
47120
  }
45496
47121
  function getAdjustMode(flag) {
45497
47122
  warnUnrecognizedOverlap(flag);
@@ -45524,7 +47149,7 @@ function adjustLate(g, am) {
45524
47149
  case AM_VPSC:
45525
47150
  return vpscAdjust(g);
45526
47151
  default:
45527
- agerrLineOn("warn", `Unhandled adjust option ${am.print}`);
47152
+ agwarningf(`Unhandled adjust option ${am.print}`);
45528
47153
  return 0;
45529
47154
  }
45530
47155
  }
@@ -46498,20 +48123,20 @@ function coincidentDelta() {
46498
48123
  } while (xdelta === 0 && ydelta === 0);
46499
48124
  return { xdelta, ydelta };
46500
48125
  }
46501
- function doRep(p, q, xdelta, ydelta, dist4) {
48126
+ function doRep(p, q, xdelta, ydelta, dist5) {
46502
48127
  let force;
46503
- if (!(dist4 > 0)) {
48128
+ if (!(dist5 > 0)) {
46504
48129
  const d = coincidentDelta();
46505
48130
  xdelta = d.xdelta;
46506
48131
  ydelta = d.ydelta;
46507
- dist4 = libmHypot(xdelta, ydelta);
48132
+ dist5 = libmHypot(xdelta, ydelta);
46508
48133
  }
46509
- if (dist4 > fdpParms.Mlimit) {
48134
+ if (dist5 > fdpParms.Mlimit) {
46510
48135
  force = 0;
46511
48136
  } else if (parms.useNew) {
46512
- force = parms.K * parms.K / (dist4 * dist4 * dist4);
48137
+ force = parms.K * parms.K / (dist5 * dist5 * dist5);
46513
48138
  } else {
46514
- force = parms.K * parms.K / (dist4 * dist4);
48139
+ force = parms.K * parms.K / (dist5 * dist5);
46515
48140
  }
46516
48141
  if (isPort(p) && isPort(q)) force *= 10;
46517
48142
  const dq = disp(q);
@@ -46533,8 +48158,8 @@ function doNeighbor(grid2, i, j, nodes) {
46533
48158
  for (const q of cellp.nodes) {
46534
48159
  const xdelta = q.info.pos[0] - p.info.pos[0];
46535
48160
  const ydelta = q.info.pos[1] - p.info.pos[1];
46536
- const dist4 = libmHypot(xdelta, ydelta);
46537
- if (dist4 < parms.Cell) doRep(p, q, xdelta, ydelta, dist4);
48161
+ const dist5 = libmHypot(xdelta, ydelta);
48162
+ if (dist5 < parms.Cell) doRep(p, q, xdelta, ydelta, dist5);
46538
48163
  }
46539
48164
  }
46540
48165
  }
@@ -46566,12 +48191,12 @@ function applyAttr(p, q, e) {
46566
48191
  ydelta = d.ydelta;
46567
48192
  dist22 = fma(xdelta, xdelta, ydelta * ydelta);
46568
48193
  }
46569
- const dist4 = Math.sqrt(dist22);
48194
+ const dist5 = Math.sqrt(dist22);
46570
48195
  let force;
46571
48196
  if (parms.useNew) {
46572
- force = (e.info.factor ?? 1) * (dist4 - (e.info.dist ?? 1)) / dist4;
48197
+ force = (e.info.factor ?? 1) * (dist5 - (e.info.dist ?? 1)) / dist5;
46573
48198
  } else {
46574
- force = (e.info.factor ?? 1) * dist4 / (e.info.dist ?? 1);
48199
+ force = (e.info.factor ?? 1) * dist5 / (e.info.dist ?? 1);
46575
48200
  }
46576
48201
  const dq = disp(q);
46577
48202
  const dp = disp(p);
@@ -46746,16 +48371,16 @@ function cntOverlaps(g) {
46746
48371
  function applyRep2(p, q, rs) {
46747
48372
  let xdelta = q.info.pos[0] - p.info.pos[0];
46748
48373
  let ydelta = q.info.pos[1] - p.info.pos[1];
46749
- let dist4 = libmHypot(xdelta, ydelta);
46750
- if (!(dist4 > 0)) {
48374
+ let dist5 = libmHypot(xdelta, ydelta);
48375
+ if (!(dist5 > 0)) {
46751
48376
  const d = coincidentDelta();
46752
48377
  xdelta = d.xdelta;
46753
48378
  ydelta = d.ydelta;
46754
- dist4 = libmHypot(xdelta, ydelta);
48379
+ dist5 = libmHypot(xdelta, ydelta);
46755
48380
  }
46756
48381
  const ov = overlap4(p, q) ? 1 : 0;
46757
- let force = ov ? rs.ov / (dist4 * dist4) : rs.nonov / (dist4 * dist4);
46758
- if (dist4 > fdpParms.Mlimit) force = 0;
48382
+ let force = ov ? rs.ov / (dist5 * dist5) : rs.nonov / (dist5 * dist5);
48383
+ if (dist5 > fdpParms.Mlimit) force = 0;
46759
48384
  const dq = disp(q);
46760
48385
  const dp = disp(p);
46761
48386
  dq[0] = fma(xdelta, force, dq[0]);
@@ -46768,10 +48393,10 @@ function applyAttr2(p, q) {
46768
48393
  if (overlap4(p, q)) return;
46769
48394
  const xdelta = q.info.pos[0] - p.info.pos[0];
46770
48395
  const ydelta = q.info.pos[1] - p.info.pos[1];
46771
- const dist4 = libmHypot(xdelta, ydelta);
48396
+ const dist5 = libmHypot(xdelta, ydelta);
46772
48397
  const din = rad(p) + rad(q);
46773
- const dout = dist4 - din;
46774
- const force = dout * dout / ((xParams.K + din) * dist4);
48398
+ const dout = dist5 - din;
48399
+ const force = dout * dout / ((xParams.K + din) * dist5);
46775
48400
  const dq = disp(q);
46776
48401
  const dp = disp(p);
46777
48402
  dq[0] = fms(xdelta, force, dq[0]);
@@ -47926,9 +49551,9 @@ function pcpRotate(n, dim, x) {
47926
49551
  axis[0] = -(-y[0] + y[3] - Math.sqrt(radicand)) / (2 * y[1]);
47927
49552
  axis[1] = 1;
47928
49553
  }
47929
- const dist4 = Math.sqrt(fma(axis[0], axis[0], 1));
47930
- axis[0] = axis[0] / dist4;
47931
- axis[1] = axis[1] / dist4;
49554
+ const dist5 = Math.sqrt(fma(axis[0], axis[0], 1));
49555
+ axis[0] = axis[0] / dist5;
49556
+ axis[1] = axis[1] / dist5;
47932
49557
  for (let i = 0; i < n; i++) {
47933
49558
  const x0 = fma(x[dim * i], axis[0], x[dim * i + 1] * axis[1]);
47934
49559
  const x1 = fma(-x[dim * i], axis[1], x[dim * i + 1] * axis[0]);
@@ -48341,10 +49966,10 @@ function buildSpanTree(nodes, edges) {
48341
49966
  }
48342
49967
  return map;
48343
49968
  }
48344
- function measureDist(leaf, anc, dist4, change) {
49969
+ function measureDist(leaf, anc, dist5, change) {
48345
49970
  const p = anc.tparent;
48346
49971
  if (!p) return;
48347
- const d = dist4 + 1;
49972
+ const d = dist5 + 1;
48348
49973
  if (p.distone === 0) {
48349
49974
  p.leafone = leaf;
48350
49975
  p.distone = d;
@@ -49844,11 +51469,11 @@ var DEFAULT_COLOR5 = "black";
49844
51469
  var PENWIDTH_NORMAL4 = 1;
49845
51470
  var PENWIDTH_THRESHOLD4 = 5e-3;
49846
51471
  var EPS3 = 1e-5;
49847
- function dist3(a, b) {
51472
+ function dist4(a, b) {
49848
51473
  return Math.sqrt(dist2(a, b));
49849
51474
  }
49850
51475
  function approxLen(list, off) {
49851
- return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
51476
+ return dist4(list[off], list[off + 1]) + dist4(list[off + 1], list[off + 2]) + dist4(list[off + 2], list[off + 3]);
49852
51477
  }
49853
51478
  function splitCubic(v, t) {
49854
51479
  const left2 = [];
@@ -49927,7 +51552,7 @@ function drawSplitSpline(list, segs, job) {
49927
51552
  return endColor;
49928
51553
  }
49929
51554
  function emitSplitEdgePaths(e, job, colorList) {
49930
- const segs = parseSegs(colorList).segs;
51555
+ const segs = parseSegs(colorList, edgeSegsContext(e)).segs;
49931
51556
  const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
49932
51557
  const spl = e.info.spl;
49933
51558
  let endColor = firstColor2;
@@ -49948,8 +51573,8 @@ var forfunc = (cur, total, init) => (1 - cur / total) * init / 2;
49948
51573
  var revfunc = (cur, total, init) => cur / total * init / 2;
49949
51574
  var nonefunc = (_cur, _total, init) => init / 2;
49950
51575
  var bothfunc = (cur, total, init) => {
49951
- const fr3 = cur / total;
49952
- return fr3 <= 0.5 ? fr3 * init : (1 - fr3) * init;
51576
+ const fr7 = cur / total;
51577
+ return fr7 <= 0.5 ? fr7 * init : (1 - fr7) * init;
49953
51578
  };
49954
51579
  function taperfun(dir, directed) {
49955
51580
  if (dir === "forward") return forfunc;
@@ -51383,7 +53008,7 @@ var DotWriterBase = class {
51383
53008
 
51384
53009
  // src/render/dot/edge-draw.ts
51385
53010
  var DEFAULT_COLOR6 = "black";
51386
- var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
53011
+ var DEFAULT_LINE_STYLE2 = ["solid", "setlinewidth(1)"];
51387
53012
  function emitArrowOp(buf, op, pen) {
51388
53013
  switch (op.kind) {
51389
53014
  case "polygon":
@@ -51418,8 +53043,9 @@ var EdgeDrawBase = class extends DotWriterBase {
51418
53043
  */
51419
53044
  attachmentPolyline(pts, pencolor, job) {
51420
53045
  const obj = job.obj;
53046
+ gvrenderSetStyle(DEFAULT_LINE_STYLE2);
51421
53047
  if (obj !== null) {
51422
- obj.rawStyle = [...DEFAULT_LINE_STYLE];
53048
+ obj.rawStyle = [...DEFAULT_LINE_STYLE2];
51423
53049
  obj.pen = 3 /* Solid */;
51424
53050
  obj.penWidth = 1;
51425
53051
  obj.penColor = resolveRenderColor(pencolor.split(":")[0]);
@@ -51473,8 +53099,8 @@ var EdgeDrawBase = class extends DotWriterBase {
51473
53099
  * under that segment's pen. Reuses the same split geometry
51474
53100
  * (splitSplineByColor) as the SVG path. @see lib/common/emit.c:1975 multicolor
51475
53101
  */
51476
- emitSplitSpline(bzList, colorAttr, edraw, job) {
51477
- const segs = parseSegs(colorAttr).segs;
53102
+ emitSplitSpline(bzList, e, colorAttr, edraw, job) {
53103
+ const segs = parseSegs(colorAttr, edgeSegsContext(e)).segs;
51478
53104
  const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
51479
53105
  let endColor = firstColor2;
51480
53106
  for (const bz of bzList) {
@@ -51497,7 +53123,7 @@ var EdgeDrawBase = class extends DotWriterBase {
51497
53123
  const segData = bzList.map(
51498
53124
  (bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
51499
53125
  );
51500
- const colors = parseSegs(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
53126
+ const colors = parseSegsSilent(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
51501
53127
  for (const color of colors) {
51502
53128
  const pen = xdotPenColor(resolveRenderColor(color));
51503
53129
  for (const sd of segData) {
@@ -51653,7 +53279,7 @@ var XdotRenderer = class extends EdgeDrawBase {
51653
53279
  let tailArrowColor;
51654
53280
  let headArrowColor;
51655
53281
  if (numsemi > 0 && numc > 0) {
51656
- const c = this.emitSplitSpline(spl.list, colorAttr, edraw, job);
53282
+ const c = this.emitSplitSpline(spl.list, e, colorAttr, edraw, job);
51657
53283
  tailArrowColor = c.firstColor;
51658
53284
  headArrowColor = c.endColor;
51659
53285
  } else if (edgeIsTapered(e)) {
@@ -51889,66 +53515,6 @@ function svgTaperedEdge(e, job) {
51889
53515
  svgArrowPolygons(e, job);
51890
53516
  }
51891
53517
 
51892
- // src/gvc/image-resolver.ts
51893
- var activeResolver = null;
51894
- var EXT_MIME = {
51895
- png: "image/png",
51896
- jpg: "image/jpeg",
51897
- jpeg: "image/jpeg",
51898
- gif: "image/gif",
51899
- svg: "image/svg+xml",
51900
- webp: "image/webp"
51901
- };
51902
- var FALLBACK_MIME = "application/octet-stream";
51903
- function inferMimeFromSrc(src) {
51904
- const dot = src.lastIndexOf(".");
51905
- if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
51906
- const ext = src.slice(dot + 1).toLowerCase();
51907
- return EXT_MIME[ext] ?? FALLBACK_MIME;
51908
- }
51909
- function findImageBytes(src, resolver) {
51910
- const active = resolver ?? activeResolver;
51911
- if (active === null) return null;
51912
- const result = active(src);
51913
- if (result === null) return null;
51914
- if (result instanceof Uint8Array) {
51915
- return { bytes: result, mime: inferMimeFromSrc(src) };
51916
- }
51917
- return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
51918
- }
51919
- var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
51920
- function base64Encode(bytes) {
51921
- const len = bytes.length;
51922
- const out = [];
51923
- let i = 0;
51924
- for (; i + 2 < len; i += 3) {
51925
- const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
51926
- out.push(
51927
- B64_CHARS[n >> 18 & 63],
51928
- B64_CHARS[n >> 12 & 63],
51929
- B64_CHARS[n >> 6 & 63],
51930
- B64_CHARS[n & 63]
51931
- );
51932
- }
51933
- const remaining = len - i;
51934
- if (remaining === 1) {
51935
- const n = bytes[i] << 16;
51936
- out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
51937
- } else if (remaining === 2) {
51938
- const n = bytes[i] << 16 | bytes[i + 1] << 8;
51939
- out.push(
51940
- B64_CHARS[n >> 18 & 63],
51941
- B64_CHARS[n >> 12 & 63],
51942
- B64_CHARS[n >> 6 & 63],
51943
- "="
51944
- );
51945
- }
51946
- return out.join("");
51947
- }
51948
- function toDataUri(bytes, mime) {
51949
- return "data:" + mime + ";base64," + base64Encode(bytes);
51950
- }
51951
-
51952
53518
  // src/render/svg.ts
51953
53519
  function emitMulticolorArrows(e, job, headColor, tailColor) {
51954
53520
  const obj = job.obj;
@@ -52364,7 +53930,7 @@ function peg$parse(input, options) {
52364
53930
  return s;
52365
53931
  }
52366
53932
  function peg$f13(t, m, attrs) {
52367
- if (m) agwarningf("attribute macros not implemented", "error");
53933
+ if (m) agwarningf("attribute macros not implemented");
52368
53934
  return { type: "attr", target: t, attrs };
52369
53935
  }
52370
53936
  function peg$f14(a) {
@@ -56263,7 +57829,7 @@ function isPeggyError(err) {
56263
57829
  function warnNumberAmbiguities(src, upTo) {
56264
57830
  for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
56265
57831
  if (a.offset > upTo) break;
56266
- agerrFinished(numberAmbiguityMessage(a), "error");
57832
+ agerrFinished(numberAmbiguityMessage(a));
56267
57833
  }
56268
57834
  }
56269
57835
  function parse(src) {