@knowvah/dot-engine 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/common/arith.d.ts +12 -0
  2. package/dist/common/arith.d.ts.map +1 -1
  3. package/dist/common/edge-in-box.d.ts +31 -0
  4. package/dist/common/edge-in-box.d.ts.map +1 -0
  5. package/dist/common/htmltable-emit.d.ts +1 -1
  6. package/dist/common/htmltable-emit.d.ts.map +1 -1
  7. package/dist/common/make-label.d.ts +3 -1
  8. package/dist/common/make-label.d.ts.map +1 -1
  9. package/dist/common/poly-gencode.d.ts +12 -1
  10. package/dist/common/poly-gencode.d.ts.map +1 -1
  11. package/dist/gvc/device.d.ts.map +1 -1
  12. package/dist/gvc/emit-gates.d.ts +35 -0
  13. package/dist/gvc/emit-gates.d.ts.map +1 -0
  14. package/dist/gvc/job.d.ts +4 -0
  15. package/dist/gvc/job.d.ts.map +1 -1
  16. package/dist/gvc/viewport.d.ts +13 -0
  17. package/dist/gvc/viewport.d.ts.map +1 -1
  18. package/dist/index.js +1030 -742
  19. package/dist/index.js.map +4 -4
  20. package/dist/layout/circo/blockpath.d.ts +1 -38
  21. package/dist/layout/circo/blockpath.d.ts.map +1 -1
  22. package/dist/layout/circo/crossings.d.ts +59 -0
  23. package/dist/layout/circo/crossings.d.ts.map +1 -0
  24. package/dist/layout/dot/edge-route-chain.d.ts +5 -3
  25. package/dist/layout/dot/edge-route-chain.d.ts.map +1 -1
  26. package/dist/layout/dot/edge-route.d.ts.map +1 -1
  27. package/dist/layout/dot/index.d.ts +10 -2
  28. package/dist/layout/dot/index.d.ts.map +1 -1
  29. package/dist/layout/dot/ortho-adapter.d.ts +7 -3
  30. package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
  31. package/dist/layout/dot/pack-components.d.ts +4 -1
  32. package/dist/layout/dot/pack-components.d.ts.map +1 -1
  33. package/dist/layout/dot/splines-flat-multi.d.ts +7 -5
  34. package/dist/layout/dot/splines-flat-multi.d.ts.map +1 -1
  35. package/dist/layout/dot/splines-flat.d.ts +2 -13
  36. package/dist/layout/dot/splines-flat.d.ts.map +1 -1
  37. package/dist/layout/dot/splines-route.d.ts.map +1 -1
  38. package/dist/layout/neato/constraint-adjust.d.ts +32 -0
  39. package/dist/layout/neato/constraint-adjust.d.ts.map +1 -1
  40. package/dist/layout/neato/multispline.d.ts.map +1 -1
  41. package/dist/layout/neato/splines.d.ts.map +1 -1
  42. package/dist/layout/pack/poly-place.d.ts.map +1 -1
  43. package/dist/layout/sfdp/__fixtures__/pcp-rotate-native.d.ts +23 -0
  44. package/dist/layout/sfdp/__fixtures__/pcp-rotate-native.d.ts.map +1 -0
  45. package/dist/layout/sfdp/spring-driver.d.ts +6 -0
  46. package/dist/layout/sfdp/spring-driver.d.ts.map +1 -1
  47. package/dist/ortho/index.d.ts +4 -1
  48. package/dist/ortho/index.d.ts.map +1 -1
  49. package/dist/ortho/maze.d.ts +5 -2
  50. package/dist/ortho/maze.d.ts.map +1 -1
  51. package/dist/ortho/partition.d.ts +8 -1
  52. package/dist/ortho/partition.d.ts.map +1 -1
  53. package/dist/ortho/trap-segment.d.ts +2 -1
  54. package/dist/ortho/trap-segment.d.ts.map +1 -1
  55. package/dist/ortho/trapezoid.d.ts.map +1 -1
  56. package/dist/parser/index.d.ts +0 -7
  57. package/dist/parser/index.d.ts.map +1 -1
  58. package/dist/parser/number-scan.d.ts +31 -0
  59. package/dist/parser/number-scan.d.ts.map +1 -0
  60. package/dist/pathplan/route.d.ts.map +1 -1
  61. package/dist/pathplan/solvers.d.ts +15 -3
  62. package/dist/pathplan/solvers.d.ts.map +1 -1
  63. package/dist/render/dot/edge-draw.d.ts +12 -0
  64. package/dist/render/dot/edge-draw.d.ts.map +1 -1
  65. package/dist/render/svg-graph.d.ts +6 -5
  66. package/dist/render/svg-graph.d.ts.map +1 -1
  67. package/dist/render/svg.d.ts +2 -21
  68. package/dist/render/svg.d.ts.map +1 -1
  69. package/dist/render.js +1030 -742
  70. package/dist/render.js.map +4 -4
  71. package/dist/xdot/parse.d.ts.map +1 -1
  72. package/package.json +1 -1
  73. package/src/common/arith.ts +25 -0
  74. package/src/common/edge-in-box.ts +54 -0
  75. package/src/common/graph-init.ts +3 -3
  76. package/src/common/htmltable-emit.ts +4 -2
  77. package/src/common/make-label.ts +3 -1
  78. package/src/common/poly-gencode.ts +18 -4
  79. package/src/gvc/device.ts +8 -41
  80. package/src/gvc/edge-labels.ts +30 -13
  81. package/src/gvc/emit-gates.ts +89 -0
  82. package/src/gvc/job.ts +4 -0
  83. package/src/gvc/viewport.ts +29 -0
  84. package/src/layout/circo/blockpath.ts +6 -125
  85. package/src/layout/circo/crossings.ts +171 -0
  86. package/src/layout/dot/__fixtures__/2784.dot +1 -0
  87. package/src/layout/dot/__fixtures__/2784.native-16.1.svg +48 -0
  88. package/src/layout/dot/edge-route-chain.ts +11 -5
  89. package/src/layout/dot/edge-route.ts +19 -8
  90. package/src/layout/dot/index.ts +14 -4
  91. package/src/layout/dot/ortho-adapter.ts +11 -6
  92. package/src/layout/dot/pack-components.ts +11 -4
  93. package/src/layout/dot/splines-flat-multi.ts +21 -8
  94. package/src/layout/dot/splines-flat.ts +8 -35
  95. package/src/layout/dot/splines-route.ts +10 -2
  96. package/src/layout/dot/splines.ts +6 -6
  97. package/src/layout/neato/constraint-adjust.ts +10 -4
  98. package/src/layout/neato/multispline.ts +26 -9
  99. package/src/layout/neato/splines.ts +7 -7
  100. package/src/layout/pack/poly-place.ts +9 -2
  101. package/src/layout/sfdp/__fixtures__/pcp-rotate-native.ts +94 -0
  102. package/src/layout/sfdp/spring-driver.ts +45 -13
  103. package/src/ortho/index.ts +22 -13
  104. package/src/ortho/maze.ts +8 -2
  105. package/src/ortho/partition.ts +17 -2
  106. package/src/ortho/trap-segment.ts +47 -24
  107. package/src/ortho/trapezoid.ts +24 -15
  108. package/src/parser/dot.js +345 -380
  109. package/src/parser/dot.pegjs +25 -10
  110. package/src/parser/index.ts +15 -0
  111. package/src/parser/number-scan.ts +118 -0
  112. package/src/pathplan/route.ts +79 -34
  113. package/src/pathplan/solvers.ts +78 -50
  114. package/src/render/dot/edge-draw.ts +25 -0
  115. package/src/render/svg-graph.ts +77 -47
  116. package/src/render/svg-helpers.ts +2 -2
  117. package/src/render/svg.ts +4 -41
  118. package/src/xdot/parse.ts +19 -5
