@knowvah/dot-engine 2.6.4 → 2.6.6

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 (93) hide show
  1. package/dist/common/arrows-shapes-poly.d.ts.map +1 -1
  2. package/dist/common/bezier.d.ts +12 -0
  3. package/dist/common/bezier.d.ts.map +1 -0
  4. package/dist/common/htmltable-attr-warn.d.ts +41 -0
  5. package/dist/common/htmltable-attr-warn.d.ts.map +1 -0
  6. package/dist/common/htmltable-fontinfo.d.ts +42 -0
  7. package/dist/common/htmltable-fontinfo.d.ts.map +1 -0
  8. package/dist/common/htmltable-lex-expat.d.ts +63 -0
  9. package/dist/common/htmltable-lex-expat.d.ts.map +1 -0
  10. package/dist/common/htmltable-lex-units.d.ts +32 -0
  11. package/dist/common/htmltable-lex-units.d.ts.map +1 -0
  12. package/dist/common/htmltable-lex.d.ts +10 -2
  13. package/dist/common/htmltable-lex.d.ts.map +1 -1
  14. package/dist/common/htmltable-parse-attrs.d.ts +7 -5
  15. package/dist/common/htmltable-parse-attrs.d.ts.map +1 -1
  16. package/dist/common/htmltable-parse-font.d.ts +33 -0
  17. package/dist/common/htmltable-parse-font.d.ts.map +1 -0
  18. package/dist/common/htmltable-parse-state.d.ts +39 -0
  19. package/dist/common/htmltable-parse-state.d.ts.map +1 -0
  20. package/dist/common/htmltable-parse.d.ts +18 -23
  21. package/dist/common/htmltable-parse.d.ts.map +1 -1
  22. package/dist/common/htmltable-pos.d.ts.map +1 -1
  23. package/dist/common/htmltable-types.d.ts +33 -3
  24. package/dist/common/htmltable-types.d.ts.map +1 -1
  25. package/dist/common/htmltable.d.ts +3 -2
  26. package/dist/common/htmltable.d.ts.map +1 -1
  27. package/dist/common/spline-midpoint.d.ts.map +1 -1
  28. package/dist/common/splines-geom.d.ts +5 -6
  29. package/dist/common/splines-geom.d.ts.map +1 -1
  30. package/dist/common/splines-routespl.d.ts.map +1 -1
  31. package/dist/common/taper.d.ts.map +1 -1
  32. package/dist/gvc/anchor.d.ts.map +1 -1
  33. package/dist/index.js +1536 -786
  34. package/dist/index.js.map +4 -4
  35. package/dist/layout/dot/compound-clip.d.ts +5 -5
  36. package/dist/layout/dot/compound-clip.d.ts.map +1 -1
  37. package/dist/layout/dot/compound-geom.d.ts +2 -7
  38. package/dist/layout/dot/compound-geom.d.ts.map +1 -1
  39. package/dist/layout/dot/compound.d.ts +1 -1
  40. package/dist/layout/dot/compound.d.ts.map +1 -1
  41. package/dist/layout/dot/edge-route-clip.d.ts +1 -1
  42. package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
  43. package/dist/layout/dot/ortho-adapter.d.ts +13 -4
  44. package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
  45. package/dist/layout/dot/splines-label.d.ts.map +1 -1
  46. package/dist/layout/neato/bfs.d.ts +10 -3
  47. package/dist/layout/neato/bfs.d.ts.map +1 -1
  48. package/dist/layout/neato/init.d.ts +6 -11
  49. package/dist/layout/neato/init.d.ts.map +1 -1
  50. package/dist/layout/neato/splines.d.ts.map +1 -1
  51. package/dist/parser/ast.d.ts +2 -0
  52. package/dist/parser/ast.d.ts.map +1 -1
  53. package/dist/parser/index.d.ts.map +1 -1
  54. package/dist/parser/scan-token.d.ts +40 -0
  55. package/dist/parser/scan-token.d.ts.map +1 -0
  56. package/dist/render/svg-edge-split.d.ts.map +1 -1
  57. package/dist/render.js +1558 -808
  58. package/dist/render.js.map +4 -4
  59. package/package.json +1 -1
  60. package/src/common/arrows-shapes-poly.ts +9 -10
  61. package/src/common/bezier.ts +33 -0
  62. package/src/common/htmltable-attr-warn.ts +270 -0
  63. package/src/common/htmltable-fontinfo.ts +83 -0
  64. package/src/common/htmltable-lex-expat.ts +357 -0
  65. package/src/common/htmltable-lex-units.ts +75 -0
  66. package/src/common/htmltable-lex.ts +221 -160
  67. package/src/common/htmltable-parse-attrs.ts +10 -14
  68. package/src/common/htmltable-parse-font.ts +92 -0
  69. package/src/common/htmltable-parse-state.ts +64 -0
  70. package/src/common/htmltable-parse.ts +138 -98
  71. package/src/common/htmltable-pos.ts +9 -8
  72. package/src/common/htmltable-types.ts +35 -3
  73. package/src/common/htmltable.ts +14 -7
  74. package/src/common/spline-midpoint.ts +2 -22
  75. package/src/common/splines-geom.ts +5 -25
  76. package/src/common/splines-routespl.ts +21 -13
  77. package/src/common/taper.ts +2 -14
  78. package/src/gvc/anchor.ts +5 -14
  79. package/src/layout/dot/compound-clip.ts +9 -19
  80. package/src/layout/dot/compound-geom.ts +6 -23
  81. package/src/layout/dot/compound.ts +1 -1
  82. package/src/layout/dot/edge-route-clip.ts +6 -29
  83. package/src/layout/dot/ortho-adapter.ts +5 -5
  84. package/src/layout/dot/splines-label.ts +3 -29
  85. package/src/layout/neato/bfs.ts +13 -4
  86. package/src/layout/neato/init.ts +15 -15
  87. package/src/layout/neato/splines.ts +4 -8
  88. package/src/parser/ast.ts +2 -0
  89. package/src/parser/dot.js +168 -137
  90. package/src/parser/dot.pegjs +13 -3
  91. package/src/parser/index.ts +17 -2
  92. package/src/parser/scan-token.ts +289 -0
  93. package/src/render/svg-edge-split.ts +5 -13
package/dist/index.js CHANGED
@@ -155,21 +155,21 @@ function peg$parse(input, options) {
155
155
  const peg$r22 = /^[^\n]/;
156
156
  const peg$e0 = peg$literalExpectation("{", false);
157
157
  const peg$e1 = peg$literalExpectation("}", false);
158
- const peg$e2 = 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);
163
- const peg$e7 = peg$literalExpectation(":", false);
164
- const peg$e8 = peg$otherExpectation("edge operator");
165
- const peg$e9 = peg$literalExpectation("->", false);
166
- const peg$e10 = peg$literalExpectation("--", false);
167
- const peg$e11 = peg$literalExpectation("+", false);
168
- const peg$e12 = peg$literalExpectation('"', false);
169
- const peg$e13 = peg$literalExpectation('\\"', false);
170
- const peg$e14 = peg$literalExpectation("\\\n", false);
171
- const peg$e15 = peg$literalExpectation("\\", false);
172
- const peg$e16 = peg$anyExpectation();
158
+ const peg$e2 = peg$anyExpectation();
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$literalExpectation("]", false);
163
+ const peg$e7 = peg$classExpectation([";", ","], false, false, false);
164
+ const peg$e8 = peg$literalExpectation(":", false);
165
+ const peg$e9 = peg$otherExpectation("edge operator");
166
+ const peg$e10 = peg$literalExpectation("->", false);
167
+ const peg$e11 = peg$literalExpectation("--", false);
168
+ const peg$e12 = peg$literalExpectation("+", false);
169
+ const peg$e13 = peg$literalExpectation('"', false);
170
+ const peg$e14 = peg$literalExpectation('\\"', false);
171
+ const peg$e15 = peg$literalExpectation("\\\n", false);
172
+ const peg$e16 = peg$literalExpectation("\\", false);
173
173
  const peg$e17 = peg$classExpectation(['"', "\\"], true, false, false);
174
174
  const peg$e18 = peg$literalExpectation("<", false);
175
175
  const peg$e19 = peg$literalExpectation(">", false);
@@ -201,86 +201,90 @@ function peg$parse(input, options) {
201
201
  const peg$e45 = peg$classExpectation(["\n"], true, false, false);
202
202
  const peg$e46 = peg$literalExpectation("\n", false);
203
203
  const peg$e47 = peg$literalExpectation("#", false);
204
- function peg$f0(s, t, id, stmts) {
204
+ function peg$f0(s, t, id, stmts, end) {
205
205
  return {
206
206
  type: "graph",
207
207
  strict: s,
208
208
  directed: t,
209
209
  id,
210
- stmts
210
+ stmts,
211
+ end
211
212
  };
212
213
  }
213
214
  function peg$f1() {
214
- return { type: "graph", strict: false, directed: false, id: null, stmts: [] };
215
+ return { type: "graph", strict: false, directed: false, id: null, stmts: [], end: text().length };
215
216
  }
216
217
  function peg$f2() {
217
- return true;
218
+ return offset();
218
219
  }
219
220
  function peg$f3() {
220
- return false;
221
+ return true;
221
222
  }
222
223
  function peg$f4() {
223
- return true;
224
+ return false;
224
225
  }
225
226
  function peg$f5() {
227
+ return true;
228
+ }
229
+ function peg$f6() {
226
230
  return false;
227
231
  }
228
- function peg$f6(a) {
232
+ function peg$f7(a) {
229
233
  return a;
230
234
  }
231
- function peg$f7() {
235
+ function peg$f8() {
232
236
  return null;
233
237
  }
234
- function peg$f8(s) {
238
+ function peg$f9(s) {
235
239
  return s;
236
240
  }
237
- function peg$f9(stmts) {
241
+ function peg$f10(stmts) {
238
242
  return stmts;
239
243
  }
240
- function peg$f10(s) {
244
+ function peg$f11(s) {
241
245
  return s;
242
246
  }
243
- function peg$f11(s) {
247
+ function peg$f12(s) {
244
248
  return s;
245
249
  }
246
- function peg$f12(t, m, attrs) {
250
+ function peg$f13(t, m, attrs) {
247
251
  if (m) console.error("Warning: attribute macros not implemented");
248
252
  return { type: "attr", target: t, attrs };
249
253
  }
250
- function peg$f13(a) {
254
+ function peg$f14(a) {
251
255
  return { type: "assign", key: a.key, value: a.value };
252
256
  }
253
- function peg$f14() {
257
+ function peg$f15() {
254
258
  return true;
255
259
  }
256
- function peg$f15() {
260
+ function peg$f16() {
257
261
  return false;
258
262
  }
259
- function peg$f16() {
263
+ function peg$f17() {
260
264
  return "graph";
261
265
  }
262
- function peg$f17() {
266
+ function peg$f18() {
263
267
  return "node";
264
268
  }
265
- function peg$f18() {
269
+ function peg$f19() {
266
270
  return "edge";
267
271
  }
268
- function peg$f19(defs, rest) {
272
+ function peg$f20(defs, rest) {
269
273
  return defs.concat(rest);
270
274
  }
271
- function peg$f20() {
275
+ function peg$f21() {
272
276
  return [];
273
277
  }
274
- function peg$f21(a) {
278
+ function peg$f22(a) {
275
279
  return a;
276
280
  }
277
- function peg$f22(pairs) {
281
+ function peg$f23(pairs) {
278
282
  return pairs;
279
283
  }
280
- function peg$f23(k, v) {
284
+ function peg$f24(k, v) {
281
285
  return { key: k, value: v };
282
286
  }
283
- function peg$f24(head, chain, attrs) {
287
+ function peg$f25(head, chain, attrs) {
284
288
  if (chain.length > 0) {
285
289
  const nodes = [head].concat(chain);
286
290
  return { type: "edge", nodes, attrs };
@@ -291,70 +295,70 @@ function peg$parse(input, options) {
291
295
  return { type: "node", id: head, attrs };
292
296
  }
293
297
  }
294
- function peg$f25(s) {
298
+ function peg$f26(s) {
295
299
  return s;
296
300
  }
297
- function peg$f26(n) {
301
+ function peg$f27(n) {
298
302
  return n;
299
303
  }
300
- function peg$f27(id, port, compass) {
304
+ function peg$f28(id, port, compass) {
301
305
  return { id, port, compass };
302
306
  }
303
- function peg$f28(id, port) {
307
+ function peg$f29(id, port) {
304
308
  return { id, port, compass: null };
305
309
  }
306
- function peg$f29(id) {
310
+ function peg$f30(id) {
307
311
  return { id, port: null, compass: null };
308
312
  }
309
- function peg$f30(s, rest) {
313
+ function peg$f31(s, rest) {
310
314
  return [s].concat(rest);
311
315
  }
312
- function peg$f31() {
316
+ function peg$f32() {
313
317
  return [];
314
318
  }
315
- function peg$f32(id, stmts) {
319
+ function peg$f33(id, stmts) {
316
320
  return { type: "subgraph", id, stmts };
317
321
  }
318
- function peg$f33(stmts) {
322
+ function peg$f34(stmts) {
319
323
  return { type: "subgraph", id: null, stmts };
320
324
  }
321
- function peg$f34(stmts) {
325
+ function peg$f35(stmts) {
322
326
  return { type: "subgraph", id: null, stmts };
323
327
  }
324
- function peg$f35(first, s) {
328
+ function peg$f36(first, s) {
325
329
  return s;
326
330
  }
327
- function peg$f36(first, rest) {
331
+ function peg$f37(first, rest) {
328
332
  return rest.length > 0 ? first + rest.join("") : first;
329
333
  }
330
- function peg$f37(chars) {
334
+ function peg$f38(chars) {
331
335
  return chars.join("");
332
336
  }
333
- function peg$f38() {
337
+ function peg$f39() {
334
338
  return '"';
335
339
  }
336
- function peg$f39() {
340
+ function peg$f40() {
337
341
  return "";
338
342
  }
339
- function peg$f40(c) {
343
+ function peg$f41(c) {
340
344
  return "\\" + c;
341
345
  }
342
- function peg$f41(content) {
346
+ function peg$f42(content) {
343
347
  return "" + content;
344
348
  }
345
- function peg$f42(chars) {
349
+ function peg$f43(chars) {
346
350
  return chars.join("");
347
351
  }
348
- function peg$f43(nested2, content) {
352
+ function peg$f44(nested2, content) {
349
353
  return "<" + content + ">";
350
354
  }
351
- function peg$f44(n) {
355
+ function peg$f45(n) {
352
356
  return n;
353
357
  }
354
- function peg$f45(first, rest) {
358
+ function peg$f46(first, rest) {
355
359
  return first + rest.join("");
356
360
  }
357
- function peg$f46(s) {
361
+ function peg$f47(s) {
358
362
  return Array.isArray(s) ? s.flat(Infinity).filter((x) => x !== null && x !== void 0).join("") : String(s);
359
363
  }
360
364
  let peg$currPos = options.peg$currPos | 0;
@@ -530,9 +534,9 @@ function peg$parse(input, options) {
530
534
  }
531
535
  }
532
536
  if (s122 !== peg$FAILED) {
533
- s13 = peg$parse_();
537
+ s13 = peg$parseGraphEof();
534
538
  peg$savedPos = s0;
535
- s0 = peg$f0(s2, s4, s6, s10);
539
+ s0 = peg$f0(s2, s4, s6, s10, s13);
536
540
  } else {
537
541
  peg$currPos = s0;
538
542
  s0 = peg$FAILED;
@@ -562,6 +566,36 @@ function peg$parse(input, options) {
562
566
  }
563
567
  return s0;
564
568
  }
569
+ function peg$parseGraphEof() {
570
+ let s0, s12, s2;
571
+ s0 = peg$currPos;
572
+ s12 = [];
573
+ if (input.length > peg$currPos) {
574
+ s2 = input.charAt(peg$currPos);
575
+ peg$currPos++;
576
+ } else {
577
+ s2 = peg$FAILED;
578
+ if (peg$silentFails === 0) {
579
+ peg$fail(peg$e2);
580
+ }
581
+ }
582
+ while (s2 !== peg$FAILED) {
583
+ s12.push(s2);
584
+ if (input.length > peg$currPos) {
585
+ s2 = input.charAt(peg$currPos);
586
+ peg$currPos++;
587
+ } else {
588
+ s2 = peg$FAILED;
589
+ if (peg$silentFails === 0) {
590
+ peg$fail(peg$e2);
591
+ }
592
+ }
593
+ }
594
+ peg$savedPos = s0;
595
+ s12 = peg$f2();
596
+ s0 = s12;
597
+ return s0;
598
+ }
565
599
  function peg$parseOptStrict() {
566
600
  let s0, s12, s2;
567
601
  s0 = peg$currPos;
@@ -569,7 +603,7 @@ function peg$parse(input, options) {
569
603
  if (s12 !== peg$FAILED) {
570
604
  s2 = peg$parse_();
571
605
  peg$savedPos = s0;
572
- s0 = peg$f2();
606
+ s0 = peg$f3();
573
607
  } else {
574
608
  peg$currPos = s0;
575
609
  s0 = peg$FAILED;
@@ -578,7 +612,7 @@ function peg$parse(input, options) {
578
612
  s0 = peg$currPos;
579
613
  s12 = "";
580
614
  peg$savedPos = s0;
581
- s12 = peg$f3();
615
+ s12 = peg$f4();
582
616
  s0 = s12;
583
617
  }
584
618
  return s0;
@@ -589,7 +623,7 @@ function peg$parse(input, options) {
589
623
  s12 = peg$parseDigraphKw();
590
624
  if (s12 !== peg$FAILED) {
591
625
  peg$savedPos = s0;
592
- s12 = peg$f4();
626
+ s12 = peg$f5();
593
627
  }
594
628
  s0 = s12;
595
629
  if (s0 === peg$FAILED) {
@@ -597,7 +631,7 @@ function peg$parse(input, options) {
597
631
  s12 = peg$parseGraphKw();
598
632
  if (s12 !== peg$FAILED) {
599
633
  peg$savedPos = s0;
600
- s12 = peg$f5();
634
+ s12 = peg$f6();
601
635
  }
602
636
  s0 = s12;
603
637
  }
@@ -610,7 +644,7 @@ function peg$parse(input, options) {
610
644
  if (s12 !== peg$FAILED) {
611
645
  s2 = peg$parse_();
612
646
  peg$savedPos = s0;
613
- s0 = peg$f6(s12);
647
+ s0 = peg$f7(s12);
614
648
  } else {
615
649
  peg$currPos = s0;
616
650
  s0 = peg$FAILED;
@@ -619,7 +653,7 @@ function peg$parse(input, options) {
619
653
  s0 = peg$currPos;
620
654
  s12 = "";
621
655
  peg$savedPos = s0;
622
- s12 = peg$f7();
656
+ s12 = peg$f8();
623
657
  s0 = s12;
624
658
  }
625
659
  return s0;
@@ -633,7 +667,7 @@ function peg$parse(input, options) {
633
667
  if (s3 !== peg$FAILED) {
634
668
  s4 = peg$parse_();
635
669
  peg$savedPos = s2;
636
- s2 = peg$f8(s3);
670
+ s2 = peg$f9(s3);
637
671
  } else {
638
672
  peg$currPos = s2;
639
673
  s2 = peg$FAILED;
@@ -645,14 +679,14 @@ function peg$parse(input, options) {
645
679
  if (s3 !== peg$FAILED) {
646
680
  s4 = peg$parse_();
647
681
  peg$savedPos = s2;
648
- s2 = peg$f8(s3);
682
+ s2 = peg$f9(s3);
649
683
  } else {
650
684
  peg$currPos = s2;
651
685
  s2 = peg$FAILED;
652
686
  }
653
687
  }
654
688
  peg$savedPos = s0;
655
- s12 = peg$f9(s12);
689
+ s12 = peg$f10(s12);
656
690
  s0 = s12;
657
691
  return s0;
658
692
  }
@@ -669,7 +703,7 @@ function peg$parse(input, options) {
669
703
  } else {
670
704
  s4 = peg$FAILED;
671
705
  if (peg$silentFails === 0) {
672
- peg$fail(peg$e2);
706
+ peg$fail(peg$e3);
673
707
  }
674
708
  }
675
709
  if (s4 !== peg$FAILED) {
@@ -684,7 +718,7 @@ function peg$parse(input, options) {
684
718
  s3 = null;
685
719
  }
686
720
  peg$savedPos = s0;
687
- s0 = peg$f10(s12);
721
+ s0 = peg$f11(s12);
688
722
  } else {
689
723
  peg$currPos = s0;
690
724
  s0 = peg$FAILED;
@@ -701,7 +735,7 @@ function peg$parse(input, options) {
701
735
  } else {
702
736
  s4 = peg$FAILED;
703
737
  if (peg$silentFails === 0) {
704
- peg$fail(peg$e2);
738
+ peg$fail(peg$e3);
705
739
  }
706
740
  }
707
741
  if (s4 !== peg$FAILED) {
@@ -716,7 +750,7 @@ function peg$parse(input, options) {
716
750
  s3 = null;
717
751
  }
718
752
  peg$savedPos = s0;
719
- s0 = peg$f11(s12);
753
+ s0 = peg$f12(s12);
720
754
  } else {
721
755
  peg$currPos = s0;
722
756
  s0 = peg$FAILED;
@@ -735,7 +769,7 @@ function peg$parse(input, options) {
735
769
  s4 = peg$parseAttrListReq();
736
770
  if (s4 !== peg$FAILED) {
737
771
  peg$savedPos = s0;
738
- s0 = peg$f12(s12, s3, s4);
772
+ s0 = peg$f13(s12, s3, s4);
739
773
  } else {
740
774
  peg$currPos = s0;
741
775
  s0 = peg$FAILED;
@@ -753,7 +787,7 @@ function peg$parse(input, options) {
753
787
  s12 = peg$parseAttrAssignment();
754
788
  if (s12 !== peg$FAILED) {
755
789
  peg$savedPos = s0;
756
- s12 = peg$f13(s12);
790
+ s12 = peg$f14(s12);
757
791
  }
758
792
  s0 = s12;
759
793
  }
@@ -771,13 +805,13 @@ function peg$parse(input, options) {
771
805
  } else {
772
806
  s3 = peg$FAILED;
773
807
  if (peg$silentFails === 0) {
774
- peg$fail(peg$e3);
808
+ peg$fail(peg$e4);
775
809
  }
776
810
  }
777
811
  if (s3 !== peg$FAILED) {
778
812
  s4 = peg$parse_();
779
813
  peg$savedPos = s0;
780
- s0 = peg$f14();
814
+ s0 = peg$f15();
781
815
  } else {
782
816
  peg$currPos = s0;
783
817
  s0 = peg$FAILED;
@@ -790,7 +824,7 @@ function peg$parse(input, options) {
790
824
  s0 = peg$currPos;
791
825
  s12 = "";
792
826
  peg$savedPos = s0;
793
- s12 = peg$f15();
827
+ s12 = peg$f16();
794
828
  s0 = s12;
795
829
  }
796
830
  return s0;
@@ -801,7 +835,7 @@ function peg$parse(input, options) {
801
835
  s12 = peg$parseGraphKw();
802
836
  if (s12 !== peg$FAILED) {
803
837
  peg$savedPos = s0;
804
- s12 = peg$f16();
838
+ s12 = peg$f17();
805
839
  }
806
840
  s0 = s12;
807
841
  if (s0 === peg$FAILED) {
@@ -809,7 +843,7 @@ function peg$parse(input, options) {
809
843
  s12 = peg$parseNodeKw();
810
844
  if (s12 !== peg$FAILED) {
811
845
  peg$savedPos = s0;
812
- s12 = peg$f17();
846
+ s12 = peg$f18();
813
847
  }
814
848
  s0 = s12;
815
849
  if (s0 === peg$FAILED) {
@@ -817,7 +851,7 @@ function peg$parse(input, options) {
817
851
  s12 = peg$parseEdgeKw();
818
852
  if (s12 !== peg$FAILED) {
819
853
  peg$savedPos = s0;
820
- s12 = peg$f18();
854
+ s12 = peg$f19();
821
855
  }
822
856
  s0 = s12;
823
857
  }
@@ -834,7 +868,7 @@ function peg$parse(input, options) {
834
868
  } else {
835
869
  s2 = peg$FAILED;
836
870
  if (peg$silentFails === 0) {
837
- peg$fail(peg$e4);
871
+ peg$fail(peg$e5);
838
872
  }
839
873
  }
840
874
  if (s2 !== peg$FAILED) {
@@ -847,14 +881,14 @@ function peg$parse(input, options) {
847
881
  } else {
848
882
  s6 = peg$FAILED;
849
883
  if (peg$silentFails === 0) {
850
- peg$fail(peg$e5);
884
+ peg$fail(peg$e6);
851
885
  }
852
886
  }
853
887
  if (s6 !== peg$FAILED) {
854
888
  s7 = peg$parseAttrList();
855
889
  if (s7 !== peg$FAILED) {
856
890
  peg$savedPos = s0;
857
- s0 = peg$f19(s4, s7);
891
+ s0 = peg$f20(s4, s7);
858
892
  } else {
859
893
  peg$currPos = s0;
860
894
  s0 = peg$FAILED;
@@ -876,7 +910,7 @@ function peg$parse(input, options) {
876
910
  s0 = peg$currPos;
877
911
  s12 = "";
878
912
  peg$savedPos = s0;
879
- s12 = peg$f20();
913
+ s12 = peg$f21();
880
914
  s0 = s12;
881
915
  }
882
916
  return s0;
@@ -896,7 +930,7 @@ function peg$parse(input, options) {
896
930
  } else {
897
931
  s6 = peg$FAILED;
898
932
  if (peg$silentFails === 0) {
899
- peg$fail(peg$e6);
933
+ peg$fail(peg$e7);
900
934
  }
901
935
  }
902
936
  if (s6 !== peg$FAILED) {
@@ -911,7 +945,7 @@ function peg$parse(input, options) {
911
945
  s5 = null;
912
946
  }
913
947
  peg$savedPos = s2;
914
- s2 = peg$f21(s3);
948
+ s2 = peg$f22(s3);
915
949
  } else {
916
950
  peg$currPos = s2;
917
951
  s2 = peg$FAILED;
@@ -929,7 +963,7 @@ function peg$parse(input, options) {
929
963
  } else {
930
964
  s6 = peg$FAILED;
931
965
  if (peg$silentFails === 0) {
932
- peg$fail(peg$e6);
966
+ peg$fail(peg$e7);
933
967
  }
934
968
  }
935
969
  if (s6 !== peg$FAILED) {
@@ -944,14 +978,14 @@ function peg$parse(input, options) {
944
978
  s5 = null;
945
979
  }
946
980
  peg$savedPos = s2;
947
- s2 = peg$f21(s3);
981
+ s2 = peg$f22(s3);
948
982
  } else {
949
983
  peg$currPos = s2;
950
984
  s2 = peg$FAILED;
951
985
  }
952
986
  }
953
987
  peg$savedPos = s0;
954
- s12 = peg$f22(s12);
988
+ s12 = peg$f23(s12);
955
989
  s0 = s12;
956
990
  return s0;
957
991
  }
@@ -967,7 +1001,7 @@ function peg$parse(input, options) {
967
1001
  } else {
968
1002
  s3 = peg$FAILED;
969
1003
  if (peg$silentFails === 0) {
970
- peg$fail(peg$e3);
1004
+ peg$fail(peg$e4);
971
1005
  }
972
1006
  }
973
1007
  if (s3 !== peg$FAILED) {
@@ -975,7 +1009,7 @@ function peg$parse(input, options) {
975
1009
  s5 = peg$parseAtom();
976
1010
  if (s5 !== peg$FAILED) {
977
1011
  peg$savedPos = s0;
978
- s0 = peg$f23(s12, s5);
1012
+ s0 = peg$f24(s12, s5);
979
1013
  } else {
980
1014
  peg$currPos = s0;
981
1015
  s0 = peg$FAILED;
@@ -1002,7 +1036,7 @@ function peg$parse(input, options) {
1002
1036
  s5 = peg$parseAttrList();
1003
1037
  if (s5 !== peg$FAILED) {
1004
1038
  peg$savedPos = s0;
1005
- s0 = peg$f24(s12, s3, s5);
1039
+ s0 = peg$f25(s12, s3, s5);
1006
1040
  } else {
1007
1041
  peg$currPos = s0;
1008
1042
  s0 = peg$FAILED;
@@ -1023,7 +1057,7 @@ function peg$parse(input, options) {
1023
1057
  s12 = peg$parseSubgraph();
1024
1058
  if (s12 !== peg$FAILED) {
1025
1059
  peg$savedPos = s0;
1026
- s12 = peg$f25(s12);
1060
+ s12 = peg$f26(s12);
1027
1061
  }
1028
1062
  s0 = s12;
1029
1063
  if (s0 === peg$FAILED) {
@@ -1031,7 +1065,7 @@ function peg$parse(input, options) {
1031
1065
  s12 = peg$parseNode();
1032
1066
  if (s12 !== peg$FAILED) {
1033
1067
  peg$savedPos = s0;
1034
- s12 = peg$f26(s12);
1068
+ s12 = peg$f27(s12);
1035
1069
  }
1036
1070
  s0 = s12;
1037
1071
  }
@@ -1049,7 +1083,7 @@ function peg$parse(input, options) {
1049
1083
  } else {
1050
1084
  s3 = peg$FAILED;
1051
1085
  if (peg$silentFails === 0) {
1052
- peg$fail(peg$e7);
1086
+ peg$fail(peg$e8);
1053
1087
  }
1054
1088
  }
1055
1089
  if (s3 !== peg$FAILED) {
@@ -1063,7 +1097,7 @@ function peg$parse(input, options) {
1063
1097
  } else {
1064
1098
  s7 = peg$FAILED;
1065
1099
  if (peg$silentFails === 0) {
1066
- peg$fail(peg$e7);
1100
+ peg$fail(peg$e8);
1067
1101
  }
1068
1102
  }
1069
1103
  if (s7 !== peg$FAILED) {
@@ -1071,7 +1105,7 @@ function peg$parse(input, options) {
1071
1105
  s9 = peg$parseAtom();
1072
1106
  if (s9 !== peg$FAILED) {
1073
1107
  peg$savedPos = s0;
1074
- s0 = peg$f27(s12, s5, s9);
1108
+ s0 = peg$f28(s12, s5, s9);
1075
1109
  } else {
1076
1110
  peg$currPos = s0;
1077
1111
  s0 = peg$FAILED;
@@ -1103,7 +1137,7 @@ function peg$parse(input, options) {
1103
1137
  } else {
1104
1138
  s3 = peg$FAILED;
1105
1139
  if (peg$silentFails === 0) {
1106
- peg$fail(peg$e7);
1140
+ peg$fail(peg$e8);
1107
1141
  }
1108
1142
  }
1109
1143
  if (s3 !== peg$FAILED) {
@@ -1111,7 +1145,7 @@ function peg$parse(input, options) {
1111
1145
  s5 = peg$parseAtom();
1112
1146
  if (s5 !== peg$FAILED) {
1113
1147
  peg$savedPos = s0;
1114
- s0 = peg$f28(s12, s5);
1148
+ s0 = peg$f29(s12, s5);
1115
1149
  } else {
1116
1150
  peg$currPos = s0;
1117
1151
  s0 = peg$FAILED;
@@ -1129,7 +1163,7 @@ function peg$parse(input, options) {
1129
1163
  s12 = peg$parseAtom();
1130
1164
  if (s12 !== peg$FAILED) {
1131
1165
  peg$savedPos = s0;
1132
- s12 = peg$f29(s12);
1166
+ s12 = peg$f30(s12);
1133
1167
  }
1134
1168
  s0 = s12;
1135
1169
  }
@@ -1148,7 +1182,7 @@ function peg$parse(input, options) {
1148
1182
  s5 = peg$parseEdgeChain();
1149
1183
  if (s5 !== peg$FAILED) {
1150
1184
  peg$savedPos = s0;
1151
- s0 = peg$f30(s3, s5);
1185
+ s0 = peg$f31(s3, s5);
1152
1186
  } else {
1153
1187
  peg$currPos = s0;
1154
1188
  s0 = peg$FAILED;
@@ -1165,7 +1199,7 @@ function peg$parse(input, options) {
1165
1199
  s0 = peg$currPos;
1166
1200
  s12 = "";
1167
1201
  peg$savedPos = s0;
1168
- s12 = peg$f31();
1202
+ s12 = peg$f32();
1169
1203
  s0 = s12;
1170
1204
  }
1171
1205
  return s0;
@@ -1179,7 +1213,7 @@ function peg$parse(input, options) {
1179
1213
  } else {
1180
1214
  s0 = peg$FAILED;
1181
1215
  if (peg$silentFails === 0) {
1182
- peg$fail(peg$e9);
1216
+ peg$fail(peg$e10);
1183
1217
  }
1184
1218
  }
1185
1219
  if (s0 === peg$FAILED) {
@@ -1189,7 +1223,7 @@ function peg$parse(input, options) {
1189
1223
  } else {
1190
1224
  s0 = peg$FAILED;
1191
1225
  if (peg$silentFails === 0) {
1192
- peg$fail(peg$e10);
1226
+ peg$fail(peg$e11);
1193
1227
  }
1194
1228
  }
1195
1229
  }
@@ -1197,7 +1231,7 @@ function peg$parse(input, options) {
1197
1231
  if (s0 === peg$FAILED) {
1198
1232
  s12 = peg$FAILED;
1199
1233
  if (peg$silentFails === 0) {
1200
- peg$fail(peg$e8);
1234
+ peg$fail(peg$e9);
1201
1235
  }
1202
1236
  }
1203
1237
  return s0;
@@ -1236,7 +1270,7 @@ function peg$parse(input, options) {
1236
1270
  }
1237
1271
  if (s9 !== peg$FAILED) {
1238
1272
  peg$savedPos = s0;
1239
- s0 = peg$f32(s3, s7);
1273
+ s0 = peg$f33(s3, s7);
1240
1274
  } else {
1241
1275
  peg$currPos = s0;
1242
1276
  s0 = peg$FAILED;
@@ -1287,7 +1321,7 @@ function peg$parse(input, options) {
1287
1321
  }
1288
1322
  if (s7 !== peg$FAILED) {
1289
1323
  peg$savedPos = s0;
1290
- s0 = peg$f33(s5);
1324
+ s0 = peg$f34(s5);
1291
1325
  } else {
1292
1326
  peg$currPos = s0;
1293
1327
  s0 = peg$FAILED;
@@ -1331,7 +1365,7 @@ function peg$parse(input, options) {
1331
1365
  }
1332
1366
  if (s5 !== peg$FAILED) {
1333
1367
  peg$savedPos = s0;
1334
- s0 = peg$f34(s3);
1368
+ s0 = peg$f35(s3);
1335
1369
  } else {
1336
1370
  peg$currPos = s0;
1337
1371
  s0 = peg$FAILED;
@@ -1362,7 +1396,7 @@ function peg$parse(input, options) {
1362
1396
  } else {
1363
1397
  s5 = peg$FAILED;
1364
1398
  if (peg$silentFails === 0) {
1365
- peg$fail(peg$e11);
1399
+ peg$fail(peg$e12);
1366
1400
  }
1367
1401
  }
1368
1402
  if (s5 !== peg$FAILED) {
@@ -1370,7 +1404,7 @@ function peg$parse(input, options) {
1370
1404
  s7 = peg$parseQAtom();
1371
1405
  if (s7 !== peg$FAILED) {
1372
1406
  peg$savedPos = s3;
1373
- s3 = peg$f35(s12, s7);
1407
+ s3 = peg$f36(s12, s7);
1374
1408
  } else {
1375
1409
  peg$currPos = s3;
1376
1410
  s3 = peg$FAILED;
@@ -1389,7 +1423,7 @@ function peg$parse(input, options) {
1389
1423
  } else {
1390
1424
  s5 = peg$FAILED;
1391
1425
  if (peg$silentFails === 0) {
1392
- peg$fail(peg$e11);
1426
+ peg$fail(peg$e12);
1393
1427
  }
1394
1428
  }
1395
1429
  if (s5 !== peg$FAILED) {
@@ -1397,7 +1431,7 @@ function peg$parse(input, options) {
1397
1431
  s7 = peg$parseQAtom();
1398
1432
  if (s7 !== peg$FAILED) {
1399
1433
  peg$savedPos = s3;
1400
- s3 = peg$f35(s12, s7);
1434
+ s3 = peg$f36(s12, s7);
1401
1435
  } else {
1402
1436
  peg$currPos = s3;
1403
1437
  s3 = peg$FAILED;
@@ -1408,7 +1442,7 @@ function peg$parse(input, options) {
1408
1442
  }
1409
1443
  }
1410
1444
  peg$savedPos = s0;
1411
- s0 = peg$f36(s12, s2);
1445
+ s0 = peg$f37(s12, s2);
1412
1446
  } else {
1413
1447
  peg$currPos = s0;
1414
1448
  s0 = peg$FAILED;
@@ -1435,7 +1469,7 @@ function peg$parse(input, options) {
1435
1469
  } else {
1436
1470
  s12 = peg$FAILED;
1437
1471
  if (peg$silentFails === 0) {
1438
- peg$fail(peg$e12);
1472
+ peg$fail(peg$e13);
1439
1473
  }
1440
1474
  }
1441
1475
  if (s12 !== peg$FAILED) {
@@ -1451,12 +1485,12 @@ function peg$parse(input, options) {
1451
1485
  } else {
1452
1486
  s3 = peg$FAILED;
1453
1487
  if (peg$silentFails === 0) {
1454
- peg$fail(peg$e12);
1488
+ peg$fail(peg$e13);
1455
1489
  }
1456
1490
  }
1457
1491
  if (s3 !== peg$FAILED) {
1458
1492
  peg$savedPos = s0;
1459
- s0 = peg$f37(s2);
1493
+ s0 = peg$f38(s2);
1460
1494
  } else {
1461
1495
  peg$currPos = s0;
1462
1496
  s0 = peg$FAILED;
@@ -1476,12 +1510,12 @@ function peg$parse(input, options) {
1476
1510
  } else {
1477
1511
  s12 = peg$FAILED;
1478
1512
  if (peg$silentFails === 0) {
1479
- peg$fail(peg$e13);
1513
+ peg$fail(peg$e14);
1480
1514
  }
1481
1515
  }
1482
1516
  if (s12 !== peg$FAILED) {
1483
1517
  peg$savedPos = s0;
1484
- s12 = peg$f38();
1518
+ s12 = peg$f39();
1485
1519
  }
1486
1520
  s0 = s12;
1487
1521
  if (s0 === peg$FAILED) {
@@ -1492,12 +1526,12 @@ function peg$parse(input, options) {
1492
1526
  } else {
1493
1527
  s12 = peg$FAILED;
1494
1528
  if (peg$silentFails === 0) {
1495
- peg$fail(peg$e14);
1529
+ peg$fail(peg$e15);
1496
1530
  }
1497
1531
  }
1498
1532
  if (s12 !== peg$FAILED) {
1499
1533
  peg$savedPos = s0;
1500
- s12 = peg$f39();
1534
+ s12 = peg$f40();
1501
1535
  }
1502
1536
  s0 = s12;
1503
1537
  if (s0 === peg$FAILED) {
@@ -1508,7 +1542,7 @@ function peg$parse(input, options) {
1508
1542
  } else {
1509
1543
  s12 = peg$FAILED;
1510
1544
  if (peg$silentFails === 0) {
1511
- peg$fail(peg$e15);
1545
+ peg$fail(peg$e16);
1512
1546
  }
1513
1547
  }
1514
1548
  if (s12 !== peg$FAILED) {
@@ -1518,12 +1552,12 @@ function peg$parse(input, options) {
1518
1552
  } else {
1519
1553
  s2 = peg$FAILED;
1520
1554
  if (peg$silentFails === 0) {
1521
- peg$fail(peg$e16);
1555
+ peg$fail(peg$e2);
1522
1556
  }
1523
1557
  }
1524
1558
  if (s2 !== peg$FAILED) {
1525
1559
  peg$savedPos = s0;
1526
- s0 = peg$f40(s2);
1560
+ s0 = peg$f41(s2);
1527
1561
  } else {
1528
1562
  peg$currPos = s0;
1529
1563
  s0 = peg$FAILED;
@@ -1572,7 +1606,7 @@ function peg$parse(input, options) {
1572
1606
  }
1573
1607
  if (s3 !== peg$FAILED) {
1574
1608
  peg$savedPos = s0;
1575
- s0 = peg$f41(s2);
1609
+ s0 = peg$f42(s2);
1576
1610
  } else {
1577
1611
  peg$currPos = s0;
1578
1612
  s0 = peg$FAILED;
@@ -1593,7 +1627,7 @@ function peg$parse(input, options) {
1593
1627
  s2 = peg$parseHtmlChar();
1594
1628
  }
1595
1629
  peg$savedPos = s0;
1596
- s12 = peg$f42(s12);
1630
+ s12 = peg$f43(s12);
1597
1631
  s0 = s12;
1598
1632
  return s0;
1599
1633
  }
@@ -1623,7 +1657,7 @@ function peg$parse(input, options) {
1623
1657
  }
1624
1658
  if (s3 !== peg$FAILED) {
1625
1659
  peg$savedPos = s0;
1626
- s0 = peg$f43(s12, s2);
1660
+ s0 = peg$f44(s12, s2);
1627
1661
  } else {
1628
1662
  peg$currPos = s0;
1629
1663
  s0 = peg$FAILED;
@@ -1668,7 +1702,7 @@ function peg$parse(input, options) {
1668
1702
  s2 = peg$parseName();
1669
1703
  if (s2 !== peg$FAILED) {
1670
1704
  peg$savedPos = s0;
1671
- s0 = peg$f44(s2);
1705
+ s0 = peg$f45(s2);
1672
1706
  } else {
1673
1707
  peg$currPos = s0;
1674
1708
  s0 = peg$FAILED;
@@ -1716,7 +1750,7 @@ function peg$parse(input, options) {
1716
1750
  }
1717
1751
  }
1718
1752
  peg$savedPos = s0;
1719
- s0 = peg$f45(s12, s2);
1753
+ s0 = peg$f46(s12, s2);
1720
1754
  } else {
1721
1755
  peg$currPos = s0;
1722
1756
  s0 = peg$FAILED;
@@ -1874,7 +1908,7 @@ function peg$parse(input, options) {
1874
1908
  }
1875
1909
  if (s12 !== peg$FAILED) {
1876
1910
  peg$savedPos = s0;
1877
- s12 = peg$f46(s12);
1911
+ s12 = peg$f47(s12);
1878
1912
  }
1879
1913
  s0 = s12;
1880
1914
  return s0;
@@ -3149,7 +3183,7 @@ function peg$parse(input, options) {
3149
3183
  } else {
3150
3184
  s5 = peg$FAILED;
3151
3185
  if (peg$silentFails === 0) {
3152
- peg$fail(peg$e16);
3186
+ peg$fail(peg$e2);
3153
3187
  }
3154
3188
  }
3155
3189
  if (s5 !== peg$FAILED) {
@@ -3191,7 +3225,7 @@ function peg$parse(input, options) {
3191
3225
  } else {
3192
3226
  s5 = peg$FAILED;
3193
3227
  if (peg$silentFails === 0) {
3194
- peg$fail(peg$e16);
3228
+ peg$fail(peg$e2);
3195
3229
  }
3196
3230
  }
3197
3231
  if (s5 !== peg$FAILED) {
@@ -3281,7 +3315,7 @@ function peg$parse(input, options) {
3281
3315
  } else {
3282
3316
  s4 = peg$FAILED;
3283
3317
  if (peg$silentFails === 0) {
3284
- peg$fail(peg$e16);
3318
+ peg$fail(peg$e2);
3285
3319
  }
3286
3320
  }
3287
3321
  peg$silentFails--;
@@ -3358,7 +3392,7 @@ function peg$parse(input, options) {
3358
3392
  } else {
3359
3393
  s4 = peg$FAILED;
3360
3394
  if (peg$silentFails === 0) {
3361
- peg$fail(peg$e16);
3395
+ peg$fail(peg$e2);
3362
3396
  }
3363
3397
  }
3364
3398
  peg$silentFails--;
@@ -4317,6 +4351,179 @@ function numberAmbiguityMessage(a) {
4317
4351
  return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
4318
4352
  }
4319
4353
 
4354
+ // src/parser/scan-token.ts
4355
+ var YY_BUF_SIZE = 16384;
4356
+ var STRING_STARTING_BYTES = 80;
4357
+ var ASCII_DEL2 = 127;
4358
+ function isLetter2(c) {
4359
+ if (c === void 0) return false;
4360
+ return c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c === "_" || c.charCodeAt(0) > ASCII_DEL2;
4361
+ }
4362
+ function isDigit2(c) {
4363
+ return c !== void 0 && c >= "0" && c <= "9";
4364
+ }
4365
+ function startsNumber2(s, i) {
4366
+ const c = s[i];
4367
+ if (isDigit2(c)) return true;
4368
+ if (c === ".") return isDigit2(s[i + 1]);
4369
+ if (c !== "-") return false;
4370
+ return isDigit2(s[i + 1]) || s[i + 1] === "." && isDigit2(s[i + 2]);
4371
+ }
4372
+ function matchNumber2(s, i) {
4373
+ let j = s[i] === "-" ? i + 1 : i;
4374
+ if (s[j] === ".") {
4375
+ j++;
4376
+ while (isDigit2(s[j])) j++;
4377
+ } else {
4378
+ while (isDigit2(s[j])) j++;
4379
+ if (s[j] === ".") {
4380
+ j++;
4381
+ while (isDigit2(s[j])) j++;
4382
+ }
4383
+ }
4384
+ if (s[j] === "." || isLetter2(s[j])) j++;
4385
+ return j;
4386
+ }
4387
+ function badlyDelimited(text) {
4388
+ const c = text[text.length - 1];
4389
+ const dot = text.indexOf(".");
4390
+ return !isDigit2(c) && c !== "." || c === "." && dot !== text.length - 1;
4391
+ }
4392
+ function lineEnd(s, i) {
4393
+ const nl = s.indexOf("\n", i);
4394
+ return nl === -1 ? s.length : nl;
4395
+ }
4396
+ function directiveLine(text) {
4397
+ const rest = text.slice(1).replace(/^line/, "");
4398
+ const m = /^\s*([+-]?\d+)/.exec(rest);
4399
+ if (m === null) return void 0;
4400
+ const lineno = Number.parseInt(m[1], 10);
4401
+ return lineno <= 0 ? void 0 : lineno - 1;
4402
+ }
4403
+ function qstringBuffer(body) {
4404
+ return body.replace(/\\\\|\\"|\\\n/g, (m) => m === '\\"' ? '"' : m === "\\\n" ? "" : m);
4405
+ }
4406
+ function lexQuoted(s, i) {
4407
+ for (let j = i + 1; j < s.length; j++) {
4408
+ if (s[j] === "\\" && j + 1 < s.length) j++;
4409
+ else if (s[j] === '"') return { kind: "token", end: j + 1, text: '"' };
4410
+ }
4411
+ return { kind: "open", state: "qstring", buffer: qstringBuffer(s.slice(i + 1)) };
4412
+ }
4413
+ function lexHtml(s, i) {
4414
+ let nest = 1;
4415
+ for (let j = i + 1; j < s.length; j++) {
4416
+ if (s[j] === "<") nest++;
4417
+ else if (s[j] === ">" && --nest === 0) return { kind: "token", end: j + 1, text: ">" };
4418
+ }
4419
+ return { kind: "open", state: "hstring", buffer: s.slice(i + 1) };
4420
+ }
4421
+ function lexComment(s, i) {
4422
+ const close = s.indexOf("*/", i + 2);
4423
+ if (close === -1) return { kind: "open", state: "comment", buffer: "" };
4424
+ return { kind: "skip", end: close + 2 };
4425
+ }
4426
+ function lexHash(s, i) {
4427
+ const end = lineEnd(s, i);
4428
+ const atLineStart = i === 0 || s[i - 1] === "\n";
4429
+ const line = atLineStart ? directiveLine(s.slice(i, end)) : void 0;
4430
+ return line === void 0 ? { kind: "skip", end } : { kind: "skip", end, line };
4431
+ }
4432
+ function lexAtom(s, i) {
4433
+ if (isLetter2(s[i])) {
4434
+ let j2 = i + 1;
4435
+ while (isLetter2(s[j2]) || isDigit2(s[j2])) j2++;
4436
+ const text = s.slice(i, j2);
4437
+ return text === "\uFEFF" ? { kind: "skip", end: j2 } : { kind: "token", end: j2, text };
4438
+ }
4439
+ if (s[i] === "-" && (s[i + 1] === "-" || s[i + 1] === ">")) {
4440
+ return { kind: "token", end: i + 2, text: s.slice(i, i + 2) };
4441
+ }
4442
+ if (!startsNumber2(s, i)) return { kind: "token", end: i + 1, text: s[i] };
4443
+ const j = matchNumber2(s, i);
4444
+ const end = badlyDelimited(s.slice(i, j)) ? j - 1 : j;
4445
+ return { kind: "token", end, text: s.slice(i, end) };
4446
+ }
4447
+ function lexTrivia(s, i) {
4448
+ const c = s[i];
4449
+ if (c === "\n" || c === " " || c === " " || c === "\r") return { kind: "skip", end: i + 1 };
4450
+ if (c === "#") return lexHash(s, i);
4451
+ if (c !== "/") return void 0;
4452
+ if (s[i + 1] === "*") return lexComment(s, i);
4453
+ if (s[i + 1] === "/") return { kind: "skip", end: lineEnd(s, i) };
4454
+ return void 0;
4455
+ }
4456
+ function lexStep(s, i) {
4457
+ const trivia = lexTrivia(s, i);
4458
+ if (trivia !== void 0) return trivia;
4459
+ if (s[i] === '"') return lexQuoted(s, i);
4460
+ if (s[i] === "<") return lexHtml(s, i);
4461
+ return lexAtom(s, i);
4462
+ }
4463
+ function countNewlines(s, from, to) {
4464
+ let n = 0;
4465
+ for (let i = s.indexOf("\n", from); i !== -1 && i < to; i = s.indexOf("\n", i + 1)) n++;
4466
+ return n;
4467
+ }
4468
+ var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
4469
+ function isTruncatedHeaderKeyword(src, step, offset, seen) {
4470
+ if (offset !== src.length || step.end !== offset || seen.length > 1) return false;
4471
+ if (seen.length === 1 && seen[0].toLowerCase() !== "strict") return false;
4472
+ const word = step.text.toLowerCase();
4473
+ return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
4474
+ }
4475
+ function reachesOffset(src, step, offset, seen) {
4476
+ if (step.end > offset) return true;
4477
+ if (isTruncatedHeaderKeyword(src, step, offset, seen)) return true;
4478
+ if (step.text !== "-" && step.text !== ".") return false;
4479
+ return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
4480
+ }
4481
+ function scanAtError(src, offset) {
4482
+ let line = 1;
4483
+ let i = 0;
4484
+ const seen = [];
4485
+ while (i < src.length) {
4486
+ const step = lexStep(src, i);
4487
+ if (step.kind === "open") {
4488
+ line += countNewlines(src, i, src.length);
4489
+ return { state: step.state, text: "", line, buffer: step.buffer };
4490
+ }
4491
+ if (step.kind === "skip" && step.line !== void 0) line = step.line;
4492
+ line += countNewlines(src, i, step.end);
4493
+ if (step.kind === "token" && reachesOffset(src, step, offset, seen)) {
4494
+ return { state: "INITIAL", text: step.text, line, buffer: "" };
4495
+ }
4496
+ if (step.kind === "token") seen.push(step.text);
4497
+ i = step.end;
4498
+ }
4499
+ return { state: "INITIAL", text: "", line, buffer: "" };
4500
+ }
4501
+ function firstBytes(s) {
4502
+ const bytes = new TextEncoder().encode(s);
4503
+ if (bytes.length <= STRING_STARTING_BYTES) return s;
4504
+ return new TextDecoder().decode(bytes.subarray(0, STRING_STARTING_BYTES));
4505
+ }
4506
+ function stateNote(at) {
4507
+ const start = at.buffer.length > 0 ? firstBytes(at.buffer) : "";
4508
+ switch (at.state) {
4509
+ case "qstring":
4510
+ return ` scanning a quoted string (missing endquote? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
4511
+ String starting:"${start}`);
4512
+ case "hstring":
4513
+ return ` scanning a HTML string (missing '>'? bad nesting? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
4514
+ String starting:<${start}`);
4515
+ case "comment":
4516
+ return ` scanning a /*...*/ comment (missing '*/? longer than ${YY_BUF_SIZE}?)`;
4517
+ case "INITIAL":
4518
+ return "";
4519
+ }
4520
+ }
4521
+ function syntaxErrorMessage(src, offset) {
4522
+ const at = scanAtError(src, offset);
4523
+ const where = `Error: syntax error in line ${at.line}`;
4524
+ return at.text === "" ? where + stateNote(at) : `${where} near '${at.text}'`;
4525
+ }
4526
+
4320
4527
  // src/errors.ts
4321
4528
  var FRIENDLY_MESSAGES = {
4322
4529
  SYNTAX_ERROR: "There is a syntax error in the DOT source.",
@@ -4497,9 +4704,9 @@ var Stripper = class _Stripper {
4497
4704
  */
4498
4705
  static blankLine(src, i, out) {
4499
4706
  const n = src.length;
4500
- const width = src[i] === "#" ? 1 : 2;
4501
- out.push(" ".repeat(width));
4502
- i += width;
4707
+ const width2 = src[i] === "#" ? 1 : 2;
4708
+ out.push(" ".repeat(width2));
4709
+ i += width2;
4503
4710
  while (i < n && src[i] !== "\n") {
4504
4711
  out.push(" ");
4505
4712
  i++;
@@ -4610,6 +4817,7 @@ function parse(src) {
4610
4817
  if (isPeggyError(err)) {
4611
4818
  const start = err.location.start;
4612
4819
  warnNumberAmbiguities(src, start.offset);
4820
+ console.error(syntaxErrorMessage(src, start.offset));
4613
4821
  const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
4614
4822
  throw new ParseError(
4615
4823
  err instanceof Error ? err.message : String(err),
@@ -4627,8 +4835,18 @@ function parse(src) {
4627
4835
  }
4628
4836
  throw err;
4629
4837
  }
4630
- warnNumberAmbiguities(src, src.length);
4631
- validateEdgeOperators(src, ast.directed);
4838
+ const lexed = src.slice(0, ast.end);
4839
+ try {
4840
+ validateEdgeOperators(lexed, ast.directed);
4841
+ } catch (err) {
4842
+ const offset = err instanceof ParseError ? err.location.offset : void 0;
4843
+ if (offset !== void 0) {
4844
+ warnNumberAmbiguities(src, offset);
4845
+ console.error(syntaxErrorMessage(src, offset));
4846
+ }
4847
+ throw err;
4848
+ }
4849
+ warnNumberAmbiguities(lexed, lexed.length);
4632
4850
  return buildFromAst(ast);
4633
4851
  }
4634
4852
 
@@ -8745,20 +8963,20 @@ function rect(x, y, w, h) {
8745
8963
  function dnaY(af) {
8746
8964
  return af[2].y + (af[0].y - af[3].y) / 2;
8747
8965
  }
8748
- function nextV(af, seg2, sides) {
8749
- return seg2 + 1 < sides ? af[seg2 + 1] : af[0];
8966
+ function nextV(af, seg2, sides2) {
8967
+ return seg2 + 1 < sides2 ? af[seg2 + 1] : af[0];
8750
8968
  }
8751
- function interpolationPoints(af, sides, shape, rounded = false) {
8969
+ function interpolationPoints(af, sides2, shape, rounded = false) {
8752
8970
  let rbconst = RBCONST;
8753
- for (let seg2 = 0; seg2 < sides; seg2++) {
8971
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
8754
8972
  const p0 = af[seg2];
8755
- const p1 = nextV(af, seg2, sides);
8973
+ const p1 = nextV(af, seg2, sides2);
8756
8974
  rbconst = Math.min(rbconst, Math.hypot(p1.x - p0.x, p1.y - p0.y) / 3);
8757
8975
  }
8758
8976
  const b = [];
8759
- for (let seg2 = 0; seg2 < sides; seg2++) {
8977
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
8760
8978
  const p0 = af[seg2];
8761
- const p1 = nextV(af, seg2, sides);
8979
+ const p1 = nextV(af, seg2, sides2);
8762
8980
  let t = rbconst / Math.hypot(p1.x - p0.x, p1.y - p0.y);
8763
8981
  if (shape === BOX3D || shape === COMPONENT) t /= 3;
8764
8982
  else if (shape === DOGEAR) t /= 2;
@@ -8795,28 +9013,28 @@ function drawCds(af, b, coord, filled, ctx) {
8795
9013
  renderShapePolygon(D, coord, ctx, filled);
8796
9014
  }
8797
9015
  function drawDogear(af, b, coord, filled, ctx) {
8798
- const sides = af.length;
8799
- const D = new Array(sides + 1);
8800
- for (let seg2 = 1; seg2 < sides; seg2++) D[seg2] = af[seg2];
8801
- D[0] = b[3 * (sides - 1) + 4];
8802
- D[sides] = b[3 * (sides - 1) + 2];
9016
+ const sides2 = af.length;
9017
+ const D = new Array(sides2 + 1);
9018
+ for (let seg2 = 1; seg2 < sides2; seg2++) D[seg2] = af[seg2];
9019
+ D[0] = b[3 * (sides2 - 1) + 4];
9020
+ D[sides2] = b[3 * (sides2 - 1) + 2];
8803
9021
  renderShapePolygon(D, coord, ctx, filled);
8804
- const s = sides - 1;
9022
+ const s = sides2 - 1;
8805
9023
  const c0 = b[3 * s + 2];
8806
9024
  const c2 = vadd(b[3 * s + 4], vsub(c0, b[3 * s + 3]));
8807
9025
  renderShapePolyline([b[3 * s + 4], c2], coord, ctx);
8808
9026
  renderShapePolyline([c0, c2], coord, ctx);
8809
9027
  }
8810
9028
  function drawTab(af, b, coord, filled, ctx) {
8811
- const sides = af.length;
9029
+ const sides2 = af.length;
8812
9030
  const w = { x: (b[3].x - b[4].x) / 3, y: (b[3].y - b[4].y) / 3 };
8813
9031
  const D = [af[0], b[2], vadd(b[2], w), vadd(b[3], w)];
8814
- for (let seg2 = 4; seg2 < sides + 2; seg2++) D.push(af[seg2 - 2]);
9032
+ for (let seg2 = 4; seg2 < sides2 + 2; seg2++) D.push(af[seg2 - 2]);
8815
9033
  renderShapePolygon(D, coord, ctx, filled);
8816
9034
  renderShapePolyline([b[3], b[2]], coord, ctx);
8817
9035
  }
8818
9036
  function drawFolder(af, b, coord, filled, ctx) {
8819
- const sides = af.length;
9037
+ const sides2 = af.length;
8820
9038
  const dx = af[0].x - b[1].x;
8821
9039
  const wy = (b[3].y - b[4].y) / 3;
8822
9040
  const D = [
@@ -8825,7 +9043,7 @@ function drawFolder(af, b, coord, filled, ctx) {
8825
9043
  { x: af[0].x - 2 * dx, y: af[0].y + wy },
8826
9044
  { x: af[0].x - 2.25 * dx, y: b[3].y }
8827
9045
  ];
8828
- for (let seg2 = 4; seg2 < sides + 3; seg2++) D.push(af[seg2 - 3]);
9046
+ for (let seg2 = 4; seg2 < sides2 + 3; seg2++) D.push(af[seg2 - 3]);
8829
9047
  renderShapePolygon(D, coord, ctx, filled);
8830
9048
  }
8831
9049
  function drawBox3d(af, b, coord, filled, ctx) {
@@ -9175,10 +9393,10 @@ function drawRoundCorners(ring, coord, filled, ctx) {
9175
9393
  else if (ctx.rounded) roundedDraw(ring, coord, filled, ctx);
9176
9394
  }
9177
9395
  function diagonalsDraw(ring, coord, filled, ctx) {
9178
- const sides = ring.length;
9179
- const b = interpolationPoints(ring, sides, 0);
9396
+ const sides2 = ring.length;
9397
+ const b = interpolationPoints(ring, sides2, 0);
9180
9398
  renderShapePolygon(ring, coord, ctx, filled);
9181
- for (let seg2 = 0; seg2 < sides; seg2++) {
9399
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
9182
9400
  renderShapePolyline([b[3 * seg2 + 2], b[3 * seg2 + 4]], coord, ctx);
9183
9401
  }
9184
9402
  }
@@ -9186,10 +9404,10 @@ function roundedDraw(ring, coord, filled, ctx) {
9186
9404
  emitRoundedBezier(ring, coord, filled, ctx);
9187
9405
  }
9188
9406
  function emitRoundedBezier(ring, coord, filled, ctx) {
9189
- const sides = ring.length;
9190
- const b = interpolationPoints(ring, sides, 0, true);
9407
+ const sides2 = ring.length;
9408
+ const b = interpolationPoints(ring, sides2, 0, true);
9191
9409
  const pts = [];
9192
- for (let seg2 = 0; seg2 < sides; seg2++) {
9410
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
9193
9411
  pts.push(b[4 * seg2], b[4 * seg2 + 1], b[4 * seg2 + 1], b[4 * seg2 + 2], b[4 * seg2 + 2], b[4 * seg2 + 3]);
9194
9412
  }
9195
9413
  pts.push(pts[0], pts[1]);
@@ -9319,11 +9537,11 @@ function zeroFlags() {
9319
9537
  };
9320
9538
  }
9321
9539
  var FUNLIMIT = 64;
9322
- function styleTokens(style) {
9323
- if (!style) return [];
9540
+ function styleTokens(style2) {
9541
+ if (!style2) return [];
9324
9542
  const out = [];
9325
9543
  let fun = 0;
9326
- for (const raw of style.split(",")) {
9544
+ for (const raw of style2.split(",")) {
9327
9545
  const token = raw.trim();
9328
9546
  if (token.length === 0) continue;
9329
9547
  if (fun === FUNLIMIT - 1) return [];
@@ -9357,11 +9575,11 @@ function firstSolidColor(raw) {
9357
9575
  const grad = parseGradientSpec(raw);
9358
9576
  return grad !== null ? grad[0] : raw;
9359
9577
  }
9360
- function parseStyleFlags(style) {
9578
+ function parseStyleFlags(style2) {
9361
9579
  const flags = zeroFlags();
9362
- if (!style) return flags;
9580
+ if (!style2) return flags;
9363
9581
  let fun = 0;
9364
- for (const raw of style.split(",")) {
9582
+ for (const raw of style2.split(",")) {
9365
9583
  const token = raw.trim();
9366
9584
  if (token.length === 0) continue;
9367
9585
  if (fun === FUNLIMIT - 1) return zeroFlags();
@@ -9375,10 +9593,10 @@ function parseStyleFlags(style) {
9375
9593
  }
9376
9594
  return flags;
9377
9595
  }
9378
- function styleHasInvisibleAlias(style) {
9379
- if (!style) return false;
9596
+ function styleHasInvisibleAlias(style2) {
9597
+ if (!style2) return false;
9380
9598
  let fun = 0;
9381
- for (const raw of style.split(",")) {
9599
+ for (const raw of style2.split(",")) {
9382
9600
  const token = raw.trim();
9383
9601
  if (token.length === 0) continue;
9384
9602
  if (fun === FUNLIMIT - 1) return false;
@@ -9433,9 +9651,9 @@ function findStopColor(colorlist) {
9433
9651
  const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
9434
9652
  return { fillColor, stopColor, frac };
9435
9653
  }
9436
- function parseAngle(gradientangle) {
9437
- if (!gradientangle || gradientangle.length === 0) return 0;
9438
- const v = parseInt(gradientangle, 10);
9654
+ function parseAngle(gradientangle2) {
9655
+ if (!gradientangle2 || gradientangle2.length === 0) return 0;
9656
+ const v = parseInt(gradientangle2, 10);
9439
9657
  return isFinite(v) ? v : 0;
9440
9658
  }
9441
9659
  function buildResolvedFill(rawColor, flags, angle) {
@@ -9540,9 +9758,9 @@ function htmlFillPenWidth() {
9540
9758
  function resetHtmlFillPenWidth() {
9541
9759
  htmlFillPen = 1;
9542
9760
  }
9543
- function penTypeOf(style) {
9544
- if (style !== void 0 && style.includes("dashed")) return 1 /* Dashed */;
9545
- if (style !== void 0 && style.includes("dotted")) return 2 /* Dotted */;
9761
+ function penTypeOf(style2) {
9762
+ if (style2 !== void 0 && style2.includes("dashed")) return 1 /* Dashed */;
9763
+ if (style2 !== void 0 && style2.includes("dotted")) return 2 /* Dotted */;
9546
9764
  return 3 /* Solid */;
9547
9765
  }
9548
9766
  function withHtmlPaint(paint, job, drawFn) {
@@ -9573,13 +9791,13 @@ function applyHtmlFill(paint) {
9573
9791
  paintObj.gradientAngle = 0;
9574
9792
  paintObj.gradientFrac = 0;
9575
9793
  }
9576
- function mkPts(b, border, pos) {
9794
+ function mkPts(b, border2, pos) {
9577
9795
  let llx = b.ll.x + pos.x;
9578
9796
  let lly = b.ll.y + pos.y;
9579
9797
  let urx = b.ur.x + pos.x;
9580
9798
  let ury = b.ur.y + pos.y;
9581
- if (border > 1) {
9582
- const delta2 = border / 2;
9799
+ if (border2 > 1) {
9800
+ const delta2 = border2 / 2;
9583
9801
  llx += delta2;
9584
9802
  lly += delta2;
9585
9803
  urx -= delta2;
@@ -9606,26 +9824,26 @@ function doSide(p, wd, ht, renderer, job) {
9606
9824
  renderer.polygon(pts, true, job);
9607
9825
  }
9608
9826
  function doBorder(spec, renderer, job) {
9609
- const { box, pos, border, color, sides, style } = spec;
9610
- htmlFillPen = border;
9611
- withHtmlPaint({ pen: color, penWidth: border, penStyle: style }, job, () => {
9612
- if (parseStyleFlags(style).rounded) {
9613
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, false, { renderer, job });
9827
+ const { box, pos, border: border2, color, sides: sides2, style: style2 } = spec;
9828
+ htmlFillPen = border2;
9829
+ withHtmlPaint({ pen: color, penWidth: border2, penStyle: style2 }, job, () => {
9830
+ if (parseStyleFlags(style2).rounded) {
9831
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, false, { renderer, job });
9614
9832
  return;
9615
9833
  }
9616
- const effSides = sides !== void 0 ? sides & BORDER_MASK : 0;
9834
+ const effSides = sides2 !== void 0 ? sides2 & BORDER_MASK : 0;
9617
9835
  if (effSides !== 0) {
9618
- const corners = mkPts(box, border, pos).map((p) => transformPoint(p, job));
9836
+ const corners = mkPts(box, border2, pos).map((p) => transformPoint(p, job));
9619
9837
  emitSidedPolylines(effSides, corners, renderer, job);
9620
9838
  } else {
9621
- emitFullBoxBorder(box, pos, border, renderer, job);
9839
+ emitFullBoxBorder(box, pos, border2, renderer, job);
9622
9840
  }
9623
9841
  });
9624
9842
  }
9625
- function emitFullBoxBorder(box, pos, border, renderer, job) {
9626
- const b2 = border > 1 ? {
9627
- ll: { x: box.ll.x + border / 2, y: box.ll.y + border / 2 },
9628
- ur: { x: box.ur.x - border / 2, y: box.ur.y - border / 2 }
9843
+ function emitFullBoxBorder(box, pos, border2, renderer, job) {
9844
+ const b2 = border2 > 1 ? {
9845
+ ll: { x: box.ll.x + border2 / 2, y: box.ll.y + border2 / 2 },
9846
+ ur: { x: box.ur.x - border2 / 2, y: box.ur.y - border2 / 2 }
9629
9847
  } : box;
9630
9848
  const pts = [
9631
9849
  { x: b2.ll.x + pos.x, y: b2.ll.y + pos.y },
@@ -9660,8 +9878,8 @@ var SIDES_TABLE = /* @__PURE__ */ new Map([
9660
9878
  [T, [[NE, NW]]],
9661
9879
  [L, [[NW, SW]]]
9662
9880
  ]);
9663
- function emitSidedPolylines(sides, corners, renderer, job) {
9664
- const seqs = SIDES_TABLE.get(sides & BORDER_MASK);
9881
+ function emitSidedPolylines(sides2, corners, renderer, job) {
9882
+ const seqs = SIDES_TABLE.get(sides2 & BORDER_MASK);
9665
9883
  if (seqs === void 0) return;
9666
9884
  for (const seq2 of seqs) {
9667
9885
  renderer.polyline(seq2.map((i) => corners[i]), job);
@@ -9819,10 +10037,10 @@ function bgFillPaint(ctx) {
9819
10037
  };
9820
10038
  }
9821
10039
  function emitBgFill(ctx) {
9822
- const { box, pos, border, renderer, job } = ctx;
10040
+ const { box, pos, border: border2, renderer, job } = ctx;
9823
10041
  withHtmlPaint(bgFillPaint(ctx), job, () => {
9824
10042
  if (parseStyleFlags(ctx.style).rounded) {
9825
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, true, { renderer, job });
10043
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, true, { renderer, job });
9826
10044
  return;
9827
10045
  }
9828
10046
  const pts = [
@@ -9887,9 +10105,9 @@ function emitHtmlImg(img, pos, renderer, job) {
9887
10105
  }
9888
10106
  renderer.usershape?.(img.src, b, job);
9889
10107
  }
9890
- function htmlStyleInvisible(style) {
9891
- if (style === void 0) return false;
9892
- return style.split(/[ ,]+/).some((tok) => {
10108
+ function htmlStyleInvisible(style2) {
10109
+ if (style2 === void 0) return false;
10110
+ return style2.split(/[ ,]+/).some((tok) => {
9893
10111
  const t = tok.toUpperCase();
9894
10112
  return t === "INVIS" || t === "INVISIBLE";
9895
10113
  });
@@ -9963,6 +10181,218 @@ function emitHtmlLabel(placed, pos, renderer, job) {
9963
10181
  }
9964
10182
  }
9965
10183
 
10184
+ // src/common/htmltable-attr-warn.ts
10185
+ var accepted = (v) => ({ keep: v, text: [], warn: false });
10186
+ var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
10187
+ var warning = (msg) => `Warning: ${msg}`;
10188
+ var lower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());
10189
+ var accept = accepted;
10190
+ var STRTOL = /^[ \t\n\v\f\r]*([+-]?\d+)/;
10191
+ function doInt(v, s, min, max) {
10192
+ const m = STRTOL.exec(v);
10193
+ if (m === null) return ignored(warning(`Improper ${s} value ${v} - ignored`));
10194
+ const b = Number(m[1]);
10195
+ if (b > max) return ignored(warning(`${s} value ${v} > ${max} - too large - ignored`));
10196
+ if (b < min) return ignored(warning(`${s} value ${v} < ${min} - too small - ignored`));
10197
+ return accepted(v);
10198
+ }
10199
+ var intHandler = (s, min, max) => (v) => doInt(v, s, min, max);
10200
+ var UCHAR_MAX = 255;
10201
+ var SCHAR_MIN = -128;
10202
+ var SCHAR_MAX = 127;
10203
+ var INT8_MAX = 127;
10204
+ var USHRT_MAX = 65535;
10205
+ var GRADIENT_MAX = 360;
10206
+ var spanHandler = (s) => (v) => {
10207
+ const r = doInt(v, s, 0, USHRT_MAX);
10208
+ if (r.keep === void 0 || Number(STRTOL.exec(v)?.[1]) !== 0) return r;
10209
+ return ignored(warning(`${s} value cannot be 0 - ignored
10210
+ `));
10211
+ };
10212
+ var wordsHandler = (words, what) => (v) => words.includes(lower(v)) ? accepted(v) : ignored(warning(`Illegal value ${v} for ${what} - ignored
10213
+ `));
10214
+ var starHandler = (what) => (v) => v.startsWith("*") ? accepted(v) : ignored(warning(`Unknown value ${v} for ${what} - ignored
10215
+ `));
10216
+ var valign = wordsHandler(["bottom", "top", "middle"], "VALIGN");
10217
+ var fixedsize = wordsHandler(["true", "false"], "FIXEDSIZE");
10218
+ var tableAlign = wordsHandler(["left", "right", "center"], "ALIGN");
10219
+ var brAlign = tableAlign;
10220
+ var cellAlign = wordsHandler(["left", "right", "text", "center"], "ALIGN in TD");
10221
+ var balign = wordsHandler(["left", "right", "center"], "BALIGN in TD");
10222
+ var SIDES_LETTERS = "ltrb";
10223
+ var sides = (v) => {
10224
+ const text = [];
10225
+ for (const b of new TextEncoder().encode(v)) {
10226
+ if (SIDES_LETTERS.includes(lower(String.fromCharCode(b)))) continue;
10227
+ const code = b > SCHAR_MAX ? b - 256 : b;
10228
+ text.push(warning(`Unrecognized character '${String.fromCharCode(b)}' (${code}) in sides attribute
10229
+ `));
10230
+ }
10231
+ return { keep: v, text, warn: false };
10232
+ };
10233
+ var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
10234
+ var STYLE_DELIM = " ,";
10235
+ function styleTokens2(v) {
10236
+ const out = [];
10237
+ const span = (from, member) => {
10238
+ let i = from;
10239
+ while (i < v.length && STYLE_DELIM.includes(v[i]) === member) i++;
10240
+ return i;
10241
+ };
10242
+ let end = span(0, false);
10243
+ out.push(v.slice(0, end));
10244
+ while (end < v.length) {
10245
+ const start = span(end, true);
10246
+ end = span(start, false);
10247
+ out.push(v.slice(start, end));
10248
+ }
10249
+ return out;
10250
+ }
10251
+ var style = (v) => {
10252
+ const legal = [];
10253
+ const text = [];
10254
+ for (const tk of styleTokens2(v)) {
10255
+ if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
10256
+ else text.push(warning(`Illegal value ${tk} for STYLE - ignored
10257
+ `));
10258
+ }
10259
+ return { keep: legal.length > 0 ? legal.join(" ") : void 0, text, warn: text.length > 0 };
10260
+ };
10261
+ var border = intHandler("BORDER", 0, UCHAR_MAX);
10262
+ var cellpadding = intHandler("CELLPADDING", 0, UCHAR_MAX);
10263
+ var cellspacing = intHandler("CELLSPACING", SCHAR_MIN, SCHAR_MAX);
10264
+ var gradientangle = intHandler("GRADIENTANGLE", 0, GRADIENT_MAX);
10265
+ var height = intHandler("HEIGHT", 0, USHRT_MAX);
10266
+ var width = intHandler("WIDTH", 0, USHRT_MAX);
10267
+ var TBL_ITEMS = /* @__PURE__ */ new Map([
10268
+ ["align", tableAlign],
10269
+ ["bgcolor", accept],
10270
+ ["border", border],
10271
+ ["cellborder", intHandler("CELLBORDER", 0, INT8_MAX)],
10272
+ ["cellpadding", cellpadding],
10273
+ ["cellspacing", cellspacing],
10274
+ ["color", accept],
10275
+ ["columns", starHandler("COLUMNS")],
10276
+ ["fixedsize", fixedsize],
10277
+ ["gradientangle", gradientangle],
10278
+ ["height", height],
10279
+ ["href", accept],
10280
+ ["id", accept],
10281
+ ["port", accept],
10282
+ ["rows", starHandler("ROWS")],
10283
+ ["sides", sides],
10284
+ ["style", style],
10285
+ ["target", accept],
10286
+ ["title", accept],
10287
+ ["tooltip", accept],
10288
+ ["valign", valign],
10289
+ ["width", width]
10290
+ ]);
10291
+ var CELL_ITEMS = /* @__PURE__ */ new Map([
10292
+ ["align", cellAlign],
10293
+ ["balign", balign],
10294
+ ["bgcolor", accept],
10295
+ ["border", border],
10296
+ ["cellpadding", cellpadding],
10297
+ ["cellspacing", cellspacing],
10298
+ ["color", accept],
10299
+ ["colspan", spanHandler("COLSPAN")],
10300
+ ["fixedsize", fixedsize],
10301
+ ["gradientangle", gradientangle],
10302
+ ["height", height],
10303
+ ["href", accept],
10304
+ ["id", accept],
10305
+ ["port", accept],
10306
+ ["rowspan", spanHandler("ROWSPAN")],
10307
+ ["sides", sides],
10308
+ ["style", style],
10309
+ ["target", accept],
10310
+ ["title", accept],
10311
+ ["tooltip", accept],
10312
+ ["valign", valign],
10313
+ ["width", width]
10314
+ ]);
10315
+ var FONT_ITEMS = /* @__PURE__ */ new Map([
10316
+ ["color", accept],
10317
+ ["face", accept],
10318
+ ["point-size", intHandler("POINT-SIZE", 0, UCHAR_MAX)]
10319
+ ]);
10320
+ var IMG_ITEMS = /* @__PURE__ */ new Map([["scale", accept], ["src", accept]]);
10321
+ var BR_ITEMS = /* @__PURE__ */ new Map([["align", brAlign]]);
10322
+ var ELEMENTS = /* @__PURE__ */ new Map([
10323
+ ["TABLE", { items: TBL_ITEMS, name: "<TABLE>" }],
10324
+ ["TD", { items: CELL_ITEMS, name: "<TD>" }],
10325
+ ["FONT", { items: FONT_ITEMS, name: "<FONT>" }],
10326
+ ["IMG", { items: IMG_ITEMS, name: "<IMG>" }],
10327
+ ["BR", { items: BR_ITEMS, name: "<BR>" }]
10328
+ ]);
10329
+ function checkAttrs(tag, pairs) {
10330
+ const el = ELEMENTS.get(tag);
10331
+ const attrs = {};
10332
+ const warnings = [];
10333
+ let warn = false;
10334
+ for (const [name, value] of pairs) {
10335
+ const key = lower(name);
10336
+ if (el === void 0) {
10337
+ attrs[key] = value;
10338
+ continue;
10339
+ }
10340
+ const handler = el.items.get(key);
10341
+ if (handler === void 0) {
10342
+ warnings.push(warning(`Illegal attribute ${name} in ${el.name} - ignored
10343
+ `));
10344
+ warn = true;
10345
+ continue;
10346
+ }
10347
+ const r = handler(value);
10348
+ warnings.push(...r.text);
10349
+ warn ||= r.warn;
10350
+ if (r.keep !== void 0) attrs[key] = r.keep;
10351
+ }
10352
+ return { attrs, warnings, warn };
10353
+ }
10354
+ var StderrLines = class {
10355
+ constructor(writeLine) {
10356
+ this.writeLine = writeLine;
10357
+ }
10358
+ writeLine;
10359
+ pending = "";
10360
+ write(text) {
10361
+ const parts = (this.pending + text).split("\n");
10362
+ this.pending = parts.pop() ?? "";
10363
+ for (const line of parts) this.writeLine(line);
10364
+ }
10365
+ flush() {
10366
+ if (this.pending === "") return;
10367
+ this.writeLine(this.pending);
10368
+ this.pending = "";
10369
+ }
10370
+ };
10371
+
10372
+ // src/common/htmltable-parse-state.ts
10373
+ var peek = (s) => s.tokens[s.pos];
10374
+ var emitWarnings = (s, tok) => {
10375
+ if (s.stderr === void 0 || s.emitted?.has(tok) === true) return;
10376
+ s.emitted?.add(tok);
10377
+ emitOutput(s, tok);
10378
+ };
10379
+ var emitOutput = (s, out) => {
10380
+ for (const text of out.warnings ?? []) s.stderr?.write(text);
10381
+ if (out.warn === true) s.warn = true;
10382
+ };
10383
+ var emitEof = (s) => {
10384
+ if (s.stderr === void 0 || s.eof === void 0) return;
10385
+ const out = s.eof;
10386
+ delete s.eof;
10387
+ emitOutput(s, out);
10388
+ };
10389
+ var consume = (s) => {
10390
+ const t = s.tokens[s.pos];
10391
+ s.pos++;
10392
+ if (t !== void 0) emitWarnings(s, t);
10393
+ return t;
10394
+ };
10395
+
9966
10396
  // src/common/html-entities.ts
9967
10397
  var HTML_ENTITIES = {
9968
10398
  "AElig": 198,
@@ -10242,6 +10672,286 @@ function htmlEntityUTF8(s) {
10242
10672
  });
10243
10673
  }
10244
10674
 
10675
+ // src/common/htmltable-lex-expat.ts
10676
+ var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
10677
+ var XML_CONTEXT_BYTES = 1024;
10678
+ var INIT_BUFFER_SIZE = 1024;
10679
+ var COMPLETE_END = (end, dup) => dup === void 0 ? { kind: "complete", end } : { kind: "complete", end, dup };
10680
+ var PARTIAL = { kind: "partial" };
10681
+ var INVALID = (offset) => ({ kind: "invalid", offset });
10682
+ var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
10683
+ var isSpace = (c) => c !== void 0 && /\s/.test(c);
10684
+ function skipSpace(text, i) {
10685
+ let j = i;
10686
+ while (isSpace(text[j])) j++;
10687
+ return j;
10688
+ }
10689
+ var byteLength = (s) => new TextEncoder().encode(s).length;
10690
+ function fedBytes(unit, isText) {
10691
+ if (!isText) return byteLength(unit);
10692
+ let text = unit.replace(/&([^;&<]*);/g, (m, name) => {
10693
+ return name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name) ? `&#${HTML_ENTITIES[name]};` : m;
10694
+ });
10695
+ if (text.endsWith("]")) text = `${text.slice(0, -1)}&#93;`;
10696
+ return byteLength(text);
10697
+ }
10698
+ function scanValue(text, j) {
10699
+ const q = text[j];
10700
+ if (q !== '"' && q !== "'") return INVALID(j);
10701
+ const close = text.indexOf(q, j + 1);
10702
+ if (close < 0) {
10703
+ const lt = text.indexOf("<", j + 1);
10704
+ return lt >= 0 ? INVALID(lt) : PARTIAL;
10705
+ }
10706
+ const next = skipSpace(text, close + 1);
10707
+ if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
10708
+ return next;
10709
+ }
10710
+ function scanPair(text, i) {
10711
+ const name = XML_NAME.exec(text.slice(i))?.[0];
10712
+ if (name === void 0) return INVALID(i);
10713
+ const eq = skipSpace(text, i + name.length);
10714
+ if (eq >= text.length) return PARTIAL;
10715
+ if (text[eq] !== "=") return INVALID(eq);
10716
+ const j = skipSpace(text, eq + 1);
10717
+ if (j >= text.length) return PARTIAL;
10718
+ const next = scanValue(text, j);
10719
+ return typeof next === "number" ? { name, next } : next;
10720
+ }
10721
+ function tagEdge(text, i) {
10722
+ const c = text[i];
10723
+ if (c === void 0) return PARTIAL;
10724
+ if (c === ">") return COMPLETE_END(i + 1);
10725
+ if (c !== "/") return void 0;
10726
+ if (i + 1 >= text.length) return PARTIAL;
10727
+ return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
10728
+ }
10729
+ function scanAttributes(text, from) {
10730
+ const seen = /* @__PURE__ */ new Set();
10731
+ let dup;
10732
+ let i = skipSpace(text, from);
10733
+ for (; ; ) {
10734
+ const edge = tagEdge(text, i);
10735
+ if (edge?.kind === "complete") return COMPLETE_END(edge.end, dup);
10736
+ if (edge !== void 0) return edge;
10737
+ const pair = scanPair(text, i);
10738
+ if ("kind" in pair) return pair;
10739
+ if (seen.has(pair.name)) dup ??= i;
10740
+ seen.add(pair.name);
10741
+ i = pair.next;
10742
+ }
10743
+ }
10744
+ function scanName(text, at) {
10745
+ const name = XML_NAME.exec(text.slice(at))?.[0];
10746
+ if (name === void 0) return at >= text.length ? PARTIAL : INVALID(at);
10747
+ return { next: at + name.length };
10748
+ }
10749
+ function scanStartTag(text, p) {
10750
+ const name = scanName(text, p + 1);
10751
+ if ("kind" in name) return name;
10752
+ const c = text[name.next];
10753
+ if (c === void 0) return PARTIAL;
10754
+ if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
10755
+ return scanAttributes(text, name.next);
10756
+ }
10757
+ function scanEndTag(text, p) {
10758
+ const name = scanName(text, p + 2);
10759
+ if ("kind" in name) return name;
10760
+ const i = skipSpace(text, name.next);
10761
+ if (i >= text.length) return PARTIAL;
10762
+ return text[i] === ">" ? COMPLETE_END(i + 1) : INVALID(i);
10763
+ }
10764
+ function scanPi(text, p) {
10765
+ const e = text.indexOf("?>", p + 2);
10766
+ return e < 0 ? PARTIAL : COMPLETE_END(e + 2);
10767
+ }
10768
+ function scanDeclaration(text, p) {
10769
+ const cdata = "<![CDATA[".startsWith(text.slice(p, p + 9));
10770
+ if (!cdata && text.length - p >= 3) return INVALID(p + 2);
10771
+ for (let i = p + 1; i < text.length; i++) {
10772
+ if (text[i] === ">") return COMPLETE_END(i + 1);
10773
+ if (text[i] === "<") return INVALID(i);
10774
+ }
10775
+ return PARTIAL;
10776
+ }
10777
+ function scanComment(text, p) {
10778
+ for (let i = p + 4; i < text.length; i++) {
10779
+ if (text[i] !== "-") continue;
10780
+ if (i + 1 >= text.length) return PARTIAL;
10781
+ if (text[i + 1] !== "-") continue;
10782
+ if (i + 2 >= text.length) return PARTIAL;
10783
+ return text[i + 2] === ">" ? COMPLETE_END(i + 3) : INVALID(i + 2);
10784
+ }
10785
+ return PARTIAL;
10786
+ }
10787
+ function scanMarkup(text, p) {
10788
+ const rest = text.slice(p, p + 4);
10789
+ if (rest === "<!--") return { scan: scanComment(text, p), kind: "comment" };
10790
+ if (text.length - p < 4 && "<!--".startsWith(rest)) return { scan: PARTIAL, kind: "comment" };
10791
+ if (rest.startsWith("<!-")) return { scan: INVALID(p + 3), kind: "comment" };
10792
+ const c = text[p + 1];
10793
+ if (c === "/") return { scan: scanEndTag(text, p), kind: "tag" };
10794
+ if (c === "?") return { scan: scanPi(text, p), kind: "pi" };
10795
+ if (c === "!") return { scan: scanDeclaration(text, p), kind: "tag" };
10796
+ return { scan: scanStartTag(text, p), kind: "tag" };
10797
+ }
10798
+ function scanContent(text, base) {
10799
+ const tokens = [];
10800
+ let p = 0;
10801
+ while (p < text.length) {
10802
+ if (text[p] !== "<") {
10803
+ const e = text.indexOf("<", p);
10804
+ const end = e < 0 ? text.length : e;
10805
+ tokens.push({ kind: "text", start: base + p, end: base + end });
10806
+ p = end;
10807
+ continue;
10808
+ }
10809
+ const { scan, kind } = scanMarkup(text, p);
10810
+ if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset };
10811
+ if (scan.kind === "partial") return { tokens, consumed: p };
10812
+ const tok = { kind, start: base + p, end: base + scan.end };
10813
+ if (scan.dup !== void 0) tok.dup = base + scan.dup;
10814
+ tokens.push(tok);
10815
+ p = scan.end;
10816
+ }
10817
+ return { tokens, consumed: p };
10818
+ }
10819
+ var InputBuffer = class {
10820
+ size = 0;
10821
+ ptr = 0;
10822
+ end = 0;
10823
+ lastRequest = 0;
10824
+ /** Bytes the last attempt could not consume; 0 once something was. */
10825
+ hadBefore = 0;
10826
+ /** `XML_GetBuffer(len)` then the append of `len` bytes. */
10827
+ append(len) {
10828
+ this.lastRequest = len;
10829
+ if (len > this.size - this.end) {
10830
+ const keep = Math.min(this.ptr, XML_CONTEXT_BYTES);
10831
+ const needed = len + (this.end - this.ptr) + keep;
10832
+ if (needed > this.size) {
10833
+ let grown = this.size;
10834
+ if (grown === 0) grown = INIT_BUFFER_SIZE;
10835
+ do
10836
+ grown *= 2;
10837
+ while (grown < needed);
10838
+ this.size = grown;
10839
+ }
10840
+ this.end = this.end - this.ptr + keep;
10841
+ this.ptr = keep;
10842
+ }
10843
+ this.end += len;
10844
+ }
10845
+ /** Bytes between the read pointer and the end of the data. */
10846
+ get have() {
10847
+ return this.end - this.ptr;
10848
+ }
10849
+ /** `callProcessor`: is it worth re-reading the partial token now? */
10850
+ get enough() {
10851
+ const available = this.ptr - Math.min(this.ptr, XML_CONTEXT_BYTES) + (this.size - this.end);
10852
+ return this.have >= 2 * this.hadBefore || this.lastRequest > available;
10853
+ }
10854
+ /** After an attempt that left `remaining` bytes unconsumed. */
10855
+ consumedTo(remaining, madeProgress) {
10856
+ this.hadBefore = madeProgress ? 0 : this.have;
10857
+ this.ptr = this.end - remaining;
10858
+ }
10859
+ };
10860
+ var ExpatFeed = class {
10861
+ constructor(src) {
10862
+ this.src = src;
10863
+ }
10864
+ src;
10865
+ buffer = new InputBuffer();
10866
+ heldStart = 0;
10867
+ fedEnd = 0;
10868
+ /** Start of the token expat still holds, or undefined when it holds nothing. */
10869
+ get held() {
10870
+ return this.heldStart < this.fedEnd ? this.heldStart : void 0;
10871
+ }
10872
+ /** One `XML_Parse(parser, src[start, end), nbytes, 0)`. */
10873
+ feed(start, end, nbytes) {
10874
+ this.buffer.append(nbytes);
10875
+ this.fedEnd = end;
10876
+ if (!this.buffer.enough) return { tokens: [] };
10877
+ const text = this.src.slice(this.heldStart, end);
10878
+ const scan = scanContent(text, this.heldStart);
10879
+ if (scan.invalid !== void 0) {
10880
+ return { tokens: scan.tokens, invalid: { message: XML_ERROR_INVALID_TOKEN, offset: scan.invalid } };
10881
+ }
10882
+ this.heldStart += scan.consumed;
10883
+ this.buffer.consumedTo(byteLength(this.src.slice(this.heldStart, end)), scan.consumed > 0);
10884
+ return { tokens: scan.tokens };
10885
+ }
10886
+ };
10887
+ var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
10888
+ var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
10889
+ function findUndefinedEntity(text) {
10890
+ for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
10891
+ if (text[t + 1] === "#") continue;
10892
+ const semi = text.indexOf(";", t + 1);
10893
+ if (semi < 0) continue;
10894
+ const key = text.slice(t + 1, semi);
10895
+ if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
10896
+ return t;
10897
+ }
10898
+ }
10899
+ return -1;
10900
+ }
10901
+ function parseTagChunk(chunk) {
10902
+ if (!chunk.endsWith(">")) return void 0;
10903
+ const body = chunk.slice(1, -1);
10904
+ if (body.startsWith("!")) return void 0;
10905
+ const close = body.startsWith("/");
10906
+ const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
10907
+ return { close, selfClose: !close && body.endsWith("/"), name };
10908
+ }
10909
+
10910
+ // src/common/htmltable-lex-units.ts
10911
+ var UNCLOSED_COMMENT = "Warning: Unclosed comment\n";
10912
+ var LABEL_CLOSED = "Warning: Label closed before end of HTML element\n";
10913
+ function eatComment(label, p) {
10914
+ let depth = 1;
10915
+ let s = p;
10916
+ while (depth > 0 && s < label.length) {
10917
+ const c = label[s++];
10918
+ if (c === "<") depth++;
10919
+ else if (c === ">") depth--;
10920
+ }
10921
+ if (depth === 0) s--;
10922
+ const warnings = [];
10923
+ if (s < label.length) {
10924
+ const t = s - 2;
10925
+ if (t < p || !label.startsWith("--", t)) warnings.push(UNCLOSED_COMMENT);
10926
+ }
10927
+ return { at: s, warnings };
10928
+ }
10929
+ function findNext(label, s) {
10930
+ let t = s + 1;
10931
+ const warnings = [];
10932
+ let warn = false;
10933
+ if (label[s] === "<") {
10934
+ if (label.startsWith("!--", t)) {
10935
+ const eaten = eatComment(label, t + 3);
10936
+ t = eaten.at;
10937
+ warnings.push(...eaten.warnings);
10938
+ warn = eaten.warnings.length > 0;
10939
+ } else {
10940
+ while (t < label.length && label[t] !== ">") t++;
10941
+ }
10942
+ if (label[t] !== ">") {
10943
+ warnings.push(LABEL_CLOSED);
10944
+ warn = true;
10945
+ } else {
10946
+ t++;
10947
+ }
10948
+ } else {
10949
+ t = s;
10950
+ while (t < label.length && label[t] !== "<") t++;
10951
+ }
10952
+ return { end: t, warnings, warn };
10953
+ }
10954
+
10245
10955
  // src/common/htmltable-lex.ts
10246
10956
  var KNOWN_TAGS = /* @__PURE__ */ new Set([
10247
10957
  "TABLE",
@@ -10268,15 +10978,15 @@ function checkTag(tag) {
10268
10978
  }
10269
10979
  }
10270
10980
  var isWs = (c) => c === " " || c === " " || c === "\n" || c === "\r";
10271
- function parseAttrs(raw) {
10272
- const out = {};
10981
+ function parseAttrPairs(raw) {
10982
+ const out = [];
10273
10983
  let i = 0;
10274
10984
  while (i < raw.length) {
10275
10985
  while (isWs(raw[i])) i++;
10276
10986
  if (i >= raw.length) break;
10277
10987
  const m = /^[\w-]+/.exec(raw.slice(i));
10278
10988
  if (m === null) throw new HtmlParseError(raw.slice(i, i + 10));
10279
- const name = m[0].toLowerCase();
10989
+ const name = m[0];
10280
10990
  i += m[0].length;
10281
10991
  while (isWs(raw[i])) i++;
10282
10992
  if (raw[i] !== "=") throw new HtmlParseError(name);
@@ -10286,7 +10996,7 @@ function parseAttrs(raw) {
10286
10996
  if (q !== '"' && q !== "'") throw new HtmlParseError(name);
10287
10997
  const end = raw.indexOf(q, i + 1);
10288
10998
  if (end < 0) throw new HtmlParseError(name);
10289
- out[name] = raw.slice(i + 1, end);
10999
+ out.push([name, raw.slice(i + 1, end)]);
10290
11000
  i = end + 1;
10291
11001
  }
10292
11002
  return out;
@@ -10305,48 +11015,36 @@ function cleanText(raw) {
10305
11015
  const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
10306
11016
  return raw.replace(/[\x00-\x1f\x7f]/g, (c) => isKeep(c) ? c : "");
10307
11017
  }
10308
- function scanText(src, start, tokens) {
10309
- let j = start;
10310
- while (j < src.length && src[j] !== "<") j++;
10311
- const clean = htmlEntityUTF8(cleanText(src.slice(start, j)));
10312
- if (clean.length > 0) tokens.push({ type: "text", value: clean });
10313
- return j;
11018
+ function textTokens(raw) {
11019
+ const clean = htmlEntityUTF8(cleanText(raw));
11020
+ return clean.length > 0 ? [{ type: "text", value: clean }] : [];
10314
11021
  }
10315
- function scanTag(src, start, tokens) {
10316
- let j = start + 1;
10317
- while (j < src.length && src[j] !== ">") j++;
10318
- const inner = src.slice(start + 1, j).trim();
10319
- const next = j + 1;
10320
- if (inner.startsWith("!--")) return next;
10321
- if (inner.startsWith("/")) {
10322
- tokens.push(parseCloseToken(inner));
10323
- return next;
10324
- }
11022
+ function tagTokens(text) {
11023
+ const inner = text.slice(1, -1).trim();
11024
+ if (inner.startsWith("/")) return [parseCloseToken(inner)];
10325
11025
  if (inner.endsWith("/")) {
10326
11026
  const open = parseOpenToken(inner.slice(0, -1).trim());
10327
- tokens.push(open, { type: "close", tag: open.tag });
10328
- return next;
11027
+ return [open, { type: "close", tag: open.tag }];
10329
11028
  }
10330
- tokens.push(parseOpenToken(inner));
10331
- return next;
11029
+ return [parseOpenToken(inner)];
11030
+ }
11031
+ function openToken(tag, raw) {
11032
+ const { attrs, warnings, warn } = checkAttrs(tag, parseAttrPairs(raw));
11033
+ const tok = { type: "open", tag, attrs };
11034
+ if (warnings.length > 0) tok.warnings = warnings;
11035
+ if (warn) tok.warn = true;
11036
+ return tok;
10332
11037
  }
10333
11038
  function parseOpenToken(inner) {
10334
11039
  const sp = inner.search(/\s/);
10335
- if (sp === -1) {
10336
- const tag2 = inner.toUpperCase();
10337
- checkTag(tag2);
10338
- return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
10339
- }
10340
- const tag = inner.slice(0, sp).toUpperCase();
11040
+ const tag = (sp === -1 ? inner : inner.slice(0, sp)).toUpperCase();
10341
11041
  checkTag(tag);
10342
- return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
11042
+ return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
10343
11043
  }
10344
11044
  var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
10345
11045
  var XML_ERROR_TAG_MISMATCH = "mismatched tag";
10346
- var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
10347
11046
  var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
10348
- var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
10349
- var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
11047
+ var SYNTAX_ERROR = "syntax error";
10350
11048
  var HtmlLexError = class extends HtmlParseError {
10351
11049
  diagnostics;
10352
11050
  constructor(tag, message, diagnostics) {
@@ -10378,112 +11076,131 @@ function htmlErrorAtToken(message, tok) {
10378
11076
  if (info === void 0) return void 0;
10379
11077
  return htmlErrorInLine(message, chunkLine(info), info.context);
10380
11078
  }
10381
- function chunkEnd(src, i) {
10382
- const j = src[i] === "<" ? src.indexOf(">", i + 1) : src.indexOf("<", i);
10383
- if (j < 0) return src.length;
10384
- return src[i] === "<" ? j + 1 : j;
10385
- }
10386
- function findUndefinedEntity(text) {
10387
- for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
10388
- if (text[t + 1] === "#") continue;
10389
- const semi = text.indexOf(";", t + 1);
10390
- if (semi < 0) continue;
10391
- const key = text.slice(t + 1, semi);
10392
- if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
10393
- return t;
10394
- }
10395
- }
10396
- return -1;
10397
- }
10398
- function parseTagChunk(chunk) {
10399
- if (!chunk.endsWith(">")) return void 0;
10400
- const body = chunk.slice(1, -1);
10401
- if (body.startsWith("!")) return void 0;
10402
- const close = body.startsWith("/");
10403
- const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
10404
- return { close, selfClose: !close && body.endsWith("/"), name };
10405
- }
10406
- var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
10407
- var isSpace = (c) => c !== void 0 && /\s/.test(c);
10408
- var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
10409
- function skipSpace(chunk, i) {
10410
- let j = i;
10411
- while (isSpace(chunk[j])) j++;
10412
- return j;
10413
- }
10414
- function readAttrPair(chunk, i) {
10415
- const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
10416
- if (name === void 0) return invalidToken(i);
10417
- let j = skipSpace(chunk, i + name.length);
10418
- if (chunk[j] !== "=") return invalidToken(j);
10419
- j = skipSpace(chunk, j + 1);
10420
- const q = chunk[j];
10421
- if (q !== '"' && q !== "'") return invalidToken(j);
10422
- const end = chunk.indexOf(q, j + 1);
10423
- return end < 0 ? void 0 : { name, next: end + 1 };
10424
- }
10425
- function findAttrError(chunk, from) {
10426
- const seen = /* @__PURE__ */ new Set();
10427
- let dup;
10428
- let i = skipSpace(chunk, from);
10429
- while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
10430
- const pair = readAttrPair(chunk, i);
10431
- if (pair === void 0) return void 0;
10432
- if ("message" in pair) return pair;
10433
- if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
10434
- seen.add(pair.name);
10435
- i = skipSpace(chunk, pair.next);
10436
- }
10437
- return dup;
10438
- }
10439
- function checkTagChunk(src, start, st) {
10440
- const tag = parseTagChunk(st.curr);
11079
+ function checkTagToken(site) {
11080
+ const { src, tok, st } = site;
11081
+ const tag = parseTagChunk(src.slice(tok.start, tok.end));
10441
11082
  if (tag === void 0) return;
11083
+ const context = st.prev + st.curr;
10442
11084
  if (tag.close) {
10443
11085
  if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
10444
- throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start), st.prev + st.curr);
11086
+ throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
10445
11087
  }
10446
11088
  } else {
10447
- const bad = findAttrError(st.curr, 1 + tag.name.length);
10448
- if (bad !== void 0) {
10449
- throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
10450
- }
11089
+ if (tok.dup !== void 0) throw htmlErrorInLine(XML_ERROR_DUPLICATE_ATTRIBUTE, lineAt(src, tok.dup), context);
10451
11090
  if (!tag.selfClose) st.stack.push(tag.name);
10452
11091
  }
10453
11092
  if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
10454
- const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
11093
+ const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, tok.start)} `;
10455
11094
  throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
10456
11095
  }
10457
- function checkChunk(src, start, st) {
10458
- if (st.curr.startsWith("<")) {
10459
- checkTagChunk(src, start, st);
10460
- return;
11096
+ function eventTokens(site) {
11097
+ const { src, tok, st } = site;
11098
+ const text = src.slice(tok.start, tok.end);
11099
+ if (tok.kind === "comment" || tok.kind === "pi") return [];
11100
+ if (tok.kind === "tag") {
11101
+ checkTagToken(site);
11102
+ return tagTokens(text);
10461
11103
  }
10462
- const off = findUndefinedEntity(st.curr);
11104
+ const off = findUndefinedEntity(text);
10463
11105
  if (off >= 0) {
10464
- throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
11106
+ throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
11107
+ }
11108
+ return textTokens(text);
11109
+ }
11110
+ function attachCarry(carry, first) {
11111
+ if (carry.warnings.length > 0) first.warnings = [...carry.warnings, ...first.warnings ?? []];
11112
+ if (carry.warn) first.warn = true;
11113
+ carry.warnings = [];
11114
+ carry.warn = false;
11115
+ }
11116
+ function absorb(carry, lost) {
11117
+ for (const t of lost) {
11118
+ carry.warnings.push(...t.warnings ?? []);
11119
+ if (t.warn === true) carry.warn = true;
11120
+ }
11121
+ }
11122
+ function eventGroups(run, res) {
11123
+ const groups = [];
11124
+ for (const tok of res.tokens) {
11125
+ const tokens = eventTokens({ src: run.src, tok, st: run.st });
11126
+ if (tokens.length > 0) groups.push({ tokens, tok });
11127
+ }
11128
+ if (res.invalid !== void 0) {
11129
+ const { message, offset } = res.invalid;
11130
+ throw htmlErrorInLine(message, lineAt(run.src, offset), run.st.prev + run.st.curr);
11131
+ }
11132
+ return groups;
11133
+ }
11134
+ function deliver(run, last) {
11135
+ const first = last.tokens[0];
11136
+ attachCarry(run.carry, first);
11137
+ const info = { src: run.src, pos: last.tok.start, end: last.tok.end, context: run.st.prev + run.st.curr };
11138
+ const prev = run.tokens.at(-1);
11139
+ if (prev?.type === "text" && first.type === "text") {
11140
+ appendString(prev, first);
11141
+ chunkInfo.set(prev, { ...info, pos: chunkInfo.get(prev)?.pos ?? info.pos });
11142
+ return;
10465
11143
  }
11144
+ for (const t of last.tokens) chunkInfo.set(t, info);
11145
+ run.tokens.push(...last.tokens);
10466
11146
  }
10467
- function tokenizeDeferred(src) {
10468
- const tokens = [];
10469
- const st = { stack: [], prev: "", curr: "" };
10470
- let i = 0;
11147
+ function runEvents(run, res) {
11148
+ const groups = eventGroups(run, res);
11149
+ const last = groups.pop();
11150
+ for (const g of groups) absorb(run.carry, g.tokens);
11151
+ if (last !== void 0) deliver(run, last);
11152
+ }
11153
+ function appendString(into, more) {
11154
+ into.value += more.value;
11155
+ if (more.warnings !== void 0) into.warnings = [...into.warnings ?? [], ...more.warnings];
11156
+ if (more.warn === true) into.warn = true;
11157
+ }
11158
+ function* lexUnits(src, label) {
11159
+ if (label.start > 0) yield { start: 0, end: label.start, warnings: [], warn: false };
11160
+ const text = src.slice(label.start, label.end);
11161
+ for (let at = 0; at < text.length; ) {
11162
+ const u = findNext(text, at);
11163
+ yield { start: label.start + at, end: label.start + u.end, warnings: u.warnings, warn: u.warn };
11164
+ at = u.end;
11165
+ }
11166
+ if (label.end < src.length) yield { start: label.end, end: src.length, warnings: [], warn: false };
11167
+ }
11168
+ function unfinishedError(run, held) {
11169
+ return htmlErrorInLine(SYNTAX_ERROR, lineAt(run.src, held), run.st.prev + run.st.curr);
11170
+ }
11171
+ var eofOutput = (carry) => {
11172
+ if (carry.warnings.length === 0 && !carry.warn) return void 0;
11173
+ return carry.warn ? { warnings: carry.warnings, warn: true } : { warnings: carry.warnings };
11174
+ };
11175
+ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
11176
+ const run = {
11177
+ src,
11178
+ tokens: [],
11179
+ st: { stack: [], prev: "", curr: "" },
11180
+ expat: new ExpatFeed(src),
11181
+ carry: { warnings: [], warn: false }
11182
+ };
11183
+ let error;
10471
11184
  try {
10472
- while (i < src.length) {
10473
- const first = tokens.length;
10474
- const start = i;
10475
- st.prev = st.curr;
10476
- st.curr = src.slice(i, chunkEnd(src, i));
10477
- checkChunk(src, i, st);
10478
- i = src[i] === "<" ? scanTag(src, i, tokens) : scanText(src, i, tokens);
10479
- const info = { src, pos: start, end: i, context: st.prev + st.curr };
10480
- for (let k = first; k < tokens.length; k++) chunkInfo.set(tokens[k], info);
10481
- }
11185
+ for (const u of lexUnits(src, label)) {
11186
+ run.st.prev = run.st.curr;
11187
+ run.st.curr = src.slice(u.start, u.end);
11188
+ run.carry.warnings.push(...u.warnings);
11189
+ if (u.warn) run.carry.warn = true;
11190
+ const nbytes = fedBytes(run.st.curr, !run.st.curr.startsWith("<"));
11191
+ runEvents(run, run.expat.feed(u.start, u.end, nbytes));
11192
+ }
11193
+ const held = run.expat.held;
11194
+ if (held !== void 0) error = unfinishedError(run, held);
10482
11195
  } catch (e) {
10483
- if (e instanceof HtmlParseError) return { tokens, error: e };
10484
- throw e;
11196
+ if (!(e instanceof HtmlParseError)) throw e;
11197
+ error = e;
10485
11198
  }
10486
- return { tokens };
11199
+ const result = { tokens: run.tokens };
11200
+ if (error !== void 0) result.error = error;
11201
+ const eof = eofOutput(run.carry);
11202
+ if (eof !== void 0) result.eof = eof;
11203
+ return result;
10487
11204
  }
10488
11205
 
10489
11206
  // src/common/htmltable-parse-attrs.ts
@@ -10523,15 +11240,9 @@ var parseSides = (v) => {
10523
11240
  if (flags === 0 || flags === BORDER_MASK) return void 0;
10524
11241
  return flags;
10525
11242
  };
10526
- var parseGradientAngle = (v) => {
10527
- if (v === void 0) return void 0;
10528
- const n = parseInt(v, 10);
10529
- if (isNaN(n) || String(n) !== v.trim()) return void 0;
10530
- if (n < 0 || n > 360) return void 0;
10531
- return n;
10532
- };
10533
- var parseColumns = (v) => v === "*" ? true : void 0;
10534
- var parseRows = (v) => v === "*" ? true : void 0;
11243
+ var parseGradientAngle = (v) => num(v);
11244
+ var parseColumns = (v) => v?.startsWith("*") === true ? true : void 0;
11245
+ var parseRows = (v) => v?.startsWith("*") === true ? true : void 0;
10535
11246
  var buildCell = (content, a) => ({
10536
11247
  kind: "cell",
10537
11248
  content,
@@ -10583,7 +11294,7 @@ var buildTable = (rows, a) => ({
10583
11294
  hrule: parseRows(a["rows"])
10584
11295
  });
10585
11296
 
10586
- // src/common/htmltable-parse.ts
11297
+ // src/common/htmltable-parse-font.ts
10587
11298
  var definedOf = (s) => Object.fromEntries(
10588
11299
  Object.entries(s).filter(([, v]) => v !== void 0)
10589
11300
  );
@@ -10607,17 +11318,6 @@ var fontItemProps = (f) => {
10607
11318
  if (f.fontSize !== void 0) out.fontSize = f.fontSize;
10608
11319
  return out;
10609
11320
  };
10610
- var MSG_SYNTAX_ERROR = "syntax error";
10611
- var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
10612
- var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
10613
- var nonSpace = (text) => /[^ \t\n\r]/.test(text);
10614
- var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
10615
- var peek = (s) => s.tokens[s.pos];
10616
- var consume = (s) => {
10617
- const t = s.tokens[s.pos];
10618
- s.pos++;
10619
- return t;
10620
- };
10621
11321
  var isInlineTag = (tag) => ["B", "I", "U", "O", "S", "SUB", "SUP"].includes(tag);
10622
11322
  var inlineFontState = (tag, _attrs) => {
10623
11323
  const fs = {};
@@ -10630,6 +11330,35 @@ var inlineFontState = (tag, _attrs) => {
10630
11330
  if (tag === "SUP") fs.superscript = true;
10631
11331
  return fs;
10632
11332
  };
11333
+ var wrapperFont = (t, fontStack) => {
11334
+ const font = fontStack[fontStack.length - 1] ?? {};
11335
+ if (t.tag !== "FONT") return mergeFontState(font, inlineFontState(t.tag, t.attrs));
11336
+ return mergeFontState(font, {
11337
+ fontColor: t.attrs["color"],
11338
+ fontFace: t.attrs["face"],
11339
+ fontSize: num(t.attrs["point-size"])
11340
+ });
11341
+ };
11342
+ var tableFont = (fontStack) => {
11343
+ if (fontStack.length < 2) return void 0;
11344
+ const { fontColor, fontFace, fontSize } = fontStack[fontStack.length - 1];
11345
+ const font = {};
11346
+ if (fontColor !== void 0) font.fontColor = fontColor;
11347
+ if (fontFace !== void 0) font.fontFace = fontFace;
11348
+ if (fontSize !== void 0) font.fontSize = fontSize;
11349
+ return font;
11350
+ };
11351
+
11352
+ // src/common/htmltable-parse.ts
11353
+ var MSG_SYNTAX_ERROR = "syntax error";
11354
+ var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
11355
+ var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
11356
+ var nonSpace = (text) => /[^ \t\n\r]/.test(text);
11357
+ var parseError = (s, tok, message) => {
11358
+ if (tok !== void 0) emitWarnings(s, tok);
11359
+ else emitEof(s);
11360
+ return (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
11361
+ };
10633
11362
  var consumeClose = (s, tag) => {
10634
11363
  const nxt = peek(s);
10635
11364
  if (nxt === void 0) return;
@@ -10700,6 +11429,45 @@ var parseText = (s, fontStack) => {
10700
11429
  }
10701
11430
  return { kind: "text", items };
10702
11431
  };
11432
+ var FONTTABLE_TAGS = ["FONT", "B", "I", "U", "O"];
11433
+ var fontTableWrapper = (s) => {
11434
+ const open = peek(s);
11435
+ if (open?.type !== "open" || !FONTTABLE_TAGS.includes(open.tag)) return void 0;
11436
+ let i = s.pos + 1;
11437
+ while (s.tokens[i]?.type === "text") i++;
11438
+ const next = s.tokens[i];
11439
+ return next?.type === "open" && next.tag === "TABLE" ? open : void 0;
11440
+ };
11441
+ var skipStrings = (s) => {
11442
+ let found = false;
11443
+ for (let t = peek(s); t?.type === "text"; t = peek(s)) {
11444
+ consume(s);
11445
+ if (nonSpace(t.value)) found = true;
11446
+ }
11447
+ return found;
11448
+ };
11449
+ var parseFontTable = (s, open, fontStack) => {
11450
+ consume(s);
11451
+ fontStack.push(wrapperFont(open, fontStack));
11452
+ const textBefore = skipStrings(s);
11453
+ const tblTok = peek(s);
11454
+ if (textBefore && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
11455
+ const table = parseTable(s, fontStack);
11456
+ const textAfter = skipStrings(s);
11457
+ const close = peek(s);
11458
+ if (close !== void 0 && textAfter) throw parseError(s, close, MSG_TEXT_AFTER_TABLE);
11459
+ if (close?.type !== "close" || close.tag !== open.tag) throw parseError(s, close, MSG_SYNTAX_ERROR);
11460
+ consume(s);
11461
+ fontStack.pop();
11462
+ return table;
11463
+ };
11464
+ var rejectTableAfterTag = (s, start) => {
11465
+ const nxt = peek(s);
11466
+ if (nxt?.type !== "open" || nxt.tag !== "TABLE") return;
11467
+ if (s.tokens.slice(start, s.pos).some((t) => t.type !== "text")) {
11468
+ throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11469
+ }
11470
+ };
10703
11471
  var parseImgContent = (s, t, cellAttrs) => {
10704
11472
  consume(s);
10705
11473
  const img = {
@@ -10721,6 +11489,7 @@ var scanCellText = (s, t, fontStack, st) => {
10721
11489
  const start = s.pos;
10722
11490
  const txt = parseText(s, fontStack);
10723
11491
  if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
11492
+ rejectTableAfterTag(s, start);
10724
11493
  if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
10725
11494
  st.kind = "text";
10726
11495
  return txt.items.length > 0 ? [txt] : [];
@@ -10737,7 +11506,13 @@ var scanCellImage = (s, t, cellAttrs, st) => {
10737
11506
  return [parseImgContent(s, t, cellAttrs)];
10738
11507
  };
10739
11508
  var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
11509
+ if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
10740
11510
  if (st.kind === "table") return scanAfterTable(s, t, st);
11511
+ const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
11512
+ if (wrapper !== void 0) {
11513
+ st.kind = "fonttable";
11514
+ return [parseFontTable(s, wrapper, fontStack)];
11515
+ }
10741
11516
  if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
10742
11517
  if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
10743
11518
  if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
@@ -10840,7 +11615,10 @@ var parseTable = (s, fontStack) => {
10840
11615
  for (let t = peek(s); t !== void 0; t = peek(s)) {
10841
11616
  if (scanTableToken(s, t, fontStack, ts)) break;
10842
11617
  }
10843
- return buildTable(ts.rows, open.attrs);
11618
+ const table = buildTable(ts.rows, open.attrs);
11619
+ const font = tableFont(fontStack);
11620
+ if (font !== void 0) table.font = font;
11621
+ return table;
10844
11622
  };
10845
11623
  var parseTableRow = (s, fontStack, opts) => {
10846
11624
  const row = parseRow(s, fontStack);
@@ -10880,6 +11658,14 @@ var finishTableLabel = (s) => {
10880
11658
  if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
10881
11659
  consume(s);
10882
11660
  };
11661
+ var parseFontTableLabel = (s, open, fontStack) => {
11662
+ const table = parseFontTable(s, open, fontStack);
11663
+ const nxt = peek(s);
11664
+ if (nxt === void 0) return { kind: "table", table };
11665
+ if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11666
+ consume(s);
11667
+ return { kind: "table", table };
11668
+ };
10883
11669
  var parseTableLabel = (s, fontStack) => {
10884
11670
  skipLeadingWs(s);
10885
11671
  const table = parseTable(s, fontStack);
@@ -10888,17 +11674,16 @@ var parseTableLabel = (s, fontStack) => {
10888
11674
  };
10889
11675
  var parseTextLabel = (s, fontStack) => {
10890
11676
  const texts = [];
11677
+ const start = s.pos;
10891
11678
  const txt = parseText(s, fontStack);
10892
11679
  if (txt.items.length > 0) texts.push(txt);
10893
11680
  const nxt = peek(s);
10894
11681
  if (nxt === void 0) return { kind: "text", texts };
10895
11682
  if (nxt.type === "open" && nxt.tag === "TABLE") {
10896
- if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) {
10897
- throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
10898
- }
10899
- throw new HtmlParseError("TABLE");
11683
+ rejectTableAfterTag(s, start);
11684
+ throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
10900
11685
  }
10901
- if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
11686
+ if (nxt.type !== "close" || nxt.tag !== "HTML" || s.pos === start) throw parseError(s, nxt, MSG_SYNTAX_ERROR);
10902
11687
  consume(s);
10903
11688
  return { kind: "text", texts };
10904
11689
  };
@@ -10906,23 +11691,38 @@ var parseTokens = (s) => {
10906
11691
  const fontStack = [{}];
10907
11692
  const htmlOpen = consume(s);
10908
11693
  if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
11694
+ const wrapper = fontTableWrapper(s);
11695
+ if (wrapper !== void 0) return parseFontTableLabel(s, wrapper, fontStack);
10909
11696
  const firstReal = findFirstRealToken(s.tokens, s.pos);
10910
11697
  if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
10911
11698
  return parseTextLabel(s, fontStack);
10912
11699
  };
10913
- var parseHtmlLabel = (src) => {
10914
- const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML>`);
10915
- const s = { tokens, pos: 0, pending: error };
10916
- let label;
11700
+ var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
11701
+ const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
11702
+ const s = {
11703
+ tokens,
11704
+ pos: 0,
11705
+ pending: error,
11706
+ stderr: new StderrLines(writeLine),
11707
+ emitted: /* @__PURE__ */ new WeakSet(),
11708
+ warn: false,
11709
+ eof
11710
+ };
10917
11711
  try {
10918
- label = parseTokens(s);
11712
+ const label = parseTokens(s);
11713
+ if (error !== void 0) throw error;
11714
+ return { label, warn: s.warn === true };
10919
11715
  } catch (e) {
10920
- if (error !== void 0 && s.pos >= tokens.length) throw error;
11716
+ if (error !== void 0 && s.pos >= tokens.length) {
11717
+ emitEof(s);
11718
+ throw error;
11719
+ }
10921
11720
  throw e;
11721
+ } finally {
11722
+ s.stderr?.flush();
10922
11723
  }
10923
- if (error !== void 0) throw error;
10924
- return label;
10925
11724
  };
11725
+ var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
10926
11726
 
10927
11727
  // src/gvc/usershape.ts
10928
11728
  var activeSizer = null;
@@ -10987,6 +11787,41 @@ var PointSet = class {
10987
11787
  }
10988
11788
  };
10989
11789
 
11790
+ // src/common/htmltable-fontinfo.ts
11791
+ var SIZE_SAVEF = { fontsize: 0 };
11792
+ var EMIT_SAVEF = { fontsize: 0 };
11793
+ var pushFontInfo = (env, fp, savp) => {
11794
+ if (fp.fontFace !== void 0) {
11795
+ savp.fontname = env.fontname;
11796
+ env.fontname = fp.fontFace;
11797
+ } else savp.fontname = void 0;
11798
+ if (env.fontcolor !== void 0) {
11799
+ if (fp.fontColor !== void 0) {
11800
+ savp.fontcolor = env.fontcolor;
11801
+ env.fontcolor = fp.fontColor;
11802
+ } else savp.fontcolor = void 0;
11803
+ }
11804
+ if (env.fontsize >= 0) {
11805
+ if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
11806
+ savp.fontsize = env.fontsize;
11807
+ env.fontsize = fp.fontSize;
11808
+ } else savp.fontsize = -1;
11809
+ }
11810
+ };
11811
+ var popFontInfo = (env, savp) => {
11812
+ if (savp.fontname !== void 0) env.fontname = savp.fontname;
11813
+ if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
11814
+ if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
11815
+ };
11816
+ var withTableFont = (env, font, slot, fn) => {
11817
+ if (font === void 0) return fn();
11818
+ const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
11819
+ pushFontInfo(env, font, savp);
11820
+ const r = fn();
11821
+ popFontInfo(env, savp);
11822
+ return r;
11823
+ };
11824
+
10990
11825
  // src/common/htmltable.ts
10991
11826
  var DEFAULT_BORDER = 1;
10992
11827
  var DEFAULT_CELLPADDING = 2;
@@ -11012,7 +11847,7 @@ var findCol = (ps, row, startCol, colspan, rowspan) => {
11012
11847
  }
11013
11848
  return col;
11014
11849
  };
11015
- var DEFAULT_SIZE_ENV = { fontsize: DEFAULT_FONTSIZE, fontname: "" };
11850
+ var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
11016
11851
  var itemFont = (item, env) => ({
11017
11852
  fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
11018
11853
  face: item.fontFace !== void 0 ? item.fontFace : env.fontname
@@ -11075,7 +11910,7 @@ var htmlTextIsSimple = (texts, env) => {
11075
11910
  }
11076
11911
  return true;
11077
11912
  };
11078
- var sizeTextContent = (texts, measurer, env = DEFAULT_SIZE_ENV) => {
11913
+ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
11079
11914
  const lines = splitSizedLines(texts, measurer, env);
11080
11915
  const simple = htmlTextIsSimple(texts, env);
11081
11916
  let w = 0;
@@ -11244,18 +12079,18 @@ var sumTableDims = (a) => {
11244
12079
  for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
11245
12080
  return { wd, ht };
11246
12081
  };
11247
- var layoutHtmlTable = (tbl, measurer, env = DEFAULT_SIZE_ENV) => {
12082
+ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
11248
12083
  const spacing = getSpacing(tbl);
11249
- const border = getBorder(tbl);
12084
+ const border2 = getBorder(tbl);
11250
12085
  const { entries, rv } = buildLayouts(tbl, measurer, env);
11251
12086
  if (entries.length === 0) {
11252
- return { entries, widths: [], heights: [], spacing, border, rv };
12087
+ return { entries, widths: [], heights: [], spacing, border: border2, rv };
11253
12088
  }
11254
12089
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
11255
12090
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
11256
12091
  const widths = setColWidths(entries, ncols, spacing);
11257
12092
  const heights = setRowHeights(entries, nrows, spacing);
11258
- return { entries, widths, heights, spacing, border, rv };
12093
+ return { entries, widths, heights, spacing, border: border2, rv };
11259
12094
  };
11260
12095
  var warnFixedTable = (tbl, dims) => {
11261
12096
  const warn = !sizeWarned.has(tbl);
@@ -11269,17 +12104,17 @@ var warnFixedTable = (tbl, dims) => {
11269
12104
  if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
11270
12105
  return 1;
11271
12106
  };
11272
- var sizeTableInner = (tbl, measurer, env) => {
11273
- const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
12107
+ var sizeTableBody = (tbl, measurer, env) => {
12108
+ const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
11274
12109
  if (entries.length === 0) {
11275
- const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
12110
+ const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
11276
12111
  tbl.dimen = { w: 0, h: 0 };
11277
12112
  return rv | fixed2;
11278
12113
  }
11279
12114
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
11280
12115
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
11281
12116
  for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
11282
- const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
12117
+ const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
11283
12118
  const baseWd = tbl.width !== void 0 ? tbl.width : 0;
11284
12119
  const baseHt = tbl.height !== void 0 ? tbl.height : 0;
11285
12120
  const fixed = warnFixedTable(tbl, { wd, ht });
@@ -11290,7 +12125,8 @@ var sizeTableInner = (tbl, measurer, env) => {
11290
12125
  };
11291
12126
  return rv | fixed;
11292
12127
  };
11293
- var sizeHtmlLabel = (label, measurer, env = DEFAULT_SIZE_ENV) => {
12128
+ var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
12129
+ var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
11294
12130
  if (label.kind === "table") {
11295
12131
  const rv = sizeTableInner(label.table, measurer, env);
11296
12132
  label.dimen = label.table.dimen;
@@ -16142,8 +16978,8 @@ function normalizeFontName(name) {
16142
16978
  for (let i = 0; i < name.length; i++) {
16143
16979
  const ch = name[i];
16144
16980
  const code = ch.charCodeAt(0);
16145
- const isLetter2 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
16146
- if (isLetter2) result += ch.toLowerCase();
16981
+ const isLetter3 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
16982
+ if (isLetter3) result += ch.toLowerCase();
16147
16983
  }
16148
16984
  return result;
16149
16985
  }
@@ -16223,30 +17059,30 @@ function fontFamilyAttrs(fontName, mode = FontnameKind.NativeFonts) {
16223
17059
  if (a === null) return null;
16224
17060
  let family;
16225
17061
  let weight;
16226
- let style;
17062
+ let style2;
16227
17063
  switch (mode) {
16228
17064
  case FontnameKind.PsFonts:
16229
17065
  family = a.name;
16230
17066
  weight = a.weight;
16231
- style = a.style;
17067
+ style2 = a.style;
16232
17068
  break;
16233
17069
  case FontnameKind.SvgFonts:
16234
17070
  family = a.svgFontFamily;
16235
17071
  weight = a.svgFontWeight;
16236
- style = a.svgFontStyle;
17072
+ style2 = a.svgFontStyle;
16237
17073
  break;
16238
17074
  default:
16239
17075
  family = a.family;
16240
17076
  weight = a.weight;
16241
- style = a.style;
17077
+ style2 = a.style;
16242
17078
  break;
16243
17079
  }
16244
17080
  const fam = a.svgFontFamily !== family ? family + "," + a.svgFontFamily : family;
16245
17081
  let attrs = ' font-family="' + fam + '"';
16246
17082
  if (weight !== null) attrs += ' font-weight="' + weight + '"';
16247
17083
  if (a.stretch !== null) attrs += ' font-stretch="' + a.stretch + '"';
16248
- if (style !== null) attrs += ' font-style="' + style + '"';
16249
- return { attrs, weight: weight !== null, style: style !== null };
17084
+ if (style2 !== null) attrs += ' font-style="' + style2 + '"';
17085
+ return { attrs, weight: weight !== null, style: style2 !== null };
16250
17086
  }
16251
17087
 
16252
17088
  // src/common/css-font.ts
@@ -16635,8 +17471,8 @@ function alignContentBox(box, cell2, w, h) {
16635
17471
  var HTML_ALL_SIDES = TOP | BOTTOM | LEFT | RIGHT;
16636
17472
  function placeCellRuns(ctx) {
16637
17473
  const { cell: cell2, tbl, box, finfo, measurer } = ctx;
16638
- const border = cellBorder(cell2, tbl);
16639
- const inset = border + cellPad(cell2, tbl);
17474
+ const border2 = cellBorder(cell2, tbl);
17475
+ const inset = border2 + cellPad(cell2, tbl);
16640
17476
  const cbox = {
16641
17477
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
16642
17478
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
@@ -16685,17 +17521,17 @@ function placeCellNested(ctx) {
16685
17521
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
16686
17522
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
16687
17523
  };
16688
- return posHtmlTable(nested2, finfo, measurer, cbox, sidesMask);
17524
+ return withTableFont(finfo, nested2.font, "emit", () => posHtmlTable(nested2, finfo, measurer, cbox, sidesMask));
16689
17525
  }
16690
17526
  function placeCell(ctx) {
16691
17527
  const { cell: cell2, tbl, box, col, row, colspan, rowspan } = ctx;
16692
- const border = cellBorder(cell2, tbl);
17528
+ const border2 = cellBorder(cell2, tbl);
16693
17529
  const vruled = cell2.vruled;
16694
17530
  const nested2 = placeCellNested(ctx);
16695
17531
  const image = nested2 === void 0 ? placeCellImage(cell2, tbl, box) : void 0;
16696
17532
  return {
16697
17533
  box,
16698
- border,
17534
+ border: border2,
16699
17535
  lines: nested2 === void 0 ? placeCellRuns(ctx) : [],
16700
17536
  image,
16701
17537
  nested: nested2,
@@ -16725,18 +17561,18 @@ function distributeExtra(sizes, del, count) {
16725
17561
  const plus = r >= 0 ? Math.floor(r + 0.5) : Math.ceil(r - 0.5);
16726
17562
  return sizes.map((w, i) => w + extra + (i < plus ? 1 : 0));
16727
17563
  }
16728
- function buildColX(pos, border, spacing, widths) {
17564
+ function buildColX(pos, border2, spacing, widths) {
16729
17565
  const colX = [];
16730
- let x = pos.ll.x + border + spacing;
17566
+ let x = pos.ll.x + border2 + spacing;
16731
17567
  for (let i = 0; i < widths.length; i++) {
16732
17568
  colX[i] = x;
16733
17569
  x += widths[i] + spacing;
16734
17570
  }
16735
17571
  return colX;
16736
17572
  }
16737
- function buildRowY(pos, border, spacing, heights) {
17573
+ function buildRowY(pos, border2, spacing, heights) {
16738
17574
  const rowY = [];
16739
- let y = pos.ur.y - border - spacing;
17575
+ let y = pos.ur.y - border2 - spacing;
16740
17576
  for (let i = 0; i < heights.length; i++) {
16741
17577
  rowY[i] = y;
16742
17578
  y -= heights[i] + spacing;
@@ -16756,14 +17592,14 @@ function tblDecoration(tbl) {
16756
17592
  gradientangle: tbl.gradientangle
16757
17593
  };
16758
17594
  }
16759
- function cellSidesMask(e, ncols, nrows, sides) {
16760
- if (sides === 0) return 0;
17595
+ function cellSidesMask(e, ncols, nrows, sides2) {
17596
+ if (sides2 === 0) return 0;
16761
17597
  let mask = 0;
16762
17598
  if (e.col === 0) mask |= LEFT;
16763
17599
  if (e.row === 0) mask |= TOP;
16764
17600
  if (e.col + e.colspan === ncols) mask |= RIGHT;
16765
17601
  if (e.row + e.rowspan === nrows) mask |= BOTTOM;
16766
- return sides & mask;
17602
+ return sides2 & mask;
16767
17603
  }
16768
17604
  function ruledBoundaries(tbl) {
16769
17605
  const bits = /* @__PURE__ */ new Set();
@@ -16773,7 +17609,7 @@ function ruledBoundaries(tbl) {
16773
17609
  return bits;
16774
17610
  }
16775
17611
  function placeCells(ctx) {
16776
- const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer } = ctx;
17612
+ const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer } = ctx;
16777
17613
  const boundaries = ruledBoundaries(tbl);
16778
17614
  return entries.map((e) => {
16779
17615
  const box = {
@@ -16790,19 +17626,19 @@ function placeCells(ctx) {
16790
17626
  row: e.row,
16791
17627
  colspan: e.colspan,
16792
17628
  rowspan: e.rowspan,
16793
- sidesMask: cellSidesMask(e, ncols, nrows, sides)
17629
+ sidesMask: cellSidesMask(e, ncols, nrows, sides2)
16794
17630
  });
16795
17631
  if (boundaries.has(e.row + e.rowspan)) placed.hruled = true;
16796
17632
  return placed;
16797
17633
  });
16798
17634
  }
16799
- function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
17635
+ function posHtmlTable(tbl, finfo, measurer, pos, sides2 = HTML_ALL_SIDES) {
16800
17636
  const dim = tbl.dimen ?? { w: 0, h: 0 };
16801
17637
  const box = pos !== void 0 ? { ll: { ...pos.ll }, ur: { ...pos.ur } } : {
16802
17638
  ll: { x: -dim.w / 2, y: -dim.h / 2 },
16803
17639
  ur: { x: dim.w / 2, y: dim.h / 2 }
16804
17640
  };
16805
- const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, {
17641
+ const { entries, widths, heights, spacing, border: border2 } = layoutHtmlTable(tbl, measurer, {
16806
17642
  fontsize: finfo.fontsize,
16807
17643
  fontname: finfo.fontname
16808
17644
  });
@@ -16834,10 +17670,10 @@ function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
16834
17670
  dely = 0;
16835
17671
  }
16836
17672
  }
16837
- const colX = buildColX(box, border, spacing, distributeExtra(widths, delx, ncols));
16838
- const rowY = buildRowY(box, border, spacing, distributeExtra(heights, dely, nrows));
16839
- const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer });
16840
- return { box, border, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides, ...tblDecoration(tbl) };
17673
+ const colX = buildColX(box, border2, spacing, distributeExtra(widths, delx, ncols));
17674
+ const rowY = buildRowY(box, border2, spacing, distributeExtra(heights, dely, nrows));
17675
+ const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer });
17676
+ return { box, border: border2, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides2, ...tblDecoration(tbl) };
16841
17677
  }
16842
17678
  function posTextLabel(label, finfo, measurer) {
16843
17679
  const dim = label.dimen ?? { w: 0, h: 0 };
@@ -16864,21 +17700,22 @@ function posTextLabel(label, finfo, measurer) {
16864
17700
  };
16865
17701
  }
16866
17702
  function posHtmlLabel(label, finfo, measurer) {
16867
- if (label.kind === "table") return posHtmlTable(label.table, finfo, measurer);
17703
+ const env = { ...finfo };
17704
+ if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
16868
17705
  return posTextLabel(label, finfo, measurer);
16869
17706
  }
16870
17707
  var HTML_PARSE_FATAL = 3;
16871
17708
  function makeHtmlLabelRv(content, finfo, measurer) {
16872
17709
  const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
16873
- let lbl;
17710
+ let lbl, lexWarn;
16874
17711
  try {
16875
- lbl = parseHtmlLabel(content);
17712
+ ({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
16876
17713
  } catch (e) {
16877
17714
  if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
16878
17715
  return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
16879
17716
  }
16880
17717
  if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
16881
- const rv = sizeHtmlLabel(lbl, measurer, {
17718
+ const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
16882
17719
  fontsize,
16883
17720
  fontname,
16884
17721
  imageSizer
@@ -17228,7 +18065,7 @@ function starRings(box, peripheries) {
17228
18065
  return rings.flat();
17229
18066
  }
17230
18067
  function computeVertices(poly, w, h, base) {
17231
- const sides = poly.sides;
18068
+ const sides2 = poly.sides;
17232
18069
  if (poly.option.fixedshape && base !== void 0) {
17233
18070
  w = base.w;
17234
18071
  h = base.h;
@@ -17236,10 +18073,10 @@ function computeVertices(poly, w, h, base) {
17236
18073
  if (poly.option.shape === CYLINDER) return cylinderVertices(w, h);
17237
18074
  const peripheries = Math.max(poly.peripheries, 1);
17238
18075
  if (poly.option.shape === STAR) return starRings({ w, h, base }, peripheries);
17239
- if (sides <= 2) {
18076
+ if (sides2 <= 2) {
17240
18077
  return ellipseRings(w, h, peripheries, poly.option.fixedshape ? base : void 0);
17241
18078
  }
17242
- if (sides === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
18079
+ if (sides2 === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
17243
18080
  return boxRings(w, h, peripheries, poly.orientation, base);
17244
18081
  }
17245
18082
  return generalPolyRings(poly, { w, h, base }, peripheries);
@@ -17364,17 +18201,17 @@ function starSize(bb) {
17364
18201
  function cylinderSize(bb) {
17365
18202
  return { x: bb.x, y: bb.y * 1.375 };
17366
18203
  }
17367
- function expandForShape(bb, sides, heightPts, valign) {
18204
+ function expandForShape(bb, sides2, heightPts, valign2) {
17368
18205
  const b = { x: bb.x, y: bb.y };
17369
18206
  const temp = b.y * SQRT2;
17370
- if (heightPts > temp && valign === "c") {
18207
+ if (heightPts > temp && valign2 === "c") {
17371
18208
  b.x *= Math.sqrt(1 / (1 - (b.y / heightPts) ** 2));
17372
18209
  } else {
17373
18210
  b.x *= SQRT2;
17374
18211
  b.y = temp;
17375
18212
  }
17376
- if (sides > 2) {
17377
- const c = Math.cos(Math.PI / sides);
18213
+ if (sides2 > 2) {
18214
+ const c = Math.cos(Math.PI / sides2);
17378
18215
  b.x /= c;
17379
18216
  b.y /= c;
17380
18217
  }
@@ -17429,21 +18266,21 @@ function vertexExtents(verts) {
17429
18266
  }
17430
18267
  return { xmax, ymax };
17431
18268
  }
17432
- function initBisector(verts, sides) {
18269
+ function initBisector(verts, sides2) {
17433
18270
  const R2 = verts[0];
17434
18271
  let Q = R2;
17435
- for (let j = 1; j < sides; j++) {
17436
- Q = verts[(sides - j) % sides];
18272
+ for (let j = 1; j < sides2; j++) {
18273
+ Q = verts[(sides2 - j) % sides2];
17437
18274
  if (Q.x !== R2.x || Q.y !== R2.y) break;
17438
18275
  }
17439
18276
  return { beta: Math.atan2(R2.y - Q.y, R2.x - Q.x), Qprev: Q, sinx: 0, cosx: 0 };
17440
18277
  }
17441
- function bisectorOffset(verts, sides, i, st) {
18278
+ function bisectorOffset(verts, sides2, i, st) {
17442
18279
  const V = verts[i];
17443
18280
  if (V.x !== st.Qprev.x || V.y !== st.Qprev.y) {
17444
18281
  let R2 = V;
17445
- for (let j = 1; j < sides; j++) {
17446
- R2 = verts[(i + j) % sides];
18282
+ for (let j = 1; j < sides2; j++) {
18283
+ R2 = verts[(i + j) % sides2];
17447
18284
  if (R2.x !== V.x || R2.y !== V.y) break;
17448
18285
  }
17449
18286
  const alpha = st.beta;
@@ -17455,32 +18292,32 @@ function bisectorOffset(verts, sides, i, st) {
17455
18292
  }
17456
18293
  st.Qprev = V;
17457
18294
  }
17458
- function polygonRingOffsets(verts, sides) {
17459
- const st = initBisector(verts, sides);
18295
+ function polygonRingOffsets(verts, sides2) {
18296
+ const st = initBisector(verts, sides2);
17460
18297
  const out = [];
17461
- for (let i = 0; i < sides; i++) {
17462
- bisectorOffset(verts, sides, i, st);
18298
+ for (let i = 0; i < sides2; i++) {
18299
+ bisectorOffset(verts, sides2, i, st);
17463
18300
  out.push({ x: st.cosx, y: st.sinx });
17464
18301
  }
17465
18302
  return out;
17466
18303
  }
17467
- function polygonOutlineRing(verts, sides, penwidth) {
17468
- const st = initBisector(verts, sides);
18304
+ function polygonOutlineRing(verts, sides2, penwidth) {
18305
+ const st = initBisector(verts, sides2);
17469
18306
  const out = [];
17470
18307
  const k = penwidth / 2 / GAP;
17471
- for (let i = 0; i < sides; i++) {
17472
- bisectorOffset(verts, sides, i, st);
18308
+ for (let i = 0; i < sides2; i++) {
18309
+ bisectorOffset(verts, sides2, i, st);
17473
18310
  const V = verts[i];
17474
18311
  out.push({ x: V.x + k * st.cosx, y: V.y + k * st.sinx });
17475
18312
  }
17476
18313
  return out;
17477
18314
  }
17478
- function polygonPeripheryBB(verts, sides, p, bb) {
17479
- const st = initBisector(verts, sides);
18315
+ function polygonPeripheryBB(verts, sides2, p, bb) {
18316
+ const st = initBisector(verts, sides2);
17480
18317
  const out = { x: bb.x, y: bb.y };
17481
18318
  const outl = { x: bb.x, y: bb.y };
17482
- for (let i = 0; i < sides; i++) {
17483
- bisectorOffset(verts, sides, i, st);
18319
+ for (let i = 0; i < sides2; i++) {
18320
+ bisectorOffset(verts, sides2, i, st);
17484
18321
  const off = p.peripheries - 1;
17485
18322
  const V = verts[i];
17486
18323
  const P = { x: V.x + off * st.cosx, y: V.y + off * st.sinx };
@@ -17504,9 +18341,9 @@ function starVertexGen(bb) {
17504
18341
  }
17505
18342
  return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
17506
18343
  }
17507
- function polygonBB(bb, minSize, p, sides, isBox3) {
18344
+ function polygonBB(bb, minSize, p, sides2, isBox3) {
17508
18345
  const geom = {
17509
- sides,
18346
+ sides: sides2,
17510
18347
  orientation: p.orientation,
17511
18348
  distortion: p.distortion,
17512
18349
  skew: p.skew
@@ -17523,7 +18360,7 @@ function polygonBB(bb, minSize, p, sides, isBox3) {
17523
18360
  v.x *= scalex;
17524
18361
  v.y *= scaley;
17525
18362
  }
17526
- return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides, p, nbb), base: nbb };
18363
+ return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
17527
18364
  }
17528
18365
  function gvNodesize(widthPts, heightPts, flip) {
17529
18366
  if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
@@ -17548,7 +18385,7 @@ function applySizeConstraints(p, bb0, width0, height0) {
17548
18385
  function polySize(p) {
17549
18386
  const init = initialSizePts(p);
17550
18387
  const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
17551
- const { sides, isBox: isBox3 } = effectiveShape(p);
18388
+ const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
17552
18389
  let bb = { x: dimen.x, y: dimen.y };
17553
18390
  if (isBox3) {
17554
18391
  } else if (p.optionShape === STAR) {
@@ -17556,13 +18393,13 @@ function polySize(p) {
17556
18393
  } else if (p.optionShape === CYLINDER) {
17557
18394
  bb = cylinderSize(bb);
17558
18395
  } else {
17559
- bb = expandForShape(bb, sides, init.height, labelValign(p));
18396
+ bb = expandForShape(bb, sides2, init.height, labelValign(p));
17560
18397
  }
17561
18398
  const minBb = bb;
17562
18399
  const c = applySizeConstraints(p, bb, init.width, init.height);
17563
18400
  const penwidth = p.penwidth ?? 1;
17564
18401
  const hasOutline = penwidth > 0 || p.peripheries < 1;
17565
- const grown = sides < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides, isBox3);
18402
+ const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2, isBox3);
17566
18403
  const result = assembleResult(p, dimen, grown, c.fixedshape);
17567
18404
  return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
17568
18405
  }
@@ -17582,10 +18419,10 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
17582
18419
  return { space: { x: spaceX, y: spaceY }, valign: labelValign(p) };
17583
18420
  }
17584
18421
  function effectiveShape(p) {
17585
- let sides = p.sides;
17586
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
17587
- const isBox3 = sides === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
17588
- return { sides, isBox: isBox3 };
18422
+ let sides2 = p.sides;
18423
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
18424
+ const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
18425
+ return { sides: sides2, isBox: isBox3 };
17589
18426
  }
17590
18427
  function labelValign(p) {
17591
18428
  const ll = p.labelloc?.[0];
@@ -17796,33 +18633,33 @@ function otherEdge(e) {
17796
18633
  elistAppend(e.tail.info.other, e);
17797
18634
  }
17798
18635
 
18636
+ // src/common/bezier.ts
18637
+ function bezier(v, t, left2, right2) {
18638
+ const degree = 3;
18639
+ const u = 1 - t;
18640
+ const tri = [[v[0], v[1], v[2], v[3]]];
18641
+ for (let i = 1; i <= degree; i++) {
18642
+ const prev = tri[i - 1];
18643
+ const row = [];
18644
+ for (let j = 0; j <= degree - i; j++) {
18645
+ row.push({
18646
+ x: fma(prev[j].x, u, t * prev[j + 1].x),
18647
+ y: fma(prev[j].y, u, t * prev[j + 1].y)
18648
+ });
18649
+ }
18650
+ tri.push(row);
18651
+ }
18652
+ if (left2 !== null) for (let j = 0; j <= degree; j++) left2[j] = tri[j][0];
18653
+ if (right2 !== null) for (let j = 0; j <= degree; j++) right2[j] = tri[degree - j][j];
18654
+ return tri[degree][0];
18655
+ }
18656
+
17799
18657
  // src/common/splines-geom.ts
17800
18658
  function approxEqPt(p, q, tol) {
17801
18659
  const dx = p.x - q.x;
17802
18660
  const dy = p.y - q.y;
17803
18661
  return dx * dx + dy * dy < tol * tol;
17804
18662
  }
17805
- function evalBezier(sp, t, left2, right2) {
17806
- const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
17807
- const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
17808
- const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
17809
- const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
17810
- const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
17811
- const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
17812
- if (left2 !== null) {
17813
- left2[0] = sp[0];
17814
- left2[1] = ab;
17815
- left2[2] = abbc;
17816
- left2[3] = pt;
17817
- }
17818
- if (right2 !== null) {
17819
- right2[0] = pt;
17820
- right2[1] = bccd;
17821
- right2[2] = cd;
17822
- right2[3] = sp[3];
17823
- }
17824
- return pt;
17825
- }
17826
18663
  var HW = 2;
17827
18664
  var SMALL2 = 1e-10;
17828
18665
  function ptToLine2(a, b, p) {
@@ -17857,7 +18694,7 @@ function updateBbBz(bb, cp) {
17857
18694
  }
17858
18695
  const left2 = [];
17859
18696
  const right2 = [];
17860
- evalBezier(cp, 0.5, left2, right2);
18697
+ bezier(cp, 0.5, left2, right2);
17861
18698
  updateBbBz(bb, left2);
17862
18699
  updateBbBz(bb, right2);
17863
18700
  }
@@ -17883,7 +18720,7 @@ function bezierClip(insideCtx, insideFn, sp, leftInside) {
17883
18720
  do {
17884
18721
  const opt = pt;
17885
18722
  const t = (high + low) / 2;
17886
- pt = evalBezier(sp, t, left2, right2);
18723
+ pt = bezier(sp, t, left2, right2);
17887
18724
  if (insideFn(insideCtx, pt)) {
17888
18725
  if (leftInside) {
17889
18726
  low = t;
@@ -18280,15 +19117,10 @@ function arrowLengthTee(lenfact, arrowsize, penwidth) {
18280
19117
  if (extendStart > 0) length += extendEnd;
18281
19118
  return length;
18282
19119
  }
18283
- var lerp = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });
18284
19120
  function cubicHalf(c, rightHalf) {
18285
- const A3 = lerp(c[0], c[1]);
18286
- const B2 = lerp(c[1], c[2]);
18287
- const C6 = lerp(c[2], c[3]);
18288
- const D = lerp(A3, B2);
18289
- const E = lerp(B2, C6);
18290
- const M2 = lerp(D, E);
18291
- return rightHalf ? [M2, E, C6, c[3]] : [c[0], A3, D, M2];
19121
+ const half = [];
19122
+ bezier(c, 0.5, rightHalf ? null : half, rightHalf ? half : null);
19123
+ return half;
18292
19124
  }
18293
19125
  function curveControlPoints(p, v, w, flag) {
18294
19126
  const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
@@ -18561,29 +19393,11 @@ function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth, rankdir = 0) {
18561
19393
  }
18562
19394
 
18563
19395
  // src/layout/dot/edge-route-clip.ts
18564
- function deCasteljauTriangle(sp, t) {
18565
- const u = 1 - t;
18566
- const v = [
18567
- [sp[0], sp[1], sp[2], sp[3]],
18568
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
18569
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
18570
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]
18571
- ];
18572
- for (let i = 1; i <= 3; i++) {
18573
- for (let j = 0; j <= 3 - i; j++) {
18574
- v[i][j] = {
18575
- x: u * v[i - 1][j].x + t * v[i - 1][j + 1].x,
18576
- y: u * v[i - 1][j].y + t * v[i - 1][j + 1].y
18577
- };
18578
- }
18579
- }
18580
- return v;
18581
- }
18582
19396
  function bezierSubdivide(sp, t) {
18583
- const v = deCasteljauTriangle(sp, t);
18584
- const left2 = [v[0][0], v[1][0], v[2][0], v[3][0]];
18585
- const right2 = [v[3][0], v[2][1], v[1][2], v[0][3]];
18586
- return [left2, right2, v[3][0]];
19397
+ const left2 = [];
19398
+ const right2 = [];
19399
+ const mid = bezier(sp, t, left2, right2);
19400
+ return [left2, right2, mid];
18587
19401
  }
18588
19402
  function bisectStep(c, insideFn, leftInside, s) {
18589
19403
  const t = (s.high + s.low) / 2;
@@ -19214,10 +20028,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
19214
20028
  const lbl = e.info.label;
19215
20029
  if (!lbl?.dimen) return 0;
19216
20030
  const flip = e.tail.root.info.flip === true;
19217
- const height = flip ? lbl.dimen.x : lbl.dimen.y;
19218
- lbl.pos = { x: a.x, y: a.y + a.sign * height / 2 };
20031
+ const height2 = flip ? lbl.dimen.x : lbl.dimen.y;
20032
+ lbl.pos = { x: a.x, y: a.y + a.sign * height2 / 2 };
19219
20033
  lbl.set = true;
19220
- return height;
20034
+ return height2;
19221
20035
  }
19222
20036
  /** Place a left/right self-loop label; return the label width that governs
19223
20037
  * the loop's widen. Under flip the label is rotated, so dimen.y is the
@@ -19226,10 +20040,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
19226
20040
  const lbl = e.info.label;
19227
20041
  if (!lbl?.dimen) return 0;
19228
20042
  const flip = e.tail.root.info.flip === true;
19229
- const width = flip ? lbl.dimen.y : lbl.dimen.x;
19230
- lbl.pos = { x: a.x + a.sign * width / 2, y: a.y };
20043
+ const width2 = flip ? lbl.dimen.y : lbl.dimen.x;
20044
+ lbl.pos = { x: a.x + a.sign * width2 / 2, y: a.y };
19231
20045
  lbl.set = true;
19232
- return width;
20046
+ return width2;
19233
20047
  }
19234
20048
  static bottomPts(a) {
19235
20049
  const { tp, hp, np, dx, dy, ty, hy } = a;
@@ -19559,11 +20373,11 @@ function processFlatEdge(g, u, e) {
19559
20373
  const isOrdered = nodeOrder(u) < nodeOrder(e.head);
19560
20374
  const t0 = isOrdered ? e.tail : e.head;
19561
20375
  const h0 = isOrdered ? e.head : e.tail;
19562
- const width = nodeRw(t0) + nodeLw(h0);
19563
- let m0 = Math.trunc(edgeMinlen(e) * nodesep + width);
20376
+ const width2 = nodeRw(t0) + nodeLw(h0);
20377
+ let m0 = Math.trunc(edgeMinlen(e) * nodesep + width2);
19564
20378
  const ex = findFastEdge(t0, h0);
19565
20379
  if (ex !== void 0) {
19566
- m0 = Math.trunc(Math.max(m0, width + nodesep + cround(edgeDist(e))));
20380
+ m0 = Math.trunc(Math.max(m0, width2 + nodesep + cround(edgeDist(e))));
19567
20381
  ex.info.minlen = Math.max(ex.info.minlen ?? 1, m0);
19568
20382
  ex.info.weight = Math.max(ex.info.weight ?? 0, edgeWeight(e));
19569
20383
  } else if (!e.info.label) {
@@ -19618,9 +20432,9 @@ function selfWidth(u) {
19618
20432
  }
19619
20433
  function lrRankPair(g, r, u, v, last) {
19620
20434
  const nodesep = lrSep(g, r);
19621
- const width = nodeRw(u) + nodeLw(v) + nodesep;
19622
- makeAuxEdge(u, v, width, 0);
19623
- const next = Math.trunc(last + width);
20435
+ const width2 = nodeRw(u) + nodeLw(v) + nodesep;
20436
+ makeAuxEdge(u, v, width2, 0);
20437
+ const next = Math.trunc(last + width2);
19624
20438
  v.info.rank = next;
19625
20439
  return next;
19626
20440
  }
@@ -22647,9 +23461,9 @@ function labelVnode(g, orig) {
22647
23461
  return v;
22648
23462
  }
22649
23463
  function incrWidth(g, v) {
22650
- const width = Math.floor((g.info.nodesep ?? 0) / 2);
22651
- v.info.lw = (v.info.lw ?? 0) + width;
22652
- v.info.rw = (v.info.rw ?? 0) + width;
23464
+ const width2 = Math.floor((g.info.nodesep ?? 0) / 2);
23465
+ v.info.lw = (v.info.lw ?? 0) + width2;
23466
+ v.info.rw = (v.info.rw ?? 0) + width2;
22653
23467
  }
22654
23468
  function plainVnode(g) {
22655
23469
  const v = virtualNode(g);
@@ -23525,8 +24339,8 @@ function recSideMask(f, i, last) {
23525
24339
  if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
23526
24340
  return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
23527
24341
  }
23528
- function posReclbl(f, ul, sides) {
23529
- f.sides = sides;
24342
+ function posReclbl(f, ul, sides2) {
24343
+ f.sides = sides2;
23530
24344
  f.b = {
23531
24345
  ll: { x: ul.x, y: ul.y - f.size.y },
23532
24346
  ur: { x: ul.x + f.size.x, y: ul.y }
@@ -23534,8 +24348,8 @@ function posReclbl(f, ul, sides) {
23534
24348
  const last = f.n_flds - 1;
23535
24349
  const pos = { x: ul.x, y: ul.y };
23536
24350
  for (let i = 0; i <= last; i++) {
23537
- const mask = sides ? recSideMask(f, i, last) : 0;
23538
- posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides & mask);
24351
+ const mask = sides2 ? recSideMask(f, i, last) : 0;
24352
+ posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides2 & mask);
23539
24353
  if (f.LR) pos.x += f.fld[i].size.x;
23540
24354
  else pos.y -= f.fld[i].size.y;
23541
24355
  }
@@ -24033,11 +24847,11 @@ function renderPolyRing(ring, coord, filled, j, ctx) {
24033
24847
  } else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
24034
24848
  }
24035
24849
  function renderPeripheries(poly, coord, filled, ctx) {
24036
- const sides = poly.sides <= 2 ? 2 : poly.sides;
24850
+ const sides2 = poly.sides <= 2 ? 2 : poly.sides;
24037
24851
  const verts = poly.vertices;
24038
24852
  for (let j = 0; j < poly.peripheries; j++) {
24039
- const ring = verts.slice(j * sides, (j + 1) * sides);
24040
- if (ring.length < sides) break;
24853
+ const ring = verts.slice(j * sides2, (j + 1) * sides2);
24854
+ if (ring.length < sides2) break;
24041
24855
  const ringFilled = j === 0 ? filled : false;
24042
24856
  if (poly.sides <= 2) {
24043
24857
  renderEllipseRing(ring, coord, ringFilled, j, ctx);
@@ -24186,12 +25000,12 @@ function resolveNodeDrawCtx(job, n) {
24186
25000
  };
24187
25001
  return { poly: drawPoly, coord, filled, ringCtx };
24188
25002
  }
24189
- function specialCornerFlags(opt, style) {
25003
+ function specialCornerFlags(opt, style2) {
24190
25004
  return {
24191
25005
  shape: opt.shape,
24192
- diagonals: opt.diagonals || style.diagonals,
24193
- rounded: opt.rounded || style.rounded,
24194
- underline: opt.underline || style.underline
25006
+ diagonals: opt.diagonals || style2.diagonals,
25007
+ rounded: opt.rounded || style2.rounded,
25008
+ underline: opt.underline || style2.underline
24195
25009
  };
24196
25010
  }
24197
25011
  function polyGencode(rawJob, rawNode) {
@@ -24264,22 +25078,22 @@ function insideScale(n, poly) {
24264
25078
  boxURy: oh / 2
24265
25079
  };
24266
25080
  }
24267
- function polygonWalk(P, vertex, sides) {
25081
+ function polygonWalk(P, vertex, sides2) {
24268
25082
  const O = { x: 0, y: 0 };
24269
25083
  let i = 0;
24270
- let i1 = 1 % sides;
25084
+ let i1 = 1 % sides2;
24271
25085
  const Q = vertex[i];
24272
25086
  const R2 = vertex[i1];
24273
25087
  if (!sameSide(P, O, Q, R2)) return false;
24274
25088
  const s = sameSide(P, Q, R2, O);
24275
25089
  if (s && sameSide(P, R2, O, Q)) return true;
24276
- for (let j = 1; j < sides; j++) {
25090
+ for (let j = 1; j < sides2; j++) {
24277
25091
  if (s) {
24278
25092
  i = i1;
24279
- i1 = (i + 1) % sides;
25093
+ i1 = (i + 1) % sides2;
24280
25094
  } else {
24281
25095
  i1 = i;
24282
- i = (i + sides - 1) % sides;
25096
+ i = (i + sides2 - 1) % sides2;
24283
25097
  }
24284
25098
  if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
24285
25099
  }
@@ -24321,15 +25135,15 @@ function starInside(ctx, p) {
24321
25135
  }
24322
25136
  const poly = n.info.shape_info;
24323
25137
  if (poly === void 0 || poly.vertices === null) return false;
24324
- const sides = poly.sides;
24325
- const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides;
24326
- const outer = poly.vertices.slice(outerStart, outerStart + sides);
24327
- const ring = polygonOutlineRing(outer, sides, poly.penwidth ?? 1);
25138
+ const sides2 = poly.sides;
25139
+ const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides2;
25140
+ const outer = poly.vertices.slice(outerStart, outerStart + sides2);
25141
+ const ring = polygonOutlineRing(outer, sides2, poly.penwidth ?? 1);
24328
25142
  const O = { x: 0, y: 0 };
24329
25143
  let outcnt = 0;
24330
- for (let i = 0; i < sides; i += 2) {
25144
+ for (let i = 0; i < sides2; i += 2) {
24331
25145
  const Q = ring[i];
24332
- const R2 = ring[(i + 4) % sides];
25146
+ const R2 = ring[(i + 4) % sides2];
24333
25147
  if (!sameSide(P, O, Q, R2)) outcnt++;
24334
25148
  if (outcnt === 2) return false;
24335
25149
  }
@@ -24475,7 +25289,7 @@ var DEFAULT_NODESEP = 0.25;
24475
25289
  var MIN_NODESEP = 0.02;
24476
25290
  var DEFAULT_RANKSEP = 0.5;
24477
25291
  var MIN_RANKSEP = 0.02;
24478
- var UCHAR_MAX = 255;
25292
+ var UCHAR_MAX2 = 255;
24479
25293
  var CHAR_UTF8 = 0;
24480
25294
  var CHAR_LATIN1 = 1;
24481
25295
  var CHAR_BIG5 = 2;
@@ -24572,7 +25386,7 @@ function graphInit(g, useRankdir) {
24572
25386
  g.info.flip = false;
24573
25387
  }
24574
25388
  parseSepAttrs(g);
24575
- g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX);
25389
+ g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX2);
24576
25390
  const fn = maptoken(g.attrs.get("fontnames"), FONTNAME_NAMES, fontnameCodes());
24577
25391
  if (fn !== -1) g.info.fontnames = fn;
24578
25392
  parseRatioDrawing(g);
@@ -24800,54 +25614,54 @@ function dirDefault(p) {
24800
25614
  function dirUnrecognized(p) {
24801
25615
  return { p, theta: 0, side: 0, constrain: false, clip: true, dyna: false, defined: false, rv: 1 };
24802
25616
  }
24803
- function dirN(rest, b, ctr, sides) {
25617
+ function dirN(rest, b, ctr, sides2) {
24804
25618
  const base = { constrain: true, clip: false, dyna: false };
24805
25619
  switch (rest) {
24806
25620
  case "":
24807
- return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides & TOP, defined: true, rv: 0 };
25621
+ return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides2 & TOP, defined: true, rv: 0 };
24808
25622
  case "e":
24809
- return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides & (TOP | RIGHT), defined: true, rv: 0 };
25623
+ return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides2 & (TOP | RIGHT), defined: true, rv: 0 };
24810
25624
  case "w":
24811
- return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides & (TOP | LEFT), defined: true, rv: 0 };
25625
+ return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides2 & (TOP | LEFT), defined: true, rv: 0 };
24812
25626
  default:
24813
25627
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
24814
25628
  }
24815
25629
  }
24816
- function dirS(rest, b, ctr, sides) {
25630
+ function dirS(rest, b, ctr, sides2) {
24817
25631
  const base = { constrain: true, clip: false, dyna: false };
24818
25632
  switch (rest) {
24819
25633
  case "":
24820
- return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides & BOTTOM, defined: true, rv: 0 };
25634
+ return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides2 & BOTTOM, defined: true, rv: 0 };
24821
25635
  case "e":
24822
- return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides & (BOTTOM | RIGHT), defined: true, rv: 0 };
25636
+ return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides2 & (BOTTOM | RIGHT), defined: true, rv: 0 };
24823
25637
  case "w":
24824
- return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides & (BOTTOM | LEFT), defined: true, rv: 0 };
25638
+ return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides2 & (BOTTOM | LEFT), defined: true, rv: 0 };
24825
25639
  default:
24826
25640
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
24827
25641
  }
24828
25642
  }
24829
- function dirE(rest, b, ctr, sides) {
25643
+ function dirE(rest, b, ctr, sides2) {
24830
25644
  if (rest.length > 0) return dirUnrecognized(ctr);
24831
- return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
25645
+ return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides2 & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
24832
25646
  }
24833
- function dirW(rest, b, ctr, sides) {
25647
+ function dirW(rest, b, ctr, sides2) {
24834
25648
  if (rest.length > 0) return dirUnrecognized(ctr);
24835
- return { p: { x: b.ll.x, y: ctr.y }, theta: Math.PI, side: sides & LEFT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
25649
+ return { p: { x: b.ll.x, y: ctr.y }, theta: Math.PI, side: sides2 & LEFT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
24836
25650
  }
24837
- function compassDirection(compass, b, ctr, sides) {
25651
+ function compassDirection(compass, b, ctr, sides2) {
24838
25652
  if (compass.length === 0) return dirDefault(ctr);
24839
25653
  const rest = compass.slice(1);
24840
25654
  switch (compass[0]) {
24841
25655
  case "n":
24842
- return dirN(rest, b, ctr, sides);
25656
+ return dirN(rest, b, ctr, sides2);
24843
25657
  case "s":
24844
- return dirS(rest, b, ctr, sides);
25658
+ return dirS(rest, b, ctr, sides2);
24845
25659
  case "e":
24846
- return dirE(rest, b, ctr, sides);
25660
+ return dirE(rest, b, ctr, sides2);
24847
25661
  case "w":
24848
- return dirW(rest, b, ctr, sides);
25662
+ return dirW(rest, b, ctr, sides2);
24849
25663
  case "_":
24850
- return { p: { ...ctr }, theta: 0, side: sides, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
25664
+ return { p: { ...ctr }, theta: 0, side: sides2, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
24851
25665
  case "c":
24852
25666
  return dirDefault(ctr);
24853
25667
  default:
@@ -24896,31 +25710,31 @@ function applyIctxt(n, dir, b, ctr) {
24896
25710
  dir.p = compassPoint(n, insideFn, yArg, xArg, gdRankdir(n));
24897
25711
  }
24898
25712
  function compassPort(n, args, pp) {
24899
- const { bp, compass, sides } = args;
25713
+ const { bp, compass, sides: sides2 } = args;
24900
25714
  const { b, p, defined: defBp } = compassBbox(n, bp);
24901
- const dir = compassDirection(compass, b, p, sides);
25715
+ const dir = compassDirection(compass, b, p, sides2);
24902
25716
  if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
24903
25717
  const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
24904
25718
  applyDir(pp, bp, dir, gdRankdir(n), defFinal);
24905
25719
  return dir.rv;
24906
25720
  }
24907
- function htmlPort(n, portname, sides) {
25721
+ function htmlPort(n, portname, sides2) {
24908
25722
  const label = n.info.label;
24909
25723
  const placed = label?.u?.kind === "html" ? label.u.html : void 0;
24910
25724
  if (placed === void 0) return null;
24911
25725
  const hit = portToTbl(placed, portname);
24912
25726
  if (hit === null) return null;
24913
- sides.value = hit.sides;
25727
+ sides2.value = hit.sides;
24914
25728
  return hit.box;
24915
25729
  }
24916
25730
  function polyPort(n, portname, compass) {
24917
25731
  if (portname.length === 0) return makePort();
24918
25732
  const compassStr = compass.length === 0 ? "_" : compass;
24919
- const sides = BOTTOM | RIGHT | TOP | LEFT;
25733
+ const sides2 = BOTTOM | RIGHT | TOP | LEFT;
24920
25734
  const rv = makePort();
24921
25735
  const label = n.info.label;
24922
25736
  if (label?.html === true) {
24923
- const sidesRef = { value: sides };
25737
+ const sidesRef = { value: sides2 };
24924
25738
  const bp = htmlPort(n, portname, sidesRef);
24925
25739
  if (bp !== null) {
24926
25740
  compassPort(n, { bp, compass: compassStr, sides: sidesRef.value }, rv);
@@ -24928,7 +25742,7 @@ function polyPort(n, portname, compass) {
24928
25742
  return rv;
24929
25743
  }
24930
25744
  }
24931
- compassPort(n, { bp: null, compass: portname, sides }, rv);
25745
+ compassPort(n, { bp: null, compass: portname, sides: sides2 }, rv);
24932
25746
  rv.name = null;
24933
25747
  return rv;
24934
25748
  }
@@ -25289,8 +26103,8 @@ function initNodeFromLabel(n, g, measurer) {
25289
26103
  return true;
25290
26104
  }
25291
26105
  function effectivePolygon(poly, p, fixedshape) {
25292
- let sides = p.sides;
25293
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
26106
+ let sides2 = p.sides;
26107
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
25294
26108
  return {
25295
26109
  ...poly,
25296
26110
  // C: poly->option.fixedshape = true inside the fixedsize="shape" branch;
@@ -25298,7 +26112,7 @@ function effectivePolygon(poly, p, fixedshape) {
25298
26112
  option: { ...poly.option, fixedshape },
25299
26113
  regular: p.regular,
25300
26114
  peripheries: p.peripheries,
25301
- sides,
26115
+ sides: sides2,
25302
26116
  orientation: p.orientation,
25303
26117
  distortion: p.distortion,
25304
26118
  skew: p.skew,
@@ -26440,8 +27254,8 @@ function orthoRoundedRadius(e, job) {
26440
27254
  if (e.head.root.attrs.get("splines") !== "ortho") return null;
26441
27255
  let wantRounded = false;
26442
27256
  let radius = 0;
26443
- const style = e.attrs.get("style");
26444
- if (style !== void 0 && style.split(",").map((s) => s.trim()).includes("rounded")) {
27257
+ const style2 = e.attrs.get("style");
27258
+ if (style2 !== void 0 && style2.split(",").map((s) => s.trim()).includes("rounded")) {
26445
27259
  wantRounded = true;
26446
27260
  }
26447
27261
  const radiusAttr = e.attrs.get("radius");
@@ -26826,20 +27640,10 @@ function checkControlPoints2(cp) {
26826
27640
  return ptToLine22(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine22(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
26827
27641
  }
26828
27642
  function bezierHalf(v) {
26829
- const t = 0.5;
26830
- const vt = [v.slice(0, 4)];
26831
- for (let i = 1; i <= 3; i++) {
26832
- vt[i] = [];
26833
- for (let j = 0; j <= 3 - i; j++) {
26834
- const a = vt[i - 1][j];
26835
- const b = vt[i - 1][j + 1];
26836
- vt[i][j] = { x: (1 - t) * a.x + t * b.x, y: (1 - t) * a.y + t * b.y };
26837
- }
26838
- }
26839
- return {
26840
- left: [vt[0][0], vt[1][0], vt[2][0], vt[3][0]],
26841
- right: [vt[3][0], vt[2][1], vt[1][2], vt[0][3]]
26842
- };
27643
+ const left2 = [];
27644
+ const right2 = [];
27645
+ bezier(v, 0.5, left2, right2);
27646
+ return { left: left2, right: right2 };
26843
27647
  }
26844
27648
  function approxBezier(cp, out) {
26845
27649
  if (checkControlPoints2(cp)) {
@@ -28397,9 +29201,9 @@ function setAspect2(g) {
28397
29201
  function placeLabelNonFlip(g) {
28398
29202
  const bb = g.info.bb;
28399
29203
  const labelPos2 = g.info.label_pos ?? 1;
28400
- const border = g.info.border;
29204
+ const border2 = g.info.border;
28401
29205
  const zero = { x: 0, y: 0 };
28402
- const d = labelPos2 & 1 ? border?.[TOP_IX] ?? zero : border?.[BOTTOM_IX] ?? zero;
29206
+ const d = labelPos2 & 1 ? border2?.[TOP_IX] ?? zero : border2?.[BOTTOM_IX] ?? zero;
28403
29207
  const py = labelPos2 & 1 ? bb.ur.y - d.y / 2 : bb.ll.y + d.y / 2;
28404
29208
  const px = labelPos2 & 4 ? bb.ur.x - d.x / 2 : labelPos2 & 2 ? bb.ll.x + d.x / 2 : (bb.ll.x + bb.ur.x) / 2;
28405
29209
  return { x: px, y: py };
@@ -28407,9 +29211,9 @@ function placeLabelNonFlip(g) {
28407
29211
  function placeLabelFlip(g) {
28408
29212
  const bb = g.info.bb;
28409
29213
  const labelPos2 = g.info.label_pos ?? 1;
28410
- const border = g.info.border;
29214
+ const border2 = g.info.border;
28411
29215
  const zero = { x: 0, y: 0 };
28412
- const d = labelPos2 & 1 ? border?.[RIGHT_IX] ?? zero : border?.[LEFT_IX] ?? zero;
29216
+ const d = labelPos2 & 1 ? border2?.[RIGHT_IX] ?? zero : border2?.[LEFT_IX] ?? zero;
28413
29217
  const px = labelPos2 & 1 ? bb.ur.x - d.x / 2 : bb.ll.x + d.x / 2;
28414
29218
  const py = labelPos2 & 4 ? bb.ll.y + d.y / 2 : labelPos2 & 2 ? bb.ur.y - d.y / 2 : (bb.ll.y + bb.ur.y) / 2;
28415
29219
  return { x: px, y: py };
@@ -29387,18 +30191,6 @@ function dist2(p, q) {
29387
30191
  function distPt(p, q) {
29388
30192
  return Math.sqrt(dist2(p, q));
29389
30193
  }
29390
- function bezier(v, t) {
29391
- const u = 1 - t;
29392
- const x = [v[0].x, v[1].x, v[2].x, v[3].x];
29393
- const y = [v[0].y, v[1].y, v[2].y, v[3].y];
29394
- for (let i = 1; i <= 3; i++) {
29395
- for (let j = 0; j <= 3 - i; j++) {
29396
- x[j] = fma(x[j], u, t * x[j + 1]);
29397
- y[j] = fma(y[j], u, t * y[j + 1]);
29398
- }
29399
- }
29400
- return { x: x[0], y: y[0] };
29401
- }
29402
30194
  function dotneatoClosest(spl, pt) {
29403
30195
  let besti = 0;
29404
30196
  let bestj = -1;
@@ -29427,7 +30219,7 @@ function dotneatoClosest(spl, pt) {
29427
30219
  let pt2;
29428
30220
  for (; ; ) {
29429
30221
  const t = (lo + hi) / 2;
29430
- pt2 = bezier(c, t);
30222
+ pt2 = bezier(c, t, null, null);
29431
30223
  if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
29432
30224
  if (dlo2 < dhi2) {
29433
30225
  hi = t;
@@ -29518,8 +30310,8 @@ function faceMidpoint(b, ix) {
29518
30310
  return { x: b.ll.x, y: cy };
29519
30311
  }
29520
30312
  function closestSide(n, other, port) {
29521
- const sides = port.side;
29522
- if (sides === 0 || sides === ALL_SIDES2) return null;
30313
+ const sides2 = port.side;
30314
+ if (sides2 === 0 || sides2 === ALL_SIDES2) return null;
29523
30315
  const rkd = (n.root.info.rankdir ?? 0) & 3;
29524
30316
  const pt = cvtPt(n.info.coord, rkd);
29525
30317
  const opt = cvtPt(other.info.coord, rkd);
@@ -29527,7 +30319,7 @@ function closestSide(n, other, port) {
29527
30319
  let rv = null;
29528
30320
  let mind = 0;
29529
30321
  for (let i = 0; i < 4; i++) {
29530
- if ((sides & 1 << i) === 0) continue;
30322
+ if ((sides2 & 1 << i) === 0) continue;
29531
30323
  const m = faceMidpoint(b, i);
29532
30324
  const d = dist2({ x: m.x + pt.x, y: m.y + pt.y }, opt);
29533
30325
  if (rv === null || d < mind) {
@@ -31244,17 +32036,20 @@ function checkPath(boxn, boxes, pp) {
31244
32036
  return false;
31245
32037
  }
31246
32038
  function deCasteljauPoint(p0, p1, p2, p3, t) {
31247
- const ax = p0.x + t * (p1.x - p0.x);
31248
- const ay = p0.y + t * (p1.y - p0.y);
31249
- const bx = p1.x + t * (p2.x - p1.x);
31250
- const by = p1.y + t * (p2.y - p1.y);
31251
- const cx = p2.x + t * (p3.x - p2.x);
31252
- const cy = p2.y + t * (p3.y - p2.y);
31253
- const dx = ax + t * (bx - ax);
31254
- const dy = ay + t * (by - ay);
31255
- const ex = bx + t * (cx - bx);
31256
- const ey = by + t * (cy - by);
31257
- return { x: dx + t * (ex - dx), y: dy + t * (ey - dy) };
32039
+ let s0x = p0.x, s0y = p0.y, s1x = p1.x, s1y = p1.y, s2x = p2.x, s2y = p2.y;
32040
+ s0x = fma(t, s1x - s0x, s0x);
32041
+ s0y = fma(t, s1y - s0y, s0y);
32042
+ s1x = fma(t, s2x - s1x, s1x);
32043
+ s1y = fma(t, s2y - s1y, s1y);
32044
+ s2x = fma(t, p3.x - s2x, s2x);
32045
+ s2y = fma(t, p3.y - s2y, s2y);
32046
+ s0x = fma(t, s1x - s0x, s0x);
32047
+ s0y = fma(t, s1y - s0y, s0y);
32048
+ s1x = fma(t, s2x - s1x, s1x);
32049
+ s1y = fma(t, s2y - s1y, s1y);
32050
+ s0x = fma(t, s1x - s0x, s0x);
32051
+ s0y = fma(t, s1y - s0y, s0y);
32052
+ return { x: s0x, y: s0y };
31258
32053
  }
31259
32054
  function updateBoxExtents(boxes, boxn, sp) {
31260
32055
  for (let bi = 0; bi < boxn; bi++) {
@@ -31275,7 +32070,7 @@ function sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv) {
31275
32070
  }
31276
32071
  }
31277
32072
  function limitBoxes(boxes, boxn, pps, pn, delta2) {
31278
- const numDiv = Math.round(delta2 * boxn);
32073
+ const numDiv = delta2 * boxn;
31279
32074
  for (let splinepi = 0; splinepi + 3 < pn; splinepi += 3) {
31280
32075
  sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv);
31281
32076
  }
@@ -31941,15 +32736,15 @@ function leftOf(p1, p2, p3) {
31941
32736
  }
31942
32737
  function lineLabelPoints(g, startp, endp, label) {
31943
32738
  const flip = g.info.flip === true;
31944
- const width = flip ? label.dimen.y : label.dimen.x;
31945
- const height = flip ? label.dimen.x : label.dimen.y;
32739
+ const width2 = flip ? label.dimen.y : label.dimen.x;
32740
+ const height2 = flip ? label.dimen.x : label.dimen.y;
31946
32741
  const lp = { x: label.pos.x, y: label.pos.y };
31947
32742
  if (leftOf(endp, startp, lp)) {
31948
- lp.x += width / 2;
31949
- lp.y -= height / 2;
32743
+ lp.x += width2 / 2;
32744
+ lp.y -= height2 / 2;
31950
32745
  } else {
31951
- lp.x -= width / 2;
31952
- lp.y += height / 2;
32746
+ lp.x -= width2 / 2;
32747
+ lp.y += height2 / 2;
31953
32748
  }
31954
32749
  return [startp, startp, lp, lp, lp, endp, endp];
31955
32750
  }
@@ -33336,8 +34131,8 @@ function findNormalOutEdge(first) {
33336
34131
  }
33337
34132
  function labelXPos(n, l) {
33338
34133
  const flip = !!n.root?.info.flip;
33339
- const width = flip ? l.dimen.y : l.dimen.x;
33340
- return n.info.coord.x + width / 2;
34134
+ const width2 = flip ? l.dimen.y : l.dimen.x;
34135
+ return n.info.coord.x + width2 / 2;
33341
34136
  }
33342
34137
  function placeVnlabel(n) {
33343
34138
  if ((n.info.in?.size ?? 0) === 0) return;
@@ -33375,22 +34170,12 @@ function setEdgeLabelPos(g) {
33375
34170
  }
33376
34171
  var PORT_LABEL_DISTANCE = 10;
33377
34172
  var PORT_LABEL_ANGLE = -25;
33378
- function cubicBezierAt(pts, t) {
33379
- const p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3];
33380
- const mt = 1 - t;
33381
- const q0 = { x: mt * p0.x + t * p1.x, y: mt * p0.y + t * p1.y };
33382
- const q1 = { x: mt * p1.x + t * p2.x, y: mt * p1.y + t * p2.y };
33383
- const q2 = { x: mt * p2.x + t * p3.x, y: mt * p2.y + t * p3.y };
33384
- const r0 = { x: mt * q0.x + t * q1.x, y: mt * q0.y + t * q1.y };
33385
- const r1 = { x: mt * q1.x + t * q2.x, y: mt * q1.y + t * q2.y };
33386
- return { x: mt * r0.x + t * r1.x, y: mt * r0.y + t * r1.y };
33387
- }
33388
34173
  function tailEndpoints(bez) {
33389
34174
  if (bez.sflag) {
33390
34175
  return { pe: bez.sp, pf: bez.list[0] };
33391
34176
  }
33392
34177
  const pe = bez.list[0];
33393
- const pf = cubicBezierAt(bez.list, 0.1);
34178
+ const pf = bezier(bez.list, 0.1, null, null);
33394
34179
  return { pe, pf };
33395
34180
  }
33396
34181
  function headEndpoints(bez) {
@@ -33399,7 +34184,7 @@ function headEndpoints(bez) {
33399
34184
  }
33400
34185
  const pe = bez.list[bez.size - 1];
33401
34186
  const last4 = bez.list.slice(bez.size - 4, bez.size);
33402
- const pf = cubicBezierAt(last4, 0.9);
34187
+ const pf = bezier(last4, 0.9, null, null);
33403
34188
  return { pe, pf };
33404
34189
  }
33405
34190
  function placePortlabel(e, headP) {
@@ -36574,22 +37359,22 @@ function gcellWalk(pd, sx, sy, boundIsX, bound) {
36574
37359
  }
36575
37360
  return out;
36576
37361
  }
36577
- function appendSide(sides, found, cp, cellIdx) {
37362
+ function appendSide(sides2, found, cp, cellIdx) {
36578
37363
  for (const np of found) {
36579
- sides.push(np);
37364
+ sides2.push(np);
36580
37365
  np.cells[cellIdx] = cp;
36581
37366
  }
36582
37367
  }
36583
37368
  function attachGcellSides(mp, hdict, vdict) {
36584
37369
  let maxdeg = 0;
36585
37370
  for (const cp of mp.gcells) {
36586
- const sides = [];
36587
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
36588
- appendSide(sides, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
36589
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
36590
- appendSide(sides, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
36591
- cp.sides = sides;
36592
- cp.nsides = sides.length;
37371
+ const sides2 = [];
37372
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
37373
+ appendSide(sides2, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
37374
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
37375
+ appendSide(sides2, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
37376
+ cp.sides = sides2;
37377
+ cp.nsides = sides2.length;
36593
37378
  if (cp.nsides > maxdeg) maxdeg = cp.nsides;
36594
37379
  }
36595
37380
  return maxdeg;
@@ -37871,21 +38656,10 @@ function inBoxf(p, bb) {
37871
38656
  function midPointf2(a, b) {
37872
38657
  return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
37873
38658
  }
37874
- function casteljauStep(prev, t) {
37875
- const u = 1 - t;
37876
- return [
37877
- { x: u * prev[0].x + t * prev[1].x, y: u * prev[0].y + t * prev[1].y },
37878
- { x: u * prev[1].x + t * prev[2].x, y: u * prev[1].y + t * prev[2].y },
37879
- { x: u * prev[2].x + t * prev[3].x, y: u * prev[2].y + t * prev[3].y },
37880
- { x: 0, y: 0 }
37881
- ];
37882
- }
37883
38659
  function subdivideBezier(v, t, side) {
37884
- const r0 = [{ ...v[0] }, { ...v[1] }, { ...v[2] }, { ...v[3] }];
37885
- const r1 = casteljauStep(r0, t);
37886
- const r2 = casteljauStep(r1, t);
37887
- const r3 = casteljauStep(r2, t);
37888
- return side === "left" ? [r0[0], r1[0], r2[0], r3[0]] : [r3[0], r2[1], r1[2], r0[3]];
38660
+ const half = [];
38661
+ bezier([...v], t, side === "left" ? half : null, side === "right" ? half : null);
38662
+ return half;
37889
38663
  }
37890
38664
  function countVertCross(pts, xcoord) {
37891
38665
  let sign2 = fcmp(pts[0].x, xcoord);
@@ -39369,10 +40143,11 @@ function bfsFixDisconnected(n, dist4, closestDist) {
39369
40143
  function bfsVisitNeighbors(vertex, graph, dist4, queue) {
39370
40144
  const vd = graph[vertex];
39371
40145
  const d = dist4[vertex];
40146
+ const unit = graph[0].ewgts.length === 0;
39372
40147
  for (let i = 1; i < vd.nedges; i++) {
39373
40148
  const nb = vd.edges[i];
39374
40149
  if (dist4[nb] < 0) {
39375
- dist4[nb] = d + 1;
40150
+ dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
39376
40151
  queue.push(nb);
39377
40152
  }
39378
40153
  }
@@ -40800,11 +41575,12 @@ function runMajorization(g, mode, model) {
40800
41575
  const nodeList = assignNodeIds2(g);
40801
41576
  const n = nodeList.length;
40802
41577
  const haveLen = graphHasLen(g);
40803
- const vtx = makeGraphDataC(g, nodeList, haveLen);
41578
+ const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
40804
41579
  checkStart(g);
40805
41580
  const maxi = lateDouble(g.attrs.get("maxiter"), DFLT_ITERATIONS, 0);
40806
41581
  const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
40807
- const Dij = haveLen ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
41582
+ const weighted = haveLen && mode !== MODE_IPSEP;
41583
+ const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
40808
41584
  const dCoords = [new Float64Array(n), new Float64Array(n)];
40809
41585
  stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
40810
41586
  dim: DFLT_DIM,
@@ -40822,11 +41598,11 @@ function graphHasLen(g) {
40822
41598
  }
40823
41599
  return false;
40824
41600
  }
40825
- function makeGraphDataC(g, nodeList, haveLen) {
41601
+ function makeGraphDataC(g, nodeList, haveLen, haveDir) {
40826
41602
  const vtx = nodeList.map((_, i) => ({
40827
41603
  nedges: 1,
40828
41604
  edges: [i],
40829
- ewgts: haveLen ? [0] : []
41605
+ ewgts: haveLen || haveDir ? [0] : []
40830
41606
  }));
40831
41607
  for (const np of nodeList) {
40832
41608
  const i = np.info.id;
@@ -40844,7 +41620,7 @@ function makeGraphDataC(g, nodeList, haveLen) {
40844
41620
  }
40845
41621
  seen.set(vid, entry.nedges);
40846
41622
  entry.edges.push(vid);
40847
- if (haveLen) entry.ewgts.push(dist4);
41623
+ if (haveLen || haveDir) entry.ewgts.push(dist4);
40848
41624
  entry.nedges++;
40849
41625
  }
40850
41626
  }
@@ -41905,7 +42681,7 @@ var RIGHT3 = 1 << 1;
41905
42681
  var TOP3 = 1 << 2;
41906
42682
  var LEFT3 = 1 << 3;
41907
42683
  var add = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
41908
- function sideCone(p, sides) {
42684
+ function sideCone(p, sides2) {
41909
42685
  const north = { x: 0, y: 1 };
41910
42686
  const northeast = { x: 1, y: 1 };
41911
42687
  const east = { x: 1, y: 0 };
@@ -41914,7 +42690,7 @@ function sideCone(p, sides) {
41914
42690
  const southwest = { x: -1, y: -1 };
41915
42691
  const west = { x: -1, y: 0 };
41916
42692
  const northwest = { x: -1, y: 1 };
41917
- switch (sides) {
42693
+ switch (sides2) {
41918
42694
  case TOP3:
41919
42695
  return [add(p, north), add(p, northwest), add(p, northeast)];
41920
42696
  case TOP3 | RIGHT3:
@@ -41935,17 +42711,17 @@ function sideCone(p, sides) {
41935
42711
  return [p, p, p];
41936
42712
  }
41937
42713
  }
41938
- function addEndpoint(rtr, p, obsId, vId, sides) {
42714
+ function addEndpoint(rtr, p, obsId, vId, sides2) {
41939
42715
  const starti = rtr.obs[obsId];
41940
42716
  const endi = rtr.obs[obsId + 1];
41941
42717
  const pts = rtr.ps;
41942
- const [vr, v0, v1] = sideCone(p, sides);
42718
+ const [vr, v0, v1] = sideCone(p, sides2);
41943
42719
  rtr.tg.nodes[vId].edges.length = 0;
41944
42720
  rtr.tg.nodes[vId].ctr = p;
41945
42721
  for (let i = starti; i < endi; i++) {
41946
42722
  const seg2 = { i, j: i < endi - 1 ? i + 1 : starti };
41947
42723
  const t = findMap(rtr.trimap, seg2.i, seg2.j);
41948
- if (sides !== 0 && !inCone(v0, p, v1, pts[seg2.i]) && !inCone(v0, p, v1, pts[seg2.j]) && !raySeg(p, vr, pts[seg2.i], pts[seg2.j])) {
42724
+ if (sides2 !== 0 && !inCone(v0, p, v1, pts[seg2.i]) && !inCone(v0, p, v1, pts[seg2.j]) && !raySeg(p, vr, pts[seg2.i], pts[seg2.j])) {
41949
42725
  continue;
41950
42726
  }
41951
42727
  addTriEdge(rtr.tg, vId, t, seg2);
@@ -42609,7 +43385,7 @@ function boxCornerMargin(j, m) {
42609
43385
  return { x: m.x, y: -m.y };
42610
43386
  }
42611
43387
  function polyObstacle(n, poly, pmargin) {
42612
- const sides = poly.sides;
43388
+ const sides2 = poly.sides;
42613
43389
  const stored = poly.vertices;
42614
43390
  if (stored == null) return null;
42615
43391
  const penwidth = poly.penwidth ?? 1;
@@ -42619,19 +43395,19 @@ function polyObstacle(n, poly, pmargin) {
42619
43395
  const storedRings = Math.max(poly.peripheries, 1);
42620
43396
  let verts;
42621
43397
  if (ringIdx < storedRings) {
42622
- verts = stored.slice(ringIdx * sides, (ringIdx + 1) * sides);
43398
+ verts = stored.slice(ringIdx * sides2, (ringIdx + 1) * sides2);
42623
43399
  } else {
42624
- const outer = stored.slice((storedRings - 1) * sides, storedRings * sides);
42625
- verts = polygonOutlineRing(outer, sides, penwidth);
43400
+ const outer = stored.slice((storedRings - 1) * sides2, storedRings * sides2);
43401
+ verts = polygonOutlineRing(outer, sides2, penwidth);
42626
43402
  }
42627
- if (verts.length < sides) return null;
42628
- const ps = new Array(sides);
42629
- for (let j = 0; j < sides; j++) {
43403
+ if (verts.length < sides2) return null;
43404
+ const ps = new Array(sides2);
43405
+ for (let j = 0; j < sides2; j++) {
42630
43406
  const v = verts[j];
42631
43407
  if (v === void 0) return null;
42632
43408
  let polyp;
42633
43409
  if (pmargin.doAdd) {
42634
- if (sides === 4) {
43410
+ if (sides2 === 4) {
42635
43411
  const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
42636
43412
  polyp = { x: v.x + m.x, y: v.y + m.y };
42637
43413
  } else {
@@ -42641,22 +43417,22 @@ function polyObstacle(n, poly, pmargin) {
42641
43417
  } else {
42642
43418
  polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
42643
43419
  }
42644
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
43420
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
42645
43421
  }
42646
43422
  return { ps };
42647
43423
  }
42648
43424
  function ellipseObstacle(n, pmargin) {
42649
- const sides = 8;
42650
- const width = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
42651
- const height = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
43425
+ const sides2 = 8;
43426
+ const width2 = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
43427
+ const height2 = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
42652
43428
  const mx = pmargin.doAdd ? pmargin.x : 0;
42653
43429
  const my = pmargin.doAdd ? pmargin.y : 0;
42654
- const a = (width + mx) / 2;
42655
- const b = (height + my) / 2;
42656
- const ps = new Array(sides);
42657
- for (let j = 0; j < sides; j++) {
42658
- const polyp = circumscribedCorner(a, b, j, sides);
42659
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
43430
+ const a = (width2 + mx) / 2;
43431
+ const b = (height2 + my) / 2;
43432
+ const ps = new Array(sides2);
43433
+ for (let j = 0; j < sides2; j++) {
43434
+ const polyp = circumscribedCorner(a, b, j, sides2);
43435
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
42660
43436
  }
42661
43437
  return { ps };
42662
43438
  }
@@ -42733,10 +43509,10 @@ function makeOrthoObstacle(n, sep) {
42733
43509
  cy += (bb.ur.y + bb.ll.y) / 2;
42734
43510
  cx += 0;
42735
43511
  } else {
42736
- const width = info.lw + info.rw;
42737
- const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width;
43512
+ const width2 = info.lw + info.rw;
43513
+ const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width2;
42738
43514
  const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
42739
- const outlineLw = width > 0 ? info.lw * outlineW / width : outlineW / 2;
43515
+ const outlineLw = width2 > 0 ? info.lw * outlineW / width2 : outlineW / 2;
42740
43516
  lw = outlineLw;
42741
43517
  rw = outlineLw;
42742
43518
  hh = outlineH / 2;
@@ -42914,17 +43690,11 @@ var OrthoHelper = class _OrthoHelper {
42914
43690
  }
42915
43691
  static buildEdges(g, nodeArr, orthoNodes) {
42916
43692
  const concentrate = g.root.info.concentrate ?? false;
42917
- const seen = /* @__PURE__ */ new Set();
43693
+ const ps = concentrate ? new PointSet() : null;
42918
43694
  const edges = [];
42919
43695
  for (const n of nodesInSeq(g)) {
42920
43696
  for (const e of n.outEdges(g)) {
42921
- if (concentrate) {
42922
- const ti = e.tail.id;
42923
- const hi = e.head.id;
42924
- const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
42925
- if (seen.has(key)) continue;
42926
- seen.add(key);
42927
- }
43697
+ if (ps && isConcentrateDup(ps, e)) continue;
42928
43698
  const tc = e.tail.info.coord;
42929
43699
  const hc = e.head.info.coord;
42930
43700
  const tp = e.info.tail_port.p;
@@ -44980,13 +45750,13 @@ function pointDistance(p1, o1, p2, o2, dim) {
44980
45750
  }
44981
45751
  return Math.sqrt(dist4);
44982
45752
  }
44983
- function quadTreeNew(dim, center, width, maxLevel) {
45753
+ function quadTreeNew(dim, center, width2, maxLevel) {
44984
45754
  return {
44985
45755
  n: 0,
44986
45756
  totalWeight: 0,
44987
45757
  dim,
44988
45758
  center: center.slice(0, dim),
44989
- width,
45759
+ width: width2,
44990
45760
  average: null,
44991
45761
  qts: null,
44992
45762
  l: null,
@@ -45004,15 +45774,15 @@ function getQuadrant(dim, center, coord, off) {
45004
45774
  }
45005
45775
  return d;
45006
45776
  }
45007
- function newInQuadrant(dim, parentCenter, width, maxLevel, i) {
45008
- const qt = quadTreeNew(dim, parentCenter, width, maxLevel);
45777
+ function newInQuadrant(dim, parentCenter, width2, maxLevel, i) {
45778
+ const qt = quadTreeNew(dim, parentCenter, width2, maxLevel);
45009
45779
  const center = qt.center;
45010
45780
  let ii = i;
45011
45781
  for (let k = 0; k < dim; k++) {
45012
45782
  if (ii % 2 === 0) {
45013
- center[k] -= width;
45783
+ center[k] -= width2;
45014
45784
  } else {
45015
- center[k] += width;
45785
+ center[k] += width2;
45016
45786
  }
45017
45787
  ii = (ii - ii % 2) / 2;
45018
45788
  }
@@ -45083,14 +45853,14 @@ function quadTreeNewFromPointList(dim, n, maxLevel, coord) {
45083
45853
  xmax[k] = Math.max(xmax[k], coord[i * dim + k]);
45084
45854
  }
45085
45855
  }
45086
- let width = xmax[0] - xmin[0];
45856
+ let width2 = xmax[0] - xmin[0];
45087
45857
  for (let i = 0; i < dim; i++) {
45088
45858
  center[i] = (xmin[i] + xmax[i]) * 0.5;
45089
- width = Math.max(width, xmax[i] - xmin[i]);
45859
+ width2 = Math.max(width2, xmax[i] - xmin[i]);
45090
45860
  }
45091
- width = Math.max(width, 1e-5);
45092
- width *= 0.52;
45093
- const qt = quadTreeNew(dim, center, width, maxLevel);
45861
+ width2 = Math.max(width2, 1e-5);
45862
+ width2 *= 0.52;
45863
+ const qt = quadTreeNew(dim, center, width2, maxLevel);
45094
45864
  for (let i = 0; i < n; i++) {
45095
45865
  quadTreeAdd(qt, coord, i * dim, 1, i);
45096
45866
  }
@@ -45910,18 +46680,18 @@ function compScanPoints(p, q) {
45910
46680
  if (pp.node < qq.node) return -1;
45911
46681
  return 0;
45912
46682
  }
45913
- function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
46683
+ function getOverlapGraph(dim, n, x, width2, checkOverlapOnly) {
45914
46684
  let A3 = smNew(n, n, MATRIX_TYPE_REAL, FORMAT_COORD);
45915
46685
  const scanpointsx = new Array(2 * n);
45916
46686
  for (let i = 0; i < n; i++) {
45917
- scanpointsx[2 * i] = { node: i, x: x[i * dim] - width[i * dim], status: INTV_OPEN };
45918
- scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width[i * dim], status: INTV_CLOSE };
46687
+ scanpointsx[2 * i] = { node: i, x: x[i * dim] - width2[i * dim], status: INTV_OPEN };
46688
+ scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width2[i * dim], status: INTV_CLOSE };
45919
46689
  }
45920
46690
  scanpointsx.sort(compScanPoints);
45921
46691
  const scanpointsy = new Array(2 * n);
45922
46692
  for (let i = 0; i < n; i++) {
45923
- scanpointsy[i] = { node: i, x: x[i * dim + 1] - width[i * dim + 1], status: INTV_OPEN };
45924
- scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width[i * dim + 1], status: INTV_CLOSE };
46693
+ scanpointsy[i] = { node: i, x: x[i * dim + 1] - width2[i * dim + 1], status: INTV_OPEN };
46694
+ scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width2[i * dim + 1], status: INTV_CLOSE };
45925
46695
  }
45926
46696
  const treey = rbTreeCreate(compScanPoints, () => void 0);
45927
46697
  outer:
@@ -45954,7 +46724,7 @@ function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
45954
46724
  A3 = smSymmetrize(B2, false);
45955
46725
  return A3;
45956
46726
  }
45957
- function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
46727
+ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
45958
46728
  const ia = A3.ia;
45959
46729
  const ja = A3.ja;
45960
46730
  const expandmax = 1.5;
@@ -45968,8 +46738,8 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
45968
46738
  const dist4 = distance(x, dim, i, jj);
45969
46739
  const dx = Math.abs(x[i * dim] - x[jj * dim]);
45970
46740
  const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
45971
- const wx = width[i * dim] + width[jj * dim];
45972
- const wy = width[i * dim + 1] + width[jj * dim + 1];
46741
+ const wx = width2[i * dim] + width2[jj * dim];
46742
+ const wy = width2[i * dim + 1] + width2[jj * dim + 1];
45973
46743
  if (dx < MACHINEACC * wx && dy < MACHINEACC * wy) {
45974
46744
  idealDistance[j] = Math.hypot(wx, wy);
45975
46745
  tmax = 2;
@@ -46000,7 +46770,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
46000
46770
  function scaleCoord(dim, m, x, scale) {
46001
46771
  for (let i = 0; i < dim * m; i++) x[i] *= scale;
46002
46772
  }
46003
- function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxiter) {
46773
+ function overlapScaling(dim, m, x, width2, scaleStaIn, scaleStoIn, epsilon, maxiter) {
46004
46774
  let scaleSta = scaleStaIn;
46005
46775
  let scaleSto = scaleStoIn;
46006
46776
  let iter = 0;
@@ -46008,7 +46778,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46008
46778
  scaleSta = 0;
46009
46779
  } else {
46010
46780
  scaleCoord(dim, m, x, scaleSta);
46011
- const C6 = getOverlapGraph(dim, m, x, width, true);
46781
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46012
46782
  if (C6.nz === 0) return;
46013
46783
  scaleCoord(dim, m, x, 1 / scaleSta);
46014
46784
  }
@@ -46023,7 +46793,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46023
46793
  do {
46024
46794
  scaleSto *= 2;
46025
46795
  scaleCoord(dim, m, x, 2);
46026
- const C6 = getOverlapGraph(dim, m, x, width, true);
46796
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46027
46797
  overlap5 = C6.nz > 0;
46028
46798
  } while (overlap5);
46029
46799
  scaleCoord(dim, m, x, 1 / scaleSto);
@@ -46032,7 +46802,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46032
46802
  while (iter++ < maxiter && scaleSto - scaleSta > epsilon) {
46033
46803
  const scale = 0.5 * (scaleSta + scaleSto);
46034
46804
  scaleCoord(dim, m, x, scale);
46035
- const C6 = getOverlapGraph(dim, m, x, width, true);
46805
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
46036
46806
  scaleCoord(dim, m, x, 1 / scale);
46037
46807
  const overlap5 = C6.nz > 0;
46038
46808
  if (overlap5) {
@@ -46043,7 +46813,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
46043
46813
  }
46044
46814
  scaleCoord(dim, m, x, scaleBest);
46045
46815
  }
46046
- function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
46816
+ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
46047
46817
  const sm = {
46048
46818
  Lw: null,
46049
46819
  Lwd: null,
@@ -46053,16 +46823,16 @@ function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
46053
46823
  };
46054
46824
  let B2 = callTri(m, x);
46055
46825
  if (!neighborhoodOnly) {
46056
- const C6 = getOverlapGraph(dim, m, x, width, false);
46826
+ const C6 = getOverlapGraph(dim, m, x, width2, false);
46057
46827
  B2 = smAdd(B2, C6);
46058
46828
  }
46059
46829
  sm.Lw = B2;
46060
46830
  sm.Lwd = smCopy(sm.Lw);
46061
- const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width, sm.Lwd.a);
46831
+ const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width2, sm.Lwd.a);
46062
46832
  if (tmax < 1 && shrink) {
46063
46833
  const scaleSta = Math.min(1, tmax * 1.0001);
46064
46834
  const scaleSto = 1;
46065
- overlapScaling(dim, m, x, width, scaleSta, scaleSto, 1e-4, 15);
46835
+ overlapScaling(dim, m, x, width2, scaleSta, scaleSto, 1e-4, 15);
46066
46836
  return { sm, maxOverlap: 1, minOverlap: tmin };
46067
46837
  }
46068
46838
  const iw = sm.Lw.ia;
@@ -46336,7 +47106,7 @@ function scAdjust(g, equal) {
46336
47106
  // src/layout/neato/simple-scale.ts
46337
47107
  var ISZERO = (d) => Math.abs(d) < 1e-9;
46338
47108
  var LF = /^\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/;
46339
- function scanPair(p) {
47109
+ function scanPair2(p) {
46340
47110
  const m1 = LF.exec(p);
46341
47111
  if (m1 === null) return [];
46342
47112
  const rest = p.slice(m1[0].length);
@@ -46347,7 +47117,7 @@ function scanPair(p) {
46347
47117
  function simpleScale(g) {
46348
47118
  const p = aggetGraph(g, "scale");
46349
47119
  if (p === void 0) return 0;
46350
- const sc = scanPair(p);
47120
+ const sc = scanPair2(p);
46351
47121
  if (sc.length === 0) return 0;
46352
47122
  const x = sc[0];
46353
47123
  if (ISZERO(x)) return 0;
@@ -46671,16 +47441,16 @@ function overlaps(p) {
46671
47441
  function initItem(n, margin) {
46672
47442
  const x = cround(SCALE * (n.info.pos?.[0] ?? 0) * POINTS_PER_INCH6);
46673
47443
  const y = cround(SCALE * (n.info.pos?.[1] ?? 0) * POINTS_PER_INCH6);
46674
- const width = n.info.width ?? 0;
46675
- const height = n.info.height ?? 0;
47444
+ const width2 = n.info.width ?? 0;
47445
+ const height2 = n.info.height ?? 0;
46676
47446
  let w2;
46677
47447
  let h2;
46678
47448
  if (margin.doAdd) {
46679
- w2 = d2i(SCALE * (cround(width / 2 * POINTS_PER_INCH6) + margin.x));
46680
- h2 = d2i(SCALE * (cround(height / 2 * POINTS_PER_INCH6) + margin.y));
47449
+ w2 = d2i(SCALE * (cround(width2 / 2 * POINTS_PER_INCH6) + margin.x));
47450
+ h2 = d2i(SCALE * (cround(height2 / 2 * POINTS_PER_INCH6) + margin.y));
46681
47451
  } else {
46682
- w2 = cround(margin.x * SCALE2 * width * POINTS_PER_INCH6);
46683
- h2 = cround(margin.y * SCALE2 * height * POINTS_PER_INCH6);
47452
+ w2 = cround(margin.x * SCALE2 * width2 * POINTS_PER_INCH6);
47453
+ h2 = cround(margin.y * SCALE2 * height2 * POINTS_PER_INCH6);
46684
47454
  }
46685
47455
  return {
46686
47456
  val: 0,
@@ -46782,12 +47552,12 @@ function atoi2(s) {
46782
47552
  }
46783
47553
  function genRound(n, xm, ym) {
46784
47554
  const isides = atoi2(n.attrs.get("samplepoints"));
46785
- const sides = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
47555
+ const sides2 = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
46786
47556
  const verts = [];
46787
- for (let i = 0; i < sides; i++) {
47557
+ for (let i = 0; i < sides2; i++) {
46788
47558
  verts.push({
46789
- x: (n.info.width / 2 + xm) * Math.cos(i / sides * Math.PI * 2),
46790
- y: (n.info.height / 2 + ym) * Math.sin(i / sides * Math.PI * 2)
47559
+ x: (n.info.width / 2 + xm) * Math.cos(i / sides2 * Math.PI * 2),
47560
+ y: (n.info.height / 2 + ym) * Math.sin(i / sides2 * Math.PI * 2)
46791
47561
  });
46792
47562
  }
46793
47563
  return verts;
@@ -49205,30 +49975,30 @@ function boundaryFromBB(bb) {
49205
49975
  x: (bb.llx + bb.urx) / 2,
49206
49976
  y: (bb.lly + bb.ury) / 2
49207
49977
  };
49208
- const width = EXPFACTOR * (bb.urx - bb.llx);
49209
- const height = EXPFACTOR * (bb.ury - bb.lly);
49210
- sizeBoundary(width, height);
49978
+ const width2 = EXPFACTOR * (bb.urx - bb.llx);
49979
+ const height2 = EXPFACTOR * (bb.ury - bb.lly);
49980
+ sizeBoundary(width2, height2);
49211
49981
  const alpha = Math.atan2(parms.Ht, parms.Wd);
49212
49982
  parms.Wd = parms.Wd / Math.cos(alpha);
49213
49983
  parms.Ht = parms.Ht / Math.sin(alpha);
49214
49984
  return ctr;
49215
49985
  }
49216
- function sizeBoundary(width, height) {
49986
+ function sizeBoundary(width2, height2) {
49217
49987
  const area = 4 * parms.Wd * parms.Ht;
49218
- let quot = width * height / area;
49988
+ let quot = width2 * height2 / area;
49219
49989
  if (quot >= 1) {
49220
- parms.Wd = width / 2;
49221
- parms.Ht = height / 2;
49990
+ parms.Wd = width2 / 2;
49991
+ parms.Ht = height2 / 2;
49222
49992
  } else if (quot > 0) {
49223
49993
  quot = 2 * Math.sqrt(quot);
49224
- parms.Wd = width / quot;
49225
- parms.Ht = height / quot;
49226
- } else if (width > 0) {
49227
- parms.Wd = width / 2;
49228
- parms.Ht = area / width / 2;
49229
- } else if (height > 0) {
49230
- parms.Wd = area / height / 2;
49231
- parms.Ht = height / 2;
49994
+ parms.Wd = width2 / quot;
49995
+ parms.Ht = height2 / quot;
49996
+ } else if (width2 > 0) {
49997
+ parms.Wd = width2 / 2;
49998
+ parms.Ht = area / width2 / 2;
49999
+ } else if (height2 > 0) {
50000
+ parms.Wd = area / height2 / 2;
50001
+ parms.Ht = height2 / 2;
49232
50002
  }
49233
50003
  }
49234
50004
  function placeWithPorts(g, pp, ctr) {
@@ -50151,7 +50921,7 @@ function finalCC(g, cc, pts, rg, infop) {
50151
50921
  };
50152
50922
  }
50153
50923
  function applyMarginAndBorder(rg, bb, margin) {
50154
- const border = rg.info.border ?? [
50924
+ const border2 = rg.info.border ?? [
50155
50925
  { x: 0, y: 0 },
50156
50926
  { x: 0, y: 0 },
50157
50927
  { x: 0, y: 0 },
@@ -50159,12 +50929,12 @@ function applyMarginAndBorder(rg, bb, margin) {
50159
50929
  ];
50160
50930
  const pt = {
50161
50931
  x: -bb.ll.x + margin,
50162
- y: -bb.ll.y + margin + border[BOTTOM_IX].y
50932
+ y: -bb.ll.y + margin + border2[BOTTOM_IX].y
50163
50933
  };
50164
50934
  bb.ll.x = 0;
50165
50935
  bb.ll.y = 0;
50166
50936
  bb.ur.x += pt.x + margin;
50167
- bb.ur.y += pt.y + margin + border[TOP_IX].y;
50937
+ bb.ur.y += pt.y + margin + border2[TOP_IX].y;
50168
50938
  return pt;
50169
50939
  }
50170
50940
  function evalPositions(g, rootg) {
@@ -52072,9 +52842,9 @@ function applyLabelExpansion(g, total, rbb) {
52072
52842
  }
52073
52843
  function addMarginAndBorder(g, margin, rbb) {
52074
52844
  let { llx, lly, urx, ury } = rbb;
52075
- const border = g.info.border;
52076
- const bottomY = border ? border[BOTTOM_IX].y : 0;
52077
- const topY = border ? border[TOP_IX].y : 0;
52845
+ const border2 = g.info.border;
52846
+ const bottomY = border2 ? border2[BOTTOM_IX].y : 0;
52847
+ const topY = border2 ? border2[TOP_IX].y : 0;
52078
52848
  llx -= margin;
52079
52849
  urx += margin;
52080
52850
  lly -= margin + bottomY;
@@ -52645,18 +53415,9 @@ function approxLen(list, off) {
52645
53415
  return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
52646
53416
  }
52647
53417
  function splitCubic(v, t) {
52648
- const u = 1 - t;
52649
- const row = [v[0], v[1], v[2], v[3]];
52650
- const left2 = [row[0]];
52651
- const right2 = new Array(4);
52652
- right2[3] = row[3];
52653
- for (let i = 1; i <= 3; i++) {
52654
- for (let j = 0; j <= 3 - i; j++) {
52655
- row[j] = { x: u * row[j].x + t * row[j + 1].x, y: u * row[j].y + t * row[j + 1].y };
52656
- }
52657
- left2.push(row[0]);
52658
- right2[3 - i] = row[3 - i];
52659
- }
53418
+ const left2 = [];
53419
+ const right2 = [];
53420
+ bezier(v, t, left2, right2);
52660
53421
  return { left: left2, right: right2 };
52661
53422
  }
52662
53423
  function splitBSpline(list, t) {
@@ -52776,17 +53537,6 @@ function mymod(original, modulus) {
52776
53537
  function l2dist(p0, p1) {
52777
53538
  return Math.hypot(p0.x - p1.x, p0.y - p1.y);
52778
53539
  }
52779
- function bezierPoint(v, t) {
52780
- const vx = [v[0].x, v[1].x, v[2].x, v[3].x];
52781
- const vy = [v[0].y, v[1].y, v[2].y, v[3].y];
52782
- for (let i = 1; i <= 3; i++) {
52783
- for (let j = 0; j <= 3 - i; j++) {
52784
- vx[j] = (1 - t) * vx[j] + t * vx[j + 1];
52785
- vy[j] = (1 - t) * vy[j] + t * vy[j + 1];
52786
- }
52787
- }
52788
- return { x: vx[0], y: vy[0] };
52789
- }
52790
53540
  function pathtolines(bez) {
52791
53541
  const arr = [];
52792
53542
  const A3 = bez.list;
@@ -52802,7 +53552,7 @@ function pathtolines(bez) {
52802
53552
  for (let j = 1; j <= 3; j++) V[j] = A3[i + j];
52803
53553
  let p0 = V[0];
52804
53554
  for (let step = 1; step <= BEZIER_SUBDIVISION; step++) {
52805
- const p1 = bezierPoint(V, step / BEZIER_SUBDIVISION);
53555
+ const p1 = bezier(V, step / BEZIER_SUBDIVISION, null, null);
52806
53556
  linelen += l2dist(p0, p1);
52807
53557
  push(p1, linelen);
52808
53558
  p0 = p1;
@@ -53027,9 +53777,9 @@ function agstrcanonText(arg) {
53027
53777
  if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
53028
53778
  return new TextDecoder().decode(new Uint8Array(out));
53029
53779
  }
53030
- const lower = arg.toLowerCase();
53780
+ const lower2 = arg.toLowerCase();
53031
53781
  for (const tok of CANON_KEYWORDS) {
53032
- if (tok === lower) return new TextDecoder().decode(new Uint8Array(out));
53782
+ if (tok === lower2) return new TextDecoder().decode(new Uint8Array(out));
53033
53783
  }
53034
53784
  return arg;
53035
53785
  }
@@ -53113,9 +53863,9 @@ function writePlainEdge(e, extend, out) {
53113
53863
  if (lbl !== void 0) {
53114
53864
  out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
53115
53865
  }
53116
- const style = lateNN(e.attrs.get("style"), "solid");
53866
+ const style2 = lateNN(e.attrs.get("style"), "solid");
53117
53867
  const color = lateNN(e.attrs.get("color"), "black");
53118
- out.push(" " + style + " " + color + "\n");
53868
+ out.push(" " + style2 + " " + color + "\n");
53119
53869
  }
53120
53870
  function writePlain(g, job, extend) {
53121
53871
  const w = plainCoord(g.info.bb.ur.x);
@@ -54682,9 +55432,9 @@ function createXdotRenderer() {
54682
55432
 
54683
55433
  // src/render/svg-tapered-edge.ts
54684
55434
  function edgeIsTapered(e) {
54685
- const style = e.attrs.get("style");
54686
- if (style === void 0 || style === "") return false;
54687
- return style.split(",").some((t) => t.trim() === "tapered");
55435
+ const style2 = e.attrs.get("style");
55436
+ if (style2 === void 0 || style2 === "") return false;
55437
+ return style2.split(",").some((t) => t.trim() === "tapered");
54688
55438
  }
54689
55439
  function svgTaperedEdge(e, job) {
54690
55440
  const spl = e.info.spl;
@@ -54905,16 +55655,16 @@ var SvgRenderer = class {
54905
55655
  */
54906
55656
  usershape(src, b, job) {
54907
55657
  const g = (n) => String(parseFloat(n.toPrecision(6)));
54908
- const width = b.ur.x - b.ll.x;
54909
- const height = b.ur.y - b.ll.y;
54910
- const originx = (b.ur.x + b.ll.x - width) / 2;
54911
- const originy = (b.ur.y + b.ll.y + height) / 2;
55658
+ const width2 = b.ur.x - b.ll.x;
55659
+ const height2 = b.ur.y - b.ll.y;
55660
+ const originx = (b.ur.x + b.ll.x - width2) / 2;
55661
+ const originy = (b.ur.y + b.ll.y + height2) / 2;
54912
55662
  let href = src;
54913
55663
  if (job.inlineImages === true) {
54914
55664
  const found = findImageBytes(src, job.imageResolver);
54915
55665
  if (found !== null) href = toDataUri(found.bytes, found.mime);
54916
55666
  }
54917
- job.write('<image xlink:href="' + escapeXml(href) + '" width="' + g(width) + 'px" height="' + g(height) + 'px" preserveAspectRatio="xMinYMin meet" x="' + g(originx) + '" y="' + g(-originy) + '"/>\n');
55667
+ job.write('<image xlink:href="' + escapeXml(href) + '" width="' + g(width2) + 'px" height="' + g(height2) + 'px" preserveAspectRatio="xMinYMin meet" x="' + g(originx) + '" y="' + g(-originy) + '"/>\n');
54918
55668
  }
54919
55669
  comment(text, job) {
54920
55670
  svgComment(text, job);