package/dist/index.js CHANGED
@@ -110,9 +110,9 @@ function peg$parse(input, options) {
110
110
  const peg$c0 = "{";
111
111
  const peg$c1 = "}";
112
112
  const peg$c2 = ";";
113
- const peg$c3 = "[";
114
- const peg$c4 = "]";
115
- const peg$c5 = "=";
113
+ const peg$c3 = "=";
114
+ const peg$c4 = "[";
115
+ const peg$c5 = "]";
116
116
  const peg$c6 = ":";
117
117
  const peg$c7 = "->";
118
118
  const peg$c8 = "--";
@@ -136,32 +136,30 @@ function peg$parse(input, options) {
136
136
  const peg$r3 = /^[A-Za-z_\x80-\uFFFF]/;
137
137
  const peg$r4 = /^[A-Za-z_0-9\x80-\uFFFF]/;
138
138
  const peg$r5 = /^[0-9]/;
139
- const peg$r6 = /^[eE]/;
140
- const peg$r7 = /^[+\-]/;
141
- const peg$r8 = /^[Ss]/;
142
- const peg$r9 = /^[Tt]/;
143
- const peg$r10 = /^[Rr]/;
144
- const peg$r11 = /^[Ii]/;
145
- const peg$r12 = /^[Cc]/;
146
- const peg$r13 = /^[Gg]/;
147
- const peg$r14 = /^[Aa]/;
148
- const peg$r15 = /^[Pp]/;
149
- const peg$r16 = /^[Hh]/;
150
- const peg$r17 = /^[Dd]/;
151
- const peg$r18 = /^[Nn]/;
152
- const peg$r19 = /^[Oo]/;
153
- const peg$r20 = /^[Ee]/;
154
- const peg$r21 = /^[Uu]/;
155
- const peg$r22 = /^[Bb]/;
156
- const peg$r23 = /^[ \t\r\n]/;
157
- const peg$r24 = /^[^\n]/;
139
+ const peg$r6 = /^[Ss]/;
140
+ const peg$r7 = /^[Tt]/;
141
+ const peg$r8 = /^[Rr]/;
142
+ const peg$r9 = /^[Ii]/;
143
+ const peg$r10 = /^[Cc]/;
144
+ const peg$r11 = /^[Gg]/;
145
+ const peg$r12 = /^[Aa]/;
146
+ const peg$r13 = /^[Pp]/;
147
+ const peg$r14 = /^[Hh]/;
148
+ const peg$r15 = /^[Dd]/;
149
+ const peg$r16 = /^[Nn]/;
150
+ const peg$r17 = /^[Oo]/;
151
+ const peg$r18 = /^[Ee]/;
152
+ const peg$r19 = /^[Uu]/;
153
+ const peg$r20 = /^[Bb]/;
154
+ const peg$r21 = /^[ \t\r\n]/;
155
+ const peg$r22 = /^[^\n]/;
158
156
  const peg$e0 = peg$literalExpectation("{", false);
159
157
  const peg$e1 = peg$literalExpectation("}", false);
160
158
  const peg$e2 = peg$literalExpectation(";", false);
161
- const peg$e3 = peg$literalExpectation("[", false);
162
- const peg$e4 = peg$literalExpectation("]", false);
163
- const peg$e5 = peg$classExpectation([";", ","], false, false, false);
164
- const peg$e6 = peg$literalExpectation("=", false);
159
+ const peg$e3 = peg$literalExpectation("=", false);
160
+ const peg$e4 = peg$literalExpectation("[", false);
161
+ const peg$e5 = peg$literalExpectation("]", false);
162
+ const peg$e6 = peg$classExpectation([";", ","], false, false, false);
165
163
  const peg$e7 = peg$literalExpectation(":", false);
166
164
  const peg$e8 = peg$otherExpectation("edge operator");
167
165
  const peg$e9 = peg$literalExpectation("->", false);
@@ -181,30 +179,28 @@ function peg$parse(input, options) {
181
179
  const peg$e23 = peg$literalExpectation("-", false);
182
180
  const peg$e24 = peg$classExpectation([["0", "9"]], false, false, false);
183
181
  const peg$e25 = peg$literalExpectation(".", false);
184
- const peg$e26 = peg$classExpectation(["e", "E"], false, false, false);
185
- const peg$e27 = peg$classExpectation(["+", "-"], false, false, false);
186
- const peg$e28 = peg$classExpectation(["S", "s"], false, false, false);
187
- const peg$e29 = peg$classExpectation(["T", "t"], false, false, false);
188
- const peg$e30 = peg$classExpectation(["R", "r"], false, false, false);
189
- const peg$e31 = peg$classExpectation(["I", "i"], false, false, false);
190
- const peg$e32 = peg$classExpectation(["C", "c"], false, false, false);
191
- const peg$e33 = peg$classExpectation(["G", "g"], false, false, false);
192
- const peg$e34 = peg$classExpectation(["A", "a"], false, false, false);
193
- const peg$e35 = peg$classExpectation(["P", "p"], false, false, false);
194
- const peg$e36 = peg$classExpectation(["H", "h"], false, false, false);
195
- const peg$e37 = peg$classExpectation(["D", "d"], false, false, false);
196
- const peg$e38 = peg$classExpectation(["N", "n"], false, false, false);
197
- const peg$e39 = peg$classExpectation(["O", "o"], false, false, false);
198
- const peg$e40 = peg$classExpectation(["E", "e"], false, false, false);
199
- const peg$e41 = peg$classExpectation(["U", "u"], false, false, false);
200
- const peg$e42 = peg$classExpectation(["B", "b"], false, false, false);
201
- const peg$e43 = peg$classExpectation([" ", " ", "\r", "\n"], false, false, false);
202
- const peg$e44 = peg$literalExpectation("/*", false);
203
- const peg$e45 = peg$literalExpectation("*/", false);
204
- const peg$e46 = peg$literalExpectation("//", false);
205
- const peg$e47 = peg$classExpectation(["\n"], true, false, false);
206
- const peg$e48 = peg$literalExpectation("\n", false);
207
- const peg$e49 = peg$literalExpectation("#", false);
182
+ const peg$e26 = peg$classExpectation(["S", "s"], false, false, false);
183
+ const peg$e27 = peg$classExpectation(["T", "t"], false, false, false);
184
+ const peg$e28 = peg$classExpectation(["R", "r"], false, false, false);
185
+ const peg$e29 = peg$classExpectation(["I", "i"], false, false, false);
186
+ const peg$e30 = peg$classExpectation(["C", "c"], false, false, false);
187
+ const peg$e31 = peg$classExpectation(["G", "g"], false, false, false);
188
+ const peg$e32 = peg$classExpectation(["A", "a"], false, false, false);
189
+ const peg$e33 = peg$classExpectation(["P", "p"], false, false, false);
190
+ const peg$e34 = peg$classExpectation(["H", "h"], false, false, false);
191
+ const peg$e35 = peg$classExpectation(["D", "d"], false, false, false);
192
+ const peg$e36 = peg$classExpectation(["N", "n"], false, false, false);
193
+ const peg$e37 = peg$classExpectation(["O", "o"], false, false, false);
194
+ const peg$e38 = peg$classExpectation(["E", "e"], false, false, false);
195
+ const peg$e39 = peg$classExpectation(["U", "u"], false, false, false);
196
+ const peg$e40 = peg$classExpectation(["B", "b"], false, false, false);
197
+ const peg$e41 = peg$classExpectation([" ", " ", "\r", "\n"], false, false, false);
198
+ const peg$e42 = peg$literalExpectation("/*", false);
199
+ const peg$e43 = peg$literalExpectation("*/", false);
200
+ const peg$e44 = peg$literalExpectation("//", false);
201
+ const peg$e45 = peg$classExpectation(["\n"], true, false, false);
202
+ const peg$e46 = peg$literalExpectation("\n", false);
203
+ const peg$e47 = peg$literalExpectation("#", false);
208
204
  function peg$f0(s, t, id, stmts) {
209
205
  return {
210
206
  type: "graph",
@@ -247,40 +243,44 @@ function peg$parse(input, options) {
247
243
  function peg$f11(s) {
248
244
  return s;
249
245
  }
250
- function peg$f12(t, attrs) {
246
+ function peg$f12(t, m, attrs) {
247
+ if (m) console.error("Warning: attribute macros not implemented");
251
248
  return { type: "attr", target: t, attrs };
252
249
  }
253
250
  function peg$f13(a) {
254
251
  return { type: "assign", key: a.key, value: a.value };
255
252
  }
256
253
  function peg$f14() {
257
- return "graph";
254
+ return true;
258
255
  }
259
256
  function peg$f15() {
260
- return "node";
257
+ return false;
261
258
  }
262
259
  function peg$f16() {
260
+ return "graph";
261
+ }
262
+ function peg$f17() {
263
+ return "node";
264
+ }
265
+ function peg$f18() {
263
266
  return "edge";
264
267
  }
265
- function peg$f17(defs, rest) {
268
+ function peg$f19(defs, rest) {
266
269
  return defs.concat(rest);
267
270
  }
268
- function peg$f18(defs) {
269
- return defs;
270
- }
271
- function peg$f19() {
271
+ function peg$f20() {
272
272
  return [];
273
273
  }
274
- function peg$f20(a) {
274
+ function peg$f21(a) {
275
275
  return a;
276
276
  }
277
- function peg$f21(pairs) {
277
+ function peg$f22(pairs) {
278
278
  return pairs;
279
279
  }
280
- function peg$f22(k, v) {
280
+ function peg$f23(k, v) {
281
281
  return { key: k, value: v };
282
282
  }
283
- function peg$f23(head, chain, attrs) {
283
+ function peg$f24(head, chain, attrs) {
284
284
  if (chain.length > 0) {
285
285
  const nodes = [head].concat(chain);
286
286
  return { type: "edge", nodes, attrs };
@@ -291,70 +291,70 @@ function peg$parse(input, options) {
291
291
  return { type: "node", id: head, attrs };
292
292
  }
293
293
  }
294
- function peg$f24(s) {
294
+ function peg$f25(s) {
295
295
  return s;
296
296
  }
297
- function peg$f25(n) {
297
+ function peg$f26(n) {
298
298
  return n;
299
299
  }
300
- function peg$f26(id, port, compass) {
300
+ function peg$f27(id, port, compass) {
301
301
  return { id, port, compass };
302
302
  }
303
- function peg$f27(id, port) {
303
+ function peg$f28(id, port) {
304
304
  return { id, port, compass: null };
305
305
  }
306
- function peg$f28(id) {
306
+ function peg$f29(id) {
307
307
  return { id, port: null, compass: null };
308
308
  }
309
- function peg$f29(s, rest) {
309
+ function peg$f30(s, rest) {
310
310
  return [s].concat(rest);
311
311
  }
312
- function peg$f30() {
312
+ function peg$f31() {
313
313
  return [];
314
314
  }
315
- function peg$f31(id, stmts) {
315
+ function peg$f32(id, stmts) {
316
316
  return { type: "subgraph", id, stmts };
317
317
  }
318
- function peg$f32(stmts) {
318
+ function peg$f33(stmts) {
319
319
  return { type: "subgraph", id: null, stmts };
320
320
  }
321
- function peg$f33(stmts) {
321
+ function peg$f34(stmts) {
322
322
  return { type: "subgraph", id: null, stmts };
323
323
  }
324
- function peg$f34(first, s) {
324
+ function peg$f35(first, s) {
325
325
  return s;
326
326
  }
327
- function peg$f35(first, rest) {
327
+ function peg$f36(first, rest) {
328
328
  return rest.length > 0 ? first + rest.join("") : first;
329
329
  }
330
- function peg$f36(chars) {
330
+ function peg$f37(chars) {
331
331
  return chars.join("");
332
332
  }
333
- function peg$f37() {
333
+ function peg$f38() {
334
334
  return '"';
335
335
  }
336
- function peg$f38() {
336
+ function peg$f39() {
337
337
  return "";
338
338
  }
339
- function peg$f39(c) {
339
+ function peg$f40(c) {
340
340
  return "\\" + c;
341
341
  }
342
- function peg$f40(content) {
342
+ function peg$f41(content) {
343
343
  return "" + content;
344
344
  }
345
- function peg$f41(chars) {
345
+ function peg$f42(chars) {
346
346
  return chars.join("");
347
347
  }
348
- function peg$f42(nested2, content) {
348
+ function peg$f43(nested2, content) {
349
349
  return "<" + content + ">";
350
350
  }
351
- function peg$f43(n) {
351
+ function peg$f44(n) {
352
352
  return n;
353
353
  }
354
- function peg$f44(first, rest) {
354
+ function peg$f45(first, rest) {
355
355
  return first + rest.join("");
356
356
  }
357
- function peg$f45(s) {
357
+ function peg$f46(s) {
358
358
  return Array.isArray(s) ? s.flat(Infinity).filter((x) => x !== null && x !== void 0).join("") : String(s);
359
359
  }
360
360
  let peg$currPos = options.peg$currPos | 0;
@@ -725,15 +725,21 @@ function peg$parse(input, options) {
725
725
  return s0;
726
726
  }
727
727
  function peg$parseAttrStmt() {
728
- let s0, s12, s2, s3;
728
+ let s0, s12, s2, s3, s4;
729
729
  s0 = peg$currPos;
730
730
  s12 = peg$parseAttrType();
731
731
  if (s12 !== peg$FAILED) {
732
732
  s2 = peg$parse_();
733
- s3 = peg$parseAttrList();
733
+ s3 = peg$parseOptMacroName();
734
734
  if (s3 !== peg$FAILED) {
735
- peg$savedPos = s0;
736
- s0 = peg$f12(s12, s3);
735
+ s4 = peg$parseAttrListReq();
736
+ if (s4 !== peg$FAILED) {
737
+ peg$savedPos = s0;
738
+ s0 = peg$f12(s12, s3, s4);
739
+ } else {
740
+ peg$currPos = s0;
741
+ s0 = peg$FAILED;
742
+ }
737
743
  } else {
738
744
  peg$currPos = s0;
739
745
  s0 = peg$FAILED;
@@ -753,13 +759,49 @@ function peg$parse(input, options) {
753
759
  }
754
760
  return s0;
755
761
  }
762
+ function peg$parseOptMacroName() {
763
+ let s0, s12, s2, s3, s4;
764
+ s0 = peg$currPos;
765
+ s12 = peg$parseAtom();
766
+ if (s12 !== peg$FAILED) {
767
+ s2 = peg$parse_();
768
+ if (input.charCodeAt(peg$currPos) === 61) {
769
+ s3 = peg$c3;
770
+ peg$currPos++;
771
+ } else {
772
+ s3 = peg$FAILED;
773
+ if (peg$silentFails === 0) {
774
+ peg$fail(peg$e3);
775
+ }
776
+ }
777
+ if (s3 !== peg$FAILED) {
778
+ s4 = peg$parse_();
779
+ peg$savedPos = s0;
780
+ s0 = peg$f14();
781
+ } else {
782
+ peg$currPos = s0;
783
+ s0 = peg$FAILED;
784
+ }
785
+ } else {
786
+ peg$currPos = s0;
787
+ s0 = peg$FAILED;
788
+ }
789
+ if (s0 === peg$FAILED) {
790
+ s0 = peg$currPos;
791
+ s12 = "";
792
+ peg$savedPos = s0;
793
+ s12 = peg$f15();
794
+ s0 = s12;
795
+ }
796
+ return s0;
797
+ }
756
798
  function peg$parseAttrType() {
757
799
  let s0, s12;
758
800
  s0 = peg$currPos;
759
801
  s12 = peg$parseGraphKw();
760
802
  if (s12 !== peg$FAILED) {
761
803
  peg$savedPos = s0;
762
- s12 = peg$f14();
804
+ s12 = peg$f16();
763
805
  }
764
806
  s0 = s12;
765
807
  if (s0 === peg$FAILED) {
@@ -767,7 +809,7 @@ function peg$parse(input, options) {
767
809
  s12 = peg$parseNodeKw();
768
810
  if (s12 !== peg$FAILED) {
769
811
  peg$savedPos = s0;
770
- s12 = peg$f15();
812
+ s12 = peg$f17();
771
813
  }
772
814
  s0 = s12;
773
815
  if (s0 === peg$FAILED) {
@@ -775,24 +817,24 @@ function peg$parse(input, options) {
775
817
  s12 = peg$parseEdgeKw();
776
818
  if (s12 !== peg$FAILED) {
777
819
  peg$savedPos = s0;
778
- s12 = peg$f16();
820
+ s12 = peg$f18();
779
821
  }
780
822
  s0 = s12;
781
823
  }
782
824
  }
783
825
  return s0;
784
826
  }
785
- function peg$parseAttrList() {
827
+ function peg$parseAttrListReq() {
786
828
  let s0, s12, s2, s3, s4, s5, s6, s7;
787
829
  s0 = peg$currPos;
788
830
  s12 = peg$parse_();
789
831
  if (input.charCodeAt(peg$currPos) === 91) {
790
- s2 = peg$c3;
832
+ s2 = peg$c4;
791
833
  peg$currPos++;
792
834
  } else {
793
835
  s2 = peg$FAILED;
794
836
  if (peg$silentFails === 0) {
795
- peg$fail(peg$e3);
837
+ peg$fail(peg$e4);
796
838
  }
797
839
  }
798
840
  if (s2 !== peg$FAILED) {
@@ -800,19 +842,19 @@ function peg$parse(input, options) {
800
842
  s4 = peg$parseAttrDefs();
801
843
  s5 = peg$parse_();
802
844
  if (input.charCodeAt(peg$currPos) === 93) {
803
- s6 = peg$c4;
845
+ s6 = peg$c5;
804
846
  peg$currPos++;
805
847
  } else {
806
848
  s6 = peg$FAILED;
807
849
  if (peg$silentFails === 0) {
808
- peg$fail(peg$e4);
850
+ peg$fail(peg$e5);
809
851
  }
810
852
  }
811
853
  if (s6 !== peg$FAILED) {
812
854
  s7 = peg$parseAttrList();
813
855
  if (s7 !== peg$FAILED) {
814
856
  peg$savedPos = s0;
815
- s0 = peg$f17(s4, s7);
857
+ s0 = peg$f19(s4, s7);
816
858
  } else {
817
859
  peg$currPos = s0;
818
860
  s0 = peg$FAILED;
@@ -825,49 +867,17 @@ function peg$parse(input, options) {
825
867
  peg$currPos = s0;
826
868
  s0 = peg$FAILED;
827
869
  }
870
+ return s0;
871
+ }
872
+ function peg$parseAttrList() {
873
+ let s0, s12;
874
+ s0 = peg$parseAttrListReq();
828
875
  if (s0 === peg$FAILED) {
829
876
  s0 = peg$currPos;
830
- s12 = peg$parse_();
831
- if (input.charCodeAt(peg$currPos) === 91) {
832
- s2 = peg$c3;
833
- peg$currPos++;
834
- } else {
835
- s2 = peg$FAILED;
836
- if (peg$silentFails === 0) {
837
- peg$fail(peg$e3);
838
- }
839
- }
840
- if (s2 !== peg$FAILED) {
841
- s3 = peg$parse_();
842
- s4 = peg$parseAttrDefs();
843
- s5 = peg$parse_();
844
- if (input.charCodeAt(peg$currPos) === 93) {
845
- s6 = peg$c4;
846
- peg$currPos++;
847
- } else {
848
- s6 = peg$FAILED;
849
- if (peg$silentFails === 0) {
850
- peg$fail(peg$e4);
851
- }
852
- }
853
- if (s6 !== peg$FAILED) {
854
- peg$savedPos = s0;
855
- s0 = peg$f18(s4);
856
- } else {
857
- peg$currPos = s0;
858
- s0 = peg$FAILED;
859
- }
860
- } else {
861
- peg$currPos = s0;
862
- s0 = peg$FAILED;
863
- }
864
- if (s0 === peg$FAILED) {
865
- s0 = peg$currPos;
866
- s12 = "";
867
- peg$savedPos = s0;
868
- s12 = peg$f19();
869
- s0 = s12;
870
- }
877
+ s12 = "";
878
+ peg$savedPos = s0;
879
+ s12 = peg$f20();
880
+ s0 = s12;
871
881
  }
872
882
  return s0;
873
883
  }
@@ -886,7 +896,7 @@ function peg$parse(input, options) {
886
896
  } else {
887
897
  s6 = peg$FAILED;
888
898
  if (peg$silentFails === 0) {
889
- peg$fail(peg$e5);
899
+ peg$fail(peg$e6);
890
900
  }
891
901
  }
892
902
  if (s6 !== peg$FAILED) {
@@ -901,7 +911,7 @@ function peg$parse(input, options) {
901
911
  s5 = null;
902
912
  }
903
913
  peg$savedPos = s2;
904
- s2 = peg$f20(s3);
914
+ s2 = peg$f21(s3);
905
915
  } else {
906
916
  peg$currPos = s2;
907
917
  s2 = peg$FAILED;
@@ -919,7 +929,7 @@ function peg$parse(input, options) {
919
929
  } else {
920
930
  s6 = peg$FAILED;
921
931
  if (peg$silentFails === 0) {
922
- peg$fail(peg$e5);
932
+ peg$fail(peg$e6);
923
933
  }
924
934
  }
925
935
  if (s6 !== peg$FAILED) {
@@ -934,14 +944,14 @@ function peg$parse(input, options) {
934
944
  s5 = null;
935
945
  }
936
946
  peg$savedPos = s2;
937
- s2 = peg$f20(s3);
947
+ s2 = peg$f21(s3);
938
948
  } else {
939
949
  peg$currPos = s2;
940
950
  s2 = peg$FAILED;
941
951
  }
942
952
  }
943
953
  peg$savedPos = s0;
944
- s12 = peg$f21(s12);
954
+ s12 = peg$f22(s12);
945
955
  s0 = s12;
946
956
  return s0;
947
957
  }
@@ -952,12 +962,12 @@ function peg$parse(input, options) {
952
962
  if (s12 !== peg$FAILED) {
953
963
  s2 = peg$parse_();
954
964
  if (input.charCodeAt(peg$currPos) === 61) {
955
- s3 = peg$c5;
965
+ s3 = peg$c3;
956
966
  peg$currPos++;
957
967
  } else {
958
968
  s3 = peg$FAILED;
959
969
  if (peg$silentFails === 0) {
960
- peg$fail(peg$e6);
970
+ peg$fail(peg$e3);
961
971
  }
962
972
  }
963
973
  if (s3 !== peg$FAILED) {
@@ -965,7 +975,7 @@ function peg$parse(input, options) {
965
975
  s5 = peg$parseAtom();
966
976
  if (s5 !== peg$FAILED) {
967
977
  peg$savedPos = s0;
968
- s0 = peg$f22(s12, s5);
978
+ s0 = peg$f23(s12, s5);
969
979
  } else {
970
980
  peg$currPos = s0;
971
981
  s0 = peg$FAILED;
@@ -992,7 +1002,7 @@ function peg$parse(input, options) {
992
1002
  s5 = peg$parseAttrList();
993
1003
  if (s5 !== peg$FAILED) {
994
1004
  peg$savedPos = s0;
995
- s0 = peg$f23(s12, s3, s5);
1005
+ s0 = peg$f24(s12, s3, s5);
996
1006
  } else {
997
1007
  peg$currPos = s0;
998
1008
  s0 = peg$FAILED;
@@ -1013,7 +1023,7 @@ function peg$parse(input, options) {
1013
1023
  s12 = peg$parseSubgraph();
1014
1024
  if (s12 !== peg$FAILED) {
1015
1025
  peg$savedPos = s0;
1016
- s12 = peg$f24(s12);
1026
+ s12 = peg$f25(s12);
1017
1027
  }
1018
1028
  s0 = s12;
1019
1029
  if (s0 === peg$FAILED) {
@@ -1021,7 +1031,7 @@ function peg$parse(input, options) {
1021
1031
  s12 = peg$parseNode();
1022
1032
  if (s12 !== peg$FAILED) {
1023
1033
  peg$savedPos = s0;
1024
- s12 = peg$f25(s12);
1034
+ s12 = peg$f26(s12);
1025
1035
  }
1026
1036
  s0 = s12;
1027
1037
  }
@@ -1061,7 +1071,7 @@ function peg$parse(input, options) {
1061
1071
  s9 = peg$parseAtom();
1062
1072
  if (s9 !== peg$FAILED) {
1063
1073
  peg$savedPos = s0;
1064
- s0 = peg$f26(s12, s5, s9);
1074
+ s0 = peg$f27(s12, s5, s9);
1065
1075
  } else {
1066
1076
  peg$currPos = s0;
1067
1077
  s0 = peg$FAILED;
@@ -1101,7 +1111,7 @@ function peg$parse(input, options) {
1101
1111
  s5 = peg$parseAtom();
1102
1112
  if (s5 !== peg$FAILED) {
1103
1113
  peg$savedPos = s0;
1104
- s0 = peg$f27(s12, s5);
1114
+ s0 = peg$f28(s12, s5);
1105
1115
  } else {
1106
1116
  peg$currPos = s0;
1107
1117
  s0 = peg$FAILED;
@@ -1119,7 +1129,7 @@ function peg$parse(input, options) {
1119
1129
  s12 = peg$parseAtom();
1120
1130
  if (s12 !== peg$FAILED) {
1121
1131
  peg$savedPos = s0;
1122
- s12 = peg$f28(s12);
1132
+ s12 = peg$f29(s12);
1123
1133
  }
1124
1134
  s0 = s12;
1125
1135
  }
@@ -1138,7 +1148,7 @@ function peg$parse(input, options) {
1138
1148
  s5 = peg$parseEdgeChain();
1139
1149
  if (s5 !== peg$FAILED) {
1140
1150
  peg$savedPos = s0;
1141
- s0 = peg$f29(s3, s5);
1151
+ s0 = peg$f30(s3, s5);
1142
1152
  } else {
1143
1153
  peg$currPos = s0;
1144
1154
  s0 = peg$FAILED;
@@ -1155,7 +1165,7 @@ function peg$parse(input, options) {
1155
1165
  s0 = peg$currPos;
1156
1166
  s12 = "";
1157
1167
  peg$savedPos = s0;
1158
- s12 = peg$f30();
1168
+ s12 = peg$f31();
1159
1169
  s0 = s12;
1160
1170
  }
1161
1171
  return s0;
@@ -1226,7 +1236,7 @@ function peg$parse(input, options) {
1226
1236
  }
1227
1237
  if (s9 !== peg$FAILED) {
1228
1238
  peg$savedPos = s0;
1229
- s0 = peg$f31(s3, s7);
1239
+ s0 = peg$f32(s3, s7);
1230
1240
  } else {
1231
1241
  peg$currPos = s0;
1232
1242
  s0 = peg$FAILED;
@@ -1277,7 +1287,7 @@ function peg$parse(input, options) {
1277
1287
  }
1278
1288
  if (s7 !== peg$FAILED) {
1279
1289
  peg$savedPos = s0;
1280
- s0 = peg$f32(s5);
1290
+ s0 = peg$f33(s5);
1281
1291
  } else {
1282
1292
  peg$currPos = s0;
1283
1293
  s0 = peg$FAILED;
@@ -1321,7 +1331,7 @@ function peg$parse(input, options) {
1321
1331
  }
1322
1332
  if (s5 !== peg$FAILED) {
1323
1333
  peg$savedPos = s0;
1324
- s0 = peg$f33(s3);
1334
+ s0 = peg$f34(s3);
1325
1335
  } else {
1326
1336
  peg$currPos = s0;
1327
1337
  s0 = peg$FAILED;
@@ -1360,7 +1370,7 @@ function peg$parse(input, options) {
1360
1370
  s7 = peg$parseQAtom();
1361
1371
  if (s7 !== peg$FAILED) {
1362
1372
  peg$savedPos = s3;
1363
- s3 = peg$f34(s12, s7);
1373
+ s3 = peg$f35(s12, s7);
1364
1374
  } else {
1365
1375
  peg$currPos = s3;
1366
1376
  s3 = peg$FAILED;
@@ -1387,7 +1397,7 @@ function peg$parse(input, options) {
1387
1397
  s7 = peg$parseQAtom();
1388
1398
  if (s7 !== peg$FAILED) {
1389
1399
  peg$savedPos = s3;
1390
- s3 = peg$f34(s12, s7);
1400
+ s3 = peg$f35(s12, s7);
1391
1401
  } else {
1392
1402
  peg$currPos = s3;
1393
1403
  s3 = peg$FAILED;
@@ -1398,7 +1408,7 @@ function peg$parse(input, options) {
1398
1408
  }
1399
1409
  }
1400
1410
  peg$savedPos = s0;
1401
- s0 = peg$f35(s12, s2);
1411
+ s0 = peg$f36(s12, s2);
1402
1412
  } else {
1403
1413
  peg$currPos = s0;
1404
1414
  s0 = peg$FAILED;
@@ -1446,7 +1456,7 @@ function peg$parse(input, options) {
1446
1456
  }
1447
1457
  if (s3 !== peg$FAILED) {
1448
1458
  peg$savedPos = s0;
1449
- s0 = peg$f36(s2);
1459
+ s0 = peg$f37(s2);
1450
1460
  } else {
1451
1461
  peg$currPos = s0;
1452
1462
  s0 = peg$FAILED;
@@ -1471,7 +1481,7 @@ function peg$parse(input, options) {
1471
1481
  }
1472
1482
  if (s12 !== peg$FAILED) {
1473
1483
  peg$savedPos = s0;
1474
- s12 = peg$f37();
1484
+ s12 = peg$f38();
1475
1485
  }
1476
1486
  s0 = s12;
1477
1487
  if (s0 === peg$FAILED) {
@@ -1487,7 +1497,7 @@ function peg$parse(input, options) {
1487
1497
  }
1488
1498
  if (s12 !== peg$FAILED) {
1489
1499
  peg$savedPos = s0;
1490
- s12 = peg$f38();
1500
+ s12 = peg$f39();
1491
1501
  }
1492
1502
  s0 = s12;
1493
1503
  if (s0 === peg$FAILED) {
@@ -1513,7 +1523,7 @@ function peg$parse(input, options) {
1513
1523
  }
1514
1524
  if (s2 !== peg$FAILED) {
1515
1525
  peg$savedPos = s0;
1516
- s0 = peg$f39(s2);
1526
+ s0 = peg$f40(s2);
1517
1527
  } else {
1518
1528
  peg$currPos = s0;
1519
1529
  s0 = peg$FAILED;
@@ -1562,7 +1572,7 @@ function peg$parse(input, options) {
1562
1572
  }
1563
1573
  if (s3 !== peg$FAILED) {
1564
1574
  peg$savedPos = s0;
1565
- s0 = peg$f40(s2);
1575
+ s0 = peg$f41(s2);
1566
1576
  } else {
1567
1577
  peg$currPos = s0;
1568
1578
  s0 = peg$FAILED;
@@ -1583,7 +1593,7 @@ function peg$parse(input, options) {
1583
1593
  s2 = peg$parseHtmlChar();
1584
1594
  }
1585
1595
  peg$savedPos = s0;
1586
- s12 = peg$f41(s12);
1596
+ s12 = peg$f42(s12);
1587
1597
  s0 = s12;
1588
1598
  return s0;
1589
1599
  }
@@ -1613,7 +1623,7 @@ function peg$parse(input, options) {
1613
1623
  }
1614
1624
  if (s3 !== peg$FAILED) {
1615
1625
  peg$savedPos = s0;
1616
- s0 = peg$f42(s12, s2);
1626
+ s0 = peg$f43(s12, s2);
1617
1627
  } else {
1618
1628
  peg$currPos = s0;
1619
1629
  s0 = peg$FAILED;
@@ -1658,7 +1668,7 @@ function peg$parse(input, options) {
1658
1668
  s2 = peg$parseName();
1659
1669
  if (s2 !== peg$FAILED) {
1660
1670
  peg$savedPos = s0;
1661
- s0 = peg$f43(s2);
1671
+ s0 = peg$f44(s2);
1662
1672
  } else {
1663
1673
  peg$currPos = s0;
1664
1674
  s0 = peg$FAILED;
@@ -1706,7 +1716,7 @@ function peg$parse(input, options) {
1706
1716
  }
1707
1717
  }
1708
1718
  peg$savedPos = s0;
1709
- s0 = peg$f44(s12, s2);
1719
+ s0 = peg$f45(s12, s2);
1710
1720
  } else {
1711
1721
  peg$currPos = s0;
1712
1722
  s0 = peg$FAILED;
@@ -1856,70 +1866,7 @@ function peg$parse(input, options) {
1856
1866
  }
1857
1867
  }
1858
1868
  if (s3 !== peg$FAILED) {
1859
- s4 = peg$currPos;
1860
- s5 = input.charAt(peg$currPos);
1861
- if (peg$r6.test(s5)) {
1862
- peg$currPos++;
1863
- } else {
1864
- s5 = peg$FAILED;
1865
- if (peg$silentFails === 0) {
1866
- peg$fail(peg$e26);
1867
- }
1868
- }
1869
- if (s5 !== peg$FAILED) {
1870
- s6 = input.charAt(peg$currPos);
1871
- if (peg$r7.test(s6)) {
1872
- peg$currPos++;
1873
- } else {
1874
- s6 = peg$FAILED;
1875
- if (peg$silentFails === 0) {
1876
- peg$fail(peg$e27);
1877
- }
1878
- }
1879
- if (s6 === peg$FAILED) {
1880
- s6 = null;
1881
- }
1882
- s7 = [];
1883
- s8 = input.charAt(peg$currPos);
1884
- if (peg$r5.test(s8)) {
1885
- peg$currPos++;
1886
- } else {
1887
- s8 = peg$FAILED;
1888
- if (peg$silentFails === 0) {
1889
- peg$fail(peg$e24);
1890
- }
1891
- }
1892
- if (s8 !== peg$FAILED) {
1893
- while (s8 !== peg$FAILED) {
1894
- s7.push(s8);
1895
- s8 = input.charAt(peg$currPos);
1896
- if (peg$r5.test(s8)) {
1897
- peg$currPos++;
1898
- } else {
1899
- s8 = peg$FAILED;
1900
- if (peg$silentFails === 0) {
1901
- peg$fail(peg$e24);
1902
- }
1903
- }
1904
- }
1905
- } else {
1906
- s7 = peg$FAILED;
1907
- }
1908
- if (s7 !== peg$FAILED) {
1909
- s5 = [s5, s6, s7];
1910
- s4 = s5;
1911
- } else {
1912
- peg$currPos = s4;
1913
- s4 = peg$FAILED;
1914
- }
1915
- } else {
1916
- peg$currPos = s4;
1917
- s4 = peg$FAILED;
1918
- }
1919
- if (s4 === peg$FAILED) {
1920
- s4 = null;
1921
- }
1922
- s2 = [s2, s3, s4];
1869
+ s2 = [s2, s3];
1923
1870
  s12 = s2;
1924
1871
  } else {
1925
1872
  peg$currPos = s12;
@@ -1927,7 +1874,7 @@ function peg$parse(input, options) {
1927
1874
  }
1928
1875
  if (s12 !== peg$FAILED) {
1929
1876
  peg$savedPos = s0;
1930
- s12 = peg$f45(s12);
1877
+ s12 = peg$f46(s12);
1931
1878
  }
1932
1879
  s0 = s12;
1933
1880
  return s0;
@@ -1936,62 +1883,62 @@ function peg$parse(input, options) {
1936
1883
  let s0, s12, s2, s3, s4, s5, s6, s7, s8;
1937
1884
  s0 = peg$currPos;
1938
1885
  s12 = input.charAt(peg$currPos);
1939
- if (peg$r8.test(s12)) {
1886
+ if (peg$r6.test(s12)) {
1940
1887
  peg$currPos++;
1941
1888
  } else {
1942
1889
  s12 = peg$FAILED;
1943
1890
  if (peg$silentFails === 0) {
1944
- peg$fail(peg$e28);
1891
+ peg$fail(peg$e26);
1945
1892
  }
1946
1893
  }
1947
1894
  if (s12 !== peg$FAILED) {
1948
1895
  s2 = input.charAt(peg$currPos);
1949
- if (peg$r9.test(s2)) {
1896
+ if (peg$r7.test(s2)) {
1950
1897
  peg$currPos++;
1951
1898
  } else {
1952
1899
  s2 = peg$FAILED;
1953
1900
  if (peg$silentFails === 0) {
1954
- peg$fail(peg$e29);
1901
+ peg$fail(peg$e27);
1955
1902
  }
1956
1903
  }
1957
1904
  if (s2 !== peg$FAILED) {
1958
1905
  s3 = input.charAt(peg$currPos);
1959
- if (peg$r10.test(s3)) {
1906
+ if (peg$r8.test(s3)) {
1960
1907
  peg$currPos++;
1961
1908
  } else {
1962
1909
  s3 = peg$FAILED;
1963
1910
  if (peg$silentFails === 0) {
1964
- peg$fail(peg$e30);
1911
+ peg$fail(peg$e28);
1965
1912
  }
1966
1913
  }
1967
1914
  if (s3 !== peg$FAILED) {
1968
1915
  s4 = input.charAt(peg$currPos);
1969
- if (peg$r11.test(s4)) {
1916
+ if (peg$r9.test(s4)) {
1970
1917
  peg$currPos++;
1971
1918
  } else {
1972
1919
  s4 = peg$FAILED;
1973
1920
  if (peg$silentFails === 0) {
1974
- peg$fail(peg$e31);
1921
+ peg$fail(peg$e29);
1975
1922
  }
1976
1923
  }
1977
1924
  if (s4 !== peg$FAILED) {
1978
1925
  s5 = input.charAt(peg$currPos);
1979
- if (peg$r12.test(s5)) {
1926
+ if (peg$r10.test(s5)) {
1980
1927
  peg$currPos++;
1981
1928
  } else {
1982
1929
  s5 = peg$FAILED;
1983
1930
  if (peg$silentFails === 0) {
1984
- peg$fail(peg$e32);
1931
+ peg$fail(peg$e30);
1985
1932
  }
1986
1933
  }
1987
1934
  if (s5 !== peg$FAILED) {
1988
1935
  s6 = input.charAt(peg$currPos);
1989
- if (peg$r9.test(s6)) {
1936
+ if (peg$r7.test(s6)) {
1990
1937
  peg$currPos++;
1991
1938
  } else {
1992
1939
  s6 = peg$FAILED;
1993
1940
  if (peg$silentFails === 0) {
1994
- peg$fail(peg$e29);
1941
+ peg$fail(peg$e27);
1995
1942
  }
1996
1943
  }
1997
1944
  if (s6 !== peg$FAILED) {
@@ -2042,52 +1989,52 @@ function peg$parse(input, options) {
2042
1989
  let s0, s12, s2, s3, s4, s5, s6, s7;
2043
1990
  s0 = peg$currPos;
2044
1991
  s12 = input.charAt(peg$currPos);
2045
- if (peg$r13.test(s12)) {
1992
+ if (peg$r11.test(s12)) {
2046
1993
  peg$currPos++;
2047
1994
  } else {
2048
1995
  s12 = peg$FAILED;
2049
1996
  if (peg$silentFails === 0) {
2050
- peg$fail(peg$e33);
1997
+ peg$fail(peg$e31);
2051
1998
  }
2052
1999
  }
2053
2000
  if (s12 !== peg$FAILED) {
2054
2001
  s2 = input.charAt(peg$currPos);
2055
- if (peg$r10.test(s2)) {
2002
+ if (peg$r8.test(s2)) {
2056
2003
  peg$currPos++;
2057
2004
  } else {
2058
2005
  s2 = peg$FAILED;
2059
2006
  if (peg$silentFails === 0) {
2060
- peg$fail(peg$e30);
2007
+ peg$fail(peg$e28);
2061
2008
  }
2062
2009
  }
2063
2010
  if (s2 !== peg$FAILED) {
2064
2011
  s3 = input.charAt(peg$currPos);
2065
- if (peg$r14.test(s3)) {
2012
+ if (peg$r12.test(s3)) {
2066
2013
  peg$currPos++;
2067
2014
  } else {
2068
2015
  s3 = peg$FAILED;
2069
2016
  if (peg$silentFails === 0) {
2070
- peg$fail(peg$e34);
2017
+ peg$fail(peg$e32);
2071
2018
  }
2072
2019
  }
2073
2020
  if (s3 !== peg$FAILED) {
2074
2021
  s4 = input.charAt(peg$currPos);
2075
- if (peg$r15.test(s4)) {
2022
+ if (peg$r13.test(s4)) {
2076
2023
  peg$currPos++;
2077
2024
  } else {
2078
2025
  s4 = peg$FAILED;
2079
2026
  if (peg$silentFails === 0) {
2080
- peg$fail(peg$e35);
2027
+ peg$fail(peg$e33);
2081
2028
  }
2082
2029
  }
2083
2030
  if (s4 !== peg$FAILED) {
2084
2031
  s5 = input.charAt(peg$currPos);
2085
- if (peg$r16.test(s5)) {
2032
+ if (peg$r14.test(s5)) {
2086
2033
  peg$currPos++;
2087
2034
  } else {
2088
2035
  s5 = peg$FAILED;
2089
2036
  if (peg$silentFails === 0) {
2090
- peg$fail(peg$e36);
2037
+ peg$fail(peg$e34);
2091
2038
  }
2092
2039
  }
2093
2040
  if (s5 !== peg$FAILED) {
@@ -2134,72 +2081,72 @@ function peg$parse(input, options) {
2134
2081
  let s0, s12, s2, s3, s4, s5, s6, s7, s8, s9;
2135
2082
  s0 = peg$currPos;
2136
2083
  s12 = input.charAt(peg$currPos);
2137
- if (peg$r17.test(s12)) {
2084
+ if (peg$r15.test(s12)) {
2138
2085
  peg$currPos++;
2139
2086
  } else {
2140
2087
  s12 = peg$FAILED;
2141
2088
  if (peg$silentFails === 0) {
2142
- peg$fail(peg$e37);
2089
+ peg$fail(peg$e35);
2143
2090
  }
2144
2091
  }
2145
2092
  if (s12 !== peg$FAILED) {
2146
2093
  s2 = input.charAt(peg$currPos);
2147
- if (peg$r11.test(s2)) {
2094
+ if (peg$r9.test(s2)) {
2148
2095
  peg$currPos++;
2149
2096
  } else {
2150
2097
  s2 = peg$FAILED;
2151
2098
  if (peg$silentFails === 0) {
2152
- peg$fail(peg$e31);
2099
+ peg$fail(peg$e29);
2153
2100
  }
2154
2101
  }
2155
2102
  if (s2 !== peg$FAILED) {
2156
2103
  s3 = input.charAt(peg$currPos);
2157
- if (peg$r13.test(s3)) {
2104
+ if (peg$r11.test(s3)) {
2158
2105
  peg$currPos++;
2159
2106
  } else {
2160
2107
  s3 = peg$FAILED;
2161
2108
  if (peg$silentFails === 0) {
2162
- peg$fail(peg$e33);
2109
+ peg$fail(peg$e31);
2163
2110
  }
2164
2111
  }
2165
2112
  if (s3 !== peg$FAILED) {
2166
2113
  s4 = input.charAt(peg$currPos);
2167
- if (peg$r10.test(s4)) {
2114
+ if (peg$r8.test(s4)) {
2168
2115
  peg$currPos++;
2169
2116
  } else {
2170
2117
  s4 = peg$FAILED;
2171
2118
  if (peg$silentFails === 0) {
2172
- peg$fail(peg$e30);
2119
+ peg$fail(peg$e28);
2173
2120
  }
2174
2121
  }
2175
2122
  if (s4 !== peg$FAILED) {
2176
2123
  s5 = input.charAt(peg$currPos);
2177
- if (peg$r14.test(s5)) {
2124
+ if (peg$r12.test(s5)) {
2178
2125
  peg$currPos++;
2179
2126
  } else {
2180
2127
  s5 = peg$FAILED;
2181
2128
  if (peg$silentFails === 0) {
2182
- peg$fail(peg$e34);
2129
+ peg$fail(peg$e32);
2183
2130
  }
2184
2131
  }
2185
2132
  if (s5 !== peg$FAILED) {
2186
2133
  s6 = input.charAt(peg$currPos);
2187
- if (peg$r15.test(s6)) {
2134
+ if (peg$r13.test(s6)) {
2188
2135
  peg$currPos++;
2189
2136
  } else {
2190
2137
  s6 = peg$FAILED;
2191
2138
  if (peg$silentFails === 0) {
2192
- peg$fail(peg$e35);
2139
+ peg$fail(peg$e33);
2193
2140
  }
2194
2141
  }
2195
2142
  if (s6 !== peg$FAILED) {
2196
2143
  s7 = input.charAt(peg$currPos);
2197
- if (peg$r16.test(s7)) {
2144
+ if (peg$r14.test(s7)) {
2198
2145
  peg$currPos++;
2199
2146
  } else {
2200
2147
  s7 = peg$FAILED;
2201
2148
  if (peg$silentFails === 0) {
2202
- peg$fail(peg$e36);
2149
+ peg$fail(peg$e34);
2203
2150
  }
2204
2151
  }
2205
2152
  if (s7 !== peg$FAILED) {
@@ -2254,42 +2201,42 @@ function peg$parse(input, options) {
2254
2201
  let s0, s12, s2, s3, s4, s5, s6;
2255
2202
  s0 = peg$currPos;
2256
2203
  s12 = input.charAt(peg$currPos);
2257
- if (peg$r18.test(s12)) {
2204
+ if (peg$r16.test(s12)) {
2258
2205
  peg$currPos++;
2259
2206
  } else {
2260
2207
  s12 = peg$FAILED;
2261
2208
  if (peg$silentFails === 0) {
2262
- peg$fail(peg$e38);
2209
+ peg$fail(peg$e36);
2263
2210
  }
2264
2211
  }
2265
2212
  if (s12 !== peg$FAILED) {
2266
2213
  s2 = input.charAt(peg$currPos);
2267
- if (peg$r19.test(s2)) {
2214
+ if (peg$r17.test(s2)) {
2268
2215
  peg$currPos++;
2269
2216
  } else {
2270
2217
  s2 = peg$FAILED;
2271
2218
  if (peg$silentFails === 0) {
2272
- peg$fail(peg$e39);
2219
+ peg$fail(peg$e37);
2273
2220
  }
2274
2221
  }
2275
2222
  if (s2 !== peg$FAILED) {
2276
2223
  s3 = input.charAt(peg$currPos);
2277
- if (peg$r17.test(s3)) {
2224
+ if (peg$r15.test(s3)) {
2278
2225
  peg$currPos++;
2279
2226
  } else {
2280
2227
  s3 = peg$FAILED;
2281
2228
  if (peg$silentFails === 0) {
2282
- peg$fail(peg$e37);
2229
+ peg$fail(peg$e35);
2283
2230
  }
2284
2231
  }
2285
2232
  if (s3 !== peg$FAILED) {
2286
2233
  s4 = input.charAt(peg$currPos);
2287
- if (peg$r20.test(s4)) {
2234
+ if (peg$r18.test(s4)) {
2288
2235
  peg$currPos++;
2289
2236
  } else {
2290
2237
  s4 = peg$FAILED;
2291
2238
  if (peg$silentFails === 0) {
2292
- peg$fail(peg$e40);
2239
+ peg$fail(peg$e38);
2293
2240
  }
2294
2241
  }
2295
2242
  if (s4 !== peg$FAILED) {
@@ -2332,42 +2279,42 @@ function peg$parse(input, options) {
2332
2279
  let s0, s12, s2, s3, s4, s5, s6;
2333
2280
  s0 = peg$currPos;
2334
2281
  s12 = input.charAt(peg$currPos);
2335
- if (peg$r20.test(s12)) {
2282
+ if (peg$r18.test(s12)) {
2336
2283
  peg$currPos++;
2337
2284
  } else {
2338
2285
  s12 = peg$FAILED;
2339
2286
  if (peg$silentFails === 0) {
2340
- peg$fail(peg$e40);
2287
+ peg$fail(peg$e38);
2341
2288
  }
2342
2289
  }
2343
2290
  if (s12 !== peg$FAILED) {
2344
2291
  s2 = input.charAt(peg$currPos);
2345
- if (peg$r17.test(s2)) {
2292
+ if (peg$r15.test(s2)) {
2346
2293
  peg$currPos++;
2347
2294
  } else {
2348
2295
  s2 = peg$FAILED;
2349
2296
  if (peg$silentFails === 0) {
2350
- peg$fail(peg$e37);
2297
+ peg$fail(peg$e35);
2351
2298
  }
2352
2299
  }
2353
2300
  if (s2 !== peg$FAILED) {
2354
2301
  s3 = input.charAt(peg$currPos);
2355
- if (peg$r13.test(s3)) {
2302
+ if (peg$r11.test(s3)) {
2356
2303
  peg$currPos++;
2357
2304
  } else {
2358
2305
  s3 = peg$FAILED;
2359
2306
  if (peg$silentFails === 0) {
2360
- peg$fail(peg$e33);
2307
+ peg$fail(peg$e31);
2361
2308
  }
2362
2309
  }
2363
2310
  if (s3 !== peg$FAILED) {
2364
2311
  s4 = input.charAt(peg$currPos);
2365
- if (peg$r20.test(s4)) {
2312
+ if (peg$r18.test(s4)) {
2366
2313
  peg$currPos++;
2367
2314
  } else {
2368
2315
  s4 = peg$FAILED;
2369
2316
  if (peg$silentFails === 0) {
2370
- peg$fail(peg$e40);
2317
+ peg$fail(peg$e38);
2371
2318
  }
2372
2319
  }
2373
2320
  if (s4 !== peg$FAILED) {
@@ -2410,82 +2357,82 @@ function peg$parse(input, options) {
2410
2357
  let s0, s12, s2, s3, s4, s5, s6, s7, s8, s9, s10;
2411
2358
  s0 = peg$currPos;
2412
2359
  s12 = input.charAt(peg$currPos);
2413
- if (peg$r8.test(s12)) {
2360
+ if (peg$r6.test(s12)) {
2414
2361
  peg$currPos++;
2415
2362
  } else {
2416
2363
  s12 = peg$FAILED;
2417
2364
  if (peg$silentFails === 0) {
2418
- peg$fail(peg$e28);
2365
+ peg$fail(peg$e26);
2419
2366
  }
2420
2367
  }
2421
2368
  if (s12 !== peg$FAILED) {
2422
2369
  s2 = input.charAt(peg$currPos);
2423
- if (peg$r21.test(s2)) {
2370
+ if (peg$r19.test(s2)) {
2424
2371
  peg$currPos++;
2425
2372
  } else {
2426
2373
  s2 = peg$FAILED;
2427
2374
  if (peg$silentFails === 0) {
2428
- peg$fail(peg$e41);
2375
+ peg$fail(peg$e39);
2429
2376
  }
2430
2377
  }
2431
2378
  if (s2 !== peg$FAILED) {
2432
2379
  s3 = input.charAt(peg$currPos);
2433
- if (peg$r22.test(s3)) {
2380
+ if (peg$r20.test(s3)) {
2434
2381
  peg$currPos++;
2435
2382
  } else {
2436
2383
  s3 = peg$FAILED;
2437
2384
  if (peg$silentFails === 0) {
2438
- peg$fail(peg$e42);
2385
+ peg$fail(peg$e40);
2439
2386
  }
2440
2387
  }
2441
2388
  if (s3 !== peg$FAILED) {
2442
2389
  s4 = input.charAt(peg$currPos);
2443
- if (peg$r13.test(s4)) {
2390
+ if (peg$r11.test(s4)) {
2444
2391
  peg$currPos++;
2445
2392
  } else {
2446
2393
  s4 = peg$FAILED;
2447
2394
  if (peg$silentFails === 0) {
2448
- peg$fail(peg$e33);
2395
+ peg$fail(peg$e31);
2449
2396
  }
2450
2397
  }
2451
2398
  if (s4 !== peg$FAILED) {
2452
2399
  s5 = input.charAt(peg$currPos);
2453
- if (peg$r10.test(s5)) {
2400
+ if (peg$r8.test(s5)) {
2454
2401
  peg$currPos++;
2455
2402
  } else {
2456
2403
  s5 = peg$FAILED;
2457
2404
  if (peg$silentFails === 0) {
2458
- peg$fail(peg$e30);
2405
+ peg$fail(peg$e28);
2459
2406
  }
2460
2407
  }
2461
2408
  if (s5 !== peg$FAILED) {
2462
2409
  s6 = input.charAt(peg$currPos);
2463
- if (peg$r14.test(s6)) {
2410
+ if (peg$r12.test(s6)) {
2464
2411
  peg$currPos++;
2465
2412
  } else {
2466
2413
  s6 = peg$FAILED;
2467
2414
  if (peg$silentFails === 0) {
2468
- peg$fail(peg$e34);
2415
+ peg$fail(peg$e32);
2469
2416
  }
2470
2417
  }
2471
2418
  if (s6 !== peg$FAILED) {
2472
2419
  s7 = input.charAt(peg$currPos);
2473
- if (peg$r15.test(s7)) {
2420
+ if (peg$r13.test(s7)) {
2474
2421
  peg$currPos++;
2475
2422
  } else {
2476
2423
  s7 = peg$FAILED;
2477
2424
  if (peg$silentFails === 0) {
2478
- peg$fail(peg$e35);
2425
+ peg$fail(peg$e33);
2479
2426
  }
2480
2427
  }
2481
2428
  if (s7 !== peg$FAILED) {
2482
2429
  s8 = input.charAt(peg$currPos);
2483
- if (peg$r16.test(s8)) {
2430
+ if (peg$r14.test(s8)) {
2484
2431
  peg$currPos++;
2485
2432
  } else {
2486
2433
  s8 = peg$FAILED;
2487
2434
  if (peg$silentFails === 0) {
2488
- peg$fail(peg$e36);
2435
+ peg$fail(peg$e34);
2489
2436
  }
2490
2437
  }
2491
2438
  if (s8 !== peg$FAILED) {
@@ -2558,62 +2505,62 @@ function peg$parse(input, options) {
2558
2505
  s0 = peg$currPos;
2559
2506
  s12 = peg$currPos;
2560
2507
  s2 = input.charAt(peg$currPos);
2561
- if (peg$r8.test(s2)) {
2508
+ if (peg$r6.test(s2)) {
2562
2509
  peg$currPos++;
2563
2510
  } else {
2564
2511
  s2 = peg$FAILED;
2565
2512
  if (peg$silentFails === 0) {
2566
- peg$fail(peg$e28);
2513
+ peg$fail(peg$e26);
2567
2514
  }
2568
2515
  }
2569
2516
  if (s2 !== peg$FAILED) {
2570
2517
  s3 = input.charAt(peg$currPos);
2571
- if (peg$r9.test(s3)) {
2518
+ if (peg$r7.test(s3)) {
2572
2519
  peg$currPos++;
2573
2520
  } else {
2574
2521
  s3 = peg$FAILED;
2575
2522
  if (peg$silentFails === 0) {
2576
- peg$fail(peg$e29);
2523
+ peg$fail(peg$e27);
2577
2524
  }
2578
2525
  }
2579
2526
  if (s3 !== peg$FAILED) {
2580
2527
  s4 = input.charAt(peg$currPos);
2581
- if (peg$r10.test(s4)) {
2528
+ if (peg$r8.test(s4)) {
2582
2529
  peg$currPos++;
2583
2530
  } else {
2584
2531
  s4 = peg$FAILED;
2585
2532
  if (peg$silentFails === 0) {
2586
- peg$fail(peg$e30);
2533
+ peg$fail(peg$e28);
2587
2534
  }
2588
2535
  }
2589
2536
  if (s4 !== peg$FAILED) {
2590
2537
  s5 = input.charAt(peg$currPos);
2591
- if (peg$r11.test(s5)) {
2538
+ if (peg$r9.test(s5)) {
2592
2539
  peg$currPos++;
2593
2540
  } else {
2594
2541
  s5 = peg$FAILED;
2595
2542
  if (peg$silentFails === 0) {
2596
- peg$fail(peg$e31);
2543
+ peg$fail(peg$e29);
2597
2544
  }
2598
2545
  }
2599
2546
  if (s5 !== peg$FAILED) {
2600
2547
  s6 = input.charAt(peg$currPos);
2601
- if (peg$r12.test(s6)) {
2548
+ if (peg$r10.test(s6)) {
2602
2549
  peg$currPos++;
2603
2550
  } else {
2604
2551
  s6 = peg$FAILED;
2605
2552
  if (peg$silentFails === 0) {
2606
- peg$fail(peg$e32);
2553
+ peg$fail(peg$e30);
2607
2554
  }
2608
2555
  }
2609
2556
  if (s6 !== peg$FAILED) {
2610
2557
  s7 = input.charAt(peg$currPos);
2611
- if (peg$r9.test(s7)) {
2558
+ if (peg$r7.test(s7)) {
2612
2559
  peg$currPos++;
2613
2560
  } else {
2614
2561
  s7 = peg$FAILED;
2615
2562
  if (peg$silentFails === 0) {
2616
- peg$fail(peg$e29);
2563
+ peg$fail(peg$e27);
2617
2564
  }
2618
2565
  }
2619
2566
  if (s7 !== peg$FAILED) {
@@ -2646,72 +2593,72 @@ function peg$parse(input, options) {
2646
2593
  if (s12 === peg$FAILED) {
2647
2594
  s12 = peg$currPos;
2648
2595
  s2 = input.charAt(peg$currPos);
2649
- if (peg$r17.test(s2)) {
2596
+ if (peg$r15.test(s2)) {
2650
2597
  peg$currPos++;
2651
2598
  } else {
2652
2599
  s2 = peg$FAILED;
2653
2600
  if (peg$silentFails === 0) {
2654
- peg$fail(peg$e37);
2601
+ peg$fail(peg$e35);
2655
2602
  }
2656
2603
  }
2657
2604
  if (s2 !== peg$FAILED) {
2658
2605
  s3 = input.charAt(peg$currPos);
2659
- if (peg$r11.test(s3)) {
2606
+ if (peg$r9.test(s3)) {
2660
2607
  peg$currPos++;
2661
2608
  } else {
2662
2609
  s3 = peg$FAILED;
2663
2610
  if (peg$silentFails === 0) {
2664
- peg$fail(peg$e31);
2611
+ peg$fail(peg$e29);
2665
2612
  }
2666
2613
  }
2667
2614
  if (s3 !== peg$FAILED) {
2668
2615
  s4 = input.charAt(peg$currPos);
2669
- if (peg$r13.test(s4)) {
2616
+ if (peg$r11.test(s4)) {
2670
2617
  peg$currPos++;
2671
2618
  } else {
2672
2619
  s4 = peg$FAILED;
2673
2620
  if (peg$silentFails === 0) {
2674
- peg$fail(peg$e33);
2621
+ peg$fail(peg$e31);
2675
2622
  }
2676
2623
  }
2677
2624
  if (s4 !== peg$FAILED) {
2678
2625
  s5 = input.charAt(peg$currPos);
2679
- if (peg$r10.test(s5)) {
2626
+ if (peg$r8.test(s5)) {
2680
2627
  peg$currPos++;
2681
2628
  } else {
2682
2629
  s5 = peg$FAILED;
2683
2630
  if (peg$silentFails === 0) {
2684
- peg$fail(peg$e30);
2631
+ peg$fail(peg$e28);
2685
2632
  }
2686
2633
  }
2687
2634
  if (s5 !== peg$FAILED) {
2688
2635
  s6 = input.charAt(peg$currPos);
2689
- if (peg$r14.test(s6)) {
2636
+ if (peg$r12.test(s6)) {
2690
2637
  peg$currPos++;
2691
2638
  } else {
2692
2639
  s6 = peg$FAILED;
2693
2640
  if (peg$silentFails === 0) {
2694
- peg$fail(peg$e34);
2641
+ peg$fail(peg$e32);
2695
2642
  }
2696
2643
  }
2697
2644
  if (s6 !== peg$FAILED) {
2698
2645
  s7 = input.charAt(peg$currPos);
2699
- if (peg$r15.test(s7)) {
2646
+ if (peg$r13.test(s7)) {
2700
2647
  peg$currPos++;
2701
2648
  } else {
2702
2649
  s7 = peg$FAILED;
2703
2650
  if (peg$silentFails === 0) {
2704
- peg$fail(peg$e35);
2651
+ peg$fail(peg$e33);
2705
2652
  }
2706
2653
  }
2707
2654
  if (s7 !== peg$FAILED) {
2708
2655
  s8 = input.charAt(peg$currPos);
2709
- if (peg$r16.test(s8)) {
2656
+ if (peg$r14.test(s8)) {
2710
2657
  peg$currPos++;
2711
2658
  } else {
2712
2659
  s8 = peg$FAILED;
2713
2660
  if (peg$silentFails === 0) {
2714
- peg$fail(peg$e36);
2661
+ peg$fail(peg$e34);
2715
2662
  }
2716
2663
  }
2717
2664
  if (s8 !== peg$FAILED) {
@@ -2748,52 +2695,52 @@ function peg$parse(input, options) {
2748
2695
  if (s12 === peg$FAILED) {
2749
2696
  s12 = peg$currPos;
2750
2697
  s2 = input.charAt(peg$currPos);
2751
- if (peg$r13.test(s2)) {
2698
+ if (peg$r11.test(s2)) {
2752
2699
  peg$currPos++;
2753
2700
  } else {
2754
2701
  s2 = peg$FAILED;
2755
2702
  if (peg$silentFails === 0) {
2756
- peg$fail(peg$e33);
2703
+ peg$fail(peg$e31);
2757
2704
  }
2758
2705
  }
2759
2706
  if (s2 !== peg$FAILED) {
2760
2707
  s3 = input.charAt(peg$currPos);
2761
- if (peg$r10.test(s3)) {
2708
+ if (peg$r8.test(s3)) {
2762
2709
  peg$currPos++;
2763
2710
  } else {
2764
2711
  s3 = peg$FAILED;
2765
2712
  if (peg$silentFails === 0) {
2766
- peg$fail(peg$e30);
2713
+ peg$fail(peg$e28);
2767
2714
  }
2768
2715
  }
2769
2716
  if (s3 !== peg$FAILED) {
2770
2717
  s4 = input.charAt(peg$currPos);
2771
- if (peg$r14.test(s4)) {
2718
+ if (peg$r12.test(s4)) {
2772
2719
  peg$currPos++;
2773
2720
  } else {
2774
2721
  s4 = peg$FAILED;
2775
2722
  if (peg$silentFails === 0) {
2776
- peg$fail(peg$e34);
2723
+ peg$fail(peg$e32);
2777
2724
  }
2778
2725
  }
2779
2726
  if (s4 !== peg$FAILED) {
2780
2727
  s5 = input.charAt(peg$currPos);
2781
- if (peg$r15.test(s5)) {
2728
+ if (peg$r13.test(s5)) {
2782
2729
  peg$currPos++;
2783
2730
  } else {
2784
2731
  s5 = peg$FAILED;
2785
2732
  if (peg$silentFails === 0) {
2786
- peg$fail(peg$e35);
2733
+ peg$fail(peg$e33);
2787
2734
  }
2788
2735
  }
2789
2736
  if (s5 !== peg$FAILED) {
2790
2737
  s6 = input.charAt(peg$currPos);
2791
- if (peg$r16.test(s6)) {
2738
+ if (peg$r14.test(s6)) {
2792
2739
  peg$currPos++;
2793
2740
  } else {
2794
2741
  s6 = peg$FAILED;
2795
2742
  if (peg$silentFails === 0) {
2796
- peg$fail(peg$e36);
2743
+ peg$fail(peg$e34);
2797
2744
  }
2798
2745
  }
2799
2746
  if (s6 !== peg$FAILED) {
@@ -2822,42 +2769,42 @@ function peg$parse(input, options) {
2822
2769
  if (s12 === peg$FAILED) {
2823
2770
  s12 = peg$currPos;
2824
2771
  s2 = input.charAt(peg$currPos);
2825
- if (peg$r18.test(s2)) {
2772
+ if (peg$r16.test(s2)) {
2826
2773
  peg$currPos++;
2827
2774
  } else {
2828
2775
  s2 = peg$FAILED;
2829
2776
  if (peg$silentFails === 0) {
2830
- peg$fail(peg$e38);
2777
+ peg$fail(peg$e36);
2831
2778
  }
2832
2779
  }
2833
2780
  if (s2 !== peg$FAILED) {
2834
2781
  s3 = input.charAt(peg$currPos);
2835
- if (peg$r19.test(s3)) {
2782
+ if (peg$r17.test(s3)) {
2836
2783
  peg$currPos++;
2837
2784
  } else {
2838
2785
  s3 = peg$FAILED;
2839
2786
  if (peg$silentFails === 0) {
2840
- peg$fail(peg$e39);
2787
+ peg$fail(peg$e37);
2841
2788
  }
2842
2789
  }
2843
2790
  if (s3 !== peg$FAILED) {
2844
2791
  s4 = input.charAt(peg$currPos);
2845
- if (peg$r17.test(s4)) {
2792
+ if (peg$r15.test(s4)) {
2846
2793
  peg$currPos++;
2847
2794
  } else {
2848
2795
  s4 = peg$FAILED;
2849
2796
  if (peg$silentFails === 0) {
2850
- peg$fail(peg$e37);
2797
+ peg$fail(peg$e35);
2851
2798
  }
2852
2799
  }
2853
2800
  if (s4 !== peg$FAILED) {
2854
2801
  s5 = input.charAt(peg$currPos);
2855
- if (peg$r20.test(s5)) {
2802
+ if (peg$r18.test(s5)) {
2856
2803
  peg$currPos++;
2857
2804
  } else {
2858
2805
  s5 = peg$FAILED;
2859
2806
  if (peg$silentFails === 0) {
2860
- peg$fail(peg$e40);
2807
+ peg$fail(peg$e38);
2861
2808
  }
2862
2809
  }
2863
2810
  if (s5 !== peg$FAILED) {
@@ -2882,42 +2829,42 @@ function peg$parse(input, options) {
2882
2829
  if (s12 === peg$FAILED) {
2883
2830
  s12 = peg$currPos;
2884
2831
  s2 = input.charAt(peg$currPos);
2885
- if (peg$r20.test(s2)) {
2832
+ if (peg$r18.test(s2)) {
2886
2833
  peg$currPos++;
2887
2834
  } else {
2888
2835
  s2 = peg$FAILED;
2889
2836
  if (peg$silentFails === 0) {
2890
- peg$fail(peg$e40);
2837
+ peg$fail(peg$e38);
2891
2838
  }
2892
2839
  }
2893
2840
  if (s2 !== peg$FAILED) {
2894
2841
  s3 = input.charAt(peg$currPos);
2895
- if (peg$r17.test(s3)) {
2842
+ if (peg$r15.test(s3)) {
2896
2843
  peg$currPos++;
2897
2844
  } else {
2898
2845
  s3 = peg$FAILED;
2899
2846
  if (peg$silentFails === 0) {
2900
- peg$fail(peg$e37);
2847
+ peg$fail(peg$e35);
2901
2848
  }
2902
2849
  }
2903
2850
  if (s3 !== peg$FAILED) {
2904
2851
  s4 = input.charAt(peg$currPos);
2905
- if (peg$r13.test(s4)) {
2852
+ if (peg$r11.test(s4)) {
2906
2853
  peg$currPos++;
2907
2854
  } else {
2908
2855
  s4 = peg$FAILED;
2909
2856
  if (peg$silentFails === 0) {
2910
- peg$fail(peg$e33);
2857
+ peg$fail(peg$e31);
2911
2858
  }
2912
2859
  }
2913
2860
  if (s4 !== peg$FAILED) {
2914
2861
  s5 = input.charAt(peg$currPos);
2915
- if (peg$r20.test(s5)) {
2862
+ if (peg$r18.test(s5)) {
2916
2863
  peg$currPos++;
2917
2864
  } else {
2918
2865
  s5 = peg$FAILED;
2919
2866
  if (peg$silentFails === 0) {
2920
- peg$fail(peg$e40);
2867
+ peg$fail(peg$e38);
2921
2868
  }
2922
2869
  }
2923
2870
  if (s5 !== peg$FAILED) {
@@ -2942,82 +2889,82 @@ function peg$parse(input, options) {
2942
2889
  if (s12 === peg$FAILED) {
2943
2890
  s12 = peg$currPos;
2944
2891
  s2 = input.charAt(peg$currPos);
2945
- if (peg$r8.test(s2)) {
2892
+ if (peg$r6.test(s2)) {
2946
2893
  peg$currPos++;
2947
2894
  } else {
2948
2895
  s2 = peg$FAILED;
2949
2896
  if (peg$silentFails === 0) {
2950
- peg$fail(peg$e28);
2897
+ peg$fail(peg$e26);
2951
2898
  }
2952
2899
  }
2953
2900
  if (s2 !== peg$FAILED) {
2954
2901
  s3 = input.charAt(peg$currPos);
2955
- if (peg$r21.test(s3)) {
2902
+ if (peg$r19.test(s3)) {
2956
2903
  peg$currPos++;
2957
2904
  } else {
2958
2905
  s3 = peg$FAILED;
2959
2906
  if (peg$silentFails === 0) {
2960
- peg$fail(peg$e41);
2907
+ peg$fail(peg$e39);
2961
2908
  }
2962
2909
  }
2963
2910
  if (s3 !== peg$FAILED) {
2964
2911
  s4 = input.charAt(peg$currPos);
2965
- if (peg$r22.test(s4)) {
2912
+ if (peg$r20.test(s4)) {
2966
2913
  peg$currPos++;
2967
2914
  } else {
2968
2915
  s4 = peg$FAILED;
2969
2916
  if (peg$silentFails === 0) {
2970
- peg$fail(peg$e42);
2917
+ peg$fail(peg$e40);
2971
2918
  }
2972
2919
  }
2973
2920
  if (s4 !== peg$FAILED) {
2974
2921
  s5 = input.charAt(peg$currPos);
2975
- if (peg$r13.test(s5)) {
2922
+ if (peg$r11.test(s5)) {
2976
2923
  peg$currPos++;
2977
2924
  } else {
2978
2925
  s5 = peg$FAILED;
2979
2926
  if (peg$silentFails === 0) {
2980
- peg$fail(peg$e33);
2927
+ peg$fail(peg$e31);
2981
2928
  }
2982
2929
  }
2983
2930
  if (s5 !== peg$FAILED) {
2984
2931
  s6 = input.charAt(peg$currPos);
2985
- if (peg$r10.test(s6)) {
2932
+ if (peg$r8.test(s6)) {
2986
2933
  peg$currPos++;
2987
2934
  } else {
2988
2935
  s6 = peg$FAILED;
2989
2936
  if (peg$silentFails === 0) {
2990
- peg$fail(peg$e30);
2937
+ peg$fail(peg$e28);
2991
2938
  }
2992
2939
  }
2993
2940
  if (s6 !== peg$FAILED) {
2994
2941
  s7 = input.charAt(peg$currPos);
2995
- if (peg$r14.test(s7)) {
2942
+ if (peg$r12.test(s7)) {
2996
2943
  peg$currPos++;
2997
2944
  } else {
2998
2945
  s7 = peg$FAILED;
2999
2946
  if (peg$silentFails === 0) {
3000
- peg$fail(peg$e34);
2947
+ peg$fail(peg$e32);
3001
2948
  }
3002
2949
  }
3003
2950
  if (s7 !== peg$FAILED) {
3004
2951
  s8 = input.charAt(peg$currPos);
3005
- if (peg$r15.test(s8)) {
2952
+ if (peg$r13.test(s8)) {
3006
2953
  peg$currPos++;
3007
2954
  } else {
3008
2955
  s8 = peg$FAILED;
3009
2956
  if (peg$silentFails === 0) {
3010
- peg$fail(peg$e35);
2957
+ peg$fail(peg$e33);
3011
2958
  }
3012
2959
  }
3013
2960
  if (s8 !== peg$FAILED) {
3014
2961
  s9 = input.charAt(peg$currPos);
3015
- if (peg$r16.test(s9)) {
2962
+ if (peg$r14.test(s9)) {
3016
2963
  peg$currPos++;
3017
2964
  } else {
3018
2965
  s9 = peg$FAILED;
3019
2966
  if (peg$silentFails === 0) {
3020
- peg$fail(peg$e36);
2967
+ peg$fail(peg$e34);
3021
2968
  }
3022
2969
  }
3023
2970
  if (s9 !== peg$FAILED) {
@@ -3089,24 +3036,24 @@ function peg$parse(input, options) {
3089
3036
  s0 = [];
3090
3037
  s12 = [];
3091
3038
  s2 = input.charAt(peg$currPos);
3092
- if (peg$r23.test(s2)) {
3039
+ if (peg$r21.test(s2)) {
3093
3040
  peg$currPos++;
3094
3041
  } else {
3095
3042
  s2 = peg$FAILED;
3096
3043
  if (peg$silentFails === 0) {
3097
- peg$fail(peg$e43);
3044
+ peg$fail(peg$e41);
3098
3045
  }
3099
3046
  }
3100
3047
  if (s2 !== peg$FAILED) {
3101
3048
  while (s2 !== peg$FAILED) {
3102
3049
  s12.push(s2);
3103
3050
  s2 = input.charAt(peg$currPos);
3104
- if (peg$r23.test(s2)) {
3051
+ if (peg$r21.test(s2)) {
3105
3052
  peg$currPos++;
3106
3053
  } else {
3107
3054
  s2 = peg$FAILED;
3108
3055
  if (peg$silentFails === 0) {
3109
- peg$fail(peg$e43);
3056
+ peg$fail(peg$e41);
3110
3057
  }
3111
3058
  }
3112
3059
  }
@@ -3126,24 +3073,24 @@ function peg$parse(input, options) {
3126
3073
  s0.push(s12);
3127
3074
  s12 = [];
3128
3075
  s2 = input.charAt(peg$currPos);
3129
- if (peg$r23.test(s2)) {
3076
+ if (peg$r21.test(s2)) {
3130
3077
  peg$currPos++;
3131
3078
  } else {
3132
3079
  s2 = peg$FAILED;
3133
3080
  if (peg$silentFails === 0) {
3134
- peg$fail(peg$e43);
3081
+ peg$fail(peg$e41);
3135
3082
  }
3136
3083
  }
3137
3084
  if (s2 !== peg$FAILED) {
3138
3085
  while (s2 !== peg$FAILED) {
3139
3086
  s12.push(s2);
3140
3087
  s2 = input.charAt(peg$currPos);
3141
- if (peg$r23.test(s2)) {
3088
+ if (peg$r21.test(s2)) {
3142
3089
  peg$currPos++;
3143
3090
  } else {
3144
3091
  s2 = peg$FAILED;
3145
3092
  if (peg$silentFails === 0) {
3146
- peg$fail(peg$e43);
3093
+ peg$fail(peg$e41);
3147
3094
  }
3148
3095
  }
3149
3096
  }
@@ -3171,7 +3118,7 @@ function peg$parse(input, options) {
3171
3118
  } else {
3172
3119
  s12 = peg$FAILED;
3173
3120
  if (peg$silentFails === 0) {
3174
- peg$fail(peg$e44);
3121
+ peg$fail(peg$e42);
3175
3122
  }
3176
3123
  }
3177
3124
  if (s12 !== peg$FAILED) {
@@ -3185,7 +3132,7 @@ function peg$parse(input, options) {
3185
3132
  } else {
3186
3133
  s5 = peg$FAILED;
3187
3134
  if (peg$silentFails === 0) {
3188
- peg$fail(peg$e45);
3135
+ peg$fail(peg$e43);
3189
3136
  }
3190
3137
  }
3191
3138
  peg$silentFails--;
@@ -3227,7 +3174,7 @@ function peg$parse(input, options) {
3227
3174
  } else {
3228
3175
  s5 = peg$FAILED;
3229
3176
  if (peg$silentFails === 0) {
3230
- peg$fail(peg$e45);
3177
+ peg$fail(peg$e43);
3231
3178
  }
3232
3179
  }
3233
3180
  peg$silentFails--;
@@ -3265,7 +3212,7 @@ function peg$parse(input, options) {
3265
3212
  } else {
3266
3213
  s3 = peg$FAILED;
3267
3214
  if (peg$silentFails === 0) {
3268
- peg$fail(peg$e45);
3215
+ peg$fail(peg$e43);
3269
3216
  }
3270
3217
  }
3271
3218
  if (s3 !== peg$FAILED) {
@@ -3290,29 +3237,29 @@ function peg$parse(input, options) {
3290
3237
  } else {
3291
3238
  s12 = peg$FAILED;
3292
3239
  if (peg$silentFails === 0) {
3293
- peg$fail(peg$e46);
3240
+ peg$fail(peg$e44);
3294
3241
  }
3295
3242
  }
3296
3243
  if (s12 !== peg$FAILED) {
3297
3244
  s2 = [];
3298
3245
  s3 = input.charAt(peg$currPos);
3299
- if (peg$r24.test(s3)) {
3246
+ if (peg$r22.test(s3)) {
3300
3247
  peg$currPos++;
3301
3248
  } else {
3302
3249
  s3 = peg$FAILED;
3303
3250
  if (peg$silentFails === 0) {
3304
- peg$fail(peg$e47);
3251
+ peg$fail(peg$e45);
3305
3252
  }
3306
3253
  }
3307
3254
  while (s3 !== peg$FAILED) {
3308
3255
  s2.push(s3);
3309
3256
  s3 = input.charAt(peg$currPos);
3310
- if (peg$r24.test(s3)) {
3257
+ if (peg$r22.test(s3)) {
3311
3258
  peg$currPos++;
3312
3259
  } else {
3313
3260
  s3 = peg$FAILED;
3314
3261
  if (peg$silentFails === 0) {
3315
- peg$fail(peg$e47);
3262
+ peg$fail(peg$e45);
3316
3263
  }
3317
3264
  }
3318
3265
  }
@@ -3322,7 +3269,7 @@ function peg$parse(input, options) {
3322
3269
  } else {
3323
3270
  s3 = peg$FAILED;
3324
3271
  if (peg$silentFails === 0) {
3325
- peg$fail(peg$e48);
3272
+ peg$fail(peg$e46);
3326
3273
  }
3327
3274
  }
3328
3275
  if (s3 === peg$FAILED) {
@@ -3367,29 +3314,29 @@ function peg$parse(input, options) {
3367
3314
  } else {
3368
3315
  s12 = peg$FAILED;
3369
3316
  if (peg$silentFails === 0) {
3370
- peg$fail(peg$e49);
3317
+ peg$fail(peg$e47);
3371
3318
  }
3372
3319
  }
3373
3320
  if (s12 !== peg$FAILED) {
3374
3321
  s2 = [];
3375
3322
  s3 = input.charAt(peg$currPos);
3376
- if (peg$r24.test(s3)) {
3323
+ if (peg$r22.test(s3)) {
3377
3324
  peg$currPos++;
3378
3325
  } else {
3379
3326
  s3 = peg$FAILED;
3380
3327
  if (peg$silentFails === 0) {
3381
- peg$fail(peg$e47);
3328
+ peg$fail(peg$e45);
3382
3329
  }
3383
3330
  }
3384
3331
  while (s3 !== peg$FAILED) {
3385
3332
  s2.push(s3);
3386
3333
  s3 = input.charAt(peg$currPos);
3387
- if (peg$r24.test(s3)) {
3334
+ if (peg$r22.test(s3)) {
3388
3335
  peg$currPos++;
3389
3336
  } else {
3390
3337
  s3 = peg$FAILED;
3391
3338
  if (peg$silentFails === 0) {
3392
- peg$fail(peg$e47);
3339
+ peg$fail(peg$e45);
3393
3340
  }
3394
3341
  }
3395
3342
  }
@@ -3399,7 +3346,7 @@ function peg$parse(input, options) {
3399
3346
  } else {
3400
3347
  s3 = peg$FAILED;
3401
3348
  if (peg$silentFails === 0) {
3402
- peg$fail(peg$e48);
3349
+ peg$fail(peg$e46);
3403
3350
  }
3404
3351
  }
3405
3352
  if (s3 === peg$FAILED) {
@@ -4301,6 +4248,75 @@ function buildFromAst(ast) {
4301
4248
  return graph;
4302
4249
  }
4303
4250
 
4251
+ // src/parser/number-scan.ts
4252
+ var ASCII_DEL = 127;
4253
+ function isLetter(c) {
4254
+ if (c === void 0) return false;
4255
+ return c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c === "_" || c.charCodeAt(0) > ASCII_DEL;
4256
+ }
4257
+ function isDigit(c) {
4258
+ return c !== void 0 && c >= "0" && c <= "9";
4259
+ }
4260
+ function startsNumber(s, i) {
4261
+ const c = s[i];
4262
+ if (isDigit(c)) return true;
4263
+ if (c === ".") return isDigit(s[i + 1]);
4264
+ if (c !== "-") return false;
4265
+ return isDigit(s[i + 1]) || s[i + 1] === "." && isDigit(s[i + 2]);
4266
+ }
4267
+ function matchNumber(s, i) {
4268
+ let j = s[i] === "-" ? i + 1 : i;
4269
+ if (s[j] === ".") {
4270
+ j++;
4271
+ while (isDigit(s[j])) j++;
4272
+ } else {
4273
+ while (isDigit(s[j])) j++;
4274
+ if (s[j] === ".") {
4275
+ j++;
4276
+ while (isDigit(s[j])) j++;
4277
+ }
4278
+ }
4279
+ if (s[j] === "." || isLetter(s[j])) j++;
4280
+ return j;
4281
+ }
4282
+ function twoDots(text) {
4283
+ const dot = text.indexOf(".");
4284
+ return dot !== -1 && dot !== text.length - 1;
4285
+ }
4286
+ function chkNum(text) {
4287
+ const c = text[text.length - 1];
4288
+ return !isDigit(c) && c !== "." || c === "." && twoDots(text);
4289
+ }
4290
+ function lexToken(s, i) {
4291
+ if (isLetter(s[i])) {
4292
+ let j2 = i + 1;
4293
+ while (isLetter(s[j2]) || isDigit(s[j2])) j2++;
4294
+ return { next: j2, bad: null };
4295
+ }
4296
+ if (s[i] === "-" && (s[i + 1] === "-" || s[i + 1] === ">")) return { next: i + 2, bad: null };
4297
+ if (!startsNumber(s, i)) return { next: i + 1, bad: null };
4298
+ const j = matchNumber(s, i);
4299
+ const text = s.slice(i, j);
4300
+ return chkNum(text) ? { next: j - 1, bad: text } : { next: j, bad: null };
4301
+ }
4302
+ function scanNumberAmbiguities(src, stripped) {
4303
+ const out = [];
4304
+ let line = 1;
4305
+ let lineAt = 0;
4306
+ for (let i = 0; i < stripped.length; ) {
4307
+ const { next, bad } = lexToken(stripped, i);
4308
+ if (bad !== null) {
4309
+ for (; lineAt < i; lineAt++) if (src[lineAt] === "\n") line++;
4310
+ out.push({ text: bad, line, offset: i });
4311
+ }
4312
+ i = next;
4313
+ }
4314
+ return out;
4315
+ }
4316
+ function numberAmbiguityMessage(a) {
4317
+ return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
4318
+ }
4319
+
4304
4320
  // src/errors.ts
4305
4321
  var FRIENDLY_MESSAGES = {
4306
4322
  SYNTAX_ERROR: "There is a syntax error in the DOT source.",
@@ -4577,6 +4593,12 @@ function isPeggyError(err) {
4577
4593
  if (typeof e["location"] !== "object" || e["location"] === null) return false;
4578
4594
  return "start" in e["location"];
4579
4595
  }
4596
+ function warnNumberAmbiguities(src, upTo) {
4597
+ for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
4598
+ if (a.offset > upTo) break;
4599
+ console.error(numberAmbiguityMessage(a));
4600
+ }
4601
+ }
4580
4602
  function parse(src) {
4581
4603
  if (typeof src !== "string") {
4582
4604
  throw invalidArgType("dotSource", "string", src);
@@ -4587,6 +4609,7 @@ function parse(src) {
4587
4609
  } catch (err) {
4588
4610
  if (isPeggyError(err)) {
4589
4611
  const start = err.location.start;
4612
+ warnNumberAmbiguities(src, start.offset);
4590
4613
  const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
4591
4614
  throw new ParseError(
4592
4615
  err instanceof Error ? err.message : String(err),
@@ -4604,6 +4627,7 @@ function parse(src) {
4604
4627
  }
4605
4628
  throw err;
4606
4629
  }
4630
+ warnNumberAmbiguities(src, src.length);
4607
4631
  validateEdgeOperators(src, ast.directed);
4608
4632
  return buildFromAst(ast);
4609
4633
  }
@@ -5587,6 +5611,10 @@ var RenderJob = class {
5587
5611
  format;
5588
5612
  bb = { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } };
5589
5613
  pad = { x: 0, y: 0 };
5614
+ /** Current page clip in graph units, as setup_page computes it from the
5615
+ * viewport focus/view (see setupPageClip). Read by the SVG page translate and
5616
+ * background. @see lib/gvc/gvcjob.h:GVJ_s.clip; lib/common/emit.c:setup_page */
5617
+ clip = { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } };
5590
5618
  /** Graph-level `margin=` (init_job_margin); page-pagination margin, distinct
5591
5619
  * from node/cluster label margin. @see lib/common/emit.c:3309-3331 */
5592
5620
  margin = { x: 0, y: 0 };
@@ -5756,6 +5784,8 @@ function gvrenderTextspan(renderer, pos, span, job) {
5756
5784
  }
5757
5785
 
5758
5786
  // src/util/math.ts
5787
+ var INT32_MAX = 2147483647;
5788
+ var INT32_MIN = -2147483648;
5759
5789
  function isExactlyEqual(a, b) {
5760
5790
  const buf = new ArrayBuffer(16);
5761
5791
  const dv = new DataView(buf);
@@ -5767,6 +5797,11 @@ function isExactlyEqual(a, b) {
5767
5797
  }
5768
5798
  return true;
5769
5799
  }
5800
+ function d2i(v) {
5801
+ if (v > INT32_MAX) return INT32_MAX;
5802
+ if (v < INT32_MIN) return INT32_MIN;
5803
+ return Math.trunc(v);
5804
+ }
5770
5805
 
5771
5806
  // src/common/colorData.ts
5772
5807
  var COLOR_LIB = [
@@ -9916,11 +9951,11 @@ function emitHtmlLabel(placed, pos, renderer, job) {
9916
9951
  style: placed.style
9917
9952
  });
9918
9953
  }
9919
- for (const cell2 of placed.cells) emitHtmlCell(cell2, pos, renderer, job);
9920
9954
  emitTableRules(placed, pos, renderer, job);
9921
9955
  if (placed.border > 0) {
9922
9956
  emitBorder({ box: placed.box, pos, border: placed.border, color: placed.color, sides: placed.sides, style: placed.style }, renderer, job);
9923
9957
  }
9958
+ for (const cell2 of placed.cells) emitHtmlCell(cell2, pos, renderer, job);
9924
9959
  }
9925
9960
  if (inAnchor) endHtmlAnchor(renderer, job);
9926
9961
  if (clustersLast && initHtmlAnchor(anchorData, tblBox, renderer, job)) {
@@ -15778,8 +15813,8 @@ function normalizeFontName(name) {
15778
15813
  for (let i = 0; i < name.length; i++) {
15779
15814
  const ch = name[i];
15780
15815
  const code = ch.charCodeAt(0);
15781
- const isLetter = code >= 65 && code <= 90 || code >= 97 && code <= 122;
15782
- if (isLetter) result += ch.toLowerCase();
15816
+ const isLetter2 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
15817
+ if (isLetter2) result += ch.toLowerCase();
15783
15818
  }
15784
15819
  return result;
15785
15820
  }
@@ -16638,7 +16673,7 @@ function interpretCRNL(str) {
16638
16673
 
16639
16674
  // src/common/make-label.ts
16640
16675
  var DEFAULT_FONTSIZE2 = 14;
16641
- var DEFAULT_FONTNAME = "Times,serif";
16676
+ var DEFAULT_FONTNAME = "Times-Roman";
16642
16677
  var DEFAULT_COLOR2 = "black";
16643
16678
  function getPenColor(obj) {
16644
16679
  if (obj === void 0) return void 0;
@@ -16905,6 +16940,18 @@ function fms(a, b, c) {
16905
16940
  function cround(v) {
16906
16941
  return v >= 0 ? Math.floor(v + 0.5) : Math.ceil(v - 0.5);
16907
16942
  }
16943
+ var INT64_MAX = 2n ** 63n - 1n;
16944
+ var INT64_MIN = -(2n ** 63n);
16945
+ var TWO_POW_63 = 2 ** 63;
16946
+ function croundNarrow32(v) {
16947
+ const r = cround(v);
16948
+ let i64;
16949
+ if (Number.isNaN(r)) i64 = 0n;
16950
+ else if (r >= TWO_POW_63) i64 = INT64_MAX;
16951
+ else if (r < -TWO_POW_63) i64 = INT64_MIN;
16952
+ else i64 = BigInt(r);
16953
+ return Number(BigInt.asIntN(32, i64));
16954
+ }
16908
16955
  function RADIANS(deg) {
16909
16956
  return deg / 180 * Math.PI;
16910
16957
  }
@@ -23611,9 +23658,12 @@ function isMulticolor(fillcolor) {
23611
23658
  return fillcolor.includes(":");
23612
23659
  }
23613
23660
  function renderEllipse(ring, coord, renderer, job, filled) {
23614
- const rx = Math.abs((ring[1].x - ring[0].x) / 2);
23615
- const ry = Math.abs((ring[1].y - ring[0].y) / 2);
23616
- const center = transformPoint(coord, job);
23661
+ const af0 = { x: ring[0].x + coord.x, y: ring[0].y + coord.y };
23662
+ const af1 = { x: ring[1].x + coord.x, y: ring[1].y + coord.y };
23663
+ const mid = { x: (af0.x + af1.x) / 2, y: (af0.y + af1.y) / 2 };
23664
+ const rx = af1.x - mid.x;
23665
+ const ry = af1.y - mid.y;
23666
+ const center = transformPoint(mid, job);
23617
23667
  renderer.ellipse(center, rx, ry, filled, job);
23618
23668
  }
23619
23669
  function renderPolygon(ring, coord, renderer, job, filled) {
@@ -25455,7 +25505,7 @@ var BGCOLOR_TRANSPARENT = "\0transparent";
25455
25505
  function formatG(n) {
25456
25506
  return String(parseFloat(n.toPrecision(6)));
25457
25507
  }
25458
- function emitSvgTag(job) {
25508
+ function emitSvgTag(job, svgid = "") {
25459
25509
  const bb = job.bb;
25460
25510
  const szx = bb.ur.x - bb.ll.x + 2 * job.pad.x;
25461
25511
  const szy = bb.ur.y - bb.ll.y + 2 * job.pad.y;
@@ -25464,16 +25514,20 @@ function emitSvgTag(job) {
25464
25514
  const rotated = job.rotation !== 0;
25465
25515
  const pageX = rotated ? viewY : viewX;
25466
25516
  const pageY = rotated ? viewX : viewY;
25467
- const w = cround(pageX + 2 * job.margin.x);
25468
- const h = cround(pageY + 2 * job.margin.y);
25517
+ const w = croundNarrow32(pageX + 2 * job.margin.x);
25518
+ const h = croundNarrow32(pageY + 2 * job.margin.y);
25469
25519
  job.write('<svg width="' + String(w) + 'pt" height="' + String(h) + 'pt"\n');
25470
- const vbLLx = cround(job.margin.x);
25471
- const vbLLy = cround(job.margin.y);
25472
- const vbURx = cround(job.margin.x + pageX);
25473
- const vbURy = cround(job.margin.y + pageY);
25520
+ const vbLLx = croundNarrow32(job.margin.x);
25521
+ const vbLLy = croundNarrow32(job.margin.y);
25522
+ const vbURx = croundNarrow32(job.margin.x + pageX);
25523
+ const vbURy = croundNarrow32(job.margin.y + pageY);
25474
25524
  job.write(' viewBox="' + String(vbLLx) + ".00 " + String(vbLLy) + ".00 " + String(vbURx) + ".00 " + String(vbURy) + '.00"\n');
25475
25525
  job.write(' xmlns="http://www.w3.org/2000/svg"');
25476
- job.write(' xmlns:xlink="http://www.w3.org/1999/xlink">\n');
25526
+ job.write(' xmlns:xlink="http://www.w3.org/1999/xlink"');
25527
+ if (svgid !== void 0 && svgid.length > 0) {
25528
+ job.write(' id="' + escapeXmlTitle(svgid) + '"');
25529
+ }
25530
+ job.write(">\n");
25477
25531
  }
25478
25532
  function emitGraphGroupOpen(graphId, classStr, tx, ty, job) {
25479
25533
  const sx = formatG(job.scale.x);
@@ -25497,12 +25551,12 @@ function resolveGraphBgcolor(bgcolorAttr) {
25497
25551
  const solid = grad !== null ? grad[0] : bgcolorAttr;
25498
25552
  return colorPaint(resolveRenderColor(solid));
25499
25553
  }
25500
- function emitGraphBackground(bb, resolvedColor, job) {
25554
+ function emitGraphBackground(clip, resolvedColor, job) {
25501
25555
  if (resolvedColor === BGCOLOR_TRANSPARENT) return;
25502
- const left2 = bb.ll.x - job.pad.x;
25503
- const right2 = bb.ur.x + job.pad.x;
25504
- const top = -(bb.ur.y + job.pad.y);
25505
- const bottom = -(bb.ll.y - job.pad.y);
25556
+ const left2 = clip.ll.x;
25557
+ const right2 = clip.ur.x;
25558
+ const top = -clip.ur.y;
25559
+ const bottom = -clip.ll.y;
25506
25560
  const corners = [
25507
25561
  [left2, bottom],
25508
25562
  [left2, top],
@@ -25519,11 +25573,11 @@ function emitGraphBackground(bb, resolvedColor, job) {
25519
25573
  });
25520
25574
  job.write('"/>\n');
25521
25575
  }
25522
- function bgGradientPts(bb, pad) {
25523
- const left2 = bb.ll.x - pad.x;
25524
- const right2 = bb.ur.x + pad.x;
25525
- const bottom = bb.ll.y - pad.y;
25526
- const top = bb.ur.y + pad.y;
25576
+ function bgGradientPts(clip) {
25577
+ const left2 = clip.ll.x;
25578
+ const right2 = clip.ur.x;
25579
+ const bottom = clip.ll.y;
25580
+ const top = clip.ur.y;
25527
25581
  return [
25528
25582
  { x: left2, y: bottom },
25529
25583
  { x: left2, y: top },
@@ -25531,11 +25585,11 @@ function bgGradientPts(bb, pad) {
25531
25585
  { x: right2, y: bottom }
25532
25586
  ];
25533
25587
  }
25534
- function writeGradientPolygon(bb, id, job) {
25535
- const left2 = bb.ll.x - job.pad.x;
25536
- const right2 = bb.ur.x + job.pad.x;
25537
- const top = -(bb.ur.y + job.pad.y);
25538
- const bottom = -(bb.ll.y - job.pad.y);
25588
+ function writeGradientPolygon(clip, id, job) {
25589
+ const left2 = clip.ll.x;
25590
+ const right2 = clip.ur.x;
25591
+ const top = -clip.ur.y;
25592
+ const bottom = -clip.ll.y;
25539
25593
  const corners = [
25540
25594
  [left2, bottom],
25541
25595
  [left2, top],
@@ -25552,7 +25606,7 @@ function writeGradientPolygon(bb, id, job) {
25552
25606
  });
25553
25607
  job.write('"/>\n');
25554
25608
  }
25555
- function emitGradientBackground(bb, spec, job) {
25609
+ function emitGradientBackground(clip, spec, job) {
25556
25610
  const obj = createObjState(0 /* RootGraph */);
25557
25611
  obj.id = "graph0";
25558
25612
  obj.fillColor = resolveRenderColor(spec.fillColor);
@@ -25567,10 +25621,10 @@ function emitGradientBackground(bb, spec, job) {
25567
25621
  emitRadialGradient(job, gid);
25568
25622
  } else {
25569
25623
  gid = gradientId("graph0", "l", job.linearGradId++);
25570
- emitLinearGradient(job, bgGradientPts(bb, job.pad), gid);
25624
+ emitLinearGradient(job, bgGradientPts(clip), gid);
25571
25625
  }
25572
25626
  job.popObj();
25573
- writeGradientPolygon(bb, gid, job);
25627
+ writeGradientPolygon(clip, gid, job);
25574
25628
  }
25575
25629
  function resolveBgGradientSpec(g, bgcolorAttr) {
25576
25630
  const stop = findStopColor(bgcolorAttr);
@@ -25580,17 +25634,17 @@ function resolveBgGradientSpec(g, bgcolorAttr) {
25580
25634
  const angle = angleStr ? parseInt(angleStr, 10) || 0 : 0;
25581
25635
  return { fillColor: stop.fillColor, stopColor: stop.stopColor, frac: stop.frac, angle, radial: flags.radial };
25582
25636
  }
25583
- function emitBgcolorBackground(g, bb, bgcolorAttr, job) {
25637
+ function emitBgcolorBackground(g, clip, bgcolorAttr, job) {
25584
25638
  if (!bgcolorAttr || bgcolorAttr.length === 0 || bgcolorAttr === "transparent") {
25585
- emitGraphBackground(bb, resolveGraphBgcolor(bgcolorAttr), job);
25639
+ emitGraphBackground(clip, resolveGraphBgcolor(bgcolorAttr), job);
25586
25640
  return;
25587
25641
  }
25588
25642
  const spec = resolveBgGradientSpec(g, bgcolorAttr);
25589
25643
  if (spec !== null) {
25590
- emitGradientBackground(bb, spec, job);
25644
+ emitGradientBackground(clip, spec, job);
25591
25645
  return;
25592
25646
  }
25593
- emitGraphBackground(bb, resolveGraphBgcolor(bgcolorAttr), job);
25647
+ emitGraphBackground(clip, resolveGraphBgcolor(bgcolorAttr), job);
25594
25648
  }
25595
25649
  function svgBeginGraph(g, job) {
25596
25650
  job.devscale = { x: 1, y: -1 };
@@ -25604,13 +25658,23 @@ function svgBeginGraph(g, job) {
25604
25658
  }
25605
25659
  job.write(SVG_DOCTYPE);
25606
25660
  job.write(SVG_GENERATOR_COMMENT);
25607
- emitSvgTag(job);
25661
+ const comment = g.attrs.get("comment");
25662
+ if (comment !== void 0 && comment.length > 0) svgComment(comment, job);
25663
+ emitTitlePagesComment(g, job);
25664
+ emitSvgTag(job, g.attrs.get("svgid"));
25665
+ }
25666
+ function emitTitlePagesComment(g, job) {
25667
+ job.write("<!--");
25668
+ if (g.name.length > 0 && g.name[0] !== "%") {
25669
+ job.write(" Title: " + escapeXmlTitle(g.name));
25670
+ }
25671
+ job.write(" Pages: 1 -->\n");
25608
25672
  }
25609
25673
  function svgBeginPage(g, job) {
25610
- const bb = job.bb;
25674
+ const clip = job.clip;
25611
25675
  const z = job.scale.x;
25612
- const tx = job.rotation !== 0 ? -(bb.ur.x + job.pad.x) - job.margin.x / z : job.pad.x + job.margin.x / z;
25613
- const ty = bb.ur.y + job.pad.y + job.margin.y / z;
25676
+ const tx = job.rotation !== 0 ? -clip.ur.x - job.margin.x / z : -clip.ll.x + job.margin.x / z;
25677
+ const ty = clip.ur.y + job.margin.y / z;
25614
25678
  emitGraphGroupOpen(
25615
25679
  job.idLayerPrefix() + svgGraphId(g, job),
25616
25680
  svgGraphClass(g),
@@ -25621,7 +25685,7 @@ function svgBeginPage(g, job) {
25621
25685
  emitGraphTitle(g, job);
25622
25686
  }
25623
25687
  function svgPageBackground(g, job) {
25624
- emitBgcolorBackground(g, job.bb, g.attrs.get("bgcolor"), job);
25688
+ emitBgcolorBackground(g, job.clip, g.attrs.get("bgcolor"), job);
25625
25689
  }
25626
25690
  function svgEndPage(job) {
25627
25691
  job.write("</g>\n");
@@ -25957,7 +26021,7 @@ function svgPolyline(pts, job) {
25957
26021
  job.write('"/>\n');
25958
26022
  }
25959
26023
  function svgComment(text, job) {
25960
- job.write("<!-- " + escapeXml(text) + " -->\n");
26024
+ job.write("<!-- " + escapeXmlTitle(text) + " -->\n");
25961
26025
  }
25962
26026
  function svgEdgePath(e, job) {
25963
26027
  const spl = e.info.spl;
@@ -26144,6 +26208,22 @@ function initJobViewportZoom(bb, size, pad) {
26144
26208
  if (drawingNeedsFit(size, szx, szy)) return Math.min(size.x / szx, size.y / szy);
26145
26209
  return 1;
26146
26210
  }
26211
+ function setupPageClip(bb, size, pad, z) {
26212
+ const jbLL = { x: bb.ll.x - pad.x, y: bb.ll.y - pad.y };
26213
+ const jbUR = { x: bb.ur.x + pad.x, y: bb.ur.y + pad.y };
26214
+ const sz = { x: jbUR.x - jbLL.x, y: jbUR.y - jbLL.y };
26215
+ if (size !== null && size.x > 1e-3 && size.y > 1e-3) {
26216
+ if (sz.x <= 1e-3) sz.x = size.x;
26217
+ if (sz.y <= 1e-3) sz.y = size.y;
26218
+ }
26219
+ const focus = { x: 0.5 * (bb.ll.x + bb.ur.x), y: 0.5 * (bb.ll.y + bb.ur.y) };
26220
+ const pageSize = { x: z * sz.x / z, y: z * sz.y / z };
26221
+ const ll = {
26222
+ x: focus.x + pageSize.x * (0 - 1 / 2),
26223
+ y: focus.y + pageSize.y * (0 - 1 / 2)
26224
+ };
26225
+ return { ll, ur: { x: ll.x + pageSize.x, y: ll.y + pageSize.y } };
26226
+ }
26147
26227
 
26148
26228
  // src/gvc/anchor.ts
26149
26229
  function attr(attrs, key) {
@@ -26655,10 +26735,22 @@ function renderClusterLabel(sg, renderer, job) {
26655
26735
  renderOneLabel(sg.info.label, renderer, job, false);
26656
26736
  }
26657
26737
 
26658
- // src/gvc/device.ts
26659
- function labelTextOf2(lp) {
26660
- return lp?.text ?? null;
26738
+ // src/common/edge-in-box.ts
26739
+ function overlapLabel(lp, b) {
26740
+ const sx = lp.dimen.x / 2;
26741
+ const sy = lp.dimen.y / 2;
26742
+ const bb = {
26743
+ ll: { x: lp.pos.x - sx, y: lp.pos.y - sy },
26744
+ ur: { x: lp.pos.x + sx, y: lp.pos.y + sy }
26745
+ };
26746
+ return boxOverlap(b, bb);
26747
+ }
26748
+ function edgeHasDrawableContent(e, clip) {
26749
+ const i = e.info;
26750
+ return i.spl !== void 0 || i.label !== void 0 && i.label.set && overlapLabel(i.label, clip) || i.xlabel !== void 0 || i.head_label !== void 0 || i.tail_label !== void 0;
26661
26751
  }
26752
+
26753
+ // src/gvc/emit-gates.ts
26662
26754
  function nodeBBox(n) {
26663
26755
  const { coord, lw, rw, ht } = n.info;
26664
26756
  return {
@@ -26673,6 +26765,26 @@ function nodeInBox(n, job) {
26673
26765
  };
26674
26766
  return boxOverlap(nodeBBox(n), clip);
26675
26767
  }
26768
+ function gvrenderComment(renderer, job, str) {
26769
+ if (str === void 0 || str.length === 0) return;
26770
+ renderer.comment?.(str, job);
26771
+ }
26772
+ function emitNodeComments(n, renderer, job) {
26773
+ gvrenderComment(renderer, job, n.name);
26774
+ gvrenderComment(renderer, job, nodeAttr(n, n.root, "comment"));
26775
+ }
26776
+ function emitEdgeComments(e, renderer, job) {
26777
+ if (!edgeHasDrawableContent(e, job.bb)) return;
26778
+ const kind = e.head.root.kind;
26779
+ const op = kind === "directed" || kind === "strict-directed" ? "->" : "--";
26780
+ gvrenderComment(renderer, job, e.tail.name + op + e.head.name);
26781
+ gvrenderComment(renderer, job, e.attrs.get("comment"));
26782
+ }
26783
+
26784
+ // src/gvc/device.ts
26785
+ function labelTextOf2(lp) {
26786
+ return lp?.text ?? null;
26787
+ }
26676
26788
  function emitNodeBody(n, renderer, job) {
26677
26789
  setHtmlAnchorObj(svgNodeId(n, job), labelTextOf2(n.info.label), job.obj ?? void 0);
26678
26790
  setHtmlObjImgscale(nodeAttr(n, n.root, "imagescale"));
@@ -26688,6 +26800,7 @@ function renderNode(n, renderer, job, done) {
26688
26800
  if (done.has(n)) return;
26689
26801
  done.add(n);
26690
26802
  if (!nodeInBox(n, job)) return;
26803
+ emitNodeComments(n, renderer, job);
26691
26804
  const nodeStyle = nodeAttr(n, n.root, "style");
26692
26805
  if (parseStyleFlags(nodeStyle).invis) return;
26693
26806
  if (!isPointNode(n) && styleHasInvisibleAlias(nodeStyle)) return;
@@ -26713,6 +26826,7 @@ function setEdgePen(e, job) {
26713
26826
  obj.rawStyle = styleTokens(e.attrs.get("style"));
26714
26827
  }
26715
26828
  function renderEdge(e, renderer, job) {
26829
+ emitEdgeComments(e, renderer, job);
26716
26830
  const edgeStyle = e.attrs.get("style");
26717
26831
  if (parseStyleFlags(edgeStyle).invis || styleHasInvisibleAlias(edgeStyle)) return;
26718
26832
  const obj = createObjState(3 /* Edge */);
@@ -26826,7 +26940,9 @@ function render(ctx, g, format, inlineImages = false) {
26826
26940
  job.bb = g.info.bb;
26827
26941
  job.pad = parseGraphPad(g.attrs.get("pad"));
26828
26942
  job.margin = parseGraphMargin(g.attrs.get("margin"));
26829
- const z = initJobViewportZoom(job.bb, parseDrawingSize(g.attrs.get("size")), job.pad);
26943
+ const drawingSize = parseDrawingSize(g.attrs.get("size"));
26944
+ const z = initJobViewportZoom(job.bb, drawingSize, job.pad);
26945
+ job.clip = setupPageClip(job.bb, drawingSize, job.pad, z);
26830
26946
  const drawingDpi = lateDouble(
26831
26947
  g.attrs.get("dpi"),
26832
26948
  lateDouble(g.attrs.get("resolution"), 0, 0),
@@ -29134,56 +29250,63 @@ function setEndTheta(P, e, merge) {
29134
29250
 
29135
29251
  // src/pathplan/solvers.ts
29136
29252
  var EPS2 = 1e-7;
29137
- var Solver = class _Solver {
29138
- static aeq0(x) {
29139
- return x < EPS2 && x > -EPS2;
29140
- }
29141
- static solve1(c, r) {
29142
- if (_Solver.aeq0(c[1])) return _Solver.aeq0(c[0]) ? 4 : 0;
29143
- r[0] = -c[0] / c[1];
29144
- return 1;
29145
- }
29146
- static solve2(c, r) {
29147
- if (_Solver.aeq0(c[2])) return _Solver.solve1(c, r);
29148
- const b2a = c[1] / (2 * c[2]);
29149
- const disc = b2a * b2a - c[0] / c[2];
29150
- if (disc < 0) return 0;
29151
- if (disc > 0) {
29152
- r[0] = -b2a + Math.sqrt(disc);
29153
- r[1] = -2 * b2a - r[0];
29154
- return 2;
29155
- }
29156
- r[0] = -b2a;
29157
- return 1;
29158
- }
29159
- static solve3neg(disc, q, b3a, r) {
29160
- const rr = 0.5 * Math.sqrt(-disc + q * q);
29253
+ function aeq02(x) {
29254
+ return x < EPS2 && x > -EPS2;
29255
+ }
29256
+ function solve3(coeff, roots) {
29257
+ const a = coeff[3], b = coeff[2], c = coeff[1], d = coeff[0];
29258
+ if (aeq02(a)) return solve2(coeff, roots);
29259
+ const bOver3a = b / (3 * a), cOverA = c / a, dOverA = d / a;
29260
+ let p = bOver3a * bOver3a;
29261
+ const q = dOverA + fma(2 * bOver3a, p, -(bOver3a * cOverA));
29262
+ p = cOverA / 3 - p;
29263
+ const disc = fma(q, q, 4 * p * p * p);
29264
+ let rootn;
29265
+ if (disc < 0) {
29266
+ const r = 0.5 * Math.sqrt(fma(q, q, -disc));
29161
29267
  const theta = Math.atan2(Math.sqrt(-disc), -q);
29162
- const temp = 2 * Math.cbrt(rr);
29163
- r[0] = temp * Math.cos(theta / 3) - b3a;
29164
- r[1] = temp * Math.cos((theta + 2 * Math.PI) / 3) - b3a;
29165
- r[2] = temp * Math.cos((theta - 2 * Math.PI) / 3) - b3a;
29166
- return 3;
29268
+ const temp = 2 * Math.cbrt(r);
29269
+ roots[0] = temp * Math.cos(theta / 3);
29270
+ roots[1] = temp * Math.cos((theta + Math.PI + Math.PI) / 3);
29271
+ roots[2] = temp * Math.cos((theta - Math.PI - Math.PI) / 3);
29272
+ rootn = 3;
29273
+ } else {
29274
+ const alpha = 0.5 * (Math.sqrt(disc) - q);
29275
+ const beta = -q - alpha;
29276
+ roots[0] = Math.cbrt(alpha) + Math.cbrt(beta);
29277
+ if (disc > 0) rootn = 1;
29278
+ else {
29279
+ roots[1] = roots[2] = -0.5 * roots[0];
29280
+ rootn = 3;
29281
+ }
29167
29282
  }
29168
- static solve3pos(disc, q, b3a, r) {
29169
- const al = 0.5 * (Math.sqrt(disc) - q);
29170
- r[0] = Math.cbrt(al) + Math.cbrt(-q - al) - b3a;
29171
- if (disc > 0) return 1;
29172
- r[1] = r[2] = -0.5 * (r[0] + b3a) - b3a;
29173
- return 3;
29283
+ for (let i = 0; i < rootn; i++) roots[i] -= bOver3a;
29284
+ return rootn;
29285
+ }
29286
+ function solve2(coeff, roots) {
29287
+ const a = coeff[2], b = coeff[1], c = coeff[0];
29288
+ if (aeq02(a)) return solve1(coeff, roots);
29289
+ const bOver2a = b / (2 * a);
29290
+ const cOverA = c / a;
29291
+ const disc = fma(bOver2a, bOver2a, -cOverA);
29292
+ if (disc < 0) {
29293
+ return 0;
29294
+ } else if (disc > 0) {
29295
+ roots[0] = -bOver2a + Math.sqrt(disc);
29296
+ roots[1] = fma(-2, bOver2a, -roots[0]);
29297
+ return 2;
29174
29298
  }
29175
- static solve3(c, r) {
29176
- const a = c[3], b = c[2], cv = c[1], d = c[0];
29177
- if (_Solver.aeq0(a)) return _Solver.solve2(c, r);
29178
- const b3a = b / (3 * a), p0 = b3a * b3a;
29179
- const q = 2 * b3a * p0 - b3a * cv / a + d / a;
29180
- const p = cv / (3 * a) - p0;
29181
- const disc = q * q + 4 * p * p * p;
29182
- return disc < 0 ? _Solver.solve3neg(disc, q, b3a, r) : _Solver.solve3pos(disc, q, b3a, r);
29299
+ roots[0] = -bOver2a;
29300
+ return 1;
29301
+ }
29302
+ function solve1(coeff, roots) {
29303
+ const a = coeff[1], b = coeff[0];
29304
+ if (aeq02(a)) {
29305
+ if (aeq02(b)) return 4;
29306
+ return 0;
29183
29307
  }
29184
- };
29185
- function solve3(coeff, roots) {
29186
- return Solver.solve3(coeff, roots);
29308
+ roots[0] = -b / a;
29309
+ return 1;
29187
29310
  }
29188
29311
 
29189
29312
  // src/pathplan/route.ts
@@ -29205,16 +29328,19 @@ var RouteHelper = class _RouteHelper {
29205
29328
  static B3(t) {
29206
29329
  return t * t * t;
29207
29330
  }
29331
+ /** @see lib/pathplan/route.c:B01 */
29208
29332
  static B01(t) {
29209
29333
  const u = 1 - t;
29210
- return u * u * (u + 3 * t);
29334
+ return u * u * fma(3, t, u);
29211
29335
  }
29336
+ /** @see lib/pathplan/route.c:B23 */
29212
29337
  static B23(t) {
29213
29338
  const u = 1 - t;
29214
- return t * t * (3 * u + t);
29339
+ return t * t * fma(3, u, t);
29215
29340
  }
29341
+ /** @see lib/pathplan/route.c:normv */
29216
29342
  static normv(v) {
29217
- const d = v.x * v.x + v.y * v.y;
29343
+ const d = fma(v.x, v.x, v.y * v.y);
29218
29344
  if (d > 1e-6) {
29219
29345
  const s = Math.sqrt(d);
29220
29346
  return { x: v.x / s, y: v.y / s };
@@ -29230,20 +29356,28 @@ var RouteHelper = class _RouteHelper {
29230
29356
  static ptScale(p, c) {
29231
29357
  return { x: p.x * c, y: p.y * c };
29232
29358
  }
29359
+ /** @see lib/pathplan/route.c:dot */
29233
29360
  static ptDot(a, b) {
29234
- return a.x * b.x + a.y * b.y;
29361
+ return fma(a.x, b.x, a.y * b.y);
29235
29362
  }
29363
+ /** @see lib/pathplan/route.c:dist (libm hypot, no contraction) */
29236
29364
  static ptDist(a, b) {
29237
- return Math.hypot(a.x - b.x, a.y - b.y);
29365
+ return libmHypot(a.x - b.x, a.y - b.y);
29238
29366
  }
29239
29367
  static distN(pts) {
29240
29368
  let rv = 0;
29241
29369
  for (let i = 1; i < pts.length; i++) rv += _RouteHelper.ptDist(pts[i], pts[i - 1]);
29242
29370
  return rv;
29243
29371
  }
29372
+ /**
29373
+ * The cubic's coefficients come out of catastrophic cancellation when the
29374
+ * spline is tangent to a barrier (tests/2646.dot), so clang's contraction
29375
+ * here decides solve3's root count; mirror it exactly.
29376
+ * @see lib/pathplan/route.c:points2coeff
29377
+ */
29244
29378
  static points2coeff(v0, v1, v2, v3, c) {
29245
- c[3] = v3 + 3 * v1 - (v0 + 3 * v2);
29246
- c[2] = 3 * v0 + 3 * v2 - 6 * v1;
29379
+ c[3] = fma(3, v1, v3) - fma(3, v2, v0);
29380
+ c[2] = fma(-6, v1, fma(3, v0, 3 * v2));
29247
29381
  c[1] = 3 * (v1 - v0);
29248
29382
  c[0] = v0;
29249
29383
  }
@@ -29283,7 +29417,7 @@ var RouteHelper = class _RouteHelper {
29283
29417
  const tv = xr[i];
29284
29418
  if (tv >= 0 && tv <= 1) {
29285
29419
  _RouteHelper.points2coeff(sps[0].y, sps[1].y, sps[2].y, sps[3].y, sc);
29286
- const sv = (sc[0] + tv * (sc[1] + tv * (sc[2] + tv * sc[3])) - lc.yc0) / lc.yc1;
29420
+ const sv = (fma(tv, fma(tv, fma(tv, sc[3], sc[2]), sc[1]), sc[0]) - lc.yc0) / lc.yc1;
29287
29421
  if (sv >= 0 && sv <= 1) _RouteHelper.addRoot(tv, acc);
29288
29422
  }
29289
29423
  }
@@ -29293,25 +29427,26 @@ var RouteHelper = class _RouteHelper {
29293
29427
  const sc = [0, 0, 0, 0], xr = [0, 0, 0];
29294
29428
  const rat = lc.yc1 / lc.xc1;
29295
29429
  _RouteHelper.points2coeff(
29296
- sps[0].y - rat * sps[0].x,
29297
- sps[1].y - rat * sps[1].x,
29298
- sps[2].y - rat * sps[2].x,
29299
- sps[3].y - rat * sps[3].x,
29430
+ fms(rat, sps[0].x, sps[0].y),
29431
+ fms(rat, sps[1].x, sps[1].y),
29432
+ fms(rat, sps[2].x, sps[2].y),
29433
+ fms(rat, sps[3].x, sps[3].y),
29300
29434
  sc
29301
29435
  );
29302
- sc[0] += rat * lc.xc0 - lc.yc0;
29436
+ sc[0] += fma(rat, lc.xc0, -lc.yc0);
29303
29437
  const xn = solve3(sc, xr);
29304
29438
  if (xn === 4) return 4;
29305
29439
  for (let i = 0; i < xn; i++) {
29306
29440
  const tv = xr[i];
29307
29441
  if (tv >= 0 && tv <= 1) {
29308
29442
  _RouteHelper.points2coeff(sps[0].x, sps[1].x, sps[2].x, sps[3].x, sc);
29309
- const sv = (sc[0] + tv * (sc[1] + tv * (sc[2] + tv * sc[3])) - lc.xc0) / lc.xc1;
29443
+ const sv = (fma(tv, fma(tv, fma(tv, sc[3], sc[2]), sc[1]), sc[0]) - lc.xc0) / lc.xc1;
29310
29444
  if (sv >= 0 && sv <= 1) _RouteHelper.addRoot(tv, acc);
29311
29445
  }
29312
29446
  }
29313
29447
  return acc.n;
29314
29448
  }
29449
+ /** @see lib/pathplan/route.c:splineintersectsline */
29315
29450
  static splineIntersectsLine(sps, lps, roots) {
29316
29451
  const lc = {
29317
29452
  xc0: lps[0].x,
@@ -29362,8 +29497,9 @@ var RouteHelper = class _RouteHelper {
29362
29497
  x0 += _RouteHelper.ptDot(tnas[i].a[0], tmp);
29363
29498
  x1 += _RouteHelper.ptDot(tnas[i].a[1], tmp);
29364
29499
  }
29365
- const det01 = c00 * c11 - c01 * c01;
29366
- const detX1 = x0 * c11 - x1 * c01, det0X = c00 * x1 - c01 * x0;
29500
+ const det01 = fma(c00, c11, -(c01 * c01));
29501
+ const det0X = fma(c00, x1, -(c01 * x0));
29502
+ const detX1 = fma(x0, c11, -(x1 * c01));
29367
29503
  if (Math.abs(det01) >= 1e-6) {
29368
29504
  scale0 = detX1 / det01;
29369
29505
  scale3 = det0X / det01;
@@ -29387,6 +29523,27 @@ var RouteHelper = class _RouteHelper {
29387
29523
  }
29388
29524
  return tnas;
29389
29525
  }
29526
+ /**
29527
+ * The max-deviation split of `reallyroutespline` (route.c:130-143): the
29528
+ * interior polyline point farthest from the fitted bezier.
29529
+ *
29530
+ * Faithful contract. On a geometrically symmetric channel two interior
29531
+ * deviations tie to within an ulp, so the split point (and the whole
29532
+ * spline) is decided by C's exact arithmetic, which this mirrors bit for
29533
+ * bit against the native arm64 oracle:
29534
+ * - `dist` is libm `hypot` (route.c:448) -> `libmHypot` via `ptDist`;
29535
+ * - the test is C's strict `(d = dist(p, inps[i])) > maxd` (route.c:139),
29536
+ * so an exact tie keeps the first index;
29537
+ * - clang's default `-ffp-contract=on` fuses the bezier eval at
29538
+ * route.c:137-138 as `fma(B3,p2, fma(B2,cp2, fma(B0,p1, B1*cp1)))`; the
29539
+ * B0..B3 weights and cp1/cp2 (route.c:130-131) are not fused. Fusing the
29540
+ * other product first is NOT equivalent (flips pt-issue-23-w9 and 32).
29541
+ * C is therefore not translation-equivariant on such ties (the winner
29542
+ * depends on absolute-coordinate rounding), and neither is this port.
29543
+ * This supersedes the former tolerant tie-break (accepted divergence A3).
29544
+ * Contraction map: .agent-notes/pathplan-fma-contraction-map.md.
29545
+ * @see lib/pathplan/route.c:reallyroutespline
29546
+ */
29390
29547
  static findMaxDev(inps, tnas, ends) {
29391
29548
  const { p0, v0, p1, v1 } = ends;
29392
29549
  const cp1 = _RouteHelper.ptAdd(p0, _RouteHelper.ptScale(v0, 1 / 3));
@@ -29394,10 +29551,12 @@ var RouteHelper = class _RouteHelper {
29394
29551
  let maxi = -1, maxd = -1;
29395
29552
  for (let i = 1; i < inps.length - 1; i++) {
29396
29553
  const t = tnas[i].t;
29397
- const px = _RouteHelper.B0(t) * p0.x + _RouteHelper.B1(t) * cp1.x + _RouteHelper.B2(t) * cp2.x + _RouteHelper.B3(t) * p1.x;
29398
- const py = _RouteHelper.B0(t) * p0.y + _RouteHelper.B1(t) * cp1.y + _RouteHelper.B2(t) * cp2.y + _RouteHelper.B3(t) * p1.y;
29554
+ const b0 = _RouteHelper.B0(t), b1 = _RouteHelper.B1(t);
29555
+ const b2 = _RouteHelper.B2(t), b3 = _RouteHelper.B3(t);
29556
+ const px = fma(b3, p1.x, fma(b2, cp2.x, fma(b0, p0.x, b1 * cp1.x)));
29557
+ const py = fma(b3, p1.y, fma(b2, cp2.y, fma(b0, p0.y, b1 * cp1.y)));
29399
29558
  const d = _RouteHelper.ptDist({ x: px, y: py }, inps[i]);
29400
- if (d > maxd * (1 + 1e-10) + 1e-10) {
29559
+ if (d > maxd) {
29401
29560
  maxd = d;
29402
29561
  maxi = i;
29403
29562
  }
@@ -31128,7 +31287,7 @@ function routeMultiRankEdgeFaithful(g, e) {
31128
31287
  }
31129
31288
  const segs = chainSegments(e);
31130
31289
  if (segs.length === 0 || segs[segs.length - 1].head !== e.head) return null;
31131
- return routeChainSegmented(g, segs[0], segs[segs.length - 1], segs);
31290
+ return routeChainSegmented(g, segs[0], segs[segs.length - 1], segs) ?? "lost";
31132
31291
  }
31133
31292
  function entryRunSegments(e) {
31134
31293
  const segs = [e];
@@ -31200,7 +31359,10 @@ function routeBackEdge(e, _tailBox, _headBox, g) {
31200
31359
  if (segs.length < 2 || segs[segs.length - 1].head !== e.tail) return;
31201
31360
  const fwdEdge = makeFwdEdge(e);
31202
31361
  const fwd = routeChainSegmented(g, segs[0], segs[segs.length - 1], segs);
31203
- if (fwd === null) return;
31362
+ if (fwd === null) {
31363
+ e.info.lost = true;
31364
+ return;
31365
+ }
31204
31366
  clipAndInstall(fwdEdge, fwdEdge.head, fwd, fwd.length, buildDotSinfo());
31205
31367
  if (swapEndsP(e)) swapEdgeSpline(e);
31206
31368
  }
@@ -31352,7 +31514,7 @@ function baseSplineForGroup(g, e0) {
31352
31514
  const orig = resolveOrigEdge(e0);
31353
31515
  const fe = isBackEdgeMember(orig) ? makeFwdEdge(orig) : orig;
31354
31516
  const pts = routeRegularEdgeFaithful(g, fe);
31355
- if (pts === "lost") return null;
31517
+ if (pts === "lost") return "lost";
31356
31518
  return pts ?? routeMultiRankEdgeFaithful(g, fe);
31357
31519
  }
31358
31520
  function isBackEdgeMember(e) {
@@ -31381,6 +31543,10 @@ function routeParallelEdgeGroup(g, edges, multisep) {
31381
31543
  return o.info.head_port?.defined || o.info.tail_port?.defined;
31382
31544
  }) ?? edges[0];
31383
31545
  const base = baseSplineForGroup(g, baseEdge);
31546
+ if (base === "lost") {
31547
+ for (const e of edges) resolveOrigEdge(e).info.lost = true;
31548
+ return;
31549
+ }
31384
31550
  if (base === null) return;
31385
31551
  if (cnt === 1) {
31386
31552
  installShiftedEdge(edges[0], base);
@@ -33548,8 +33714,9 @@ function normalizeCopiedFlatSpline(orig, auxe) {
33548
33714
  if (orig.info.spl === void 0) return;
33549
33715
  if (swapEndsP(auxe) !== swapEndsP(orig)) swapEdgeSpline(orig);
33550
33716
  }
33551
- function makeFlatAdjEdges(g, edges, cnt, _et) {
33717
+ function makeFlatAdjEdges(g, edges, cnt, et) {
33552
33718
  const aux = buildFlatAux(g, edges, cnt);
33719
+ aux.auxg.info.flags = aux.auxg.info.flags & ~15 | et & 15;
33553
33720
  dotInitNodeEdge(aux.auxg);
33554
33721
  dotRank(aux.auxg);
33555
33722
  if (dotMincross(aux.auxg) !== 0) return 1;
@@ -33660,88 +33827,6 @@ function assembleFlatPath(P, tend, hend, mid) {
33660
33827
  for (let i = hend.boxn - 1; i >= 0; i--) addBox(P, hend.boxes[i]);
33661
33828
  }
33662
33829
 
33663
- // src/layout/dot/splines-flat-multi.ts
33664
- function portEq2(a, b) {
33665
- if (!a.defined && !b.defined) return true;
33666
- if (!a.defined || !b.defined) return false;
33667
- return a.p.x === b.p.x && a.p.y === b.p.y;
33668
- }
33669
- function flatPortKey(e, lo) {
33670
- return e.tail === lo ? { loP: e.info.tail_port, hiP: e.info.head_port } : { loP: e.info.head_port, hiP: e.info.tail_port };
33671
- }
33672
- function isNonAdjGroupable(x, g) {
33673
- return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && !isFlatAdjacent(g, x);
33674
- }
33675
- function samePortsAs(x, lo, key) {
33676
- const k = flatPortKey(x, lo);
33677
- return portEq2(k.loP, key.loP) && portEq2(k.hiP, key.hiP);
33678
- }
33679
- function collectNonAdjacentFlatGroup(e, g) {
33680
- const u = e.tail, v = e.head;
33681
- const lo = (u.info.order ?? 0) <= (v.info.order ?? 0) ? u : v;
33682
- const key = flatPortKey(e, lo);
33683
- const sharesPair = (x) => x.tail === u && x.head === v || x.tail === v && x.head === u;
33684
- const group = g.edges.filter(
33685
- (x) => sharesPair(x) && isNonAdjGroupable(x, g) && samePortsAs(x, lo, key) && x.info.label === e.info.label
33686
- );
33687
- group.sort((a, b) => Number(b.tail === lo) - Number(a.tail === lo) || a.seq - b.seq);
33688
- return group;
33689
- }
33690
- function copyPathEnd(end) {
33691
- return {
33692
- ...end,
33693
- boxes: end.boxes.map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } }))
33694
- };
33695
- }
33696
- function routeGroupEdge(e, i, c) {
33697
- c.P.nbox = 0;
33698
- const endStepX = (i + 1) * c.stepx;
33699
- const endStepY = (i + 1) * c.stepy;
33700
- const mid = c.bottom ? bottomBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy) : topBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy);
33701
- assembleFlatPath(c.P, copyPathEnd(c.tend), copyPathEnd(c.hend), mid);
33702
- const pts = routeSplines(c.P);
33703
- if (pts === null || pts.length === 0) return false;
33704
- if (e.tail !== c.leftNode) pts.reverse();
33705
- clipAndInstall(e, e.head, pts, pts.length, { ...buildDotSinfo(), ignoreSwap: true });
33706
- return true;
33707
- }
33708
- function routeFlatEdgeGroupFaithful(g, edges, cnt) {
33709
- const lead = edges[0];
33710
- if (g.info.rank === void 0 || lead.tail.info.rank === void 0 || lead.head.info.rank !== lead.tail.info.rank) return false;
33711
- const tailIsLeft = (lead.tail.info.order ?? 0) <= (lead.head.info.order ?? 0);
33712
- const leftNode = tailIsLeft ? lead.tail : lead.head;
33713
- const rightNode = tailIsLeft ? lead.head : lead.tail;
33714
- const sample = tailIsLeft ? lead : {
33715
- ...lead,
33716
- tail: leftNode,
33717
- head: rightNode,
33718
- info: { ...lead.info, tail_port: lead.info.head_port, head_port: lead.info.tail_port }
33719
- };
33720
- const { bottom, side } = flatSide(sample);
33721
- const ctx = flatBboxCtx(g);
33722
- const ranksep = graphRanksep(g);
33723
- const P = freshFlatPath();
33724
- const tend = makeFlatEndBox({ ctx, P, e: sample, n: leftNode, side, ranksep, isBegin: true });
33725
- const hend = makeFlatEndBox({ ctx, P, e: sample, n: rightNode, side, ranksep, isBegin: false });
33726
- const stepx = (g.info.nodesep ?? 18) / (cnt + 1);
33727
- const stepy = flatVspace(g, leftNode, !bottom) / (cnt + 1);
33728
- const rc = {
33729
- P,
33730
- tend,
33731
- hend,
33732
- tlast: tend.boxes[tend.boxn - 1],
33733
- hlast: hend.boxes[hend.boxn - 1],
33734
- bottom,
33735
- stepx,
33736
- stepy,
33737
- leftNode
33738
- };
33739
- for (let i = 0; i < cnt; i++) {
33740
- if (!routeGroupEdge(edges[i], i, rc)) return false;
33741
- }
33742
- return true;
33743
- }
33744
-
33745
33830
  // src/layout/dot/splines-flat-labeled.ts
33746
33831
  var LBL_SPACE = 6;
33747
33832
  function findLabelNode(e) {
@@ -33996,6 +34081,93 @@ function makeAdjFlatNoPortEdge(g, e) {
33996
34081
  return true;
33997
34082
  }
33998
34083
 
34084
+ // src/layout/dot/splines-flat-multi.ts
34085
+ function portEq2(a, b) {
34086
+ if (!a.defined && !b.defined) return true;
34087
+ if (!a.defined || !b.defined) return false;
34088
+ return a.p.x === b.p.x && a.p.y === b.p.y;
34089
+ }
34090
+ function flatPortKey(e, lo) {
34091
+ return e.tail === lo ? { loP: e.info.tail_port, hiP: e.info.head_port } : { loP: e.info.head_port, hiP: e.info.tail_port };
34092
+ }
34093
+ function isNonAdjGroupable(x, g) {
34094
+ return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && !isFlatAdjacent(g, x);
34095
+ }
34096
+ function samePortsAs(x, lo, key) {
34097
+ const k = flatPortKey(x, lo);
34098
+ return portEq2(k.loP, key.loP) && portEq2(k.hiP, key.hiP);
34099
+ }
34100
+ function collectNonAdjacentFlatGroup(e, g) {
34101
+ const u = e.tail, v = e.head;
34102
+ const lo = (u.info.order ?? 0) <= (v.info.order ?? 0) ? u : v;
34103
+ const key = flatPortKey(e, lo);
34104
+ const sharesPair = (x) => x.tail === u && x.head === v || x.tail === v && x.head === u;
34105
+ const group = g.edges.filter(
34106
+ (x) => sharesPair(x) && isNonAdjGroupable(x, g) && samePortsAs(x, lo, key) && x.info.label === e.info.label
34107
+ );
34108
+ group.sort((a, b) => Number(b.tail === lo) - Number(a.tail === lo) || a.seq - b.seq);
34109
+ return group;
34110
+ }
34111
+ function copyPathEnd(end) {
34112
+ return {
34113
+ ...end,
34114
+ boxes: end.boxes.map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } }))
34115
+ };
34116
+ }
34117
+ function routeGroupEdge(e, i, c) {
34118
+ c.P.nbox = 0;
34119
+ const endStepX = (i + 1) * c.stepx;
34120
+ const endStepY = (i + 1) * c.stepy;
34121
+ const mid = c.bottom ? bottomBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy) : topBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy);
34122
+ assembleFlatPath(c.P, copyPathEnd(c.tend), copyPathEnd(c.hend), mid);
34123
+ const pts = c.et === EDGETYPE_SPLINE ? routeSplines(c.P) : routePolylines(c.P);
34124
+ if (pts === null || pts.length === 0) return false;
34125
+ if (e.tail !== c.leftNode) pts.reverse();
34126
+ clipAndInstall(e, e.head, pts, pts.length, { ...buildDotSinfo(), ignoreSwap: true });
34127
+ return true;
34128
+ }
34129
+ function routeFlatEdgeGroupFaithful(g, edges, cnt, et) {
34130
+ const lead = edges[0];
34131
+ if (g.info.rank === void 0 || lead.tail.info.rank === void 0 || lead.head.info.rank !== lead.tail.info.rank) return false;
34132
+ if (et === EDGETYPE_LINE) {
34133
+ makeSimpleFlat(edges, et);
34134
+ return true;
34135
+ }
34136
+ const tailIsLeft = (lead.tail.info.order ?? 0) <= (lead.head.info.order ?? 0);
34137
+ const leftNode = tailIsLeft ? lead.tail : lead.head;
34138
+ const rightNode = tailIsLeft ? lead.head : lead.tail;
34139
+ const sample = tailIsLeft ? lead : {
34140
+ ...lead,
34141
+ tail: leftNode,
34142
+ head: rightNode,
34143
+ info: { ...lead.info, tail_port: lead.info.head_port, head_port: lead.info.tail_port }
34144
+ };
34145
+ const { bottom, side } = flatSide(sample);
34146
+ const ctx = flatBboxCtx(g);
34147
+ const ranksep = graphRanksep(g);
34148
+ const P = freshFlatPath();
34149
+ const tend = makeFlatEndBox({ ctx, P, e: sample, n: leftNode, side, ranksep, isBegin: true });
34150
+ const hend = makeFlatEndBox({ ctx, P, e: sample, n: rightNode, side, ranksep, isBegin: false });
34151
+ const stepx = (g.info.nodesep ?? 18) / (cnt + 1);
34152
+ const stepy = flatVspace(g, leftNode, !bottom) / (cnt + 1);
34153
+ const rc = {
34154
+ P,
34155
+ tend,
34156
+ hend,
34157
+ tlast: tend.boxes[tend.boxn - 1],
34158
+ hlast: hend.boxes[hend.boxn - 1],
34159
+ bottom,
34160
+ et,
34161
+ stepx,
34162
+ stepy,
34163
+ leftNode
34164
+ };
34165
+ for (let i = 0; i < cnt; i++) {
34166
+ if (!routeGroupEdge(edges[i], i, rc)) return false;
34167
+ }
34168
+ return true;
34169
+ }
34170
+
33999
34171
  // src/layout/dot/edge-route-boxes.ts
34000
34172
  var FUDGE2 = 2;
34001
34173
  function makeTailBox(nb, startPy) {
@@ -34280,6 +34452,10 @@ function routeOneEdge(e, g) {
34280
34452
  function routeFaithfulMultiRank(e, g) {
34281
34453
  const pts = routeMultiRankEdgeFaithful(g, e);
34282
34454
  if (pts === null) return false;
34455
+ if (pts === "lost") {
34456
+ e.info.lost = true;
34457
+ return true;
34458
+ }
34283
34459
  clipAndInstall(e, e.head, pts, pts.length, buildDotSinfo());
34284
34460
  return true;
34285
34461
  }
@@ -34295,7 +34471,10 @@ function isAdjacentPortFlat(e, g) {
34295
34471
  return e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank && isFlatAdjacent(g, e) && hasDefinedPort(e);
34296
34472
  }
34297
34473
  function isGroupableFlat(x, g) {
34298
- return x.info.spl === void 0 && isAdjacentPortFlat(x, g);
34474
+ return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && isFlatAdjacent(g, x);
34475
+ }
34476
+ function joinsPortedFlatGroup(e, g) {
34477
+ return isAdjFlatCandidate(e) && isGroupableFlat(e, g) && collectAdjacentFlatGroup(e, g).some(hasDefinedPort);
34299
34478
  }
34300
34479
  function collectAdjacentFlatGroup(e, g) {
34301
34480
  const u = e.tail, v = e.head;
@@ -34310,11 +34489,11 @@ function routeFaithfulSidePort(e, g) {
34310
34489
  const sameRank = e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank;
34311
34490
  if (sameRank && isFlatAdjacent(g, e)) {
34312
34491
  const group = collectAdjacentFlatGroup(e, g);
34313
- return makeFlatAdjEdges(g, group, group.length, EDGETYPE_SPLINE) === 0 && e.info.spl !== void 0;
34492
+ return makeFlatAdjEdges(g, group, group.length, edgeType(g)) === 0 && e.info.spl !== void 0;
34314
34493
  }
34315
34494
  if (sameRank) {
34316
34495
  const group = collectNonAdjacentFlatGroup(e, g);
34317
- return routeFlatEdgeGroupFaithful(g, group, group.length) && e.info.spl !== void 0;
34496
+ return routeFlatEdgeGroupFaithful(g, group, group.length, edgeType(g)) && e.info.spl !== void 0;
34318
34497
  }
34319
34498
  const pts = routeRegularEdgeFaithful(g, e);
34320
34499
  if (pts === null) return false;
@@ -34335,11 +34514,12 @@ function isLostFlatAdjRecordEdge(g, e) {
34335
34514
  function routeFlatEdge(e, g) {
34336
34515
  if (isLostFlatAdjRecordEdge(g, e)) return true;
34337
34516
  if (makeFlatLabeledEdge(g, e)) return true;
34517
+ if (joinsPortedFlatGroup(e, g) && routeFaithfulSidePort(e, g)) return true;
34338
34518
  if (makeAdjFlatNoPortEdge(g, e)) return true;
34339
34519
  if ((hasSidePort(e) || isAdjacentPortFlat(e, g)) && routeFaithfulSidePort(e, g)) return true;
34340
34520
  if (e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank && e.info.label === void 0 && !isFlatAdjacent(g, e)) {
34341
34521
  const group = collectNonAdjacentFlatGroup(e, g);
34342
- if (group.length > 0 && routeFlatEdgeGroupFaithful(g, group, group.length) && e.info.spl !== void 0) return true;
34522
+ if (group.length > 0 && routeFlatEdgeGroupFaithful(g, group, group.length, edgeType(g)) && e.info.spl !== void 0) return true;
34343
34523
  }
34344
34524
  return false;
34345
34525
  }
@@ -34784,24 +34964,28 @@ function addSegment(segnum, seg2, tr, qs) {
34784
34964
  swapSegEndpoints(s);
34785
34965
  isSwapped = true;
34786
34966
  }
34787
- let tfirst;
34788
- if (!inserted(segnum, seg2, isSwapped ? LASTPT : FIRSTPT)) {
34789
- tfirst = insertV0(s, seg2, tr, qs, segnum);
34790
- } else {
34791
- tfirst = locateEndpoint(s.v0, s.v1, s.root0, seg2, qs);
34967
+ const ctx = { s, seg: seg2, tr, qs, segnum, tribot: false, isSwapped };
34968
+ const tfirst = firstTrap(ctx);
34969
+ const tlast = lastTrap(ctx);
34970
+ if (threadSegment(ctx, tfirst, tlast) !== 0) return -1;
34971
+ seg2[segnum].isInserted = true;
34972
+ return 0;
34973
+ }
34974
+ function firstTrap(c) {
34975
+ if (!inserted(c.segnum, c.seg, c.isSwapped ? LASTPT : FIRSTPT)) {
34976
+ return insertV0(c.s, c.seg, c.tr, c.qs, c.segnum);
34792
34977
  }
34793
- let tlast;
34794
- let tribot = false;
34795
- if (!inserted(segnum, seg2, isSwapped ? FIRSTPT : LASTPT)) {
34796
- tlast = insertV1(s, seg2, tr, qs, segnum);
34797
- } else {
34798
- tlast = locateEndpoint(s.v1, s.v0, s.root1, seg2, qs);
34799
- tribot = true;
34978
+ return locateEndpoint(c.s.v0, c.s.v1, c.s.root0, c.seg, c.qs);
34979
+ }
34980
+ function lastTrap(c) {
34981
+ if (!inserted(c.segnum, c.seg, c.isSwapped ? FIRSTPT : LASTPT)) {
34982
+ return insertV1(c.s, c.seg, c.tr, c.qs, c.segnum);
34800
34983
  }
34801
- threadSegment(s, seg2, tr, qs, segnum, tfirst, tlast, tribot, isSwapped);
34802
- seg2[segnum].isInserted = true;
34984
+ c.tribot = true;
34985
+ return locateEndpoint(c.s.v1, c.s.v0, c.s.root1, c.seg, c.qs);
34803
34986
  }
34804
- function threadSegment(s, seg2, tr, qs, segnum, tfirst, tlast, tribot, isSwapped) {
34987
+ function threadSegment(c, tfirst, tlast) {
34988
+ const { s, seg: seg2, tr, qs, segnum, tribot, isSwapped } = c;
34805
34989
  let tfirstr = INVALID_TRAP;
34806
34990
  let tlastr = INVALID_TRAP;
34807
34991
  let t = tfirst;
@@ -34828,17 +35012,20 @@ function threadSegment(s, seg2, tr, qs, segnum, tfirst, tlast, tribot, isSwapped
34828
35012
  if (equalTo(tr[t].lo, tr[tlast].lo)) tlastr = tn;
34829
35013
  const tSav = t;
34830
35014
  const tnSav = tn;
35015
+ if (!isValidTrap(tr[t].d0) && !isValidTrap(tr[t].d1)) {
35016
+ console.error("trapezoid segment construction failed");
35017
+ return -1;
35018
+ }
34831
35019
  t = advanceT(s, seg2, tr, t, tn, tlast, segnum, isSwapped, tribot);
34832
35020
  tr[tSav].rseg = segnum;
34833
35021
  tr[tnSav].lseg = segnum;
34834
35022
  }
34835
35023
  mergeTrapezoids(segnum, tfirst, tlast, S_LEFT, tr, qs);
34836
35024
  mergeTrapezoids(segnum, tfirstr, tlastr, S_RIGHT, tr, qs);
35025
+ return 0;
34837
35026
  }
34838
35027
  function advanceT(s, seg2, tr, t, tn, tlast, segnum, isSwapped, tribot) {
34839
- if (!isValidTrap(tr[t].d0) && !isValidTrap(tr[t].d1)) {
34840
- return INVALID_TRAP;
34841
- } else if (isValidTrap(tr[t].d0) && !isValidTrap(tr[t].d1)) {
35028
+ if (isValidTrap(tr[t].d0) && !isValidTrap(tr[t].d1)) {
34842
35029
  handleD0Only(s, seg2, tr, t, tn, tlast, segnum, isSwapped, tribot);
34843
35030
  return tr[t].d0;
34844
35031
  } else if (!isValidTrap(tr[t].d0) && isValidTrap(tr[t].d1)) {
@@ -34858,33 +35045,16 @@ function findNewRoots(segnum, seg2, tr, qs) {
34858
35045
  // src/ortho/trapezoid.ts
34859
35046
  function constructTrapezoids(nseg, seg2, permute) {
34860
35047
  const qs = [];
34861
- const tr = [];
34862
- tr.push({
34863
- lseg: 0,
34864
- rseg: 0,
34865
- hi: { x: 0, y: 0 },
34866
- lo: { x: 0, y: 0 },
34867
- u0: 0,
34868
- u1: 0,
34869
- d0: 0,
34870
- d1: 0,
34871
- sink: 0,
34872
- usave: 0,
34873
- uside: 0,
34874
- isValid: false
34875
- });
35048
+ const tr = [sentinelTrap()];
34876
35049
  let segi = 0;
34877
35050
  const root = initQueryStructure(permute[segi++], seg2, tr, qs);
34878
- for (let i = 1; i <= nseg; i++) {
34879
- seg2[i].root0 = root;
34880
- seg2[i].root1 = root;
34881
- }
35051
+ seedRoots(nseg, seg2, root);
34882
35052
  const logstar = mathLogstarN(nseg);
34883
35053
  for (let h = 1; h <= logstar; h++) {
34884
35054
  const lo = mathN(nseg, h - 1) + 1;
34885
35055
  const hi = mathN(nseg, h);
34886
35056
  for (let i = lo; i <= hi; i++) {
34887
- addSegment(permute[segi++], seg2, tr, qs);
35057
+ if (addSegment(permute[segi++], seg2, tr, qs) !== 0) return [];
34888
35058
  }
34889
35059
  for (let i = 1; i <= nseg; i++) {
34890
35060
  findNewRoots(i, seg2, tr, qs);
@@ -34892,10 +35062,32 @@ function constructTrapezoids(nseg, seg2, permute) {
34892
35062
  }
34893
35063
  const remaining = mathN(nseg, logstar) + 1;
34894
35064
  for (let i = remaining; i <= nseg; i++) {
34895
- addSegment(permute[segi++], seg2, tr, qs);
35065
+ if (addSegment(permute[segi++], seg2, tr, qs) !== 0) return [];
34896
35066
  }
34897
35067
  return tr;
34898
35068
  }
35069
+ function sentinelTrap() {
35070
+ return {
35071
+ lseg: 0,
35072
+ rseg: 0,
35073
+ hi: { x: 0, y: 0 },
35074
+ lo: { x: 0, y: 0 },
35075
+ u0: 0,
35076
+ u1: 0,
35077
+ d0: 0,
35078
+ d1: 0,
35079
+ sink: 0,
35080
+ usave: 0,
35081
+ uside: 0,
35082
+ isValid: false
35083
+ };
35084
+ }
35085
+ function seedRoots(nseg, seg2, root) {
35086
+ for (let i = 1; i <= nseg; i++) {
35087
+ seg2[i].root0 = root;
35088
+ seg2[i].root1 = root;
35089
+ }
35090
+ }
34899
35091
  function initQueryStructure(segnum, seg2, tr, qs) {
34900
35092
  const s = seg2[segnum];
34901
35093
  const i1 = newQNode(qs);
@@ -35199,10 +35391,18 @@ function partition(cells, bb) {
35199
35391
  const hSeg = h.genSegments(cells, bb, false);
35200
35392
  const hPerm = h.generateRandomOrdering(nsegs);
35201
35393
  const hTr = constructTrapezoids(nsegs, hSeg, hPerm);
35394
+ if (hTr.length === 0) {
35395
+ console.error("horizontal trapezoid construction failed");
35396
+ return null;
35397
+ }
35202
35398
  const hDecomp = h.monotonateTrapezoids(hTr, hSeg, false);
35203
35399
  const vSeg = h.genSegments(cells, bb, true);
35204
35400
  const vPerm = h.generateRandomOrdering(nsegs);
35205
35401
  const vTr = constructTrapezoids(nsegs, vSeg, vPerm);
35402
+ if (vTr.length === 0) {
35403
+ console.error("vertical trapezoid construction failed");
35404
+ return null;
35405
+ }
35206
35406
  const vDecomp = h.monotonateTrapezoids(vTr, vSeg, true);
35207
35407
  const result = [];
35208
35408
  for (const v of vDecomp) {
@@ -35211,7 +35411,7 @@ function partition(cells, bb) {
35211
35411
  if (isect) result.push(isect);
35212
35412
  }
35213
35413
  }
35214
- return result;
35414
+ return result.length === 0 ? null : result;
35215
35415
  }
35216
35416
 
35217
35417
  // src/ortho/rawgraph.ts
@@ -36059,6 +36259,7 @@ function mkMaze(g) {
36059
36259
  UR: { x: BB.UR.x + MARGIN, y: BB.UR.y + MARGIN }
36060
36260
  };
36061
36261
  const rects = partition(gcells, BB);
36262
+ if (rects === null) return null;
36062
36263
  const cells = rects.map((bb) => ({
36063
36264
  flags: 0,
36064
36265
  nedges: 0,
@@ -36540,6 +36741,24 @@ function buildSpline(e, rte, mp) {
36540
36741
  pts.push({ ...p });
36541
36742
  return pts;
36542
36743
  }
36744
+ function ensureDummyNodes(sg, gstart) {
36745
+ while (sg.nodes.length < gstart + 2) {
36746
+ sg.nodes.push({
36747
+ nVal: 0,
36748
+ nIdx: 0,
36749
+ nDad: null,
36750
+ nEdge: null,
36751
+ nAdj: 0,
36752
+ saveNAdj: 0,
36753
+ cells: [null, null],
36754
+ adjEdgeList: [],
36755
+ index: sg.nodes.length,
36756
+ isVert: false,
36757
+ x: 0,
36758
+ y: 0
36759
+ });
36760
+ }
36761
+ }
36543
36762
  function orthoEdges(g, useLbls, clipAndInstall2) {
36544
36763
  if (useLbls) {
36545
36764
  console.warn(
@@ -36549,6 +36768,7 @@ function orthoEdges(g, useLbls, clipAndInstall2) {
36549
36768
  }
36550
36769
  void useLbls;
36551
36770
  const mp = mkMaze(g);
36771
+ if (mp === null) return -1;
36552
36772
  const sg = mp.sg;
36553
36773
  const es = g.edges.map((e) => ({ e, d: edgeLen(e) }));
36554
36774
  gvQsort(es, edgeCmp);
@@ -36558,22 +36778,7 @@ function orthoEdges(g, useLbls, clipAndInstall2) {
36558
36778
  const pq = pqGenForGraph(sg);
36559
36779
  const sn = sg.nodes[gstart];
36560
36780
  const dn = sg.nodes[gstart + 1];
36561
- while (sg.nodes.length < gstart + 2) {
36562
- sg.nodes.push({
36563
- nVal: 0,
36564
- nIdx: 0,
36565
- nDad: null,
36566
- nEdge: null,
36567
- nAdj: 0,
36568
- saveNAdj: 0,
36569
- cells: [null, null],
36570
- adjEdgeList: [],
36571
- index: sg.nodes.length,
36572
- isVert: false,
36573
- x: 0,
36574
- y: 0
36575
- });
36576
- }
36781
+ ensureDummyNodes(sg, gstart);
36577
36782
  for (let i = 0; i < nEdges; i++) {
36578
36783
  const e = es[i].e;
36579
36784
  const start = mp.gcells[g.nodes.indexOf(e.tail)];
@@ -36587,7 +36792,7 @@ function orthoEdges(g, useLbls, clipAndInstall2) {
36587
36792
  if (shortPath(pq, sg, dn, sn) !== 0) {
36588
36793
  pqFree(pq);
36589
36794
  freeMaze(mp);
36590
- return;
36795
+ return 0;
36591
36796
  }
36592
36797
  routeList[i] = convertSPtoRoute(sg, sn, dn);
36593
36798
  reset(sg);
@@ -36598,7 +36803,7 @@ function orthoEdges(g, useLbls, clipAndInstall2) {
36598
36803
  assignSegs(routeList, mp);
36599
36804
  if (assignTracks(mp) !== 0) {
36600
36805
  freeMaze(mp);
36601
- return;
36806
+ return 0;
36602
36807
  }
36603
36808
  if (clipAndInstall2) {
36604
36809
  for (let i = 0; i < nEdges; i++) {
@@ -36609,6 +36814,7 @@ function orthoEdges(g, useLbls, clipAndInstall2) {
36609
36814
  }
36610
36815
  }
36611
36816
  freeMaze(mp);
36817
+ return 0;
36612
36818
  }
36613
36819
 
36614
36820
  // src/layout/dot/ortho-adapter.ts
@@ -36636,7 +36842,6 @@ function buildEdges(g, nodeArr, orthoNodes) {
36636
36842
  const oes = outIndex.get(n);
36637
36843
  if (oes === void 0) continue;
36638
36844
  for (const e of oes) {
36639
- if (e.tail === e.head) continue;
36640
36845
  if (concentrate) {
36641
36846
  const ti = e.tail.id;
36642
36847
  const hi = e.head.id;
@@ -36680,7 +36885,7 @@ function installOrthoResult(oe, pts) {
36680
36885
  clipAndInstall(origEdge, origEdge.head, pts, pts.length, ORTHO_SINFO);
36681
36886
  }
36682
36887
  function dispatchOrthoEdges(g, useLbls) {
36683
- orthoEdges(
36888
+ return orthoEdges(
36684
36889
  buildOrthoGraph(g),
36685
36890
  useLbls,
36686
36891
  (_og, oe, pts) => installOrthoResult(oe, pts)
@@ -37217,12 +37422,12 @@ function resetRW(g) {
37217
37422
  }
37218
37423
  function orthoDispatch(g) {
37219
37424
  resetRW(g);
37425
+ let rc;
37220
37426
  if (((g.root.info.has_labels ?? 0) & EDGE_LABEL) !== 0) {
37221
37427
  setEdgeLabelPos(g);
37222
- dispatchOrthoEdges(g, true);
37223
- } else {
37224
- dispatchOrthoEdges(g, false);
37225
- }
37428
+ rc = dispatchOrthoEdges(g, true);
37429
+ } else rc = dispatchOrthoEdges(g, false);
37430
+ if (rc !== 0) return rc;
37226
37431
  placePortLabels(g);
37227
37432
  g.info.edgeLabelsDone = true;
37228
37433
  return 0;
@@ -37878,7 +38083,7 @@ function computeStep2(bbs, margin) {
37878
38083
  c -= W * H;
37879
38084
  }
37880
38085
  const r = Math.sqrt(b * b - 4 * a * c);
37881
- const root = Math.trunc((-b + r) / (2 * a));
38086
+ const root = d2i((-b + r) / (2 * a));
37882
38087
  return root === 0 ? 1 : root;
37883
38088
  }
37884
38089
  function lineXDominant(st, ps) {
@@ -38024,7 +38229,7 @@ function fits2(x, y, info, ctx) {
38024
38229
  }
38025
38230
  const bb = ctx.bbs[info.index];
38026
38231
  const LL = { x: cround(bb.ll.x), y: cround(bb.ll.y) };
38027
- ctx.places[info.index] = { x: ctx.step * x - LL.x, y: ctx.step * y - LL.y };
38232
+ ctx.places[info.index] = { x: Math.imul(ctx.step, x) - LL.x, y: Math.imul(ctx.step, y) - LL.y };
38028
38233
  for (const c of info.cells) ctx.ps.add(c.x + x, c.y + y);
38029
38234
  return true;
38030
38235
  }
@@ -38510,7 +38715,7 @@ function dotLayoutComponent(sg, root) {
38510
38715
  dotRank(sg);
38511
38716
  dotMincross(sg);
38512
38717
  dotPosition(sg);
38513
- dotPhasePostNoFinish(sg);
38718
+ return dotPhasePostNoFinish(sg);
38514
38719
  }
38515
38720
  function mapClust(clone, origOf) {
38516
38721
  const orig = origOf.get(clone);
@@ -38596,7 +38801,9 @@ function packComponentsClusterAware(root, comps, pinfo) {
38596
38801
  }
38597
38802
  function layoutAndPack(root, comps, pinfo, origOf) {
38598
38803
  dotGraphInit(root);
38599
- for (const sg of comps) dotLayoutComponent(sg, root);
38804
+ for (const sg of comps) {
38805
+ if (dotLayoutComponent(sg, root) !== 0) return;
38806
+ }
38600
38807
  packComponentsClusterAware(root, comps, pinfo);
38601
38808
  copyClusterInfo(comps, root, origOf);
38602
38809
  expandRootBbForClusters(root);
@@ -38628,11 +38835,13 @@ function dotPhaseInit(g) {
38628
38835
  function dotPhasePostNoFinish(g) {
38629
38836
  removeFill(g);
38630
38837
  dotSameports(g);
38631
- dotSplines(g);
38838
+ const r = dotSplines(g);
38839
+ if (r !== 0) return r;
38632
38840
  if (mapbool2(g.attrs.get("compound") ?? g.root.attrs.get("compound"))) dotCompoundEdges(g);
38841
+ return 0;
38633
38842
  }
38634
38843
  function dotPhasePost(g) {
38635
- dotPhasePostNoFinish(g);
38844
+ if (dotPhasePostNoFinish(g) !== 0) return;
38636
38845
  gvPostprocess(g);
38637
38846
  }
38638
38847
  function graphPhase(g) {
@@ -41518,10 +41727,10 @@ function raySegIntersect(v, w, a, b) {
41518
41727
  const mv = { x: w.x - v.x, y: w.y - v.y };
41519
41728
  const lv = { x: b.x - a.x, y: b.y - a.y };
41520
41729
  const ln = { x: -lv.y, y: lv.x };
41521
- const lc = -(ln.x * a.x + ln.y * a.y);
41522
- const dt = ln.x * mv.x + ln.y * mv.y;
41730
+ const lc = -fma(ln.x, a.x, ln.y * a.y);
41731
+ const dt = fma(ln.x, mv.x, ln.y * mv.y);
41523
41732
  if (Math.abs(dt) < SMALL3) return null;
41524
- const s = (ln.x * v.x + ln.y * v.y + lc) / dt;
41733
+ const s = (fma(ln.x, v.x, ln.y * v.y) + lc) / dt;
41525
41734
  return { x: v.x - s * mv.x, y: v.y - s * mv.y };
41526
41735
  }
41527
41736
  function triPoint(trip, vx, v, w) {
@@ -41539,36 +41748,44 @@ function ctrlPtIdx(v, ps) {
41539
41748
  return -1;
41540
41749
  }
41541
41750
  var SEP = 15;
41751
+ function bisectorTarget(v, cosTheta, sinTheta) {
41752
+ return { x: fma(cosTheta, 100, v.x), y: fma(sinTheta, 100, v.y) };
41753
+ }
41754
+ function distFused(p, q) {
41755
+ const dx = p.x - q.x;
41756
+ const dy = p.y - q.y;
41757
+ return Math.sqrt(fma(dx, dx, dy * dy));
41758
+ }
41542
41759
  function mkCtrlPts(s, mult, prev, v, nxt, trip) {
41543
41760
  const idx = ctrlPtIdx(v, trip.ps);
41544
41761
  if (idx < 0) return null;
41545
41762
  const theta = bisect(prev, v, nxt);
41546
41763
  let sinTheta = Math.sin(theta);
41547
41764
  let cosTheta = Math.cos(theta);
41548
- let w = { x: v.x + 100 * cosTheta, y: v.y + 100 * sinTheta };
41765
+ let w = bisectorTarget(v, cosTheta, sinTheta);
41549
41766
  if (idx > s) {
41550
41767
  if (wind(prev, v, w) !== 1) {
41551
41768
  sinTheta *= -1;
41552
41769
  cosTheta *= -1;
41553
- w = { x: v.x + 100 * cosTheta, y: v.y + 100 * sinTheta };
41770
+ w = bisectorTarget(v, cosTheta, sinTheta);
41554
41771
  }
41555
41772
  } else if (wind(prev, v, w) !== -1) {
41556
41773
  sinTheta *= -1;
41557
41774
  cosTheta *= -1;
41558
- w = { x: v.x + 100 * cosTheta, y: v.y + 100 * sinTheta };
41775
+ w = bisectorTarget(v, cosTheta, sinTheta);
41559
41776
  }
41560
41777
  const q = triPoint(trip, idx, v, w);
41561
41778
  if (q === null) return null;
41562
- const d = Math.hypot(q.x - v.x, q.y - v.y);
41779
+ const d = distFused(q, v);
41563
41780
  const sep = d >= mult * SEP ? SEP : d / mult;
41564
41781
  const ps = new Array(mult);
41565
41782
  if (idx < s) {
41566
41783
  for (let i = 0; i < mult; i++) {
41567
- ps[i] = { x: v.x + i * sep * cosTheta, y: v.y + i * sep * sinTheta };
41784
+ ps[i] = { x: fma(i * sep, cosTheta, v.x), y: fma(i * sep, sinTheta, v.y) };
41568
41785
  }
41569
41786
  } else {
41570
41787
  for (let i = 0; i < mult; i++) {
41571
- ps[mult - i - 1] = { x: v.x + i * sep * cosTheta, y: v.y + i * sep * sinTheta };
41788
+ ps[mult - i - 1] = { x: fma(i * sep, cosTheta, v.x), y: fma(i * sep, sinTheta, v.y) };
41572
41789
  }
41573
41790
  }
41574
41791
  return ps;
@@ -42002,7 +42219,7 @@ var ObstacleHelper = class {
42002
42219
  };
42003
42220
  function ellipseTangentSlope(a, b, p) {
42004
42221
  const signY = p.y >= 0 ? 1 : -1;
42005
- return -signY * (b * p.x) / (a * Math.sqrt(a * a - p.x * p.x));
42222
+ return -signY * (b * p.x) / (a * Math.sqrt(fma(a, a, -(p.x * p.x))));
42006
42223
  }
42007
42224
  function circumscribedCorner(a, b, i, nsides) {
42008
42225
  const angle0 = 2 * Math.PI * (i - 0.5) / nsides;
@@ -42011,8 +42228,8 @@ function circumscribedCorner(a, b, i, nsides) {
42011
42228
  const p1 = { x: a * Math.cos(angle1), y: b * Math.sin(angle1) };
42012
42229
  const m0 = ellipseTangentSlope(a, b, p0);
42013
42230
  const m1 = ellipseTangentSlope(a, b, p1);
42014
- const x = (m0 * p0.x - p0.y - m1 * p1.x + p1.y) / (m0 - m1);
42015
- const y = p0.y + m0 * (x - p0.x);
42231
+ const x = (fms(p1.x, m1, fma(m0, p0.x, -p0.y)) + p1.y) / (m0 - m1);
42232
+ const y = fma(m0, x - p0.x, p0.y);
42016
42233
  return { x, y };
42017
42234
  }
42018
42235
  function boxCornerMargin(j, m) {
@@ -46089,8 +46306,8 @@ function initItem(n, margin) {
46089
46306
  let w2;
46090
46307
  let h2;
46091
46308
  if (margin.doAdd) {
46092
- w2 = Math.trunc(SCALE * (cround(width / 2 * POINTS_PER_INCH6) + margin.x));
46093
- h2 = Math.trunc(SCALE * (cround(height / 2 * POINTS_PER_INCH6) + margin.y));
46309
+ w2 = d2i(SCALE * (cround(width / 2 * POINTS_PER_INCH6) + margin.x));
46310
+ h2 = d2i(SCALE * (cround(height / 2 * POINTS_PER_INCH6) + margin.y));
46094
46311
  } else {
46095
46312
  w2 = cround(margin.x * SCALE2 * width * POINTS_PER_INCH6);
46096
46313
  h2 = cround(margin.y * SCALE2 * height * POINTS_PER_INCH6);
@@ -48189,11 +48406,11 @@ function addClusters(g) {
48189
48406
  g.info.clust = clusters;
48190
48407
  g.info.n_cluster = clusters.length;
48191
48408
  }
48192
- function layoutComponents(g, comps, solve2, pinned) {
48409
+ function layoutComponents(g, comps, solve4, pinned) {
48193
48410
  for (const gc of comps) {
48194
48411
  setEdgeTypeFromAttr(gc, EDGETYPE_LINE);
48195
- solveModel2(gc, solve2.mode, solve2.model);
48196
- maybeRemoveOverlap(gc, solve2.am);
48412
+ solveModel2(gc, solve4.mode, solve4.model);
48413
+ maybeRemoveOverlap(gc, solve4.am);
48197
48414
  splineEdgesShifted(gc);
48198
48415
  }
48199
48416
  const pinfo = {
@@ -50098,6 +50315,20 @@ function powerLawGraph(A3) {
50098
50315
  }
50099
50316
  return mask[1] > 0.8 * max && mask[1] > 0.3 * m;
50100
50317
  }
50318
+ var PCP_COVARIANCE_LANES = 4;
50319
+ function pcpCovariance(n, dim, x, y) {
50320
+ const nUnfused = n - n % PCP_COVARIANCE_LANES;
50321
+ for (let i = 0; i < n; i++) {
50322
+ for (let k = 0; k < dim; k++) {
50323
+ for (let l = 0; l < dim; l++) {
50324
+ const a = x[i * dim + k];
50325
+ const b = x[i * dim + l];
50326
+ const acc = y[dim * k + l];
50327
+ y[dim * k + l] = i < nUnfused ? acc + a * b : fma(a, b, acc);
50328
+ }
50329
+ }
50330
+ }
50331
+ }
50101
50332
  function pcpRotate(n, dim, x) {
50102
50333
  const y = [0, 0, 0, 0];
50103
50334
  const center = [0, 0];
@@ -50108,24 +50339,23 @@ function pcpRotate(n, dim, x) {
50108
50339
  for (let i = 0; i < n; i++) {
50109
50340
  for (let k = 0; k < dim; k++) x[dim * i + k] -= center[k];
50110
50341
  }
50111
- for (let i = 0; i < n; i++) {
50112
- for (let k = 0; k < dim; k++) {
50113
- for (let l = 0; l < dim; l++) {
50114
- y[dim * k + l] = fma(x[i * dim + k], x[i * dim + l], y[dim * k + l]);
50115
- }
50116
- }
50117
- }
50342
+ pcpCovariance(n, dim, x, y);
50118
50343
  const axis = [0, 1];
50119
50344
  if (y[1] !== 0) {
50120
- axis[0] = -(-y[0] + y[3] - Math.sqrt(y[0] * y[0] + 4 * y[1] * y[1] - 2 * y[0] * y[3] + y[3] * y[3])) / (2 * y[1]);
50345
+ const radicand = fma(
50346
+ y[3],
50347
+ y[3],
50348
+ fma(-2 * y[0], y[3], fma(y[0], y[0], 4 * y[1] * y[1]))
50349
+ );
50350
+ axis[0] = -(-y[0] + y[3] - Math.sqrt(radicand)) / (2 * y[1]);
50121
50351
  axis[1] = 1;
50122
50352
  }
50123
- const dist4 = Math.sqrt(1 + axis[0] * axis[0]);
50353
+ const dist4 = Math.sqrt(fma(axis[0], axis[0], 1));
50124
50354
  axis[0] = axis[0] / dist4;
50125
50355
  axis[1] = axis[1] / dist4;
50126
50356
  for (let i = 0; i < n; i++) {
50127
- const x0 = x[dim * i] * axis[0] + x[dim * i + 1] * axis[1];
50128
- const x1 = -x[dim * i] * axis[1] + x[dim * i + 1] * axis[0];
50357
+ const x0 = fma(x[dim * i], axis[0], x[dim * i + 1] * axis[1]);
50358
+ const x1 = fma(-x[dim * i], axis[1], x[dim * i + 1] * axis[0]);
50129
50359
  x[dim * i] = x0;
50130
50360
  x[dim * i + 1] = x1;
50131
50361
  }
@@ -50388,16 +50618,7 @@ function makeCData(dn) {
50388
50618
  };
50389
50619
  }
50390
50620
 
50391
- // src/layout/circo/blockpath.ts
50392
- function blockGraph(allEdges3, sn) {
50393
- const ns = new Set(sn.subGraph.nodes);
50394
- for (const n of sn.subGraph.nodes) {
50395
- for (const e of allEdges3) {
50396
- if (e.tail === n && ns.has(e.head) && !sn.subGraph.edges.includes(e))
50397
- sn.subGraph.edges.push(e);
50398
- }
50399
- }
50400
- }
50621
+ // src/layout/circo/crossings.ts
50401
50622
  function derivedOf(n) {
50402
50623
  return n.info.alg?.derivedNode ?? null;
50403
50624
  }
@@ -50408,27 +50629,51 @@ function closeOpenEdge(e, d, opened) {
50408
50629
  }
50409
50630
  return cross2;
50410
50631
  }
50411
- function openEdgesAt(d, edges, opened, order) {
50632
+ function agfstedgeLists(edges) {
50633
+ const seq2 = /* @__PURE__ */ new Map();
50634
+ edges.forEach((e, i) => seq2.set(e, i));
50635
+ const by = (end) => (a, b) => end(a).orig.id - end(b).orig.id || seq2.get(a) - seq2.get(b);
50636
+ const out = /* @__PURE__ */ new Map();
50637
+ const inn = /* @__PURE__ */ new Map();
50412
50638
  for (const e of edges) {
50413
- if (e.order === 0 && (e.tail === d || e.head === d)) {
50414
- e.order = order;
50415
- opened.push(e);
50416
- }
50639
+ out.set(e.tail, [...out.get(e.tail) ?? [], e]);
50640
+ inn.set(e.head, [...inn.get(e.head) ?? [], e]);
50641
+ }
50642
+ const lists = /* @__PURE__ */ new Map();
50643
+ for (const d of /* @__PURE__ */ new Set([...out.keys(), ...inn.keys()])) {
50644
+ const o = (out.get(d) ?? []).sort(by((e) => e.head));
50645
+ const i = (inn.get(d) ?? []).sort(by((e) => e.tail));
50646
+ lists.set(d, [...o, ...i]);
50417
50647
  }
50648
+ return lists;
50418
50649
  }
50419
50650
  function countCrossings(list, edges) {
50420
50651
  for (const e of edges) e.order = 0;
50421
- const opened = [];
50652
+ const incident = agfstedgeLists(edges);
50653
+ const opened = /* @__PURE__ */ new Map();
50422
50654
  let crossings = 0;
50423
50655
  let order = 1;
50424
50656
  for (const n of list) {
50425
50657
  const d = derivedOf(n);
50426
50658
  if (!d) continue;
50427
- for (const e of edges) {
50428
- if (e.order > 0 && (e.tail === d || e.head === d))
50429
- crossings += closeOpenEdge(e, d, opened);
50659
+ const es = incident.get(d) ?? [];
50660
+ crossings += closeEdgesAt(d, es, opened);
50661
+ for (const e of es) {
50662
+ if (e.order === 0) {
50663
+ e.order = order;
50664
+ opened.set(e, d);
50665
+ }
50430
50666
  }
50431
- openEdgesAt(d, edges, opened, order++);
50667
+ order++;
50668
+ }
50669
+ return crossings;
50670
+ }
50671
+ function closeEdgesAt(d, es, opened) {
50672
+ let crossings = 0;
50673
+ for (const e of es) {
50674
+ if (e.order === 0) continue;
50675
+ crossings += closeOpenEdge(e, d, opened.keys());
50676
+ if (opened.get(e) === d) opened.delete(e);
50432
50677
  }
50433
50678
  return crossings;
50434
50679
  }
@@ -50481,6 +50726,17 @@ function spanIncident(dn, edges, ord, seq2) {
50481
50726
  const inn = edges.filter((e) => e.head === dn).sort((a, b) => (ord.get(a.tail) ?? 0) - (ord.get(b.tail) ?? 0) || (seq2.get(a) ?? 0) - (seq2.get(b) ?? 0));
50482
50727
  return [...out, ...inn];
50483
50728
  }
50729
+
50730
+ // src/layout/circo/blockpath.ts
50731
+ function blockGraph(allEdges3, sn) {
50732
+ const ns = new Set(sn.subGraph.nodes);
50733
+ for (const n of sn.subGraph.nodes) {
50734
+ for (const e of allEdges3) {
50735
+ if (e.tail === n && ns.has(e.head) && !sn.subGraph.edges.includes(e))
50736
+ sn.subGraph.edges.push(e);
50737
+ }
50738
+ }
50739
+ }
50484
50740
  function dfsSpan(sn, map, edges, ord, seq2) {
50485
50741
  sn.visited = true;
50486
50742
  for (const e of spanIncident(sn.dn, edges, ord, seq2)) {
@@ -51959,17 +52215,30 @@ function renderEdgeLabels(e, renderer, job) {
51959
52215
  }
51960
52216
  function emitEdgeLabel(lp, id, hs, renderer, job, spl, emitState) {
51961
52217
  if (!lp?.set) return;
51962
- const open = hs.url !== null || hs.explicit;
51963
- if (open) openAnchorWith(renderer, job, hs.url, hs.tooltip, hs.target, id);
51964
- const savedOverride = job.labelEmitOverride;
51965
- if (emitState !== void 0) job.labelEmitOverride = emitState;
51966
- try {
51967
- renderOneLabel(lp, renderer, job);
51968
- } finally {
51969
- job.labelEmitOverride = savedOverride;
52218
+ withObjEmitState(job, emitState ?? 11 /* ELabel */, () => {
52219
+ const open = hs.url !== null || hs.explicit;
52220
+ if (open) openAnchorWith(renderer, job, hs.url, hs.tooltip, hs.target, id);
52221
+ const savedOverride = job.labelEmitOverride;
52222
+ if (emitState !== void 0) job.labelEmitOverride = emitState;
52223
+ try {
52224
+ renderOneLabel(lp, renderer, job);
52225
+ } finally {
52226
+ job.labelEmitOverride = savedOverride;
52227
+ }
52228
+ if (spl) emitAttachment(lp, spl, renderer, job);
52229
+ if (open) renderer.endAnchor?.(job);
52230
+ });
52231
+ }
52232
+ function withObjEmitState(job, lkind, fn) {
52233
+ const obj = job.obj;
52234
+ if (obj === null) {
52235
+ fn();
52236
+ return;
51970
52237
  }
51971
- if (spl) emitAttachment(lp, spl, renderer, job);
51972
- if (open) renderer.endAnchor?.(job);
52238
+ const oldEmitState = obj.emitState;
52239
+ obj.emitState = lkind;
52240
+ fn();
52241
+ obj.emitState = oldEmitState;
51973
52242
  }
51974
52243
  function emitAttachment(lp, spl, renderer, job) {
51975
52244
  if (!lp?.set) return;
@@ -53555,6 +53824,7 @@ var DotWriterBase = class {
53555
53824
 
53556
53825
  // src/render/dot/edge-draw.ts
53557
53826
  var DEFAULT_COLOR5 = "black";
53827
+ var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
53558
53828
  function emitArrowOp(buf, op, pen) {
53559
53829
  switch (op.kind) {
53560
53830
  case "polygon":
@@ -53578,6 +53848,25 @@ function emitArrowOp(buf, op, pen) {
53578
53848
  var EdgeDrawBase = class extends DotWriterBase {
53579
53849
  /** setlinewidth state per emit_state. @see gvrender_core_dot.c penwidth[] */
53580
53850
  penwidth = new Array(12).fill(1);
53851
+ /**
53852
+ * emit_attachment's draw calls (decorate=true): gvrender_set_style with the
53853
+ * default line style sets the obj's rawstyle/pen/penwidth (setlinewidth 1),
53854
+ * gvrender_set_pencolor sets the pen to the label fontcolor (first entry of
53855
+ * a color list), then gvrender_polyline → xdot_polyline emits the style ops
53856
+ * (`S 5 -solid`; setlinewidth is filtered), the pen color and `L 3`.
53857
+ * @see lib/common/emit.c:emit_attachment (1886-1893)
53858
+ * @see lib/gvc/gvrender.c:gvrender_set_style / gvrender_set_pencolor
53859
+ */
53860
+ attachmentPolyline(pts, pencolor, job) {
53861
+ const obj = job.obj;
53862
+ if (obj !== null) {
53863
+ obj.rawStyle = [...DEFAULT_LINE_STYLE];
53864
+ obj.pen = 3 /* Solid */;
53865
+ obj.penWidth = 1;
53866
+ obj.penColor = resolveRenderColor(pencolor.split(":")[0]);
53867
+ }
53868
+ this.polyline(pts, job);
53869
+ }
53581
53870
  /**
53582
53871
  * The plain single-colour spline branch of beginEdge — lifted verbatim so the
53583
53872
  * four-way spline-kind chain above stays readable; no branch was reordered or
@@ -54117,19 +54406,6 @@ function emitMulticolorArrows(e, job, headColor, tailColor) {
54117
54406
  emitArrowOps(headOps, headColor, job, pw, colorOpacity(resolveRenderColor(headColor)));
54118
54407
  }
54119
54408
  }
54120
- function overlapLabel(lp, b) {
54121
- const sx = lp.dimen.x / 2;
54122
- const sy = lp.dimen.y / 2;
54123
- const bb = {
54124
- ll: { x: lp.pos.x - sx, y: lp.pos.y - sy },
54125
- ur: { x: lp.pos.x + sx, y: lp.pos.y + sy }
54126
- };
54127
- return boxOverlap(b, bb);
54128
- }
54129
- function edgeHasDrawableContent(e, clip) {
54130
- const i = e.info;
54131
- return i.spl !== void 0 || i.label !== void 0 && i.label.set && overlapLabel(i.label, clip) || i.xlabel !== void 0 || i.head_label !== void 0 || i.tail_label !== void 0;
54132
- }
54133
54409
  var SvgRenderer = class {
54134
54410
  type = "svg";
54135
54411
  /** @see plugin/core/gvplugin_core.c registration table */
@@ -54286,6 +54562,7 @@ function createSvgRenderer() {
54286
54562
  var XDOT_PARSE_ERROR = 1;
54287
54563
 
54288
54564
  // src/xdot/parse.ts
54565
+ var ULONG_MAX = 0xffffffffffffffffn;
54289
54566
  var XdotParser = class _XdotParser {
54290
54567
  static isWs(c) {
54291
54568
  return c === " " || c === " " || c === "\n" || c === "\r";
@@ -54329,12 +54606,23 @@ var XdotParser = class _XdotParser {
54329
54606
  if (i === digStart) return null;
54330
54607
  return { val: parseInt(s.slice(start, i), 10), pos: i };
54331
54608
  }
54609
+ /**
54610
+ * strtoul(s, &endp, 10) cast to unsigned int: optional sign, a leading "-"
54611
+ * negates modulo 2^64, magnitude overflow saturates to ULONG_MAX, and the
54612
+ * result keeps the low 32 bits.
54613
+ * @see lib/xdot/xdot.c:parseUInt
54614
+ */
54332
54615
  static parseUInt_(s, pos) {
54333
54616
  const i = _XdotParser.skipWs(s, pos);
54334
- const start = i;
54335
- const end = _XdotParser.consumeDigits(s, i);
54617
+ let start = i;
54618
+ const negative = i < s.length && s[i] === "-";
54619
+ if (i < s.length && (s[i] === "-" || s[i] === "+")) start++;
54620
+ const end = _XdotParser.consumeDigits(s, start);
54336
54621
  if (end === start) return null;
54337
- return { val: parseInt(s.slice(start, end), 10), pos: end };
54622
+ const mag = BigInt(s.slice(start, end));
54623
+ const clamped = mag > ULONG_MAX ? ULONG_MAX : mag;
54624
+ const wrapped = negative && mag <= ULONG_MAX ? BigInt.asUintN(64, -clamped) : clamped;
54625
+ return { val: Number(BigInt.asUintN(32, wrapped)), pos: end };
54338
54626
  }
54339
54627
  static parseRect(s, pos) {
54340
54628
  const rx = _XdotParser.parseReal(s, pos);
@@ -54431,7 +54719,7 @@ var XdotParser = class _XdotParser {
54431
54719
  if (!rx1) return null;
54432
54720
  const ry1 = _XdotParser.parseReal(s, rx1.pos);
54433
54721
  if (!ry1) return null;
54434
- const rn = _XdotParser.parseInt_(s, ry1.pos);
54722
+ const rn = _XdotParser.parseUInt_(s, ry1.pos);
54435
54723
  if (!rn) return null;
54436
54724
  const rs = _XdotParser.parseStops(s, rn.pos, rn.val);
54437
54725
  if (!rs) return null;
@@ -54450,7 +54738,7 @@ var XdotParser = class _XdotParser {
54450
54738
  if (!ry1) return null;
54451
54739
  const rr1 = _XdotParser.parseReal(s, ry1.pos);
54452
54740
  if (!rr1) return null;
54453
- const rn = _XdotParser.parseInt_(s, rr1.pos);
54741
+ const rn = _XdotParser.parseUInt_(s, rr1.pos);
54454
54742
  if (!rn) return null;
54455
54743
  const rs = _XdotParser.parseStops(s, rn.pos, rn.val);
54456
54744
  if (!rs) return null;