@knowvah/dot-engine 2.6.3 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) 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 +1366 -648
  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-flat-labeled.d.ts.map +1 -1
  46. package/dist/layout/dot/splines-label.d.ts.map +1 -1
  47. package/dist/layout/neato/bfs.d.ts +10 -3
  48. package/dist/layout/neato/bfs.d.ts.map +1 -1
  49. package/dist/layout/neato/init.d.ts +6 -11
  50. package/dist/layout/neato/init.d.ts.map +1 -1
  51. package/dist/layout/neato/splines.d.ts.map +1 -1
  52. package/dist/parser/index.d.ts.map +1 -1
  53. package/dist/parser/scan-token.d.ts +40 -0
  54. package/dist/parser/scan-token.d.ts.map +1 -0
  55. package/dist/render/svg-edge-split.d.ts.map +1 -1
  56. package/dist/render.js +1388 -670
  57. package/dist/render.js.map +4 -4
  58. package/package.json +1 -1
  59. package/src/common/arrows-shapes-poly.ts +9 -10
  60. package/src/common/bezier.ts +33 -0
  61. package/src/common/htmltable-attr-warn.ts +270 -0
  62. package/src/common/htmltable-fontinfo.ts +83 -0
  63. package/src/common/htmltable-lex-expat.ts +357 -0
  64. package/src/common/htmltable-lex-units.ts +75 -0
  65. package/src/common/htmltable-lex.ts +221 -160
  66. package/src/common/htmltable-parse-attrs.ts +10 -14
  67. package/src/common/htmltable-parse-font.ts +92 -0
  68. package/src/common/htmltable-parse-state.ts +64 -0
  69. package/src/common/htmltable-parse.ts +138 -98
  70. package/src/common/htmltable-pos.ts +9 -8
  71. package/src/common/htmltable-types.ts +35 -3
  72. package/src/common/htmltable.ts +14 -7
  73. package/src/common/spline-midpoint.ts +2 -22
  74. package/src/common/splines-geom.ts +5 -25
  75. package/src/common/splines-routespl.ts +21 -13
  76. package/src/common/taper.ts +2 -14
  77. package/src/gvc/anchor.ts +5 -14
  78. package/src/layout/dot/__fixtures__/2796-flat-labeled-lost.dot +161 -0
  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-flat-labeled.ts +3 -1
  85. package/src/layout/dot/splines-label.ts +3 -29
  86. package/src/layout/neato/bfs.ts +13 -4
  87. package/src/layout/neato/init.ts +15 -15
  88. package/src/layout/neato/splines.ts +4 -8
  89. package/src/parser/index.ts +13 -1
  90. package/src/parser/scan-token.ts +289 -0
  91. package/src/render/svg-edge-split.ts +5 -13
package/dist/render.js CHANGED
@@ -5086,8 +5086,8 @@ function normalizeFontName(name) {
5086
5086
  for (let i = 0; i < name.length; i++) {
5087
5087
  const ch = name[i];
5088
5088
  const code = ch.charCodeAt(0);
5089
- const isLetter2 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
5090
- if (isLetter2) result += ch.toLowerCase();
5089
+ const isLetter3 = code >= 65 && code <= 90 || code >= 97 && code <= 122;
5090
+ if (isLetter3) result += ch.toLowerCase();
5091
5091
  }
5092
5092
  return result;
5093
5093
  }
@@ -5193,30 +5193,30 @@ function fontFamilyAttrs(fontName, mode = FontnameKind.NativeFonts) {
5193
5193
  if (a === null) return null;
5194
5194
  let family;
5195
5195
  let weight;
5196
- let style;
5196
+ let style2;
5197
5197
  switch (mode) {
5198
5198
  case FontnameKind.PsFonts:
5199
5199
  family = a.name;
5200
5200
  weight = a.weight;
5201
- style = a.style;
5201
+ style2 = a.style;
5202
5202
  break;
5203
5203
  case FontnameKind.SvgFonts:
5204
5204
  family = a.svgFontFamily;
5205
5205
  weight = a.svgFontWeight;
5206
- style = a.svgFontStyle;
5206
+ style2 = a.svgFontStyle;
5207
5207
  break;
5208
5208
  default:
5209
5209
  family = a.family;
5210
5210
  weight = a.weight;
5211
- style = a.style;
5211
+ style2 = a.style;
5212
5212
  break;
5213
5213
  }
5214
5214
  const fam = a.svgFontFamily !== family ? family + "," + a.svgFontFamily : family;
5215
5215
  let attrs = ' font-family="' + fam + '"';
5216
5216
  if (weight !== null) attrs += ' font-weight="' + weight + '"';
5217
5217
  if (a.stretch !== null) attrs += ' font-stretch="' + a.stretch + '"';
5218
- if (style !== null) attrs += ' font-style="' + style + '"';
5219
- return { attrs, weight: weight !== null, style: style !== null };
5218
+ if (style2 !== null) attrs += ' font-style="' + style2 + '"';
5219
+ return { attrs, weight: weight !== null, style: style2 !== null };
5220
5220
  }
5221
5221
 
5222
5222
  // src/common/css-font.ts
@@ -5476,6 +5476,218 @@ var BORDER_RIGHT = 1 << 12;
5476
5476
  var BORDER_BOTTOM = 1 << 13;
5477
5477
  var BORDER_MASK = BORDER_LEFT | BORDER_TOP | BORDER_RIGHT | BORDER_BOTTOM;
5478
5478
 
5479
+ // src/common/htmltable-attr-warn.ts
5480
+ var accepted = (v) => ({ keep: v, text: [], warn: false });
5481
+ var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
5482
+ var warning = (msg) => `Warning: ${msg}`;
5483
+ var lower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());
5484
+ var accept = accepted;
5485
+ var STRTOL = /^[ \t\n\v\f\r]*([+-]?\d+)/;
5486
+ function doInt(v, s, min, max) {
5487
+ const m = STRTOL.exec(v);
5488
+ if (m === null) return ignored(warning(`Improper ${s} value ${v} - ignored`));
5489
+ const b = Number(m[1]);
5490
+ if (b > max) return ignored(warning(`${s} value ${v} > ${max} - too large - ignored`));
5491
+ if (b < min) return ignored(warning(`${s} value ${v} < ${min} - too small - ignored`));
5492
+ return accepted(v);
5493
+ }
5494
+ var intHandler = (s, min, max) => (v) => doInt(v, s, min, max);
5495
+ var UCHAR_MAX = 255;
5496
+ var SCHAR_MIN = -128;
5497
+ var SCHAR_MAX = 127;
5498
+ var INT8_MAX = 127;
5499
+ var USHRT_MAX = 65535;
5500
+ var GRADIENT_MAX = 360;
5501
+ var spanHandler = (s) => (v) => {
5502
+ const r = doInt(v, s, 0, USHRT_MAX);
5503
+ if (r.keep === void 0 || Number(STRTOL.exec(v)?.[1]) !== 0) return r;
5504
+ return ignored(warning(`${s} value cannot be 0 - ignored
5505
+ `));
5506
+ };
5507
+ var wordsHandler = (words, what) => (v) => words.includes(lower(v)) ? accepted(v) : ignored(warning(`Illegal value ${v} for ${what} - ignored
5508
+ `));
5509
+ var starHandler = (what) => (v) => v.startsWith("*") ? accepted(v) : ignored(warning(`Unknown value ${v} for ${what} - ignored
5510
+ `));
5511
+ var valign = wordsHandler(["bottom", "top", "middle"], "VALIGN");
5512
+ var fixedsize = wordsHandler(["true", "false"], "FIXEDSIZE");
5513
+ var tableAlign = wordsHandler(["left", "right", "center"], "ALIGN");
5514
+ var brAlign = tableAlign;
5515
+ var cellAlign = wordsHandler(["left", "right", "text", "center"], "ALIGN in TD");
5516
+ var balign = wordsHandler(["left", "right", "center"], "BALIGN in TD");
5517
+ var SIDES_LETTERS = "ltrb";
5518
+ var sides = (v) => {
5519
+ const text = [];
5520
+ for (const b of new TextEncoder().encode(v)) {
5521
+ if (SIDES_LETTERS.includes(lower(String.fromCharCode(b)))) continue;
5522
+ const code = b > SCHAR_MAX ? b - 256 : b;
5523
+ text.push(warning(`Unrecognized character '${String.fromCharCode(b)}' (${code}) in sides attribute
5524
+ `));
5525
+ }
5526
+ return { keep: v, text, warn: false };
5527
+ };
5528
+ var STYLE_WORDS = ["rounded", "radial", "solid", "invisible", "invis", "dotted", "dashed"];
5529
+ var STYLE_DELIM = " ,";
5530
+ function styleTokens(v) {
5531
+ const out = [];
5532
+ const span = (from, member) => {
5533
+ let i = from;
5534
+ while (i < v.length && STYLE_DELIM.includes(v[i]) === member) i++;
5535
+ return i;
5536
+ };
5537
+ let end = span(0, false);
5538
+ out.push(v.slice(0, end));
5539
+ while (end < v.length) {
5540
+ const start = span(end, true);
5541
+ end = span(start, false);
5542
+ out.push(v.slice(start, end));
5543
+ }
5544
+ return out;
5545
+ }
5546
+ var style = (v) => {
5547
+ const legal = [];
5548
+ const text = [];
5549
+ for (const tk of styleTokens(v)) {
5550
+ if (STYLE_WORDS.includes(lower(tk))) legal.push(tk);
5551
+ else text.push(warning(`Illegal value ${tk} for STYLE - ignored
5552
+ `));
5553
+ }
5554
+ return { keep: legal.length > 0 ? legal.join(" ") : void 0, text, warn: text.length > 0 };
5555
+ };
5556
+ var border = intHandler("BORDER", 0, UCHAR_MAX);
5557
+ var cellpadding = intHandler("CELLPADDING", 0, UCHAR_MAX);
5558
+ var cellspacing = intHandler("CELLSPACING", SCHAR_MIN, SCHAR_MAX);
5559
+ var gradientangle = intHandler("GRADIENTANGLE", 0, GRADIENT_MAX);
5560
+ var height = intHandler("HEIGHT", 0, USHRT_MAX);
5561
+ var width = intHandler("WIDTH", 0, USHRT_MAX);
5562
+ var TBL_ITEMS = /* @__PURE__ */ new Map([
5563
+ ["align", tableAlign],
5564
+ ["bgcolor", accept],
5565
+ ["border", border],
5566
+ ["cellborder", intHandler("CELLBORDER", 0, INT8_MAX)],
5567
+ ["cellpadding", cellpadding],
5568
+ ["cellspacing", cellspacing],
5569
+ ["color", accept],
5570
+ ["columns", starHandler("COLUMNS")],
5571
+ ["fixedsize", fixedsize],
5572
+ ["gradientangle", gradientangle],
5573
+ ["height", height],
5574
+ ["href", accept],
5575
+ ["id", accept],
5576
+ ["port", accept],
5577
+ ["rows", starHandler("ROWS")],
5578
+ ["sides", sides],
5579
+ ["style", style],
5580
+ ["target", accept],
5581
+ ["title", accept],
5582
+ ["tooltip", accept],
5583
+ ["valign", valign],
5584
+ ["width", width]
5585
+ ]);
5586
+ var CELL_ITEMS = /* @__PURE__ */ new Map([
5587
+ ["align", cellAlign],
5588
+ ["balign", balign],
5589
+ ["bgcolor", accept],
5590
+ ["border", border],
5591
+ ["cellpadding", cellpadding],
5592
+ ["cellspacing", cellspacing],
5593
+ ["color", accept],
5594
+ ["colspan", spanHandler("COLSPAN")],
5595
+ ["fixedsize", fixedsize],
5596
+ ["gradientangle", gradientangle],
5597
+ ["height", height],
5598
+ ["href", accept],
5599
+ ["id", accept],
5600
+ ["port", accept],
5601
+ ["rowspan", spanHandler("ROWSPAN")],
5602
+ ["sides", sides],
5603
+ ["style", style],
5604
+ ["target", accept],
5605
+ ["title", accept],
5606
+ ["tooltip", accept],
5607
+ ["valign", valign],
5608
+ ["width", width]
5609
+ ]);
5610
+ var FONT_ITEMS = /* @__PURE__ */ new Map([
5611
+ ["color", accept],
5612
+ ["face", accept],
5613
+ ["point-size", intHandler("POINT-SIZE", 0, UCHAR_MAX)]
5614
+ ]);
5615
+ var IMG_ITEMS = /* @__PURE__ */ new Map([["scale", accept], ["src", accept]]);
5616
+ var BR_ITEMS = /* @__PURE__ */ new Map([["align", brAlign]]);
5617
+ var ELEMENTS = /* @__PURE__ */ new Map([
5618
+ ["TABLE", { items: TBL_ITEMS, name: "<TABLE>" }],
5619
+ ["TD", { items: CELL_ITEMS, name: "<TD>" }],
5620
+ ["FONT", { items: FONT_ITEMS, name: "<FONT>" }],
5621
+ ["IMG", { items: IMG_ITEMS, name: "<IMG>" }],
5622
+ ["BR", { items: BR_ITEMS, name: "<BR>" }]
5623
+ ]);
5624
+ function checkAttrs(tag, pairs) {
5625
+ const el = ELEMENTS.get(tag);
5626
+ const attrs = {};
5627
+ const warnings = [];
5628
+ let warn = false;
5629
+ for (const [name, value] of pairs) {
5630
+ const key = lower(name);
5631
+ if (el === void 0) {
5632
+ attrs[key] = value;
5633
+ continue;
5634
+ }
5635
+ const handler = el.items.get(key);
5636
+ if (handler === void 0) {
5637
+ warnings.push(warning(`Illegal attribute ${name} in ${el.name} - ignored
5638
+ `));
5639
+ warn = true;
5640
+ continue;
5641
+ }
5642
+ const r = handler(value);
5643
+ warnings.push(...r.text);
5644
+ warn ||= r.warn;
5645
+ if (r.keep !== void 0) attrs[key] = r.keep;
5646
+ }
5647
+ return { attrs, warnings, warn };
5648
+ }
5649
+ var StderrLines = class {
5650
+ constructor(writeLine) {
5651
+ this.writeLine = writeLine;
5652
+ }
5653
+ writeLine;
5654
+ pending = "";
5655
+ write(text) {
5656
+ const parts = (this.pending + text).split("\n");
5657
+ this.pending = parts.pop() ?? "";
5658
+ for (const line of parts) this.writeLine(line);
5659
+ }
5660
+ flush() {
5661
+ if (this.pending === "") return;
5662
+ this.writeLine(this.pending);
5663
+ this.pending = "";
5664
+ }
5665
+ };
5666
+
5667
+ // src/common/htmltable-parse-state.ts
5668
+ var peek = (s) => s.tokens[s.pos];
5669
+ var emitWarnings = (s, tok) => {
5670
+ if (s.stderr === void 0 || s.emitted?.has(tok) === true) return;
5671
+ s.emitted?.add(tok);
5672
+ emitOutput(s, tok);
5673
+ };
5674
+ var emitOutput = (s, out) => {
5675
+ for (const text of out.warnings ?? []) s.stderr?.write(text);
5676
+ if (out.warn === true) s.warn = true;
5677
+ };
5678
+ var emitEof = (s) => {
5679
+ if (s.stderr === void 0 || s.eof === void 0) return;
5680
+ const out = s.eof;
5681
+ delete s.eof;
5682
+ emitOutput(s, out);
5683
+ };
5684
+ var consume = (s) => {
5685
+ const t = s.tokens[s.pos];
5686
+ s.pos++;
5687
+ if (t !== void 0) emitWarnings(s, t);
5688
+ return t;
5689
+ };
5690
+
5479
5691
  // src/common/html-entities.ts
5480
5692
  var HTML_ENTITIES = {
5481
5693
  "AElig": 198,
@@ -5755,6 +5967,286 @@ function htmlEntityUTF8(s) {
5755
5967
  });
5756
5968
  }
5757
5969
 
5970
+ // src/common/htmltable-lex-expat.ts
5971
+ var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
5972
+ var XML_CONTEXT_BYTES = 1024;
5973
+ var INIT_BUFFER_SIZE = 1024;
5974
+ var COMPLETE_END = (end, dup) => dup === void 0 ? { kind: "complete", end } : { kind: "complete", end, dup };
5975
+ var PARTIAL = { kind: "partial" };
5976
+ var INVALID = (offset) => ({ kind: "invalid", offset });
5977
+ var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
5978
+ var isSpace = (c) => c !== void 0 && /\s/.test(c);
5979
+ function skipSpace(text, i) {
5980
+ let j = i;
5981
+ while (isSpace(text[j])) j++;
5982
+ return j;
5983
+ }
5984
+ var byteLength = (s) => new TextEncoder().encode(s).length;
5985
+ function fedBytes(unit, isText) {
5986
+ if (!isText) return byteLength(unit);
5987
+ let text = unit.replace(/&([^;&<]*);/g, (m, name) => {
5988
+ return name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name) ? `&#${HTML_ENTITIES[name]};` : m;
5989
+ });
5990
+ if (text.endsWith("]")) text = `${text.slice(0, -1)}&#93;`;
5991
+ return byteLength(text);
5992
+ }
5993
+ function scanValue(text, j) {
5994
+ const q = text[j];
5995
+ if (q !== '"' && q !== "'") return INVALID(j);
5996
+ const close = text.indexOf(q, j + 1);
5997
+ if (close < 0) {
5998
+ const lt = text.indexOf("<", j + 1);
5999
+ return lt >= 0 ? INVALID(lt) : PARTIAL;
6000
+ }
6001
+ const next = skipSpace(text, close + 1);
6002
+ if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
6003
+ return next;
6004
+ }
6005
+ function scanPair(text, i) {
6006
+ const name = XML_NAME.exec(text.slice(i))?.[0];
6007
+ if (name === void 0) return INVALID(i);
6008
+ const eq = skipSpace(text, i + name.length);
6009
+ if (eq >= text.length) return PARTIAL;
6010
+ if (text[eq] !== "=") return INVALID(eq);
6011
+ const j = skipSpace(text, eq + 1);
6012
+ if (j >= text.length) return PARTIAL;
6013
+ const next = scanValue(text, j);
6014
+ return typeof next === "number" ? { name, next } : next;
6015
+ }
6016
+ function tagEdge(text, i) {
6017
+ const c = text[i];
6018
+ if (c === void 0) return PARTIAL;
6019
+ if (c === ">") return COMPLETE_END(i + 1);
6020
+ if (c !== "/") return void 0;
6021
+ if (i + 1 >= text.length) return PARTIAL;
6022
+ return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
6023
+ }
6024
+ function scanAttributes(text, from) {
6025
+ const seen = /* @__PURE__ */ new Set();
6026
+ let dup;
6027
+ let i = skipSpace(text, from);
6028
+ for (; ; ) {
6029
+ const edge = tagEdge(text, i);
6030
+ if (edge?.kind === "complete") return COMPLETE_END(edge.end, dup);
6031
+ if (edge !== void 0) return edge;
6032
+ const pair = scanPair(text, i);
6033
+ if ("kind" in pair) return pair;
6034
+ if (seen.has(pair.name)) dup ??= i;
6035
+ seen.add(pair.name);
6036
+ i = pair.next;
6037
+ }
6038
+ }
6039
+ function scanName(text, at) {
6040
+ const name = XML_NAME.exec(text.slice(at))?.[0];
6041
+ if (name === void 0) return at >= text.length ? PARTIAL : INVALID(at);
6042
+ return { next: at + name.length };
6043
+ }
6044
+ function scanStartTag(text, p) {
6045
+ const name = scanName(text, p + 1);
6046
+ if ("kind" in name) return name;
6047
+ const c = text[name.next];
6048
+ if (c === void 0) return PARTIAL;
6049
+ if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
6050
+ return scanAttributes(text, name.next);
6051
+ }
6052
+ function scanEndTag(text, p) {
6053
+ const name = scanName(text, p + 2);
6054
+ if ("kind" in name) return name;
6055
+ const i = skipSpace(text, name.next);
6056
+ if (i >= text.length) return PARTIAL;
6057
+ return text[i] === ">" ? COMPLETE_END(i + 1) : INVALID(i);
6058
+ }
6059
+ function scanPi(text, p) {
6060
+ const e = text.indexOf("?>", p + 2);
6061
+ return e < 0 ? PARTIAL : COMPLETE_END(e + 2);
6062
+ }
6063
+ function scanDeclaration(text, p) {
6064
+ const cdata = "<![CDATA[".startsWith(text.slice(p, p + 9));
6065
+ if (!cdata && text.length - p >= 3) return INVALID(p + 2);
6066
+ for (let i = p + 1; i < text.length; i++) {
6067
+ if (text[i] === ">") return COMPLETE_END(i + 1);
6068
+ if (text[i] === "<") return INVALID(i);
6069
+ }
6070
+ return PARTIAL;
6071
+ }
6072
+ function scanComment(text, p) {
6073
+ for (let i = p + 4; i < text.length; i++) {
6074
+ if (text[i] !== "-") continue;
6075
+ if (i + 1 >= text.length) return PARTIAL;
6076
+ if (text[i + 1] !== "-") continue;
6077
+ if (i + 2 >= text.length) return PARTIAL;
6078
+ return text[i + 2] === ">" ? COMPLETE_END(i + 3) : INVALID(i + 2);
6079
+ }
6080
+ return PARTIAL;
6081
+ }
6082
+ function scanMarkup(text, p) {
6083
+ const rest = text.slice(p, p + 4);
6084
+ if (rest === "<!--") return { scan: scanComment(text, p), kind: "comment" };
6085
+ if (text.length - p < 4 && "<!--".startsWith(rest)) return { scan: PARTIAL, kind: "comment" };
6086
+ if (rest.startsWith("<!-")) return { scan: INVALID(p + 3), kind: "comment" };
6087
+ const c = text[p + 1];
6088
+ if (c === "/") return { scan: scanEndTag(text, p), kind: "tag" };
6089
+ if (c === "?") return { scan: scanPi(text, p), kind: "pi" };
6090
+ if (c === "!") return { scan: scanDeclaration(text, p), kind: "tag" };
6091
+ return { scan: scanStartTag(text, p), kind: "tag" };
6092
+ }
6093
+ function scanContent(text, base) {
6094
+ const tokens = [];
6095
+ let p = 0;
6096
+ while (p < text.length) {
6097
+ if (text[p] !== "<") {
6098
+ const e = text.indexOf("<", p);
6099
+ const end = e < 0 ? text.length : e;
6100
+ tokens.push({ kind: "text", start: base + p, end: base + end });
6101
+ p = end;
6102
+ continue;
6103
+ }
6104
+ const { scan, kind } = scanMarkup(text, p);
6105
+ if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset };
6106
+ if (scan.kind === "partial") return { tokens, consumed: p };
6107
+ const tok = { kind, start: base + p, end: base + scan.end };
6108
+ if (scan.dup !== void 0) tok.dup = base + scan.dup;
6109
+ tokens.push(tok);
6110
+ p = scan.end;
6111
+ }
6112
+ return { tokens, consumed: p };
6113
+ }
6114
+ var InputBuffer = class {
6115
+ size = 0;
6116
+ ptr = 0;
6117
+ end = 0;
6118
+ lastRequest = 0;
6119
+ /** Bytes the last attempt could not consume; 0 once something was. */
6120
+ hadBefore = 0;
6121
+ /** `XML_GetBuffer(len)` then the append of `len` bytes. */
6122
+ append(len) {
6123
+ this.lastRequest = len;
6124
+ if (len > this.size - this.end) {
6125
+ const keep = Math.min(this.ptr, XML_CONTEXT_BYTES);
6126
+ const needed = len + (this.end - this.ptr) + keep;
6127
+ if (needed > this.size) {
6128
+ let grown = this.size;
6129
+ if (grown === 0) grown = INIT_BUFFER_SIZE;
6130
+ do
6131
+ grown *= 2;
6132
+ while (grown < needed);
6133
+ this.size = grown;
6134
+ }
6135
+ this.end = this.end - this.ptr + keep;
6136
+ this.ptr = keep;
6137
+ }
6138
+ this.end += len;
6139
+ }
6140
+ /** Bytes between the read pointer and the end of the data. */
6141
+ get have() {
6142
+ return this.end - this.ptr;
6143
+ }
6144
+ /** `callProcessor`: is it worth re-reading the partial token now? */
6145
+ get enough() {
6146
+ const available = this.ptr - Math.min(this.ptr, XML_CONTEXT_BYTES) + (this.size - this.end);
6147
+ return this.have >= 2 * this.hadBefore || this.lastRequest > available;
6148
+ }
6149
+ /** After an attempt that left `remaining` bytes unconsumed. */
6150
+ consumedTo(remaining, madeProgress) {
6151
+ this.hadBefore = madeProgress ? 0 : this.have;
6152
+ this.ptr = this.end - remaining;
6153
+ }
6154
+ };
6155
+ var ExpatFeed = class {
6156
+ constructor(src) {
6157
+ this.src = src;
6158
+ }
6159
+ src;
6160
+ buffer = new InputBuffer();
6161
+ heldStart = 0;
6162
+ fedEnd = 0;
6163
+ /** Start of the token expat still holds, or undefined when it holds nothing. */
6164
+ get held() {
6165
+ return this.heldStart < this.fedEnd ? this.heldStart : void 0;
6166
+ }
6167
+ /** One `XML_Parse(parser, src[start, end), nbytes, 0)`. */
6168
+ feed(start, end, nbytes) {
6169
+ this.buffer.append(nbytes);
6170
+ this.fedEnd = end;
6171
+ if (!this.buffer.enough) return { tokens: [] };
6172
+ const text = this.src.slice(this.heldStart, end);
6173
+ const scan = scanContent(text, this.heldStart);
6174
+ if (scan.invalid !== void 0) {
6175
+ return { tokens: scan.tokens, invalid: { message: XML_ERROR_INVALID_TOKEN, offset: scan.invalid } };
6176
+ }
6177
+ this.heldStart += scan.consumed;
6178
+ this.buffer.consumedTo(byteLength(this.src.slice(this.heldStart, end)), scan.consumed > 0);
6179
+ return { tokens: scan.tokens };
6180
+ }
6181
+ };
6182
+ var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
6183
+ var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
6184
+ function findUndefinedEntity(text) {
6185
+ for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
6186
+ if (text[t + 1] === "#") continue;
6187
+ const semi = text.indexOf(";", t + 1);
6188
+ if (semi < 0) continue;
6189
+ const key = text.slice(t + 1, semi);
6190
+ if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
6191
+ return t;
6192
+ }
6193
+ }
6194
+ return -1;
6195
+ }
6196
+ function parseTagChunk(chunk) {
6197
+ if (!chunk.endsWith(">")) return void 0;
6198
+ const body = chunk.slice(1, -1);
6199
+ if (body.startsWith("!")) return void 0;
6200
+ const close = body.startsWith("/");
6201
+ const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
6202
+ return { close, selfClose: !close && body.endsWith("/"), name };
6203
+ }
6204
+
6205
+ // src/common/htmltable-lex-units.ts
6206
+ var UNCLOSED_COMMENT = "Warning: Unclosed comment\n";
6207
+ var LABEL_CLOSED = "Warning: Label closed before end of HTML element\n";
6208
+ function eatComment(label, p) {
6209
+ let depth = 1;
6210
+ let s = p;
6211
+ while (depth > 0 && s < label.length) {
6212
+ const c = label[s++];
6213
+ if (c === "<") depth++;
6214
+ else if (c === ">") depth--;
6215
+ }
6216
+ if (depth === 0) s--;
6217
+ const warnings = [];
6218
+ if (s < label.length) {
6219
+ const t = s - 2;
6220
+ if (t < p || !label.startsWith("--", t)) warnings.push(UNCLOSED_COMMENT);
6221
+ }
6222
+ return { at: s, warnings };
6223
+ }
6224
+ function findNext(label, s) {
6225
+ let t = s + 1;
6226
+ const warnings = [];
6227
+ let warn = false;
6228
+ if (label[s] === "<") {
6229
+ if (label.startsWith("!--", t)) {
6230
+ const eaten = eatComment(label, t + 3);
6231
+ t = eaten.at;
6232
+ warnings.push(...eaten.warnings);
6233
+ warn = eaten.warnings.length > 0;
6234
+ } else {
6235
+ while (t < label.length && label[t] !== ">") t++;
6236
+ }
6237
+ if (label[t] !== ">") {
6238
+ warnings.push(LABEL_CLOSED);
6239
+ warn = true;
6240
+ } else {
6241
+ t++;
6242
+ }
6243
+ } else {
6244
+ t = s;
6245
+ while (t < label.length && label[t] !== "<") t++;
6246
+ }
6247
+ return { end: t, warnings, warn };
6248
+ }
6249
+
5758
6250
  // src/common/htmltable-lex.ts
5759
6251
  var KNOWN_TAGS = /* @__PURE__ */ new Set([
5760
6252
  "TABLE",
@@ -5781,15 +6273,15 @@ function checkTag(tag) {
5781
6273
  }
5782
6274
  }
5783
6275
  var isWs = (c) => c === " " || c === " " || c === "\n" || c === "\r";
5784
- function parseAttrs(raw) {
5785
- const out = {};
6276
+ function parseAttrPairs(raw) {
6277
+ const out = [];
5786
6278
  let i = 0;
5787
6279
  while (i < raw.length) {
5788
6280
  while (isWs(raw[i])) i++;
5789
6281
  if (i >= raw.length) break;
5790
6282
  const m = /^[\w-]+/.exec(raw.slice(i));
5791
6283
  if (m === null) throw new HtmlParseError(raw.slice(i, i + 10));
5792
- const name = m[0].toLowerCase();
6284
+ const name = m[0];
5793
6285
  i += m[0].length;
5794
6286
  while (isWs(raw[i])) i++;
5795
6287
  if (raw[i] !== "=") throw new HtmlParseError(name);
@@ -5799,7 +6291,7 @@ function parseAttrs(raw) {
5799
6291
  if (q !== '"' && q !== "'") throw new HtmlParseError(name);
5800
6292
  const end = raw.indexOf(q, i + 1);
5801
6293
  if (end < 0) throw new HtmlParseError(name);
5802
- out[name] = raw.slice(i + 1, end);
6294
+ out.push([name, raw.slice(i + 1, end)]);
5803
6295
  i = end + 1;
5804
6296
  }
5805
6297
  return out;
@@ -5818,48 +6310,36 @@ function cleanText(raw) {
5818
6310
  const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
5819
6311
  return raw.replace(/[\x00-\x1f\x7f]/g, (c) => isKeep(c) ? c : "");
5820
6312
  }
5821
- function scanText(src, start, tokens) {
5822
- let j = start;
5823
- while (j < src.length && src[j] !== "<") j++;
5824
- const clean = htmlEntityUTF8(cleanText(src.slice(start, j)));
5825
- if (clean.length > 0) tokens.push({ type: "text", value: clean });
5826
- return j;
6313
+ function textTokens(raw) {
6314
+ const clean = htmlEntityUTF8(cleanText(raw));
6315
+ return clean.length > 0 ? [{ type: "text", value: clean }] : [];
5827
6316
  }
5828
- function scanTag(src, start, tokens) {
5829
- let j = start + 1;
5830
- while (j < src.length && src[j] !== ">") j++;
5831
- const inner = src.slice(start + 1, j).trim();
5832
- const next = j + 1;
5833
- if (inner.startsWith("!--")) return next;
5834
- if (inner.startsWith("/")) {
5835
- tokens.push(parseCloseToken(inner));
5836
- return next;
5837
- }
6317
+ function tagTokens(text) {
6318
+ const inner = text.slice(1, -1).trim();
6319
+ if (inner.startsWith("/")) return [parseCloseToken(inner)];
5838
6320
  if (inner.endsWith("/")) {
5839
6321
  const open = parseOpenToken(inner.slice(0, -1).trim());
5840
- tokens.push(open, { type: "close", tag: open.tag });
5841
- return next;
6322
+ return [open, { type: "close", tag: open.tag }];
5842
6323
  }
5843
- tokens.push(parseOpenToken(inner));
5844
- return next;
6324
+ return [parseOpenToken(inner)];
6325
+ }
6326
+ function openToken(tag, raw) {
6327
+ const { attrs, warnings, warn } = checkAttrs(tag, parseAttrPairs(raw));
6328
+ const tok = { type: "open", tag, attrs };
6329
+ if (warnings.length > 0) tok.warnings = warnings;
6330
+ if (warn) tok.warn = true;
6331
+ return tok;
5845
6332
  }
5846
6333
  function parseOpenToken(inner) {
5847
6334
  const sp = inner.search(/\s/);
5848
- if (sp === -1) {
5849
- const tag2 = inner.toUpperCase();
5850
- checkTag(tag2);
5851
- return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
5852
- }
5853
- const tag = inner.slice(0, sp).toUpperCase();
6335
+ const tag = (sp === -1 ? inner : inner.slice(0, sp)).toUpperCase();
5854
6336
  checkTag(tag);
5855
- return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
6337
+ return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
5856
6338
  }
5857
6339
  var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
5858
6340
  var XML_ERROR_TAG_MISMATCH = "mismatched tag";
5859
- var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
5860
6341
  var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
5861
- var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
5862
- var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
6342
+ var SYNTAX_ERROR = "syntax error";
5863
6343
  var HtmlLexError = class extends HtmlParseError {
5864
6344
  diagnostics;
5865
6345
  constructor(tag, message, diagnostics) {
@@ -5891,112 +6371,131 @@ function htmlErrorAtToken(message, tok) {
5891
6371
  if (info === void 0) return void 0;
5892
6372
  return htmlErrorInLine(message, chunkLine(info), info.context);
5893
6373
  }
5894
- function chunkEnd(src, i) {
5895
- const j = src[i] === "<" ? src.indexOf(">", i + 1) : src.indexOf("<", i);
5896
- if (j < 0) return src.length;
5897
- return src[i] === "<" ? j + 1 : j;
5898
- }
5899
- function findUndefinedEntity(text) {
5900
- for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
5901
- if (text[t + 1] === "#") continue;
5902
- const semi = text.indexOf(";", t + 1);
5903
- if (semi < 0) continue;
5904
- const key = text.slice(t + 1, semi);
5905
- if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
5906
- return t;
5907
- }
5908
- }
5909
- return -1;
5910
- }
5911
- function parseTagChunk(chunk) {
5912
- if (!chunk.endsWith(">")) return void 0;
5913
- const body = chunk.slice(1, -1);
5914
- if (body.startsWith("!")) return void 0;
5915
- const close = body.startsWith("/");
5916
- const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
5917
- return { close, selfClose: !close && body.endsWith("/"), name };
5918
- }
5919
- var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
5920
- var isSpace = (c) => c !== void 0 && /\s/.test(c);
5921
- var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
5922
- function skipSpace(chunk, i) {
5923
- let j = i;
5924
- while (isSpace(chunk[j])) j++;
5925
- return j;
5926
- }
5927
- function readAttrPair(chunk, i) {
5928
- const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
5929
- if (name === void 0) return invalidToken(i);
5930
- let j = skipSpace(chunk, i + name.length);
5931
- if (chunk[j] !== "=") return invalidToken(j);
5932
- j = skipSpace(chunk, j + 1);
5933
- const q = chunk[j];
5934
- if (q !== '"' && q !== "'") return invalidToken(j);
5935
- const end = chunk.indexOf(q, j + 1);
5936
- return end < 0 ? void 0 : { name, next: end + 1 };
5937
- }
5938
- function findAttrError(chunk, from) {
5939
- const seen = /* @__PURE__ */ new Set();
5940
- let dup;
5941
- let i = skipSpace(chunk, from);
5942
- while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
5943
- const pair = readAttrPair(chunk, i);
5944
- if (pair === void 0) return void 0;
5945
- if ("message" in pair) return pair;
5946
- if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
5947
- seen.add(pair.name);
5948
- i = skipSpace(chunk, pair.next);
5949
- }
5950
- return dup;
5951
- }
5952
- function checkTagChunk(src, start, st) {
5953
- const tag = parseTagChunk(st.curr);
6374
+ function checkTagToken(site) {
6375
+ const { src, tok, st } = site;
6376
+ const tag = parseTagChunk(src.slice(tok.start, tok.end));
5954
6377
  if (tag === void 0) return;
6378
+ const context = st.prev + st.curr;
5955
6379
  if (tag.close) {
5956
6380
  if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
5957
- throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start), st.prev + st.curr);
6381
+ throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
5958
6382
  }
5959
6383
  } else {
5960
- const bad = findAttrError(st.curr, 1 + tag.name.length);
5961
- if (bad !== void 0) {
5962
- throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
5963
- }
6384
+ if (tok.dup !== void 0) throw htmlErrorInLine(XML_ERROR_DUPLICATE_ATTRIBUTE, lineAt(src, tok.dup), context);
5964
6385
  if (!tag.selfClose) st.stack.push(tag.name);
5965
6386
  }
5966
6387
  if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
5967
- const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
6388
+ const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, tok.start)} `;
5968
6389
  throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
5969
6390
  }
5970
- function checkChunk(src, start, st) {
5971
- if (st.curr.startsWith("<")) {
5972
- checkTagChunk(src, start, st);
5973
- return;
6391
+ function eventTokens(site) {
6392
+ const { src, tok, st } = site;
6393
+ const text = src.slice(tok.start, tok.end);
6394
+ if (tok.kind === "comment" || tok.kind === "pi") return [];
6395
+ if (tok.kind === "tag") {
6396
+ checkTagToken(site);
6397
+ return tagTokens(text);
5974
6398
  }
5975
- const off = findUndefinedEntity(st.curr);
6399
+ const off = findUndefinedEntity(text);
5976
6400
  if (off >= 0) {
5977
- throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
6401
+ throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
6402
+ }
6403
+ return textTokens(text);
6404
+ }
6405
+ function attachCarry(carry, first) {
6406
+ if (carry.warnings.length > 0) first.warnings = [...carry.warnings, ...first.warnings ?? []];
6407
+ if (carry.warn) first.warn = true;
6408
+ carry.warnings = [];
6409
+ carry.warn = false;
6410
+ }
6411
+ function absorb(carry, lost) {
6412
+ for (const t of lost) {
6413
+ carry.warnings.push(...t.warnings ?? []);
6414
+ if (t.warn === true) carry.warn = true;
6415
+ }
6416
+ }
6417
+ function eventGroups(run, res) {
6418
+ const groups = [];
6419
+ for (const tok of res.tokens) {
6420
+ const tokens = eventTokens({ src: run.src, tok, st: run.st });
6421
+ if (tokens.length > 0) groups.push({ tokens, tok });
6422
+ }
6423
+ if (res.invalid !== void 0) {
6424
+ const { message, offset } = res.invalid;
6425
+ throw htmlErrorInLine(message, lineAt(run.src, offset), run.st.prev + run.st.curr);
6426
+ }
6427
+ return groups;
6428
+ }
6429
+ function deliver(run, last) {
6430
+ const first = last.tokens[0];
6431
+ attachCarry(run.carry, first);
6432
+ const info = { src: run.src, pos: last.tok.start, end: last.tok.end, context: run.st.prev + run.st.curr };
6433
+ const prev = run.tokens.at(-1);
6434
+ if (prev?.type === "text" && first.type === "text") {
6435
+ appendString(prev, first);
6436
+ chunkInfo.set(prev, { ...info, pos: chunkInfo.get(prev)?.pos ?? info.pos });
6437
+ return;
5978
6438
  }
6439
+ for (const t of last.tokens) chunkInfo.set(t, info);
6440
+ run.tokens.push(...last.tokens);
5979
6441
  }
5980
- function tokenizeDeferred(src) {
5981
- const tokens = [];
5982
- const st = { stack: [], prev: "", curr: "" };
5983
- let i = 0;
6442
+ function runEvents(run, res) {
6443
+ const groups = eventGroups(run, res);
6444
+ const last = groups.pop();
6445
+ for (const g of groups) absorb(run.carry, g.tokens);
6446
+ if (last !== void 0) deliver(run, last);
6447
+ }
6448
+ function appendString(into, more) {
6449
+ into.value += more.value;
6450
+ if (more.warnings !== void 0) into.warnings = [...into.warnings ?? [], ...more.warnings];
6451
+ if (more.warn === true) into.warn = true;
6452
+ }
6453
+ function* lexUnits(src, label) {
6454
+ if (label.start > 0) yield { start: 0, end: label.start, warnings: [], warn: false };
6455
+ const text = src.slice(label.start, label.end);
6456
+ for (let at = 0; at < text.length; ) {
6457
+ const u = findNext(text, at);
6458
+ yield { start: label.start + at, end: label.start + u.end, warnings: u.warnings, warn: u.warn };
6459
+ at = u.end;
6460
+ }
6461
+ if (label.end < src.length) yield { start: label.end, end: src.length, warnings: [], warn: false };
6462
+ }
6463
+ function unfinishedError(run, held) {
6464
+ return htmlErrorInLine(SYNTAX_ERROR, lineAt(run.src, held), run.st.prev + run.st.curr);
6465
+ }
6466
+ var eofOutput = (carry) => {
6467
+ if (carry.warnings.length === 0 && !carry.warn) return void 0;
6468
+ return carry.warn ? { warnings: carry.warnings, warn: true } : { warnings: carry.warnings };
6469
+ };
6470
+ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
6471
+ const run = {
6472
+ src,
6473
+ tokens: [],
6474
+ st: { stack: [], prev: "", curr: "" },
6475
+ expat: new ExpatFeed(src),
6476
+ carry: { warnings: [], warn: false }
6477
+ };
6478
+ let error;
5984
6479
  try {
5985
- while (i < src.length) {
5986
- const first = tokens.length;
5987
- const start = i;
5988
- st.prev = st.curr;
5989
- st.curr = src.slice(i, chunkEnd(src, i));
5990
- checkChunk(src, i, st);
5991
- i = src[i] === "<" ? scanTag(src, i, tokens) : scanText(src, i, tokens);
5992
- const info = { src, pos: start, end: i, context: st.prev + st.curr };
5993
- for (let k = first; k < tokens.length; k++) chunkInfo.set(tokens[k], info);
5994
- }
6480
+ for (const u of lexUnits(src, label)) {
6481
+ run.st.prev = run.st.curr;
6482
+ run.st.curr = src.slice(u.start, u.end);
6483
+ run.carry.warnings.push(...u.warnings);
6484
+ if (u.warn) run.carry.warn = true;
6485
+ const nbytes = fedBytes(run.st.curr, !run.st.curr.startsWith("<"));
6486
+ runEvents(run, run.expat.feed(u.start, u.end, nbytes));
6487
+ }
6488
+ const held = run.expat.held;
6489
+ if (held !== void 0) error = unfinishedError(run, held);
5995
6490
  } catch (e) {
5996
- if (e instanceof HtmlParseError) return { tokens, error: e };
5997
- throw e;
6491
+ if (!(e instanceof HtmlParseError)) throw e;
6492
+ error = e;
5998
6493
  }
5999
- return { tokens };
6494
+ const result = { tokens: run.tokens };
6495
+ if (error !== void 0) result.error = error;
6496
+ const eof = eofOutput(run.carry);
6497
+ if (eof !== void 0) result.eof = eof;
6498
+ return result;
6000
6499
  }
6001
6500
 
6002
6501
  // src/common/htmltable-parse-attrs.ts
@@ -6036,15 +6535,9 @@ var parseSides = (v) => {
6036
6535
  if (flags === 0 || flags === BORDER_MASK) return void 0;
6037
6536
  return flags;
6038
6537
  };
6039
- var parseGradientAngle = (v) => {
6040
- if (v === void 0) return void 0;
6041
- const n = parseInt(v, 10);
6042
- if (isNaN(n) || String(n) !== v.trim()) return void 0;
6043
- if (n < 0 || n > 360) return void 0;
6044
- return n;
6045
- };
6046
- var parseColumns = (v) => v === "*" ? true : void 0;
6047
- var parseRows = (v) => v === "*" ? true : void 0;
6538
+ var parseGradientAngle = (v) => num(v);
6539
+ var parseColumns = (v) => v?.startsWith("*") === true ? true : void 0;
6540
+ var parseRows = (v) => v?.startsWith("*") === true ? true : void 0;
6048
6541
  var buildCell = (content, a) => ({
6049
6542
  kind: "cell",
6050
6543
  content,
@@ -6096,7 +6589,7 @@ var buildTable = (rows, a) => ({
6096
6589
  hrule: parseRows(a["rows"])
6097
6590
  });
6098
6591
 
6099
- // src/common/htmltable-parse.ts
6592
+ // src/common/htmltable-parse-font.ts
6100
6593
  var definedOf = (s) => Object.fromEntries(
6101
6594
  Object.entries(s).filter(([, v]) => v !== void 0)
6102
6595
  );
@@ -6120,17 +6613,6 @@ var fontItemProps = (f) => {
6120
6613
  if (f.fontSize !== void 0) out.fontSize = f.fontSize;
6121
6614
  return out;
6122
6615
  };
6123
- var MSG_SYNTAX_ERROR = "syntax error";
6124
- var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
6125
- var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
6126
- var nonSpace = (text) => /[^ \t\n\r]/.test(text);
6127
- var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
6128
- var peek = (s) => s.tokens[s.pos];
6129
- var consume = (s) => {
6130
- const t = s.tokens[s.pos];
6131
- s.pos++;
6132
- return t;
6133
- };
6134
6616
  var isInlineTag = (tag) => ["B", "I", "U", "O", "S", "SUB", "SUP"].includes(tag);
6135
6617
  var inlineFontState = (tag, _attrs) => {
6136
6618
  const fs = {};
@@ -6143,6 +6625,35 @@ var inlineFontState = (tag, _attrs) => {
6143
6625
  if (tag === "SUP") fs.superscript = true;
6144
6626
  return fs;
6145
6627
  };
6628
+ var wrapperFont = (t, fontStack) => {
6629
+ const font = fontStack[fontStack.length - 1] ?? {};
6630
+ if (t.tag !== "FONT") return mergeFontState(font, inlineFontState(t.tag, t.attrs));
6631
+ return mergeFontState(font, {
6632
+ fontColor: t.attrs["color"],
6633
+ fontFace: t.attrs["face"],
6634
+ fontSize: num(t.attrs["point-size"])
6635
+ });
6636
+ };
6637
+ var tableFont = (fontStack) => {
6638
+ if (fontStack.length < 2) return void 0;
6639
+ const { fontColor, fontFace, fontSize } = fontStack[fontStack.length - 1];
6640
+ const font = {};
6641
+ if (fontColor !== void 0) font.fontColor = fontColor;
6642
+ if (fontFace !== void 0) font.fontFace = fontFace;
6643
+ if (fontSize !== void 0) font.fontSize = fontSize;
6644
+ return font;
6645
+ };
6646
+
6647
+ // src/common/htmltable-parse.ts
6648
+ var MSG_SYNTAX_ERROR = "syntax error";
6649
+ var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
6650
+ var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
6651
+ var nonSpace = (text) => /[^ \t\n\r]/.test(text);
6652
+ var parseError = (s, tok, message) => {
6653
+ if (tok !== void 0) emitWarnings(s, tok);
6654
+ else emitEof(s);
6655
+ return (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
6656
+ };
6146
6657
  var consumeClose = (s, tag) => {
6147
6658
  const nxt = peek(s);
6148
6659
  if (nxt === void 0) return;
@@ -6213,6 +6724,45 @@ var parseText = (s, fontStack) => {
6213
6724
  }
6214
6725
  return { kind: "text", items };
6215
6726
  };
6727
+ var FONTTABLE_TAGS = ["FONT", "B", "I", "U", "O"];
6728
+ var fontTableWrapper = (s) => {
6729
+ const open = peek(s);
6730
+ if (open?.type !== "open" || !FONTTABLE_TAGS.includes(open.tag)) return void 0;
6731
+ let i = s.pos + 1;
6732
+ while (s.tokens[i]?.type === "text") i++;
6733
+ const next = s.tokens[i];
6734
+ return next?.type === "open" && next.tag === "TABLE" ? open : void 0;
6735
+ };
6736
+ var skipStrings = (s) => {
6737
+ let found = false;
6738
+ for (let t = peek(s); t?.type === "text"; t = peek(s)) {
6739
+ consume(s);
6740
+ if (nonSpace(t.value)) found = true;
6741
+ }
6742
+ return found;
6743
+ };
6744
+ var parseFontTable = (s, open, fontStack) => {
6745
+ consume(s);
6746
+ fontStack.push(wrapperFont(open, fontStack));
6747
+ const textBefore = skipStrings(s);
6748
+ const tblTok = peek(s);
6749
+ if (textBefore && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
6750
+ const table = parseTable(s, fontStack);
6751
+ const textAfter = skipStrings(s);
6752
+ const close = peek(s);
6753
+ if (close !== void 0 && textAfter) throw parseError(s, close, MSG_TEXT_AFTER_TABLE);
6754
+ if (close?.type !== "close" || close.tag !== open.tag) throw parseError(s, close, MSG_SYNTAX_ERROR);
6755
+ consume(s);
6756
+ fontStack.pop();
6757
+ return table;
6758
+ };
6759
+ var rejectTableAfterTag = (s, start) => {
6760
+ const nxt = peek(s);
6761
+ if (nxt?.type !== "open" || nxt.tag !== "TABLE") return;
6762
+ if (s.tokens.slice(start, s.pos).some((t) => t.type !== "text")) {
6763
+ throw parseError(s, nxt, MSG_SYNTAX_ERROR);
6764
+ }
6765
+ };
6216
6766
  var parseImgContent = (s, t, cellAttrs) => {
6217
6767
  consume(s);
6218
6768
  const img = {
@@ -6234,6 +6784,7 @@ var scanCellText = (s, t, fontStack, st) => {
6234
6784
  const start = s.pos;
6235
6785
  const txt = parseText(s, fontStack);
6236
6786
  if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
6787
+ rejectTableAfterTag(s, start);
6237
6788
  if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
6238
6789
  st.kind = "text";
6239
6790
  return txt.items.length > 0 ? [txt] : [];
@@ -6250,7 +6801,13 @@ var scanCellImage = (s, t, cellAttrs, st) => {
6250
6801
  return [parseImgContent(s, t, cellAttrs)];
6251
6802
  };
6252
6803
  var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
6804
+ if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
6253
6805
  if (st.kind === "table") return scanAfterTable(s, t, st);
6806
+ const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
6807
+ if (wrapper !== void 0) {
6808
+ st.kind = "fonttable";
6809
+ return [parseFontTable(s, wrapper, fontStack)];
6810
+ }
6254
6811
  if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
6255
6812
  if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
6256
6813
  if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
@@ -6353,7 +6910,10 @@ var parseTable = (s, fontStack) => {
6353
6910
  for (let t = peek(s); t !== void 0; t = peek(s)) {
6354
6911
  if (scanTableToken(s, t, fontStack, ts)) break;
6355
6912
  }
6356
- return buildTable(ts.rows, open.attrs);
6913
+ const table = buildTable(ts.rows, open.attrs);
6914
+ const font = tableFont(fontStack);
6915
+ if (font !== void 0) table.font = font;
6916
+ return table;
6357
6917
  };
6358
6918
  var parseTableRow = (s, fontStack, opts) => {
6359
6919
  const row = parseRow(s, fontStack);
@@ -6393,6 +6953,14 @@ var finishTableLabel = (s) => {
6393
6953
  if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
6394
6954
  consume(s);
6395
6955
  };
6956
+ var parseFontTableLabel = (s, open, fontStack) => {
6957
+ const table = parseFontTable(s, open, fontStack);
6958
+ const nxt = peek(s);
6959
+ if (nxt === void 0) return { kind: "table", table };
6960
+ if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
6961
+ consume(s);
6962
+ return { kind: "table", table };
6963
+ };
6396
6964
  var parseTableLabel = (s, fontStack) => {
6397
6965
  skipLeadingWs(s);
6398
6966
  const table = parseTable(s, fontStack);
@@ -6401,17 +6969,16 @@ var parseTableLabel = (s, fontStack) => {
6401
6969
  };
6402
6970
  var parseTextLabel = (s, fontStack) => {
6403
6971
  const texts = [];
6972
+ const start = s.pos;
6404
6973
  const txt = parseText(s, fontStack);
6405
6974
  if (txt.items.length > 0) texts.push(txt);
6406
6975
  const nxt = peek(s);
6407
6976
  if (nxt === void 0) return { kind: "text", texts };
6408
6977
  if (nxt.type === "open" && nxt.tag === "TABLE") {
6409
- if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) {
6410
- throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
6411
- }
6412
- throw new HtmlParseError("TABLE");
6978
+ rejectTableAfterTag(s, start);
6979
+ throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
6413
6980
  }
6414
- if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
6981
+ if (nxt.type !== "close" || nxt.tag !== "HTML" || s.pos === start) throw parseError(s, nxt, MSG_SYNTAX_ERROR);
6415
6982
  consume(s);
6416
6983
  return { kind: "text", texts };
6417
6984
  };
@@ -6419,23 +6986,38 @@ var parseTokens = (s) => {
6419
6986
  const fontStack = [{}];
6420
6987
  const htmlOpen = consume(s);
6421
6988
  if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
6989
+ const wrapper = fontTableWrapper(s);
6990
+ if (wrapper !== void 0) return parseFontTableLabel(s, wrapper, fontStack);
6422
6991
  const firstReal = findFirstRealToken(s.tokens, s.pos);
6423
6992
  if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
6424
6993
  return parseTextLabel(s, fontStack);
6425
6994
  };
6426
- var parseHtmlLabel = (src) => {
6427
- const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML>`);
6428
- const s = { tokens, pos: 0, pending: error };
6429
- let label;
6995
+ var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
6996
+ const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
6997
+ const s = {
6998
+ tokens,
6999
+ pos: 0,
7000
+ pending: error,
7001
+ stderr: new StderrLines(writeLine),
7002
+ emitted: /* @__PURE__ */ new WeakSet(),
7003
+ warn: false,
7004
+ eof
7005
+ };
6430
7006
  try {
6431
- label = parseTokens(s);
7007
+ const label = parseTokens(s);
7008
+ if (error !== void 0) throw error;
7009
+ return { label, warn: s.warn === true };
6432
7010
  } catch (e) {
6433
- if (error !== void 0 && s.pos >= tokens.length) throw error;
7011
+ if (error !== void 0 && s.pos >= tokens.length) {
7012
+ emitEof(s);
7013
+ throw error;
7014
+ }
6434
7015
  throw e;
7016
+ } finally {
7017
+ s.stderr?.flush();
6435
7018
  }
6436
- if (error !== void 0) throw error;
6437
- return label;
6438
7019
  };
7020
+ var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
6439
7021
 
6440
7022
  // src/gvc/usershape.ts
6441
7023
  var activeSizer = null;
@@ -6494,6 +7076,41 @@ var PointSet = class {
6494
7076
  }
6495
7077
  };
6496
7078
 
7079
+ // src/common/htmltable-fontinfo.ts
7080
+ var SIZE_SAVEF = { fontsize: 0 };
7081
+ var EMIT_SAVEF = { fontsize: 0 };
7082
+ var pushFontInfo = (env, fp, savp) => {
7083
+ if (fp.fontFace !== void 0) {
7084
+ savp.fontname = env.fontname;
7085
+ env.fontname = fp.fontFace;
7086
+ } else savp.fontname = void 0;
7087
+ if (env.fontcolor !== void 0) {
7088
+ if (fp.fontColor !== void 0) {
7089
+ savp.fontcolor = env.fontcolor;
7090
+ env.fontcolor = fp.fontColor;
7091
+ } else savp.fontcolor = void 0;
7092
+ }
7093
+ if (env.fontsize >= 0) {
7094
+ if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
7095
+ savp.fontsize = env.fontsize;
7096
+ env.fontsize = fp.fontSize;
7097
+ } else savp.fontsize = -1;
7098
+ }
7099
+ };
7100
+ var popFontInfo = (env, savp) => {
7101
+ if (savp.fontname !== void 0) env.fontname = savp.fontname;
7102
+ if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
7103
+ if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
7104
+ };
7105
+ var withTableFont = (env, font, slot, fn) => {
7106
+ if (font === void 0) return fn();
7107
+ const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
7108
+ pushFontInfo(env, font, savp);
7109
+ const r = fn();
7110
+ popFontInfo(env, savp);
7111
+ return r;
7112
+ };
7113
+
6497
7114
  // src/common/htmltable.ts
6498
7115
  var DEFAULT_BORDER = 1;
6499
7116
  var DEFAULT_CELLPADDING = 2;
@@ -6519,7 +7136,7 @@ var findCol = (ps, row, startCol, colspan, rowspan) => {
6519
7136
  }
6520
7137
  return col;
6521
7138
  };
6522
- var DEFAULT_SIZE_ENV = { fontsize: DEFAULT_FONTSIZE, fontname: "" };
7139
+ var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
6523
7140
  var itemFont = (item, env) => ({
6524
7141
  fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
6525
7142
  face: item.fontFace !== void 0 ? item.fontFace : env.fontname
@@ -6582,7 +7199,7 @@ var htmlTextIsSimple = (texts, env) => {
6582
7199
  }
6583
7200
  return true;
6584
7201
  };
6585
- var sizeTextContent = (texts, measurer, env = DEFAULT_SIZE_ENV) => {
7202
+ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
6586
7203
  const lines = splitSizedLines(texts, measurer, env);
6587
7204
  const simple = htmlTextIsSimple(texts, env);
6588
7205
  let w = 0;
@@ -6751,18 +7368,18 @@ var sumTableDims = (a) => {
6751
7368
  for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
6752
7369
  return { wd, ht };
6753
7370
  };
6754
- var layoutHtmlTable = (tbl, measurer, env = DEFAULT_SIZE_ENV) => {
7371
+ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
6755
7372
  const spacing = getSpacing(tbl);
6756
- const border = getBorder(tbl);
7373
+ const border2 = getBorder(tbl);
6757
7374
  const { entries, rv } = buildLayouts(tbl, measurer, env);
6758
7375
  if (entries.length === 0) {
6759
- return { entries, widths: [], heights: [], spacing, border, rv };
7376
+ return { entries, widths: [], heights: [], spacing, border: border2, rv };
6760
7377
  }
6761
7378
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
6762
7379
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
6763
7380
  const widths = setColWidths(entries, ncols, spacing);
6764
7381
  const heights = setRowHeights(entries, nrows, spacing);
6765
- return { entries, widths, heights, spacing, border, rv };
7382
+ return { entries, widths, heights, spacing, border: border2, rv };
6766
7383
  };
6767
7384
  var warnFixedTable = (tbl, dims) => {
6768
7385
  const warn = !sizeWarned.has(tbl);
@@ -6776,17 +7393,17 @@ var warnFixedTable = (tbl, dims) => {
6776
7393
  if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
6777
7394
  return 1;
6778
7395
  };
6779
- var sizeTableInner = (tbl, measurer, env) => {
6780
- const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
7396
+ var sizeTableBody = (tbl, measurer, env) => {
7397
+ const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
6781
7398
  if (entries.length === 0) {
6782
- const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
7399
+ const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
6783
7400
  tbl.dimen = { w: 0, h: 0 };
6784
7401
  return rv | fixed2;
6785
7402
  }
6786
7403
  const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
6787
7404
  const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
6788
7405
  for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
6789
- const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
7406
+ const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
6790
7407
  const baseWd = tbl.width !== void 0 ? tbl.width : 0;
6791
7408
  const baseHt = tbl.height !== void 0 ? tbl.height : 0;
6792
7409
  const fixed = warnFixedTable(tbl, { wd, ht });
@@ -6797,7 +7414,8 @@ var sizeTableInner = (tbl, measurer, env) => {
6797
7414
  };
6798
7415
  return rv | fixed;
6799
7416
  };
6800
- var sizeHtmlLabel = (label, measurer, env = DEFAULT_SIZE_ENV) => {
7417
+ var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
7418
+ var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
6801
7419
  if (label.kind === "table") {
6802
7420
  const rv = sizeTableInner(label.table, measurer, env);
6803
7421
  label.dimen = label.table.dimen;
@@ -7015,8 +7633,8 @@ function alignContentBox(box, cell2, w, h) {
7015
7633
  var HTML_ALL_SIDES = TOP | BOTTOM | LEFT | RIGHT;
7016
7634
  function placeCellRuns(ctx) {
7017
7635
  const { cell: cell2, tbl, box, finfo, measurer } = ctx;
7018
- const border = cellBorder(cell2, tbl);
7019
- const inset = border + cellPad(cell2, tbl);
7636
+ const border2 = cellBorder(cell2, tbl);
7637
+ const inset = border2 + cellPad(cell2, tbl);
7020
7638
  const cbox = {
7021
7639
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
7022
7640
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
@@ -7065,17 +7683,17 @@ function placeCellNested(ctx) {
7065
7683
  ll: { x: box.ll.x + inset, y: box.ll.y + inset },
7066
7684
  ur: { x: box.ur.x - inset, y: box.ur.y - inset }
7067
7685
  };
7068
- return posHtmlTable(nested2, finfo, measurer, cbox, sidesMask);
7686
+ return withTableFont(finfo, nested2.font, "emit", () => posHtmlTable(nested2, finfo, measurer, cbox, sidesMask));
7069
7687
  }
7070
7688
  function placeCell(ctx) {
7071
7689
  const { cell: cell2, tbl, box, col, row, colspan, rowspan } = ctx;
7072
- const border = cellBorder(cell2, tbl);
7690
+ const border2 = cellBorder(cell2, tbl);
7073
7691
  const vruled = cell2.vruled;
7074
7692
  const nested2 = placeCellNested(ctx);
7075
7693
  const image = nested2 === void 0 ? placeCellImage(cell2, tbl, box) : void 0;
7076
7694
  return {
7077
7695
  box,
7078
- border,
7696
+ border: border2,
7079
7697
  lines: nested2 === void 0 ? placeCellRuns(ctx) : [],
7080
7698
  image,
7081
7699
  nested: nested2,
@@ -7105,18 +7723,18 @@ function distributeExtra(sizes, del, count) {
7105
7723
  const plus = r >= 0 ? Math.floor(r + 0.5) : Math.ceil(r - 0.5);
7106
7724
  return sizes.map((w, i) => w + extra + (i < plus ? 1 : 0));
7107
7725
  }
7108
- function buildColX(pos, border, spacing, widths) {
7726
+ function buildColX(pos, border2, spacing, widths) {
7109
7727
  const colX = [];
7110
- let x = pos.ll.x + border + spacing;
7728
+ let x = pos.ll.x + border2 + spacing;
7111
7729
  for (let i = 0; i < widths.length; i++) {
7112
7730
  colX[i] = x;
7113
7731
  x += widths[i] + spacing;
7114
7732
  }
7115
7733
  return colX;
7116
7734
  }
7117
- function buildRowY(pos, border, spacing, heights) {
7735
+ function buildRowY(pos, border2, spacing, heights) {
7118
7736
  const rowY = [];
7119
- let y = pos.ur.y - border - spacing;
7737
+ let y = pos.ur.y - border2 - spacing;
7120
7738
  for (let i = 0; i < heights.length; i++) {
7121
7739
  rowY[i] = y;
7122
7740
  y -= heights[i] + spacing;
@@ -7136,14 +7754,14 @@ function tblDecoration(tbl) {
7136
7754
  gradientangle: tbl.gradientangle
7137
7755
  };
7138
7756
  }
7139
- function cellSidesMask(e, ncols, nrows, sides) {
7140
- if (sides === 0) return 0;
7757
+ function cellSidesMask(e, ncols, nrows, sides2) {
7758
+ if (sides2 === 0) return 0;
7141
7759
  let mask = 0;
7142
7760
  if (e.col === 0) mask |= LEFT;
7143
7761
  if (e.row === 0) mask |= TOP;
7144
7762
  if (e.col + e.colspan === ncols) mask |= RIGHT;
7145
7763
  if (e.row + e.rowspan === nrows) mask |= BOTTOM;
7146
- return sides & mask;
7764
+ return sides2 & mask;
7147
7765
  }
7148
7766
  function ruledBoundaries(tbl) {
7149
7767
  const bits = /* @__PURE__ */ new Set();
@@ -7153,7 +7771,7 @@ function ruledBoundaries(tbl) {
7153
7771
  return bits;
7154
7772
  }
7155
7773
  function placeCells(ctx) {
7156
- const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer } = ctx;
7774
+ const { tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer } = ctx;
7157
7775
  const boundaries = ruledBoundaries(tbl);
7158
7776
  return entries.map((e) => {
7159
7777
  const box = {
@@ -7170,19 +7788,19 @@ function placeCells(ctx) {
7170
7788
  row: e.row,
7171
7789
  colspan: e.colspan,
7172
7790
  rowspan: e.rowspan,
7173
- sidesMask: cellSidesMask(e, ncols, nrows, sides)
7791
+ sidesMask: cellSidesMask(e, ncols, nrows, sides2)
7174
7792
  });
7175
7793
  if (boundaries.has(e.row + e.rowspan)) placed.hruled = true;
7176
7794
  return placed;
7177
7795
  });
7178
7796
  }
7179
- function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
7797
+ function posHtmlTable(tbl, finfo, measurer, pos, sides2 = HTML_ALL_SIDES) {
7180
7798
  const dim = tbl.dimen ?? { w: 0, h: 0 };
7181
7799
  const box = pos !== void 0 ? { ll: { ...pos.ll }, ur: { ...pos.ur } } : {
7182
7800
  ll: { x: -dim.w / 2, y: -dim.h / 2 },
7183
7801
  ur: { x: dim.w / 2, y: dim.h / 2 }
7184
7802
  };
7185
- const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, {
7803
+ const { entries, widths, heights, spacing, border: border2 } = layoutHtmlTable(tbl, measurer, {
7186
7804
  fontsize: finfo.fontsize,
7187
7805
  fontname: finfo.fontname
7188
7806
  });
@@ -7214,10 +7832,10 @@ function posHtmlTable(tbl, finfo, measurer, pos, sides = HTML_ALL_SIDES) {
7214
7832
  dely = 0;
7215
7833
  }
7216
7834
  }
7217
- const colX = buildColX(box, border, spacing, distributeExtra(widths, delx, ncols));
7218
- const rowY = buildRowY(box, border, spacing, distributeExtra(heights, dely, nrows));
7219
- const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides, finfo, measurer });
7220
- return { box, border, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides, ...tblDecoration(tbl) };
7835
+ const colX = buildColX(box, border2, spacing, distributeExtra(widths, delx, ncols));
7836
+ const rowY = buildRowY(box, border2, spacing, distributeExtra(heights, dely, nrows));
7837
+ const cells = placeCells({ tbl, entries, colX, rowY, spacing, ncols, nrows, sides: sides2, finfo, measurer });
7838
+ return { box, border: border2, cells, spacing, columnCount: ncols, rowCount: nrows, port: tbl.port, boundarySides: sides2, ...tblDecoration(tbl) };
7221
7839
  }
7222
7840
  function posTextLabel(label, finfo, measurer) {
7223
7841
  const dim = label.dimen ?? { w: 0, h: 0 };
@@ -7244,21 +7862,22 @@ function posTextLabel(label, finfo, measurer) {
7244
7862
  };
7245
7863
  }
7246
7864
  function posHtmlLabel(label, finfo, measurer) {
7247
- if (label.kind === "table") return posHtmlTable(label.table, finfo, measurer);
7865
+ const env = { ...finfo };
7866
+ if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
7248
7867
  return posTextLabel(label, finfo, measurer);
7249
7868
  }
7250
7869
  var HTML_PARSE_FATAL = 3;
7251
7870
  function makeHtmlLabelRv(content, finfo, measurer) {
7252
7871
  const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
7253
- let lbl;
7872
+ let lbl, lexWarn;
7254
7873
  try {
7255
- lbl = parseHtmlLabel(content);
7874
+ ({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
7256
7875
  } catch (e) {
7257
7876
  if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
7258
7877
  return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
7259
7878
  }
7260
7879
  if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
7261
- const rv = sizeHtmlLabel(lbl, measurer, {
7880
+ const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
7262
7881
  fontsize,
7263
7882
  fontname,
7264
7883
  imageSizer
@@ -8100,33 +8719,53 @@ function otherEdge(e) {
8100
8719
  elistAppend(e.tail.info.other, e);
8101
8720
  }
8102
8721
 
8722
+ // src/common/fma.ts
8723
+ var SPLIT = 134217729;
8724
+ function fma(a, b, c) {
8725
+ const p = a * b;
8726
+ const at = SPLIT * a;
8727
+ const ahi = at - (at - a);
8728
+ const alo = a - ahi;
8729
+ const bt = SPLIT * b;
8730
+ const bhi = bt - (bt - b);
8731
+ const blo = b - bhi;
8732
+ const e = ahi * bhi - p + ahi * blo + alo * bhi + alo * blo;
8733
+ const s = p + c;
8734
+ const bv = s - p;
8735
+ const err = p - (s - bv) + (c - bv);
8736
+ return s + (err + e);
8737
+ }
8738
+ function fms(a, b, c) {
8739
+ return fma(-a, b, c);
8740
+ }
8741
+
8742
+ // src/common/bezier.ts
8743
+ function bezier(v, t, left2, right2) {
8744
+ const degree = 3;
8745
+ const u = 1 - t;
8746
+ const tri = [[v[0], v[1], v[2], v[3]]];
8747
+ for (let i = 1; i <= degree; i++) {
8748
+ const prev = tri[i - 1];
8749
+ const row = [];
8750
+ for (let j = 0; j <= degree - i; j++) {
8751
+ row.push({
8752
+ x: fma(prev[j].x, u, t * prev[j + 1].x),
8753
+ y: fma(prev[j].y, u, t * prev[j + 1].y)
8754
+ });
8755
+ }
8756
+ tri.push(row);
8757
+ }
8758
+ if (left2 !== null) for (let j = 0; j <= degree; j++) left2[j] = tri[j][0];
8759
+ if (right2 !== null) for (let j = 0; j <= degree; j++) right2[j] = tri[degree - j][j];
8760
+ return tri[degree][0];
8761
+ }
8762
+
8103
8763
  // src/common/splines-geom.ts
8104
8764
  function approxEqPt(p, q, tol) {
8105
8765
  const dx = p.x - q.x;
8106
8766
  const dy = p.y - q.y;
8107
8767
  return dx * dx + dy * dy < tol * tol;
8108
8768
  }
8109
- function evalBezier(sp, t, left2, right2) {
8110
- const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
8111
- const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
8112
- const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
8113
- const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
8114
- const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
8115
- const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
8116
- if (left2 !== null) {
8117
- left2[0] = sp[0];
8118
- left2[1] = ab;
8119
- left2[2] = abbc;
8120
- left2[3] = pt;
8121
- }
8122
- if (right2 !== null) {
8123
- right2[0] = pt;
8124
- right2[1] = bccd;
8125
- right2[2] = cd;
8126
- right2[3] = sp[3];
8127
- }
8128
- return pt;
8129
- }
8130
8769
  var HW = 2;
8131
8770
  var SMALL = 1e-10;
8132
8771
  function ptToLine2(a, b, p) {
@@ -8161,7 +8800,7 @@ function updateBbBz(bb, cp) {
8161
8800
  }
8162
8801
  const left2 = [];
8163
8802
  const right2 = [];
8164
- evalBezier(cp, 0.5, left2, right2);
8803
+ bezier(cp, 0.5, left2, right2);
8165
8804
  updateBbBz(bb, left2);
8166
8805
  updateBbBz(bb, right2);
8167
8806
  }
@@ -8187,7 +8826,7 @@ function bezierClip(insideCtx, insideFn, sp, leftInside) {
8187
8826
  do {
8188
8827
  const opt = pt;
8189
8828
  const t = (high + low) / 2;
8190
- pt = evalBezier(sp, t, left2, right2);
8829
+ pt = bezier(sp, t, left2, right2);
8191
8830
  if (insideFn(insideCtx, pt)) {
8192
8831
  if (leftInside) {
8193
8832
  low = t;
@@ -8618,15 +9257,10 @@ function arrowLengthTee(lenfact, arrowsize, penwidth) {
8618
9257
  if (extendStart > 0) length += extendEnd;
8619
9258
  return length;
8620
9259
  }
8621
- var lerp = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });
8622
9260
  function cubicHalf(c, rightHalf) {
8623
- const A3 = lerp(c[0], c[1]);
8624
- const B2 = lerp(c[1], c[2]);
8625
- const C6 = lerp(c[2], c[3]);
8626
- const D = lerp(A3, B2);
8627
- const E = lerp(B2, C6);
8628
- const M2 = lerp(D, E);
8629
- return rightHalf ? [M2, E, C6, c[3]] : [c[0], A3, D, M2];
9261
+ const half = [];
9262
+ bezier(c, 0.5, rightHalf ? null : half, rightHalf ? half : null);
9263
+ return half;
8630
9264
  }
8631
9265
  function curveControlPoints(p, v, w, flag) {
8632
9266
  const AF0 = { x: p.x + v.x + w.x, y: p.y + v.y + w.y };
@@ -8899,29 +9533,11 @@ function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth, rankdir = 0) {
8899
9533
  }
8900
9534
 
8901
9535
  // src/layout/dot/edge-route-clip.ts
8902
- function deCasteljauTriangle(sp, t) {
8903
- const u = 1 - t;
8904
- const v = [
8905
- [sp[0], sp[1], sp[2], sp[3]],
8906
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
8907
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }],
8908
- [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]
8909
- ];
8910
- for (let i = 1; i <= 3; i++) {
8911
- for (let j = 0; j <= 3 - i; j++) {
8912
- v[i][j] = {
8913
- x: u * v[i - 1][j].x + t * v[i - 1][j + 1].x,
8914
- y: u * v[i - 1][j].y + t * v[i - 1][j + 1].y
8915
- };
8916
- }
8917
- }
8918
- return v;
8919
- }
8920
9536
  function bezierSubdivide(sp, t) {
8921
- const v = deCasteljauTriangle(sp, t);
8922
- const left2 = [v[0][0], v[1][0], v[2][0], v[3][0]];
8923
- const right2 = [v[3][0], v[2][1], v[1][2], v[0][3]];
8924
- return [left2, right2, v[3][0]];
9537
+ const left2 = [];
9538
+ const right2 = [];
9539
+ const mid = bezier(sp, t, left2, right2);
9540
+ return [left2, right2, mid];
8925
9541
  }
8926
9542
  function bisectStep(c, insideFn, leftInside, s) {
8927
9543
  const t = (s.high + s.low) / 2;
@@ -10039,20 +10655,20 @@ function rect(x, y, w, h) {
10039
10655
  function dnaY(af) {
10040
10656
  return af[2].y + (af[0].y - af[3].y) / 2;
10041
10657
  }
10042
- function nextV(af, seg2, sides) {
10043
- return seg2 + 1 < sides ? af[seg2 + 1] : af[0];
10658
+ function nextV(af, seg2, sides2) {
10659
+ return seg2 + 1 < sides2 ? af[seg2 + 1] : af[0];
10044
10660
  }
10045
- function interpolationPoints(af, sides, shape, rounded = false) {
10661
+ function interpolationPoints(af, sides2, shape, rounded = false) {
10046
10662
  let rbconst = RBCONST;
10047
- for (let seg2 = 0; seg2 < sides; seg2++) {
10663
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
10048
10664
  const p0 = af[seg2];
10049
- const p1 = nextV(af, seg2, sides);
10665
+ const p1 = nextV(af, seg2, sides2);
10050
10666
  rbconst = Math.min(rbconst, Math.hypot(p1.x - p0.x, p1.y - p0.y) / 3);
10051
10667
  }
10052
10668
  const b = [];
10053
- for (let seg2 = 0; seg2 < sides; seg2++) {
10669
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
10054
10670
  const p0 = af[seg2];
10055
- const p1 = nextV(af, seg2, sides);
10671
+ const p1 = nextV(af, seg2, sides2);
10056
10672
  let t = rbconst / Math.hypot(p1.x - p0.x, p1.y - p0.y);
10057
10673
  if (shape === BOX3D || shape === COMPONENT) t /= 3;
10058
10674
  else if (shape === DOGEAR) t /= 2;
@@ -10089,28 +10705,28 @@ function drawCds(af, b, coord, filled, ctx) {
10089
10705
  renderShapePolygon(D, coord, ctx, filled);
10090
10706
  }
10091
10707
  function drawDogear(af, b, coord, filled, ctx) {
10092
- const sides = af.length;
10093
- const D = new Array(sides + 1);
10094
- for (let seg2 = 1; seg2 < sides; seg2++) D[seg2] = af[seg2];
10095
- D[0] = b[3 * (sides - 1) + 4];
10096
- D[sides] = b[3 * (sides - 1) + 2];
10708
+ const sides2 = af.length;
10709
+ const D = new Array(sides2 + 1);
10710
+ for (let seg2 = 1; seg2 < sides2; seg2++) D[seg2] = af[seg2];
10711
+ D[0] = b[3 * (sides2 - 1) + 4];
10712
+ D[sides2] = b[3 * (sides2 - 1) + 2];
10097
10713
  renderShapePolygon(D, coord, ctx, filled);
10098
- const s = sides - 1;
10714
+ const s = sides2 - 1;
10099
10715
  const c0 = b[3 * s + 2];
10100
10716
  const c2 = vadd2(b[3 * s + 4], vsub2(c0, b[3 * s + 3]));
10101
10717
  renderShapePolyline([b[3 * s + 4], c2], coord, ctx);
10102
10718
  renderShapePolyline([c0, c2], coord, ctx);
10103
10719
  }
10104
10720
  function drawTab(af, b, coord, filled, ctx) {
10105
- const sides = af.length;
10721
+ const sides2 = af.length;
10106
10722
  const w = { x: (b[3].x - b[4].x) / 3, y: (b[3].y - b[4].y) / 3 };
10107
10723
  const D = [af[0], b[2], vadd2(b[2], w), vadd2(b[3], w)];
10108
- for (let seg2 = 4; seg2 < sides + 2; seg2++) D.push(af[seg2 - 2]);
10724
+ for (let seg2 = 4; seg2 < sides2 + 2; seg2++) D.push(af[seg2 - 2]);
10109
10725
  renderShapePolygon(D, coord, ctx, filled);
10110
10726
  renderShapePolyline([b[3], b[2]], coord, ctx);
10111
10727
  }
10112
10728
  function drawFolder(af, b, coord, filled, ctx) {
10113
- const sides = af.length;
10729
+ const sides2 = af.length;
10114
10730
  const dx = af[0].x - b[1].x;
10115
10731
  const wy = (b[3].y - b[4].y) / 3;
10116
10732
  const D = [
@@ -10119,7 +10735,7 @@ function drawFolder(af, b, coord, filled, ctx) {
10119
10735
  { x: af[0].x - 2 * dx, y: af[0].y + wy },
10120
10736
  { x: af[0].x - 2.25 * dx, y: b[3].y }
10121
10737
  ];
10122
- for (let seg2 = 4; seg2 < sides + 3; seg2++) D.push(af[seg2 - 3]);
10738
+ for (let seg2 = 4; seg2 < sides2 + 3; seg2++) D.push(af[seg2 - 3]);
10123
10739
  renderShapePolygon(D, coord, ctx, filled);
10124
10740
  }
10125
10741
  function drawBox3d(af, b, coord, filled, ctx) {
@@ -10469,10 +11085,10 @@ function drawRoundCorners(ring, coord, filled, ctx) {
10469
11085
  else if (ctx.rounded) roundedDraw(ring, coord, filled, ctx);
10470
11086
  }
10471
11087
  function diagonalsDraw(ring, coord, filled, ctx) {
10472
- const sides = ring.length;
10473
- const b = interpolationPoints(ring, sides, 0);
11088
+ const sides2 = ring.length;
11089
+ const b = interpolationPoints(ring, sides2, 0);
10474
11090
  renderShapePolygon(ring, coord, ctx, filled);
10475
- for (let seg2 = 0; seg2 < sides; seg2++) {
11091
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
10476
11092
  renderShapePolyline([b[3 * seg2 + 2], b[3 * seg2 + 4]], coord, ctx);
10477
11093
  }
10478
11094
  }
@@ -10480,10 +11096,10 @@ function roundedDraw(ring, coord, filled, ctx) {
10480
11096
  emitRoundedBezier(ring, coord, filled, ctx);
10481
11097
  }
10482
11098
  function emitRoundedBezier(ring, coord, filled, ctx) {
10483
- const sides = ring.length;
10484
- const b = interpolationPoints(ring, sides, 0, true);
11099
+ const sides2 = ring.length;
11100
+ const b = interpolationPoints(ring, sides2, 0, true);
10485
11101
  const pts = [];
10486
- for (let seg2 = 0; seg2 < sides; seg2++) {
11102
+ for (let seg2 = 0; seg2 < sides2; seg2++) {
10487
11103
  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]);
10488
11104
  }
10489
11105
  pts.push(pts[0], pts[1]);
@@ -10658,10 +11274,10 @@ function bgFillPaint(ctx) {
10658
11274
  };
10659
11275
  }
10660
11276
  function emitBgFill(ctx) {
10661
- const { box, pos, border, renderer, job } = ctx;
11277
+ const { box, pos, border: border2, renderer, job } = ctx;
10662
11278
  withHtmlPaint(bgFillPaint(ctx), job, () => {
10663
11279
  if (parseStyleFlags(ctx.style).rounded) {
10664
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, true, { renderer, job });
11280
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, true, { renderer, job });
10665
11281
  return;
10666
11282
  }
10667
11283
  const pts = [
@@ -10726,9 +11342,9 @@ function emitHtmlImg(img, pos, renderer, job) {
10726
11342
  }
10727
11343
  renderer.usershape?.(img.src, b, job);
10728
11344
  }
10729
- function htmlStyleInvisible(style) {
10730
- if (style === void 0) return false;
10731
- return style.split(/[ ,]+/).some((tok) => {
11345
+ function htmlStyleInvisible(style2) {
11346
+ if (style2 === void 0) return false;
11347
+ return style2.split(/[ ,]+/).some((tok) => {
10732
11348
  const t = tok.toUpperCase();
10733
11349
  return t === "INVIS" || t === "INVISIBLE";
10734
11350
  });
@@ -10941,7 +11557,7 @@ function starRings(box, peripheries) {
10941
11557
  return rings.flat();
10942
11558
  }
10943
11559
  function computeVertices(poly, w, h, base) {
10944
- const sides = poly.sides;
11560
+ const sides2 = poly.sides;
10945
11561
  if (poly.option.fixedshape && base !== void 0) {
10946
11562
  w = base.w;
10947
11563
  h = base.h;
@@ -10949,35 +11565,15 @@ function computeVertices(poly, w, h, base) {
10949
11565
  if (poly.option.shape === CYLINDER) return cylinderVertices(w, h);
10950
11566
  const peripheries = Math.max(poly.peripheries, 1);
10951
11567
  if (poly.option.shape === STAR) return starRings({ w, h, base }, peripheries);
10952
- if (sides <= 2) {
11568
+ if (sides2 <= 2) {
10953
11569
  return ellipseRings(w, h, peripheries, poly.option.fixedshape ? base : void 0);
10954
11570
  }
10955
- if (sides === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
11571
+ if (sides2 === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
10956
11572
  return boxRings(w, h, peripheries, poly.orientation, base);
10957
11573
  }
10958
11574
  return generalPolyRings(poly, { w, h, base }, peripheries);
10959
11575
  }
10960
11576
 
10961
- // src/common/fma.ts
10962
- var SPLIT = 134217729;
10963
- function fma(a, b, c) {
10964
- const p = a * b;
10965
- const at = SPLIT * a;
10966
- const ahi = at - (at - a);
10967
- const alo = a - ahi;
10968
- const bt = SPLIT * b;
10969
- const bhi = bt - (bt - b);
10970
- const blo = b - bhi;
10971
- const e = ahi * bhi - p + ahi * blo + alo * bhi + alo * blo;
10972
- const s = p + c;
10973
- const bv = s - p;
10974
- const err = p - (s - bv) + (c - bv);
10975
- return s + (err + e);
10976
- }
10977
- function fms(a, b, c) {
10978
- return fma(-a, b, c);
10979
- }
10980
-
10981
11577
  // src/common/arith.ts
10982
11578
  function cround(v) {
10983
11579
  return v >= 0 ? Math.floor(v + 0.5) : Math.ceil(v - 0.5);
@@ -11077,17 +11673,17 @@ function starSize(bb) {
11077
11673
  function cylinderSize(bb) {
11078
11674
  return { x: bb.x, y: bb.y * 1.375 };
11079
11675
  }
11080
- function expandForShape(bb, sides, heightPts, valign) {
11676
+ function expandForShape(bb, sides2, heightPts, valign2) {
11081
11677
  const b = { x: bb.x, y: bb.y };
11082
11678
  const temp = b.y * SQRT2;
11083
- if (heightPts > temp && valign === "c") {
11679
+ if (heightPts > temp && valign2 === "c") {
11084
11680
  b.x *= Math.sqrt(1 / (1 - (b.y / heightPts) ** 2));
11085
11681
  } else {
11086
11682
  b.x *= SQRT2;
11087
11683
  b.y = temp;
11088
11684
  }
11089
- if (sides > 2) {
11090
- const c = Math.cos(Math.PI / sides);
11685
+ if (sides2 > 2) {
11686
+ const c = Math.cos(Math.PI / sides2);
11091
11687
  b.x /= c;
11092
11688
  b.y /= c;
11093
11689
  }
@@ -11142,21 +11738,21 @@ function vertexExtents(verts) {
11142
11738
  }
11143
11739
  return { xmax, ymax };
11144
11740
  }
11145
- function initBisector(verts, sides) {
11741
+ function initBisector(verts, sides2) {
11146
11742
  const R2 = verts[0];
11147
11743
  let Q = R2;
11148
- for (let j = 1; j < sides; j++) {
11149
- Q = verts[(sides - j) % sides];
11744
+ for (let j = 1; j < sides2; j++) {
11745
+ Q = verts[(sides2 - j) % sides2];
11150
11746
  if (Q.x !== R2.x || Q.y !== R2.y) break;
11151
11747
  }
11152
11748
  return { beta: Math.atan2(R2.y - Q.y, R2.x - Q.x), Qprev: Q, sinx: 0, cosx: 0 };
11153
11749
  }
11154
- function bisectorOffset(verts, sides, i, st) {
11750
+ function bisectorOffset(verts, sides2, i, st) {
11155
11751
  const V = verts[i];
11156
11752
  if (V.x !== st.Qprev.x || V.y !== st.Qprev.y) {
11157
11753
  let R2 = V;
11158
- for (let j = 1; j < sides; j++) {
11159
- R2 = verts[(i + j) % sides];
11754
+ for (let j = 1; j < sides2; j++) {
11755
+ R2 = verts[(i + j) % sides2];
11160
11756
  if (R2.x !== V.x || R2.y !== V.y) break;
11161
11757
  }
11162
11758
  const alpha = st.beta;
@@ -11168,32 +11764,32 @@ function bisectorOffset(verts, sides, i, st) {
11168
11764
  }
11169
11765
  st.Qprev = V;
11170
11766
  }
11171
- function polygonRingOffsets(verts, sides) {
11172
- const st = initBisector(verts, sides);
11767
+ function polygonRingOffsets(verts, sides2) {
11768
+ const st = initBisector(verts, sides2);
11173
11769
  const out = [];
11174
- for (let i = 0; i < sides; i++) {
11175
- bisectorOffset(verts, sides, i, st);
11770
+ for (let i = 0; i < sides2; i++) {
11771
+ bisectorOffset(verts, sides2, i, st);
11176
11772
  out.push({ x: st.cosx, y: st.sinx });
11177
11773
  }
11178
11774
  return out;
11179
11775
  }
11180
- function polygonOutlineRing(verts, sides, penwidth) {
11181
- const st = initBisector(verts, sides);
11776
+ function polygonOutlineRing(verts, sides2, penwidth) {
11777
+ const st = initBisector(verts, sides2);
11182
11778
  const out = [];
11183
11779
  const k = penwidth / 2 / GAP;
11184
- for (let i = 0; i < sides; i++) {
11185
- bisectorOffset(verts, sides, i, st);
11780
+ for (let i = 0; i < sides2; i++) {
11781
+ bisectorOffset(verts, sides2, i, st);
11186
11782
  const V = verts[i];
11187
11783
  out.push({ x: V.x + k * st.cosx, y: V.y + k * st.sinx });
11188
11784
  }
11189
11785
  return out;
11190
11786
  }
11191
- function polygonPeripheryBB(verts, sides, p, bb) {
11192
- const st = initBisector(verts, sides);
11787
+ function polygonPeripheryBB(verts, sides2, p, bb) {
11788
+ const st = initBisector(verts, sides2);
11193
11789
  const out = { x: bb.x, y: bb.y };
11194
11790
  const outl = { x: bb.x, y: bb.y };
11195
- for (let i = 0; i < sides; i++) {
11196
- bisectorOffset(verts, sides, i, st);
11791
+ for (let i = 0; i < sides2; i++) {
11792
+ bisectorOffset(verts, sides2, i, st);
11197
11793
  const off = p.peripheries - 1;
11198
11794
  const V = verts[i];
11199
11795
  const P = { x: V.x + off * st.cosx, y: V.y + off * st.sinx };
@@ -11217,9 +11813,9 @@ function starVertexGen(bb) {
11217
11813
  }
11218
11814
  return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
11219
11815
  }
11220
- function polygonBB(bb, minSize, p, sides, isBox3) {
11816
+ function polygonBB(bb, minSize, p, sides2, isBox3) {
11221
11817
  const geom = {
11222
- sides,
11818
+ sides: sides2,
11223
11819
  orientation: p.orientation,
11224
11820
  distortion: p.distortion,
11225
11821
  skew: p.skew
@@ -11236,7 +11832,7 @@ function polygonBB(bb, minSize, p, sides, isBox3) {
11236
11832
  v.x *= scalex;
11237
11833
  v.y *= scaley;
11238
11834
  }
11239
- return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides, p, nbb), base: nbb };
11835
+ return { ...polygonPeripheryBB(verts, isBox3 ? 4 : sides2, p, nbb), base: nbb };
11240
11836
  }
11241
11837
  function gvNodesize(widthPts, heightPts, flip) {
11242
11838
  if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
@@ -11261,7 +11857,7 @@ function applySizeConstraints(p, bb0, width0, height0) {
11261
11857
  function polySize(p) {
11262
11858
  const init = initialSizePts(p);
11263
11859
  const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
11264
- const { sides, isBox: isBox3 } = effectiveShape(p);
11860
+ const { sides: sides2, isBox: isBox3 } = effectiveShape(p);
11265
11861
  let bb = { x: dimen.x, y: dimen.y };
11266
11862
  if (isBox3) {
11267
11863
  } else if (p.optionShape === STAR) {
@@ -11269,13 +11865,13 @@ function polySize(p) {
11269
11865
  } else if (p.optionShape === CYLINDER) {
11270
11866
  bb = cylinderSize(bb);
11271
11867
  } else {
11272
- bb = expandForShape(bb, sides, init.height, labelValign(p));
11868
+ bb = expandForShape(bb, sides2, init.height, labelValign(p));
11273
11869
  }
11274
11870
  const minBb = bb;
11275
11871
  const c = applySizeConstraints(p, bb, init.width, init.height);
11276
11872
  const penwidth = p.penwidth ?? 1;
11277
11873
  const hasOutline = penwidth > 0 || p.peripheries < 1;
11278
- 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);
11874
+ 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);
11279
11875
  const result = assembleResult(p, dimen, grown, c.fixedshape);
11280
11876
  return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox3, c.fixedshape) };
11281
11877
  }
@@ -11295,10 +11891,10 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
11295
11891
  return { space: { x: spaceX, y: spaceY }, valign: labelValign(p) };
11296
11892
  }
11297
11893
  function effectiveShape(p) {
11298
- let sides = p.sides;
11299
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
11300
- const isBox3 = sides === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
11301
- return { sides, isBox: isBox3 };
11894
+ let sides2 = p.sides;
11895
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
11896
+ const isBox3 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
11897
+ return { sides: sides2, isBox: isBox3 };
11302
11898
  }
11303
11899
  function labelValign(p) {
11304
11900
  const ll = p.labelloc?.[0];
@@ -11584,8 +12180,8 @@ function recSideMask(f, i, last) {
11584
12180
  if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
11585
12181
  return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
11586
12182
  }
11587
- function posReclbl(f, ul, sides) {
11588
- f.sides = sides;
12183
+ function posReclbl(f, ul, sides2) {
12184
+ f.sides = sides2;
11589
12185
  f.b = {
11590
12186
  ll: { x: ul.x, y: ul.y - f.size.y },
11591
12187
  ur: { x: ul.x + f.size.x, y: ul.y }
@@ -11593,8 +12189,8 @@ function posReclbl(f, ul, sides) {
11593
12189
  const last = f.n_flds - 1;
11594
12190
  const pos = { x: ul.x, y: ul.y };
11595
12191
  for (let i = 0; i <= last; i++) {
11596
- const mask = sides ? recSideMask(f, i, last) : 0;
11597
- posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides & mask);
12192
+ const mask = sides2 ? recSideMask(f, i, last) : 0;
12193
+ posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides2 & mask);
11598
12194
  if (f.LR) pos.x += f.fld[i].size.x;
11599
12195
  else pos.y -= f.fld[i].size.y;
11600
12196
  }
@@ -15097,11 +15693,11 @@ function renderPolyRing(ring, coord, filled, j, ctx) {
15097
15693
  } else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
15098
15694
  }
15099
15695
  function renderPeripheries(poly, coord, filled, ctx) {
15100
- const sides = poly.sides <= 2 ? 2 : poly.sides;
15696
+ const sides2 = poly.sides <= 2 ? 2 : poly.sides;
15101
15697
  const verts = poly.vertices;
15102
15698
  for (let j = 0; j < poly.peripheries; j++) {
15103
- const ring = verts.slice(j * sides, (j + 1) * sides);
15104
- if (ring.length < sides) break;
15699
+ const ring = verts.slice(j * sides2, (j + 1) * sides2);
15700
+ if (ring.length < sides2) break;
15105
15701
  const ringFilled = j === 0 ? filled : false;
15106
15702
  if (poly.sides <= 2) {
15107
15703
  renderEllipseRing(ring, coord, ringFilled, j, ctx);
@@ -15205,7 +15801,7 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
15205
15801
  obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
15206
15802
  obj.pen = resolvePenType(flags);
15207
15803
  obj.penWidth = resolvePenWidth(flags, penwidthAttr);
15208
- obj.rawStyle = styleTokens(styleAttr);
15804
+ obj.rawStyle = styleTokens2(styleAttr);
15209
15805
  }
15210
15806
  function applyNodeStyle(obj, n, job) {
15211
15807
  const styleAttr = nodeAttr(n, n.root, "style");
@@ -15250,12 +15846,12 @@ function resolveNodeDrawCtx(job, n) {
15250
15846
  };
15251
15847
  return { poly: drawPoly, coord, filled, ringCtx };
15252
15848
  }
15253
- function specialCornerFlags(opt, style) {
15849
+ function specialCornerFlags(opt, style2) {
15254
15850
  return {
15255
15851
  shape: opt.shape,
15256
- diagonals: opt.diagonals || style.diagonals,
15257
- rounded: opt.rounded || style.rounded,
15258
- underline: opt.underline || style.underline
15852
+ diagonals: opt.diagonals || style2.diagonals,
15853
+ rounded: opt.rounded || style2.rounded,
15854
+ underline: opt.underline || style2.underline
15259
15855
  };
15260
15856
  }
15261
15857
  function polyGencode(rawJob, rawNode) {
@@ -15328,22 +15924,22 @@ function insideScale(n, poly) {
15328
15924
  boxURy: oh / 2
15329
15925
  };
15330
15926
  }
15331
- function polygonWalk(P, vertex, sides) {
15927
+ function polygonWalk(P, vertex, sides2) {
15332
15928
  const O = { x: 0, y: 0 };
15333
15929
  let i = 0;
15334
- let i1 = 1 % sides;
15930
+ let i1 = 1 % sides2;
15335
15931
  const Q = vertex[i];
15336
15932
  const R2 = vertex[i1];
15337
15933
  if (!sameSide(P, O, Q, R2)) return false;
15338
15934
  const s = sameSide(P, Q, R2, O);
15339
15935
  if (s && sameSide(P, R2, O, Q)) return true;
15340
- for (let j = 1; j < sides; j++) {
15936
+ for (let j = 1; j < sides2; j++) {
15341
15937
  if (s) {
15342
15938
  i = i1;
15343
- i1 = (i + 1) % sides;
15939
+ i1 = (i + 1) % sides2;
15344
15940
  } else {
15345
15941
  i1 = i;
15346
- i = (i + sides - 1) % sides;
15942
+ i = (i + sides2 - 1) % sides2;
15347
15943
  }
15348
15944
  if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
15349
15945
  }
@@ -15385,15 +15981,15 @@ function starInside(ctx, p) {
15385
15981
  }
15386
15982
  const poly = n.info.shape_info;
15387
15983
  if (poly === void 0 || poly.vertices === null) return false;
15388
- const sides = poly.sides;
15389
- const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides;
15390
- const outer = poly.vertices.slice(outerStart, outerStart + sides);
15391
- const ring = polygonOutlineRing(outer, sides, poly.penwidth ?? 1);
15984
+ const sides2 = poly.sides;
15985
+ const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides2;
15986
+ const outer = poly.vertices.slice(outerStart, outerStart + sides2);
15987
+ const ring = polygonOutlineRing(outer, sides2, poly.penwidth ?? 1);
15392
15988
  const O = { x: 0, y: 0 };
15393
15989
  let outcnt = 0;
15394
- for (let i = 0; i < sides; i += 2) {
15990
+ for (let i = 0; i < sides2; i += 2) {
15395
15991
  const Q = ring[i];
15396
- const R2 = ring[(i + 4) % sides];
15992
+ const R2 = ring[(i + 4) % sides2];
15397
15993
  if (!sameSide(P, O, Q, R2)) outcnt++;
15398
15994
  if (outcnt === 2) return false;
15399
15995
  }
@@ -16814,9 +17410,9 @@ function labelVnode(g, orig) {
16814
17410
  return v;
16815
17411
  }
16816
17412
  function incrWidth(g, v) {
16817
- const width = Math.floor((g.info.nodesep ?? 0) / 2);
16818
- v.info.lw = (v.info.lw ?? 0) + width;
16819
- v.info.rw = (v.info.rw ?? 0) + width;
17413
+ const width2 = Math.floor((g.info.nodesep ?? 0) / 2);
17414
+ v.info.lw = (v.info.lw ?? 0) + width2;
17415
+ v.info.rw = (v.info.rw ?? 0) + width2;
16820
17416
  }
16821
17417
  function plainVnode(g) {
16822
17418
  const v = virtualNode(g);
@@ -17160,7 +17756,7 @@ var DEFAULT_NODESEP = 0.25;
17160
17756
  var MIN_NODESEP = 0.02;
17161
17757
  var DEFAULT_RANKSEP = 0.5;
17162
17758
  var MIN_RANKSEP = 0.02;
17163
- var UCHAR_MAX = 255;
17759
+ var UCHAR_MAX2 = 255;
17164
17760
  var CHAR_UTF8 = 0;
17165
17761
  var CHAR_LATIN1 = 1;
17166
17762
  var CHAR_BIG5 = 2;
@@ -17257,7 +17853,7 @@ function graphInit(g, useRankdir) {
17257
17853
  g.info.flip = false;
17258
17854
  }
17259
17855
  parseSepAttrs(g);
17260
- g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX);
17856
+ g.info.showboxes = Math.min(lateInt(g.attrs.get("showboxes"), 0, 0), UCHAR_MAX2);
17261
17857
  const fn = maptoken(g.attrs.get("fontnames"), FONTNAME_NAMES, fontnameCodes());
17262
17858
  if (fn !== -1) g.info.fontnames = fn;
17263
17859
  parseRatioDrawing(g);
@@ -17485,54 +18081,54 @@ function dirDefault(p) {
17485
18081
  function dirUnrecognized(p) {
17486
18082
  return { p, theta: 0, side: 0, constrain: false, clip: true, dyna: false, defined: false, rv: 1 };
17487
18083
  }
17488
- function dirN(rest, b, ctr, sides) {
18084
+ function dirN(rest, b, ctr, sides2) {
17489
18085
  const base = { constrain: true, clip: false, dyna: false };
17490
18086
  switch (rest) {
17491
18087
  case "":
17492
- return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides & TOP, defined: true, rv: 0 };
18088
+ return { ...base, p: { x: ctr.x, y: b.ur.y }, theta: Math.PI * 0.5, side: sides2 & TOP, defined: true, rv: 0 };
17493
18089
  case "e":
17494
- return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides & (TOP | RIGHT), defined: true, rv: 0 };
18090
+ return { ...base, p: { x: b.ur.x, y: b.ur.y }, theta: Math.PI * 0.25, side: sides2 & (TOP | RIGHT), defined: true, rv: 0 };
17495
18091
  case "w":
17496
- return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides & (TOP | LEFT), defined: true, rv: 0 };
18092
+ return { ...base, p: { x: b.ll.x, y: b.ur.y }, theta: Math.PI * 0.75, side: sides2 & (TOP | LEFT), defined: true, rv: 0 };
17497
18093
  default:
17498
18094
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
17499
18095
  }
17500
18096
  }
17501
- function dirS(rest, b, ctr, sides) {
18097
+ function dirS(rest, b, ctr, sides2) {
17502
18098
  const base = { constrain: true, clip: false, dyna: false };
17503
18099
  switch (rest) {
17504
18100
  case "":
17505
- return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides & BOTTOM, defined: true, rv: 0 };
18101
+ return { ...base, p: { x: ctr.x, y: b.ll.y }, theta: -Math.PI * 0.5, side: sides2 & BOTTOM, defined: true, rv: 0 };
17506
18102
  case "e":
17507
- return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides & (BOTTOM | RIGHT), defined: true, rv: 0 };
18103
+ return { ...base, p: { x: b.ur.x, y: b.ll.y }, theta: -Math.PI * 0.25, side: sides2 & (BOTTOM | RIGHT), defined: true, rv: 0 };
17508
18104
  case "w":
17509
- return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides & (BOTTOM | LEFT), defined: true, rv: 0 };
18105
+ return { ...base, p: { x: b.ll.x, y: b.ll.y }, theta: -Math.PI * 0.75, side: sides2 & (BOTTOM | LEFT), defined: true, rv: 0 };
17510
18106
  default:
17511
18107
  return dirUnrecognized({ x: ctr.x, y: ctr.y });
17512
18108
  }
17513
18109
  }
17514
- function dirE(rest, b, ctr, sides) {
18110
+ function dirE(rest, b, ctr, sides2) {
17515
18111
  if (rest.length > 0) return dirUnrecognized(ctr);
17516
- return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
18112
+ return { p: { x: b.ur.x, y: ctr.y }, theta: 0, side: sides2 & RIGHT, constrain: true, clip: false, dyna: false, defined: true, rv: 0 };
17517
18113
  }
17518
- function dirW(rest, b, ctr, sides) {
18114
+ function dirW(rest, b, ctr, sides2) {
17519
18115
  if (rest.length > 0) return dirUnrecognized(ctr);
17520
- 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 };
18116
+ 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 };
17521
18117
  }
17522
- function compassDirection(compass, b, ctr, sides) {
18118
+ function compassDirection(compass, b, ctr, sides2) {
17523
18119
  if (compass.length === 0) return dirDefault(ctr);
17524
18120
  const rest = compass.slice(1);
17525
18121
  switch (compass[0]) {
17526
18122
  case "n":
17527
- return dirN(rest, b, ctr, sides);
18123
+ return dirN(rest, b, ctr, sides2);
17528
18124
  case "s":
17529
- return dirS(rest, b, ctr, sides);
18125
+ return dirS(rest, b, ctr, sides2);
17530
18126
  case "e":
17531
- return dirE(rest, b, ctr, sides);
18127
+ return dirE(rest, b, ctr, sides2);
17532
18128
  case "w":
17533
- return dirW(rest, b, ctr, sides);
18129
+ return dirW(rest, b, ctr, sides2);
17534
18130
  case "_":
17535
- return { p: { ...ctr }, theta: 0, side: sides, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
18131
+ return { p: { ...ctr }, theta: 0, side: sides2, constrain: false, clip: true, dyna: true, defined: false, rv: 0 };
17536
18132
  case "c":
17537
18133
  return dirDefault(ctr);
17538
18134
  default:
@@ -17581,31 +18177,31 @@ function applyIctxt(n, dir, b, ctr) {
17581
18177
  dir.p = compassPoint(n, insideFn, yArg, xArg, gdRankdir(n));
17582
18178
  }
17583
18179
  function compassPort(n, args, pp) {
17584
- const { bp, compass, sides } = args;
18180
+ const { bp, compass, sides: sides2 } = args;
17585
18181
  const { b, p, defined: defBp } = compassBbox(n, bp);
17586
- const dir = compassDirection(compass, b, p, sides);
18182
+ const dir = compassDirection(compass, b, p, sides2);
17587
18183
  if (bp === null && !isBox(n)) applyIctxt(n, dir, b, p);
17588
18184
  const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
17589
18185
  applyDir(pp, bp, dir, gdRankdir(n), defFinal);
17590
18186
  return dir.rv;
17591
18187
  }
17592
- function htmlPort(n, portname, sides) {
18188
+ function htmlPort(n, portname, sides2) {
17593
18189
  const label = n.info.label;
17594
18190
  const placed = label?.u?.kind === "html" ? label.u.html : void 0;
17595
18191
  if (placed === void 0) return null;
17596
18192
  const hit = portToTbl(placed, portname);
17597
18193
  if (hit === null) return null;
17598
- sides.value = hit.sides;
18194
+ sides2.value = hit.sides;
17599
18195
  return hit.box;
17600
18196
  }
17601
18197
  function polyPort(n, portname, compass) {
17602
18198
  if (portname.length === 0) return makePort();
17603
18199
  const compassStr = compass.length === 0 ? "_" : compass;
17604
- const sides = BOTTOM | RIGHT | TOP | LEFT;
18200
+ const sides2 = BOTTOM | RIGHT | TOP | LEFT;
17605
18201
  const rv = makePort();
17606
18202
  const label = n.info.label;
17607
18203
  if (label?.html === true) {
17608
- const sidesRef = { value: sides };
18204
+ const sidesRef = { value: sides2 };
17609
18205
  const bp = htmlPort(n, portname, sidesRef);
17610
18206
  if (bp !== null) {
17611
18207
  compassPort(n, { bp, compass: compassStr, sides: sidesRef.value }, rv);
@@ -17613,7 +18209,7 @@ function polyPort(n, portname, compass) {
17613
18209
  return rv;
17614
18210
  }
17615
18211
  }
17616
- compassPort(n, { bp: null, compass: portname, sides }, rv);
18212
+ compassPort(n, { bp: null, compass: portname, sides: sides2 }, rv);
17617
18213
  rv.name = null;
17618
18214
  return rv;
17619
18215
  }
@@ -17974,8 +18570,8 @@ function initNodeFromLabel(n, g, measurer) {
17974
18570
  return true;
17975
18571
  }
17976
18572
  function effectivePolygon(poly, p, fixedshape) {
17977
- let sides = p.sides;
17978
- if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
18573
+ let sides2 = p.sides;
18574
+ if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
17979
18575
  return {
17980
18576
  ...poly,
17981
18577
  // C: poly->option.fixedshape = true inside the fixedsize="shape" branch;
@@ -17983,7 +18579,7 @@ function effectivePolygon(poly, p, fixedshape) {
17983
18579
  option: { ...poly.option, fixedshape },
17984
18580
  regular: p.regular,
17985
18581
  peripheries: p.peripheries,
17986
- sides,
18582
+ sides: sides2,
17987
18583
  orientation: p.orientation,
17988
18584
  distortion: p.distortion,
17989
18585
  skew: p.skew,
@@ -19125,8 +19721,8 @@ function orthoRoundedRadius(e, job) {
19125
19721
  if (e.head.root.attrs.get("splines") !== "ortho") return null;
19126
19722
  let wantRounded = false;
19127
19723
  let radius = 0;
19128
- const style = e.attrs.get("style");
19129
- if (style !== void 0 && style.split(",").map((s) => s.trim()).includes("rounded")) {
19724
+ const style2 = e.attrs.get("style");
19725
+ if (style2 !== void 0 && style2.split(",").map((s) => s.trim()).includes("rounded")) {
19130
19726
  wantRounded = true;
19131
19727
  }
19132
19728
  const radiusAttr = e.attrs.get("radius");
@@ -19511,20 +20107,10 @@ function checkControlPoints2(cp) {
19511
20107
  return ptToLine22(cp[0], cp[3], cp[1]) < MAP_HW * MAP_HW && ptToLine22(cp[0], cp[3], cp[2]) < MAP_HW * MAP_HW;
19512
20108
  }
19513
20109
  function bezierHalf(v) {
19514
- const t = 0.5;
19515
- const vt = [v.slice(0, 4)];
19516
- for (let i = 1; i <= 3; i++) {
19517
- vt[i] = [];
19518
- for (let j = 0; j <= 3 - i; j++) {
19519
- const a = vt[i - 1][j];
19520
- const b = vt[i - 1][j + 1];
19521
- vt[i][j] = { x: (1 - t) * a.x + t * b.x, y: (1 - t) * a.y + t * b.y };
19522
- }
19523
- }
19524
- return {
19525
- left: [vt[0][0], vt[1][0], vt[2][0], vt[3][0]],
19526
- right: [vt[3][0], vt[2][1], vt[1][2], vt[0][3]]
19527
- };
20110
+ const left2 = [];
20111
+ const right2 = [];
20112
+ bezier(v, 0.5, left2, right2);
20113
+ return { left: left2, right: right2 };
19528
20114
  }
19529
20115
  function approxBezier(cp, out) {
19530
20116
  if (checkControlPoints2(cp)) {
@@ -19868,7 +20454,7 @@ function setEdgePen(e, job) {
19868
20454
  );
19869
20455
  obj.pen = resolvePenType(flags);
19870
20456
  obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
19871
- obj.rawStyle = styleTokens(e.attrs.get("style"));
20457
+ obj.rawStyle = styleTokens2(e.attrs.get("style"));
19872
20458
  }
19873
20459
  function renderEdge(e, renderer, job) {
19874
20460
  emitEdgeComments(e, renderer, job);
@@ -20067,9 +20653,9 @@ function htmlFillPenWidth() {
20067
20653
  function resetHtmlFillPenWidth() {
20068
20654
  htmlFillPen = 1;
20069
20655
  }
20070
- function penTypeOf(style) {
20071
- if (style !== void 0 && style.includes("dashed")) return 1 /* Dashed */;
20072
- if (style !== void 0 && style.includes("dotted")) return 2 /* Dotted */;
20656
+ function penTypeOf(style2) {
20657
+ if (style2 !== void 0 && style2.includes("dashed")) return 1 /* Dashed */;
20658
+ if (style2 !== void 0 && style2.includes("dotted")) return 2 /* Dotted */;
20073
20659
  return 3 /* Solid */;
20074
20660
  }
20075
20661
  function withHtmlPaint(paint, job, drawFn) {
@@ -20100,13 +20686,13 @@ function applyHtmlFill(paint) {
20100
20686
  paintObj.gradientAngle = 0;
20101
20687
  paintObj.gradientFrac = 0;
20102
20688
  }
20103
- function mkPts(b, border, pos) {
20689
+ function mkPts(b, border2, pos) {
20104
20690
  let llx = b.ll.x + pos.x;
20105
20691
  let lly = b.ll.y + pos.y;
20106
20692
  let urx = b.ur.x + pos.x;
20107
20693
  let ury = b.ur.y + pos.y;
20108
- if (border > 1) {
20109
- const delta2 = border / 2;
20694
+ if (border2 > 1) {
20695
+ const delta2 = border2 / 2;
20110
20696
  llx += delta2;
20111
20697
  lly += delta2;
20112
20698
  urx -= delta2;
@@ -20133,26 +20719,26 @@ function doSide(p, wd, ht, renderer, job) {
20133
20719
  renderer.polygon(pts, true, job);
20134
20720
  }
20135
20721
  function doBorder(spec, renderer, job) {
20136
- const { box, pos, border, color, sides, style } = spec;
20137
- htmlFillPen = border;
20138
- withHtmlPaint({ pen: color, penWidth: border, penStyle: style }, job, () => {
20139
- if (parseStyleFlags(style).rounded) {
20140
- emitRoundedBezier(mkPts(box, border, pos), { x: 0, y: 0 }, false, { renderer, job });
20722
+ const { box, pos, border: border2, color, sides: sides2, style: style2 } = spec;
20723
+ htmlFillPen = border2;
20724
+ withHtmlPaint({ pen: color, penWidth: border2, penStyle: style2 }, job, () => {
20725
+ if (parseStyleFlags(style2).rounded) {
20726
+ emitRoundedBezier(mkPts(box, border2, pos), { x: 0, y: 0 }, false, { renderer, job });
20141
20727
  return;
20142
20728
  }
20143
- const effSides = sides !== void 0 ? sides & BORDER_MASK : 0;
20729
+ const effSides = sides2 !== void 0 ? sides2 & BORDER_MASK : 0;
20144
20730
  if (effSides !== 0) {
20145
- const corners = mkPts(box, border, pos).map((p) => transformPoint(p, job));
20731
+ const corners = mkPts(box, border2, pos).map((p) => transformPoint(p, job));
20146
20732
  emitSidedPolylines(effSides, corners, renderer, job);
20147
20733
  } else {
20148
- emitFullBoxBorder(box, pos, border, renderer, job);
20734
+ emitFullBoxBorder(box, pos, border2, renderer, job);
20149
20735
  }
20150
20736
  });
20151
20737
  }
20152
- function emitFullBoxBorder(box, pos, border, renderer, job) {
20153
- const b2 = border > 1 ? {
20154
- ll: { x: box.ll.x + border / 2, y: box.ll.y + border / 2 },
20155
- ur: { x: box.ur.x - border / 2, y: box.ur.y - border / 2 }
20738
+ function emitFullBoxBorder(box, pos, border2, renderer, job) {
20739
+ const b2 = border2 > 1 ? {
20740
+ ll: { x: box.ll.x + border2 / 2, y: box.ll.y + border2 / 2 },
20741
+ ur: { x: box.ur.x - border2 / 2, y: box.ur.y - border2 / 2 }
20156
20742
  } : box;
20157
20743
  const pts = [
20158
20744
  { x: b2.ll.x + pos.x, y: b2.ll.y + pos.y },
@@ -20187,8 +20773,8 @@ var SIDES_TABLE = /* @__PURE__ */ new Map([
20187
20773
  [T, [[NE, NW]]],
20188
20774
  [L, [[NW, SW]]]
20189
20775
  ]);
20190
- function emitSidedPolylines(sides, corners, renderer, job) {
20191
- const seqs = SIDES_TABLE.get(sides & BORDER_MASK);
20776
+ function emitSidedPolylines(sides2, corners, renderer, job) {
20777
+ const seqs = SIDES_TABLE.get(sides2 & BORDER_MASK);
20192
20778
  if (seqs === void 0) return;
20193
20779
  for (const seq2 of seqs) {
20194
20780
  renderer.polyline(seq2.map((i) => corners[i]), job);
@@ -20228,11 +20814,11 @@ function zeroFlags() {
20228
20814
  };
20229
20815
  }
20230
20816
  var FUNLIMIT = 64;
20231
- function styleTokens(style) {
20232
- if (!style) return [];
20817
+ function styleTokens2(style2) {
20818
+ if (!style2) return [];
20233
20819
  const out = [];
20234
20820
  let fun = 0;
20235
- for (const raw of style.split(",")) {
20821
+ for (const raw of style2.split(",")) {
20236
20822
  const token = raw.trim();
20237
20823
  if (token.length === 0) continue;
20238
20824
  if (fun === FUNLIMIT - 1) return [];
@@ -20266,11 +20852,11 @@ function firstSolidColor(raw) {
20266
20852
  const grad = parseGradientSpec(raw);
20267
20853
  return grad !== null ? grad[0] : raw;
20268
20854
  }
20269
- function parseStyleFlags(style) {
20855
+ function parseStyleFlags(style2) {
20270
20856
  const flags = zeroFlags();
20271
- if (!style) return flags;
20857
+ if (!style2) return flags;
20272
20858
  let fun = 0;
20273
- for (const raw of style.split(",")) {
20859
+ for (const raw of style2.split(",")) {
20274
20860
  const token = raw.trim();
20275
20861
  if (token.length === 0) continue;
20276
20862
  if (fun === FUNLIMIT - 1) return zeroFlags();
@@ -20284,10 +20870,10 @@ function parseStyleFlags(style) {
20284
20870
  }
20285
20871
  return flags;
20286
20872
  }
20287
- function styleHasInvisibleAlias(style) {
20288
- if (!style) return false;
20873
+ function styleHasInvisibleAlias(style2) {
20874
+ if (!style2) return false;
20289
20875
  let fun = 0;
20290
- for (const raw of style.split(",")) {
20876
+ for (const raw of style2.split(",")) {
20291
20877
  const token = raw.trim();
20292
20878
  if (token.length === 0) continue;
20293
20879
  if (fun === FUNLIMIT - 1) return false;
@@ -20342,9 +20928,9 @@ function findStopColor(colorlist) {
20342
20928
  const frac = seg0.hasFraction ? seg0.t : seg1.hasFraction ? 1 - seg1.t : 0;
20343
20929
  return { fillColor, stopColor, frac };
20344
20930
  }
20345
- function parseAngle(gradientangle) {
20346
- if (!gradientangle || gradientangle.length === 0) return 0;
20347
- const v = parseInt(gradientangle, 10);
20931
+ function parseAngle(gradientangle2) {
20932
+ if (!gradientangle2 || gradientangle2.length === 0) return 0;
20933
+ const v = parseInt(gradientangle2, 10);
20348
20934
  return isFinite(v) ? v : 0;
20349
20935
  }
20350
20936
  function buildResolvedFill(rawColor, flags, angle) {
@@ -20881,10 +21467,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
20881
21467
  const lbl = e.info.label;
20882
21468
  if (!lbl?.dimen) return 0;
20883
21469
  const flip = e.tail.root.info.flip === true;
20884
- const height = flip ? lbl.dimen.x : lbl.dimen.y;
20885
- lbl.pos = { x: a.x, y: a.y + a.sign * height / 2 };
21470
+ const height2 = flip ? lbl.dimen.x : lbl.dimen.y;
21471
+ lbl.pos = { x: a.x, y: a.y + a.sign * height2 / 2 };
20886
21472
  lbl.set = true;
20887
- return height;
21473
+ return height2;
20888
21474
  }
20889
21475
  /** Place a left/right self-loop label; return the label width that governs
20890
21476
  * the loop's widen. Under flip the label is rotated, so dimen.y is the
@@ -20893,10 +21479,10 @@ var SelfEdgeImpl = class _SelfEdgeImpl {
20893
21479
  const lbl = e.info.label;
20894
21480
  if (!lbl?.dimen) return 0;
20895
21481
  const flip = e.tail.root.info.flip === true;
20896
- const width = flip ? lbl.dimen.y : lbl.dimen.x;
20897
- lbl.pos = { x: a.x + a.sign * width / 2, y: a.y };
21482
+ const width2 = flip ? lbl.dimen.y : lbl.dimen.x;
21483
+ lbl.pos = { x: a.x + a.sign * width2 / 2, y: a.y };
20898
21484
  lbl.set = true;
20899
- return width;
21485
+ return width2;
20900
21486
  }
20901
21487
  static bottomPts(a) {
20902
21488
  const { tp, hp, np, dx, dy, ty, hy } = a;
@@ -21226,11 +21812,11 @@ function processFlatEdge(g, u, e) {
21226
21812
  const isOrdered = nodeOrder(u) < nodeOrder(e.head);
21227
21813
  const t0 = isOrdered ? e.tail : e.head;
21228
21814
  const h0 = isOrdered ? e.head : e.tail;
21229
- const width = nodeRw(t0) + nodeLw(h0);
21230
- let m0 = Math.trunc(edgeMinlen(e) * nodesep + width);
21815
+ const width2 = nodeRw(t0) + nodeLw(h0);
21816
+ let m0 = Math.trunc(edgeMinlen(e) * nodesep + width2);
21231
21817
  const ex = findFastEdge(t0, h0);
21232
21818
  if (ex !== void 0) {
21233
- m0 = Math.trunc(Math.max(m0, width + nodesep + cround(edgeDist(e))));
21819
+ m0 = Math.trunc(Math.max(m0, width2 + nodesep + cround(edgeDist(e))));
21234
21820
  ex.info.minlen = Math.max(ex.info.minlen ?? 1, m0);
21235
21821
  ex.info.weight = Math.max(ex.info.weight ?? 0, edgeWeight2(e));
21236
21822
  } else if (!e.info.label) {
@@ -21285,9 +21871,9 @@ function selfWidth(u) {
21285
21871
  }
21286
21872
  function lrRankPair(g, r, u, v, last) {
21287
21873
  const nodesep = lrSep(g, r);
21288
- const width = nodeRw(u) + nodeLw(v) + nodesep;
21289
- makeAuxEdge(u, v, width, 0);
21290
- const next = Math.trunc(last + width);
21874
+ const width2 = nodeRw(u) + nodeLw(v) + nodesep;
21875
+ makeAuxEdge(u, v, width2, 0);
21876
+ const next = Math.trunc(last + width2);
21291
21877
  v.info.rank = next;
21292
21878
  return next;
21293
21879
  }
@@ -24401,9 +24987,9 @@ function setAspect2(g) {
24401
24987
  function placeLabelNonFlip(g) {
24402
24988
  const bb = g.info.bb;
24403
24989
  const labelPos2 = g.info.label_pos ?? 1;
24404
- const border = g.info.border;
24990
+ const border2 = g.info.border;
24405
24991
  const zero = { x: 0, y: 0 };
24406
- const d = labelPos2 & 1 ? border?.[TOP_IX] ?? zero : border?.[BOTTOM_IX] ?? zero;
24992
+ const d = labelPos2 & 1 ? border2?.[TOP_IX] ?? zero : border2?.[BOTTOM_IX] ?? zero;
24407
24993
  const py = labelPos2 & 1 ? bb.ur.y - d.y / 2 : bb.ll.y + d.y / 2;
24408
24994
  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;
24409
24995
  return { x: px, y: py };
@@ -24411,9 +24997,9 @@ function placeLabelNonFlip(g) {
24411
24997
  function placeLabelFlip(g) {
24412
24998
  const bb = g.info.bb;
24413
24999
  const labelPos2 = g.info.label_pos ?? 1;
24414
- const border = g.info.border;
25000
+ const border2 = g.info.border;
24415
25001
  const zero = { x: 0, y: 0 };
24416
- const d = labelPos2 & 1 ? border?.[RIGHT_IX] ?? zero : border?.[LEFT_IX] ?? zero;
25002
+ const d = labelPos2 & 1 ? border2?.[RIGHT_IX] ?? zero : border2?.[LEFT_IX] ?? zero;
24417
25003
  const px = labelPos2 & 1 ? bb.ur.x - d.x / 2 : bb.ll.x + d.x / 2;
24418
25004
  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;
24419
25005
  return { x: px, y: py };
@@ -25391,18 +25977,6 @@ function dist2(p, q) {
25391
25977
  function distPt(p, q) {
25392
25978
  return Math.sqrt(dist2(p, q));
25393
25979
  }
25394
- function bezier(v, t) {
25395
- const u = 1 - t;
25396
- const x = [v[0].x, v[1].x, v[2].x, v[3].x];
25397
- const y = [v[0].y, v[1].y, v[2].y, v[3].y];
25398
- for (let i = 1; i <= 3; i++) {
25399
- for (let j = 0; j <= 3 - i; j++) {
25400
- x[j] = fma(x[j], u, t * x[j + 1]);
25401
- y[j] = fma(y[j], u, t * y[j + 1]);
25402
- }
25403
- }
25404
- return { x: x[0], y: y[0] };
25405
- }
25406
25980
  function dotneatoClosest(spl, pt) {
25407
25981
  let besti = 0;
25408
25982
  let bestj = -1;
@@ -25431,7 +26005,7 @@ function dotneatoClosest(spl, pt) {
25431
26005
  let pt2;
25432
26006
  for (; ; ) {
25433
26007
  const t = (lo + hi) / 2;
25434
- pt2 = bezier(c, t);
26008
+ pt2 = bezier(c, t, null, null);
25435
26009
  if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
25436
26010
  if (dlo2 < dhi2) {
25437
26011
  hi = t;
@@ -25522,8 +26096,8 @@ function faceMidpoint(b, ix) {
25522
26096
  return { x: b.ll.x, y: cy };
25523
26097
  }
25524
26098
  function closestSide(n, other, port) {
25525
- const sides = port.side;
25526
- if (sides === 0 || sides === ALL_SIDES2) return null;
26099
+ const sides2 = port.side;
26100
+ if (sides2 === 0 || sides2 === ALL_SIDES2) return null;
25527
26101
  const rkd = (n.root.info.rankdir ?? 0) & 3;
25528
26102
  const pt = cvtPt(n.info.coord, rkd);
25529
26103
  const opt = cvtPt(other.info.coord, rkd);
@@ -25531,7 +26105,7 @@ function closestSide(n, other, port) {
25531
26105
  let rv = null;
25532
26106
  let mind = 0;
25533
26107
  for (let i = 0; i < 4; i++) {
25534
- if ((sides & 1 << i) === 0) continue;
26108
+ if ((sides2 & 1 << i) === 0) continue;
25535
26109
  const m = faceMidpoint(b, i);
25536
26110
  const d = dist2({ x: m.x + pt.x, y: m.y + pt.y }, opt);
25537
26111
  if (rv === null || d < mind) {
@@ -27248,17 +27822,20 @@ function checkPath(boxn, boxes, pp) {
27248
27822
  return false;
27249
27823
  }
27250
27824
  function deCasteljauPoint(p0, p1, p2, p3, t) {
27251
- const ax = p0.x + t * (p1.x - p0.x);
27252
- const ay = p0.y + t * (p1.y - p0.y);
27253
- const bx = p1.x + t * (p2.x - p1.x);
27254
- const by = p1.y + t * (p2.y - p1.y);
27255
- const cx = p2.x + t * (p3.x - p2.x);
27256
- const cy = p2.y + t * (p3.y - p2.y);
27257
- const dx = ax + t * (bx - ax);
27258
- const dy = ay + t * (by - ay);
27259
- const ex = bx + t * (cx - bx);
27260
- const ey = by + t * (cy - by);
27261
- return { x: dx + t * (ex - dx), y: dy + t * (ey - dy) };
27825
+ let s0x = p0.x, s0y = p0.y, s1x = p1.x, s1y = p1.y, s2x = p2.x, s2y = p2.y;
27826
+ s0x = fma(t, s1x - s0x, s0x);
27827
+ s0y = fma(t, s1y - s0y, s0y);
27828
+ s1x = fma(t, s2x - s1x, s1x);
27829
+ s1y = fma(t, s2y - s1y, s1y);
27830
+ s2x = fma(t, p3.x - s2x, s2x);
27831
+ s2y = fma(t, p3.y - s2y, s2y);
27832
+ s0x = fma(t, s1x - s0x, s0x);
27833
+ s0y = fma(t, s1y - s0y, s0y);
27834
+ s1x = fma(t, s2x - s1x, s1x);
27835
+ s1y = fma(t, s2y - s1y, s1y);
27836
+ s0x = fma(t, s1x - s0x, s0x);
27837
+ s0y = fma(t, s1y - s0y, s0y);
27838
+ return { x: s0x, y: s0y };
27262
27839
  }
27263
27840
  function updateBoxExtents(boxes, boxn, sp) {
27264
27841
  for (let bi = 0; bi < boxn; bi++) {
@@ -27279,7 +27856,7 @@ function sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv) {
27279
27856
  }
27280
27857
  }
27281
27858
  function limitBoxes(boxes, boxn, pps, pn, delta2) {
27282
- const numDiv = Math.round(delta2 * boxn);
27859
+ const numDiv = delta2 * boxn;
27283
27860
  for (let splinepi = 0; splinepi + 3 < pn; splinepi += 3) {
27284
27861
  sampleBezierSegment(boxes, boxn, pps, splinepi, numDiv);
27285
27862
  }
@@ -27945,15 +28522,15 @@ function leftOf(p1, p2, p3) {
27945
28522
  }
27946
28523
  function lineLabelPoints(g, startp, endp, label) {
27947
28524
  const flip = g.info.flip === true;
27948
- const width = flip ? label.dimen.y : label.dimen.x;
27949
- const height = flip ? label.dimen.x : label.dimen.y;
28525
+ const width2 = flip ? label.dimen.y : label.dimen.x;
28526
+ const height2 = flip ? label.dimen.x : label.dimen.y;
27950
28527
  const lp = { x: label.pos.x, y: label.pos.y };
27951
28528
  if (leftOf(endp, startp, lp)) {
27952
- lp.x += width / 2;
27953
- lp.y -= height / 2;
28529
+ lp.x += width2 / 2;
28530
+ lp.y -= height2 / 2;
27954
28531
  } else {
27955
- lp.x -= width / 2;
27956
- lp.y += height / 2;
28532
+ lp.x -= width2 / 2;
28533
+ lp.y += height2 / 2;
27957
28534
  }
27958
28535
  return [startp, startp, lp, lp, lp, endp, endp];
27959
28536
  }
@@ -29340,8 +29917,8 @@ function findNormalOutEdge(first) {
29340
29917
  }
29341
29918
  function labelXPos(n, l) {
29342
29919
  const flip = !!n.root?.info.flip;
29343
- const width = flip ? l.dimen.y : l.dimen.x;
29344
- return n.info.coord.x + width / 2;
29920
+ const width2 = flip ? l.dimen.y : l.dimen.x;
29921
+ return n.info.coord.x + width2 / 2;
29345
29922
  }
29346
29923
  function placeVnlabel(n) {
29347
29924
  if ((n.info.in?.size ?? 0) === 0) return;
@@ -29379,22 +29956,12 @@ function setEdgeLabelPos(g) {
29379
29956
  }
29380
29957
  var PORT_LABEL_DISTANCE = 10;
29381
29958
  var PORT_LABEL_ANGLE = -25;
29382
- function cubicBezierAt(pts, t) {
29383
- const p0 = pts[0], p1 = pts[1], p2 = pts[2], p3 = pts[3];
29384
- const mt = 1 - t;
29385
- const q0 = { x: mt * p0.x + t * p1.x, y: mt * p0.y + t * p1.y };
29386
- const q1 = { x: mt * p1.x + t * p2.x, y: mt * p1.y + t * p2.y };
29387
- const q2 = { x: mt * p2.x + t * p3.x, y: mt * p2.y + t * p3.y };
29388
- const r0 = { x: mt * q0.x + t * q1.x, y: mt * q0.y + t * q1.y };
29389
- const r1 = { x: mt * q1.x + t * q2.x, y: mt * q1.y + t * q2.y };
29390
- return { x: mt * r0.x + t * r1.x, y: mt * r0.y + t * r1.y };
29391
- }
29392
29959
  function tailEndpoints(bez) {
29393
29960
  if (bez.sflag) {
29394
29961
  return { pe: bez.sp, pf: bez.list[0] };
29395
29962
  }
29396
29963
  const pe = bez.list[0];
29397
- const pf = cubicBezierAt(bez.list, 0.1);
29964
+ const pf = bezier(bez.list, 0.1, null, null);
29398
29965
  return { pe, pf };
29399
29966
  }
29400
29967
  function headEndpoints(bez) {
@@ -29403,7 +29970,7 @@ function headEndpoints(bez) {
29403
29970
  }
29404
29971
  const pe = bez.list[bez.size - 1];
29405
29972
  const last4 = bez.list.slice(bez.size - 4, bez.size);
29406
- const pf = cubicBezierAt(last4, 0.9);
29973
+ const pf = bezier(last4, 0.9, null, null);
29407
29974
  return { pe, pf };
29408
29975
  }
29409
29976
  function placePortlabel(e, headP) {
@@ -30290,7 +30857,10 @@ function makeFlatLabeledEdge(g, e) {
30290
30857
  info: { ...e.info, tail_port: e.info.head_port, head_port: e.info.tail_port }
30291
30858
  };
30292
30859
  const ps = routeFlatLabeledChannel(g, sample, ln, et);
30293
- if (ps === null || ps.length === 0) return true;
30860
+ if (ps === null || ps.length === 0) {
30861
+ e.info.lost = true;
30862
+ return true;
30863
+ }
30294
30864
  if (!tailIsLeft) ps.reverse();
30295
30865
  clipAndInstall(e, e.head, ps, ps.length, { ...buildDotSinfo(), ignoreSwap: true });
30296
30866
  return true;
@@ -32575,22 +33145,22 @@ function gcellWalk(pd, sx, sy, boundIsX, bound) {
32575
33145
  }
32576
33146
  return out;
32577
33147
  }
32578
- function appendSide(sides, found, cp, cellIdx) {
33148
+ function appendSide(sides2, found, cp, cellIdx) {
32579
33149
  for (const np of found) {
32580
- sides.push(np);
33150
+ sides2.push(np);
32581
33151
  np.cells[cellIdx] = cp;
32582
33152
  }
32583
33153
  }
32584
33154
  function attachGcellSides(mp, hdict, vdict) {
32585
33155
  let maxdeg = 0;
32586
33156
  for (const cp of mp.gcells) {
32587
- const sides = [];
32588
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
32589
- appendSide(sides, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
32590
- appendSide(sides, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
32591
- appendSide(sides, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
32592
- cp.sides = sides;
32593
- cp.nsides = sides.length;
33157
+ const sides2 = [];
33158
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.LL.y, true, cp.bb.UR.x), cp, 1);
33159
+ appendSide(sides2, gcellWalk(vdict, cp.bb.LL.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 1);
33160
+ appendSide(sides2, gcellWalk(hdict, cp.bb.LL.x, cp.bb.UR.y, true, cp.bb.UR.x), cp, 0);
33161
+ appendSide(sides2, gcellWalk(vdict, cp.bb.UR.x, cp.bb.LL.y, false, cp.bb.UR.y), cp, 0);
33162
+ cp.sides = sides2;
33163
+ cp.nsides = sides2.length;
32594
33164
  if (cp.nsides > maxdeg) maxdeg = cp.nsides;
32595
33165
  }
32596
33166
  return maxdeg;
@@ -33872,21 +34442,10 @@ function inBoxf(p, bb) {
33872
34442
  function midPointf2(a, b) {
33873
34443
  return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
33874
34444
  }
33875
- function casteljauStep(prev, t) {
33876
- const u = 1 - t;
33877
- return [
33878
- { x: u * prev[0].x + t * prev[1].x, y: u * prev[0].y + t * prev[1].y },
33879
- { x: u * prev[1].x + t * prev[2].x, y: u * prev[1].y + t * prev[2].y },
33880
- { x: u * prev[2].x + t * prev[3].x, y: u * prev[2].y + t * prev[3].y },
33881
- { x: 0, y: 0 }
33882
- ];
33883
- }
33884
34445
  function subdivideBezier(v, t, side) {
33885
- const r0 = [{ ...v[0] }, { ...v[1] }, { ...v[2] }, { ...v[3] }];
33886
- const r1 = casteljauStep(r0, t);
33887
- const r2 = casteljauStep(r1, t);
33888
- const r3 = casteljauStep(r2, t);
33889
- return side === "left" ? [r0[0], r1[0], r2[0], r3[0]] : [r3[0], r2[1], r1[2], r0[3]];
34446
+ const half = [];
34447
+ bezier([...v], t, side === "left" ? half : null, side === "right" ? half : null);
34448
+ return half;
33890
34449
  }
33891
34450
  function countVertCross(pts, xcoord) {
33892
34451
  let sign2 = fcmp(pts[0].x, xcoord);
@@ -35370,10 +35929,11 @@ function bfsFixDisconnected(n, dist4, closestDist) {
35370
35929
  function bfsVisitNeighbors(vertex, graph, dist4, queue) {
35371
35930
  const vd = graph[vertex];
35372
35931
  const d = dist4[vertex];
35932
+ const unit = graph[0].ewgts.length === 0;
35373
35933
  for (let i = 1; i < vd.nedges; i++) {
35374
35934
  const nb = vd.edges[i];
35375
35935
  if (dist4[nb] < 0) {
35376
- dist4[nb] = d + 1;
35936
+ dist4[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
35377
35937
  queue.push(nb);
35378
35938
  }
35379
35939
  }
@@ -36801,11 +37361,12 @@ function runMajorization(g, mode, model) {
36801
37361
  const nodeList = assignNodeIds2(g);
36802
37362
  const n = nodeList.length;
36803
37363
  const haveLen = graphHasLen(g);
36804
- const vtx = makeGraphDataC(g, nodeList, haveLen);
37364
+ const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
36805
37365
  checkStart(g);
36806
37366
  const maxi = lateDouble(g.attrs.get("maxiter"), DFLT_ITERATIONS, 0);
36807
37367
  const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
36808
- const Dij = haveLen ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
37368
+ const weighted = haveLen && mode !== MODE_IPSEP;
37369
+ const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
36809
37370
  const dCoords = [new Float64Array(n), new Float64Array(n)];
36810
37371
  stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
36811
37372
  dim: DFLT_DIM,
@@ -36823,11 +37384,11 @@ function graphHasLen(g) {
36823
37384
  }
36824
37385
  return false;
36825
37386
  }
36826
- function makeGraphDataC(g, nodeList, haveLen) {
37387
+ function makeGraphDataC(g, nodeList, haveLen, haveDir) {
36827
37388
  const vtx = nodeList.map((_, i) => ({
36828
37389
  nedges: 1,
36829
37390
  edges: [i],
36830
- ewgts: haveLen ? [0] : []
37391
+ ewgts: haveLen || haveDir ? [0] : []
36831
37392
  }));
36832
37393
  for (const np of nodeList) {
36833
37394
  const i = np.info.id;
@@ -36845,7 +37406,7 @@ function makeGraphDataC(g, nodeList, haveLen) {
36845
37406
  }
36846
37407
  seen.set(vid, entry.nedges);
36847
37408
  entry.edges.push(vid);
36848
- if (haveLen) entry.ewgts.push(dist4);
37409
+ if (haveLen || haveDir) entry.ewgts.push(dist4);
36849
37410
  entry.nedges++;
36850
37411
  }
36851
37412
  }
@@ -37906,7 +38467,7 @@ var RIGHT3 = 1 << 1;
37906
38467
  var TOP3 = 1 << 2;
37907
38468
  var LEFT3 = 1 << 3;
37908
38469
  var add = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
37909
- function sideCone(p, sides) {
38470
+ function sideCone(p, sides2) {
37910
38471
  const north = { x: 0, y: 1 };
37911
38472
  const northeast = { x: 1, y: 1 };
37912
38473
  const east = { x: 1, y: 0 };
@@ -37915,7 +38476,7 @@ function sideCone(p, sides) {
37915
38476
  const southwest = { x: -1, y: -1 };
37916
38477
  const west = { x: -1, y: 0 };
37917
38478
  const northwest = { x: -1, y: 1 };
37918
- switch (sides) {
38479
+ switch (sides2) {
37919
38480
  case TOP3:
37920
38481
  return [add(p, north), add(p, northwest), add(p, northeast)];
37921
38482
  case TOP3 | RIGHT3:
@@ -37936,17 +38497,17 @@ function sideCone(p, sides) {
37936
38497
  return [p, p, p];
37937
38498
  }
37938
38499
  }
37939
- function addEndpoint(rtr, p, obsId, vId, sides) {
38500
+ function addEndpoint(rtr, p, obsId, vId, sides2) {
37940
38501
  const starti = rtr.obs[obsId];
37941
38502
  const endi = rtr.obs[obsId + 1];
37942
38503
  const pts = rtr.ps;
37943
- const [vr, v0, v1] = sideCone(p, sides);
38504
+ const [vr, v0, v1] = sideCone(p, sides2);
37944
38505
  rtr.tg.nodes[vId].edges.length = 0;
37945
38506
  rtr.tg.nodes[vId].ctr = p;
37946
38507
  for (let i = starti; i < endi; i++) {
37947
38508
  const seg2 = { i, j: i < endi - 1 ? i + 1 : starti };
37948
38509
  const t = findMap(rtr.trimap, seg2.i, seg2.j);
37949
- 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])) {
38510
+ 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])) {
37950
38511
  continue;
37951
38512
  }
37952
38513
  addTriEdge(rtr.tg, vId, t, seg2);
@@ -38610,7 +39171,7 @@ function boxCornerMargin(j, m) {
38610
39171
  return { x: m.x, y: -m.y };
38611
39172
  }
38612
39173
  function polyObstacle(n, poly, pmargin) {
38613
- const sides = poly.sides;
39174
+ const sides2 = poly.sides;
38614
39175
  const stored = poly.vertices;
38615
39176
  if (stored == null) return null;
38616
39177
  const penwidth = poly.penwidth ?? 1;
@@ -38620,19 +39181,19 @@ function polyObstacle(n, poly, pmargin) {
38620
39181
  const storedRings = Math.max(poly.peripheries, 1);
38621
39182
  let verts;
38622
39183
  if (ringIdx < storedRings) {
38623
- verts = stored.slice(ringIdx * sides, (ringIdx + 1) * sides);
39184
+ verts = stored.slice(ringIdx * sides2, (ringIdx + 1) * sides2);
38624
39185
  } else {
38625
- const outer = stored.slice((storedRings - 1) * sides, storedRings * sides);
38626
- verts = polygonOutlineRing(outer, sides, penwidth);
39186
+ const outer = stored.slice((storedRings - 1) * sides2, storedRings * sides2);
39187
+ verts = polygonOutlineRing(outer, sides2, penwidth);
38627
39188
  }
38628
- if (verts.length < sides) return null;
38629
- const ps = new Array(sides);
38630
- for (let j = 0; j < sides; j++) {
39189
+ if (verts.length < sides2) return null;
39190
+ const ps = new Array(sides2);
39191
+ for (let j = 0; j < sides2; j++) {
38631
39192
  const v = verts[j];
38632
39193
  if (v === void 0) return null;
38633
39194
  let polyp;
38634
39195
  if (pmargin.doAdd) {
38635
- if (sides === 4) {
39196
+ if (sides2 === 4) {
38636
39197
  const m = boxCornerMargin(j, { x: pmargin.x, y: pmargin.y });
38637
39198
  polyp = { x: v.x + m.x, y: v.y + m.y };
38638
39199
  } else {
@@ -38642,22 +39203,22 @@ function polyObstacle(n, poly, pmargin) {
38642
39203
  } else {
38643
39204
  polyp = { x: v.x * pmargin.x, y: v.y * pmargin.y };
38644
39205
  }
38645
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
39206
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
38646
39207
  }
38647
39208
  return { ps };
38648
39209
  }
38649
39210
  function ellipseObstacle(n, pmargin) {
38650
- const sides = 8;
38651
- const width = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
38652
- const height = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
39211
+ const sides2 = 8;
39212
+ const width2 = (n.info.outline_width ?? 0) > 0 ? n.info.outline_width * 72 : n.info.lw + n.info.rw;
39213
+ const height2 = (n.info.outline_height ?? 0) > 0 ? n.info.outline_height * 72 : n.info.ht;
38653
39214
  const mx = pmargin.doAdd ? pmargin.x : 0;
38654
39215
  const my = pmargin.doAdd ? pmargin.y : 0;
38655
- const a = (width + mx) / 2;
38656
- const b = (height + my) / 2;
38657
- const ps = new Array(sides);
38658
- for (let j = 0; j < sides; j++) {
38659
- const polyp = circumscribedCorner(a, b, j, sides);
38660
- ps[sides - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
39216
+ const a = (width2 + mx) / 2;
39217
+ const b = (height2 + my) / 2;
39218
+ const ps = new Array(sides2);
39219
+ for (let j = 0; j < sides2; j++) {
39220
+ const polyp = circumscribedCorner(a, b, j, sides2);
39221
+ ps[sides2 - j - 1] = { x: polyp.x + n.info.coord.x, y: polyp.y + n.info.coord.y };
38661
39222
  }
38662
39223
  return { ps };
38663
39224
  }
@@ -38734,10 +39295,10 @@ function makeOrthoObstacle(n, sep) {
38734
39295
  cy += (bb.ur.y + bb.ll.y) / 2;
38735
39296
  cx += 0;
38736
39297
  } else {
38737
- const width = info.lw + info.rw;
38738
- const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width;
39298
+ const width2 = info.lw + info.rw;
39299
+ const outlineW = (info.outline_width ?? 0) > 0 ? info.outline_width * 72 : width2;
38739
39300
  const outlineH = (info.outline_height ?? 0) > 0 ? info.outline_height * 72 : info.ht;
38740
- const outlineLw = width > 0 ? info.lw * outlineW / width : outlineW / 2;
39301
+ const outlineLw = width2 > 0 ? info.lw * outlineW / width2 : outlineW / 2;
38741
39302
  lw = outlineLw;
38742
39303
  rw = outlineLw;
38743
39304
  hh = outlineH / 2;
@@ -38915,17 +39476,11 @@ var OrthoHelper = class _OrthoHelper {
38915
39476
  }
38916
39477
  static buildEdges(g, nodeArr, orthoNodes) {
38917
39478
  const concentrate = g.root.info.concentrate ?? false;
38918
- const seen = /* @__PURE__ */ new Set();
39479
+ const ps = concentrate ? new PointSet() : null;
38919
39480
  const edges = [];
38920
39481
  for (const n of nodesInSeq(g)) {
38921
39482
  for (const e of n.outEdges(g)) {
38922
- if (concentrate) {
38923
- const ti = e.tail.id;
38924
- const hi = e.head.id;
38925
- const key = ti <= hi ? `${ti}|${hi}` : `${hi}|${ti}`;
38926
- if (seen.has(key)) continue;
38927
- seen.add(key);
38928
- }
39483
+ if (ps && isConcentrateDup(ps, e)) continue;
38929
39484
  const tc = e.tail.info.coord;
38930
39485
  const hc = e.head.info.coord;
38931
39486
  const tp = e.info.tail_port.p;
@@ -40981,13 +41536,13 @@ function pointDistance(p1, o1, p2, o2, dim) {
40981
41536
  }
40982
41537
  return Math.sqrt(dist4);
40983
41538
  }
40984
- function quadTreeNew(dim, center, width, maxLevel) {
41539
+ function quadTreeNew(dim, center, width2, maxLevel) {
40985
41540
  return {
40986
41541
  n: 0,
40987
41542
  totalWeight: 0,
40988
41543
  dim,
40989
41544
  center: center.slice(0, dim),
40990
- width,
41545
+ width: width2,
40991
41546
  average: null,
40992
41547
  qts: null,
40993
41548
  l: null,
@@ -41005,15 +41560,15 @@ function getQuadrant(dim, center, coord, off) {
41005
41560
  }
41006
41561
  return d;
41007
41562
  }
41008
- function newInQuadrant(dim, parentCenter, width, maxLevel, i) {
41009
- const qt = quadTreeNew(dim, parentCenter, width, maxLevel);
41563
+ function newInQuadrant(dim, parentCenter, width2, maxLevel, i) {
41564
+ const qt = quadTreeNew(dim, parentCenter, width2, maxLevel);
41010
41565
  const center = qt.center;
41011
41566
  let ii = i;
41012
41567
  for (let k = 0; k < dim; k++) {
41013
41568
  if (ii % 2 === 0) {
41014
- center[k] -= width;
41569
+ center[k] -= width2;
41015
41570
  } else {
41016
- center[k] += width;
41571
+ center[k] += width2;
41017
41572
  }
41018
41573
  ii = (ii - ii % 2) / 2;
41019
41574
  }
@@ -41084,14 +41639,14 @@ function quadTreeNewFromPointList(dim, n, maxLevel, coord) {
41084
41639
  xmax[k] = Math.max(xmax[k], coord[i * dim + k]);
41085
41640
  }
41086
41641
  }
41087
- let width = xmax[0] - xmin[0];
41642
+ let width2 = xmax[0] - xmin[0];
41088
41643
  for (let i = 0; i < dim; i++) {
41089
41644
  center[i] = (xmin[i] + xmax[i]) * 0.5;
41090
- width = Math.max(width, xmax[i] - xmin[i]);
41645
+ width2 = Math.max(width2, xmax[i] - xmin[i]);
41091
41646
  }
41092
- width = Math.max(width, 1e-5);
41093
- width *= 0.52;
41094
- const qt = quadTreeNew(dim, center, width, maxLevel);
41647
+ width2 = Math.max(width2, 1e-5);
41648
+ width2 *= 0.52;
41649
+ const qt = quadTreeNew(dim, center, width2, maxLevel);
41095
41650
  for (let i = 0; i < n; i++) {
41096
41651
  quadTreeAdd(qt, coord, i * dim, 1, i);
41097
41652
  }
@@ -41911,18 +42466,18 @@ function compScanPoints(p, q) {
41911
42466
  if (pp.node < qq.node) return -1;
41912
42467
  return 0;
41913
42468
  }
41914
- function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
42469
+ function getOverlapGraph(dim, n, x, width2, checkOverlapOnly) {
41915
42470
  let A3 = smNew(n, n, MATRIX_TYPE_REAL, FORMAT_COORD);
41916
42471
  const scanpointsx = new Array(2 * n);
41917
42472
  for (let i = 0; i < n; i++) {
41918
- scanpointsx[2 * i] = { node: i, x: x[i * dim] - width[i * dim], status: INTV_OPEN };
41919
- scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width[i * dim], status: INTV_CLOSE };
42473
+ scanpointsx[2 * i] = { node: i, x: x[i * dim] - width2[i * dim], status: INTV_OPEN };
42474
+ scanpointsx[2 * i + 1] = { node: i + n, x: x[i * dim] + width2[i * dim], status: INTV_CLOSE };
41920
42475
  }
41921
42476
  scanpointsx.sort(compScanPoints);
41922
42477
  const scanpointsy = new Array(2 * n);
41923
42478
  for (let i = 0; i < n; i++) {
41924
- scanpointsy[i] = { node: i, x: x[i * dim + 1] - width[i * dim + 1], status: INTV_OPEN };
41925
- scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width[i * dim + 1], status: INTV_CLOSE };
42479
+ scanpointsy[i] = { node: i, x: x[i * dim + 1] - width2[i * dim + 1], status: INTV_OPEN };
42480
+ scanpointsy[i + n] = { node: i, x: x[i * dim + 1] + width2[i * dim + 1], status: INTV_CLOSE };
41926
42481
  }
41927
42482
  const treey = rbTreeCreate(compScanPoints, () => void 0);
41928
42483
  outer:
@@ -41955,7 +42510,7 @@ function getOverlapGraph(dim, n, x, width, checkOverlapOnly) {
41955
42510
  A3 = smSymmetrize(B2, false);
41956
42511
  return A3;
41957
42512
  }
41958
- function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
42513
+ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
41959
42514
  const ia = A3.ia;
41960
42515
  const ja = A3.ja;
41961
42516
  const expandmax = 1.5;
@@ -41969,8 +42524,8 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
41969
42524
  const dist4 = distance(x, dim, i, jj);
41970
42525
  const dx = Math.abs(x[i * dim] - x[jj * dim]);
41971
42526
  const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
41972
- const wx = width[i * dim] + width[jj * dim];
41973
- const wy = width[i * dim + 1] + width[jj * dim + 1];
42527
+ const wx = width2[i * dim] + width2[jj * dim];
42528
+ const wy = width2[i * dim + 1] + width2[jj * dim + 1];
41974
42529
  if (dx < MACHINEACC * wx && dy < MACHINEACC * wy) {
41975
42530
  idealDistance[j] = Math.hypot(wx, wy);
41976
42531
  tmax = 2;
@@ -42001,7 +42556,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width, idealDistance) {
42001
42556
  function scaleCoord(dim, m, x, scale) {
42002
42557
  for (let i = 0; i < dim * m; i++) x[i] *= scale;
42003
42558
  }
42004
- function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxiter) {
42559
+ function overlapScaling(dim, m, x, width2, scaleStaIn, scaleStoIn, epsilon, maxiter) {
42005
42560
  let scaleSta = scaleStaIn;
42006
42561
  let scaleSto = scaleStoIn;
42007
42562
  let iter = 0;
@@ -42009,7 +42564,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
42009
42564
  scaleSta = 0;
42010
42565
  } else {
42011
42566
  scaleCoord(dim, m, x, scaleSta);
42012
- const C6 = getOverlapGraph(dim, m, x, width, true);
42567
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
42013
42568
  if (C6.nz === 0) return;
42014
42569
  scaleCoord(dim, m, x, 1 / scaleSta);
42015
42570
  }
@@ -42024,7 +42579,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
42024
42579
  do {
42025
42580
  scaleSto *= 2;
42026
42581
  scaleCoord(dim, m, x, 2);
42027
- const C6 = getOverlapGraph(dim, m, x, width, true);
42582
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
42028
42583
  overlap5 = C6.nz > 0;
42029
42584
  } while (overlap5);
42030
42585
  scaleCoord(dim, m, x, 1 / scaleSto);
@@ -42033,7 +42588,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
42033
42588
  while (iter++ < maxiter && scaleSto - scaleSta > epsilon) {
42034
42589
  const scale = 0.5 * (scaleSta + scaleSto);
42035
42590
  scaleCoord(dim, m, x, scale);
42036
- const C6 = getOverlapGraph(dim, m, x, width, true);
42591
+ const C6 = getOverlapGraph(dim, m, x, width2, true);
42037
42592
  scaleCoord(dim, m, x, 1 / scale);
42038
42593
  const overlap5 = C6.nz > 0;
42039
42594
  if (overlap5) {
@@ -42044,7 +42599,7 @@ function overlapScaling(dim, m, x, width, scaleStaIn, scaleStoIn, epsilon, maxit
42044
42599
  }
42045
42600
  scaleCoord(dim, m, x, scaleBest);
42046
42601
  }
42047
- function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
42602
+ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
42048
42603
  const sm = {
42049
42604
  Lw: null,
42050
42605
  Lwd: null,
@@ -42054,16 +42609,16 @@ function overlapSmootherNew(m, dim, x, width, neighborhoodOnly, shrink) {
42054
42609
  };
42055
42610
  let B2 = callTri(m, x);
42056
42611
  if (!neighborhoodOnly) {
42057
- const C6 = getOverlapGraph(dim, m, x, width, false);
42612
+ const C6 = getOverlapGraph(dim, m, x, width2, false);
42058
42613
  B2 = smAdd(B2, C6);
42059
42614
  }
42060
42615
  sm.Lw = B2;
42061
42616
  sm.Lwd = smCopy(sm.Lw);
42062
- const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width, sm.Lwd.a);
42617
+ const { tmax, tmin } = idealDistanceAvoidOverlap(dim, sm.Lwd, x, width2, sm.Lwd.a);
42063
42618
  if (tmax < 1 && shrink) {
42064
42619
  const scaleSta = Math.min(1, tmax * 1.0001);
42065
42620
  const scaleSto = 1;
42066
- overlapScaling(dim, m, x, width, scaleSta, scaleSto, 1e-4, 15);
42621
+ overlapScaling(dim, m, x, width2, scaleSta, scaleSto, 1e-4, 15);
42067
42622
  return { sm, maxOverlap: 1, minOverlap: tmin };
42068
42623
  }
42069
42624
  const iw = sm.Lw.ia;
@@ -42337,7 +42892,7 @@ function scAdjust(g, equal) {
42337
42892
  // src/layout/neato/simple-scale.ts
42338
42893
  var ISZERO = (d) => Math.abs(d) < 1e-9;
42339
42894
  var LF = /^\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/;
42340
- function scanPair(p) {
42895
+ function scanPair2(p) {
42341
42896
  const m1 = LF.exec(p);
42342
42897
  if (m1 === null) return [];
42343
42898
  const rest = p.slice(m1[0].length);
@@ -42348,7 +42903,7 @@ function scanPair(p) {
42348
42903
  function simpleScale(g) {
42349
42904
  const p = aggetGraph(g, "scale");
42350
42905
  if (p === void 0) return 0;
42351
- const sc = scanPair(p);
42906
+ const sc = scanPair2(p);
42352
42907
  if (sc.length === 0) return 0;
42353
42908
  const x = sc[0];
42354
42909
  if (ISZERO(x)) return 0;
@@ -42672,16 +43227,16 @@ function overlaps(p) {
42672
43227
  function initItem(n, margin) {
42673
43228
  const x = cround(SCALE * (n.info.pos?.[0] ?? 0) * POINTS_PER_INCH6);
42674
43229
  const y = cround(SCALE * (n.info.pos?.[1] ?? 0) * POINTS_PER_INCH6);
42675
- const width = n.info.width ?? 0;
42676
- const height = n.info.height ?? 0;
43230
+ const width2 = n.info.width ?? 0;
43231
+ const height2 = n.info.height ?? 0;
42677
43232
  let w2;
42678
43233
  let h2;
42679
43234
  if (margin.doAdd) {
42680
- w2 = d2i(SCALE * (cround(width / 2 * POINTS_PER_INCH6) + margin.x));
42681
- h2 = d2i(SCALE * (cround(height / 2 * POINTS_PER_INCH6) + margin.y));
43235
+ w2 = d2i(SCALE * (cround(width2 / 2 * POINTS_PER_INCH6) + margin.x));
43236
+ h2 = d2i(SCALE * (cround(height2 / 2 * POINTS_PER_INCH6) + margin.y));
42682
43237
  } else {
42683
- w2 = cround(margin.x * SCALE2 * width * POINTS_PER_INCH6);
42684
- h2 = cround(margin.y * SCALE2 * height * POINTS_PER_INCH6);
43238
+ w2 = cround(margin.x * SCALE2 * width2 * POINTS_PER_INCH6);
43239
+ h2 = cround(margin.y * SCALE2 * height2 * POINTS_PER_INCH6);
42685
43240
  }
42686
43241
  return {
42687
43242
  val: 0,
@@ -42783,12 +43338,12 @@ function atoi2(s) {
42783
43338
  }
42784
43339
  function genRound(n, xm, ym) {
42785
43340
  const isides = atoi2(n.attrs.get("samplepoints"));
42786
- const sides = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
43341
+ const sides2 = isides < MIN_SAMPLES ? DFLT_SAMPLE2 : isides;
42787
43342
  const verts = [];
42788
- for (let i = 0; i < sides; i++) {
43343
+ for (let i = 0; i < sides2; i++) {
42789
43344
  verts.push({
42790
- x: (n.info.width / 2 + xm) * Math.cos(i / sides * Math.PI * 2),
42791
- y: (n.info.height / 2 + ym) * Math.sin(i / sides * Math.PI * 2)
43345
+ x: (n.info.width / 2 + xm) * Math.cos(i / sides2 * Math.PI * 2),
43346
+ y: (n.info.height / 2 + ym) * Math.sin(i / sides2 * Math.PI * 2)
42792
43347
  });
42793
43348
  }
42794
43349
  return verts;
@@ -45206,30 +45761,30 @@ function boundaryFromBB(bb) {
45206
45761
  x: (bb.llx + bb.urx) / 2,
45207
45762
  y: (bb.lly + bb.ury) / 2
45208
45763
  };
45209
- const width = EXPFACTOR * (bb.urx - bb.llx);
45210
- const height = EXPFACTOR * (bb.ury - bb.lly);
45211
- sizeBoundary(width, height);
45764
+ const width2 = EXPFACTOR * (bb.urx - bb.llx);
45765
+ const height2 = EXPFACTOR * (bb.ury - bb.lly);
45766
+ sizeBoundary(width2, height2);
45212
45767
  const alpha = Math.atan2(parms.Ht, parms.Wd);
45213
45768
  parms.Wd = parms.Wd / Math.cos(alpha);
45214
45769
  parms.Ht = parms.Ht / Math.sin(alpha);
45215
45770
  return ctr;
45216
45771
  }
45217
- function sizeBoundary(width, height) {
45772
+ function sizeBoundary(width2, height2) {
45218
45773
  const area = 4 * parms.Wd * parms.Ht;
45219
- let quot = width * height / area;
45774
+ let quot = width2 * height2 / area;
45220
45775
  if (quot >= 1) {
45221
- parms.Wd = width / 2;
45222
- parms.Ht = height / 2;
45776
+ parms.Wd = width2 / 2;
45777
+ parms.Ht = height2 / 2;
45223
45778
  } else if (quot > 0) {
45224
45779
  quot = 2 * Math.sqrt(quot);
45225
- parms.Wd = width / quot;
45226
- parms.Ht = height / quot;
45227
- } else if (width > 0) {
45228
- parms.Wd = width / 2;
45229
- parms.Ht = area / width / 2;
45230
- } else if (height > 0) {
45231
- parms.Wd = area / height / 2;
45232
- parms.Ht = height / 2;
45780
+ parms.Wd = width2 / quot;
45781
+ parms.Ht = height2 / quot;
45782
+ } else if (width2 > 0) {
45783
+ parms.Wd = width2 / 2;
45784
+ parms.Ht = area / width2 / 2;
45785
+ } else if (height2 > 0) {
45786
+ parms.Wd = area / height2 / 2;
45787
+ parms.Ht = height2 / 2;
45233
45788
  }
45234
45789
  }
45235
45790
  function placeWithPorts(g, pp, ctr) {
@@ -46152,7 +46707,7 @@ function finalCC(g, cc, pts, rg, infop) {
46152
46707
  };
46153
46708
  }
46154
46709
  function applyMarginAndBorder(rg, bb, margin) {
46155
- const border = rg.info.border ?? [
46710
+ const border2 = rg.info.border ?? [
46156
46711
  { x: 0, y: 0 },
46157
46712
  { x: 0, y: 0 },
46158
46713
  { x: 0, y: 0 },
@@ -46160,12 +46715,12 @@ function applyMarginAndBorder(rg, bb, margin) {
46160
46715
  ];
46161
46716
  const pt = {
46162
46717
  x: -bb.ll.x + margin,
46163
- y: -bb.ll.y + margin + border[BOTTOM_IX].y
46718
+ y: -bb.ll.y + margin + border2[BOTTOM_IX].y
46164
46719
  };
46165
46720
  bb.ll.x = 0;
46166
46721
  bb.ll.y = 0;
46167
46722
  bb.ur.x += pt.x + margin;
46168
- bb.ur.y += pt.y + margin + border[TOP_IX].y;
46723
+ bb.ur.y += pt.y + margin + border2[TOP_IX].y;
46169
46724
  return pt;
46170
46725
  }
46171
46726
  function evalPositions(g, rootg) {
@@ -48073,9 +48628,9 @@ function applyLabelExpansion(g, total, rbb) {
48073
48628
  }
48074
48629
  function addMarginAndBorder(g, margin, rbb) {
48075
48630
  let { llx, lly, urx, ury } = rbb;
48076
- const border = g.info.border;
48077
- const bottomY = border ? border[BOTTOM_IX].y : 0;
48078
- const topY = border ? border[TOP_IX].y : 0;
48631
+ const border2 = g.info.border;
48632
+ const bottomY = border2 ? border2[BOTTOM_IX].y : 0;
48633
+ const topY = border2 ? border2[TOP_IX].y : 0;
48079
48634
  llx -= margin;
48080
48635
  urx += margin;
48081
48636
  lly -= margin + bottomY;
@@ -48646,18 +49201,9 @@ function approxLen(list, off) {
48646
49201
  return dist3(list[off], list[off + 1]) + dist3(list[off + 1], list[off + 2]) + dist3(list[off + 2], list[off + 3]);
48647
49202
  }
48648
49203
  function splitCubic(v, t) {
48649
- const u = 1 - t;
48650
- const row = [v[0], v[1], v[2], v[3]];
48651
- const left2 = [row[0]];
48652
- const right2 = new Array(4);
48653
- right2[3] = row[3];
48654
- for (let i = 1; i <= 3; i++) {
48655
- for (let j = 0; j <= 3 - i; j++) {
48656
- row[j] = { x: u * row[j].x + t * row[j + 1].x, y: u * row[j].y + t * row[j + 1].y };
48657
- }
48658
- left2.push(row[0]);
48659
- right2[3 - i] = row[3 - i];
48660
- }
49204
+ const left2 = [];
49205
+ const right2 = [];
49206
+ bezier(v, t, left2, right2);
48661
49207
  return { left: left2, right: right2 };
48662
49208
  }
48663
49209
  function splitBSpline(list, t) {
@@ -48777,17 +49323,6 @@ function mymod(original, modulus) {
48777
49323
  function l2dist(p0, p1) {
48778
49324
  return Math.hypot(p0.x - p1.x, p0.y - p1.y);
48779
49325
  }
48780
- function bezierPoint(v, t) {
48781
- const vx = [v[0].x, v[1].x, v[2].x, v[3].x];
48782
- const vy = [v[0].y, v[1].y, v[2].y, v[3].y];
48783
- for (let i = 1; i <= 3; i++) {
48784
- for (let j = 0; j <= 3 - i; j++) {
48785
- vx[j] = (1 - t) * vx[j] + t * vx[j + 1];
48786
- vy[j] = (1 - t) * vy[j] + t * vy[j + 1];
48787
- }
48788
- }
48789
- return { x: vx[0], y: vy[0] };
48790
- }
48791
49326
  function pathtolines(bez) {
48792
49327
  const arr = [];
48793
49328
  const A3 = bez.list;
@@ -48803,7 +49338,7 @@ function pathtolines(bez) {
48803
49338
  for (let j = 1; j <= 3; j++) V[j] = A3[i + j];
48804
49339
  let p0 = V[0];
48805
49340
  for (let step = 1; step <= BEZIER_SUBDIVISION; step++) {
48806
- const p1 = bezierPoint(V, step / BEZIER_SUBDIVISION);
49341
+ const p1 = bezier(V, step / BEZIER_SUBDIVISION, null, null);
48807
49342
  linelen += l2dist(p0, p1);
48808
49343
  push(p1, linelen);
48809
49344
  p0 = p1;
@@ -49028,9 +49563,9 @@ function agstrcanonText(arg) {
49028
49563
  if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
49029
49564
  return new TextDecoder().decode(new Uint8Array(out));
49030
49565
  }
49031
- const lower = arg.toLowerCase();
49566
+ const lower2 = arg.toLowerCase();
49032
49567
  for (const tok of CANON_KEYWORDS) {
49033
- if (tok === lower) return new TextDecoder().decode(new Uint8Array(out));
49568
+ if (tok === lower2) return new TextDecoder().decode(new Uint8Array(out));
49034
49569
  }
49035
49570
  return arg;
49036
49571
  }
@@ -49114,9 +49649,9 @@ function writePlainEdge(e, extend, out) {
49114
49649
  if (lbl !== void 0) {
49115
49650
  out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
49116
49651
  }
49117
- const style = lateNN(e.attrs.get("style"), "solid");
49652
+ const style2 = lateNN(e.attrs.get("style"), "solid");
49118
49653
  const color = lateNN(e.attrs.get("color"), "black");
49119
- out.push(" " + style + " " + color + "\n");
49654
+ out.push(" " + style2 + " " + color + "\n");
49120
49655
  }
49121
49656
  function writePlain(g, job, extend) {
49122
49657
  const w = plainCoord(g.info.bb.ur.x);
@@ -50683,9 +51218,9 @@ function createXdotRenderer() {
50683
51218
 
50684
51219
  // src/render/svg-tapered-edge.ts
50685
51220
  function edgeIsTapered(e) {
50686
- const style = e.attrs.get("style");
50687
- if (style === void 0 || style === "") return false;
50688
- return style.split(",").some((t) => t.trim() === "tapered");
51221
+ const style2 = e.attrs.get("style");
51222
+ if (style2 === void 0 || style2 === "") return false;
51223
+ return style2.split(",").some((t) => t.trim() === "tapered");
50689
51224
  }
50690
51225
  function svgTaperedEdge(e, job) {
50691
51226
  const spl = e.info.spl;
@@ -50900,16 +51435,16 @@ var SvgRenderer = class {
50900
51435
  */
50901
51436
  usershape(src, b, job) {
50902
51437
  const g = (n) => String(parseFloat(n.toPrecision(6)));
50903
- const width = b.ur.x - b.ll.x;
50904
- const height = b.ur.y - b.ll.y;
50905
- const originx = (b.ur.x + b.ll.x - width) / 2;
50906
- const originy = (b.ur.y + b.ll.y + height) / 2;
51438
+ const width2 = b.ur.x - b.ll.x;
51439
+ const height2 = b.ur.y - b.ll.y;
51440
+ const originx = (b.ur.x + b.ll.x - width2) / 2;
51441
+ const originy = (b.ur.y + b.ll.y + height2) / 2;
50907
51442
  let href = src;
50908
51443
  if (job.inlineImages === true) {
50909
51444
  const found = findImageBytes(src, job.imageResolver);
50910
51445
  if (found !== null) href = toDataUri(found.bytes, found.mime);
50911
51446
  }
50912
- 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');
51447
+ 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');
50913
51448
  }
50914
51449
  comment(text, job) {
50915
51450
  svgComment(text, job);
@@ -54709,6 +55244,179 @@ function numberAmbiguityMessage(a) {
54709
55244
  return `Warning: syntax ambiguity - badly delimited number '${a.text}' in line ${a.line} of input splits into two tokens`;
54710
55245
  }
54711
55246
 
55247
+ // src/parser/scan-token.ts
55248
+ var YY_BUF_SIZE = 16384;
55249
+ var STRING_STARTING_BYTES = 80;
55250
+ var ASCII_DEL2 = 127;
55251
+ function isLetter2(c) {
55252
+ if (c === void 0) return false;
55253
+ return c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c === "_" || c.charCodeAt(0) > ASCII_DEL2;
55254
+ }
55255
+ function isDigit2(c) {
55256
+ return c !== void 0 && c >= "0" && c <= "9";
55257
+ }
55258
+ function startsNumber2(s, i) {
55259
+ const c = s[i];
55260
+ if (isDigit2(c)) return true;
55261
+ if (c === ".") return isDigit2(s[i + 1]);
55262
+ if (c !== "-") return false;
55263
+ return isDigit2(s[i + 1]) || s[i + 1] === "." && isDigit2(s[i + 2]);
55264
+ }
55265
+ function matchNumber2(s, i) {
55266
+ let j = s[i] === "-" ? i + 1 : i;
55267
+ if (s[j] === ".") {
55268
+ j++;
55269
+ while (isDigit2(s[j])) j++;
55270
+ } else {
55271
+ while (isDigit2(s[j])) j++;
55272
+ if (s[j] === ".") {
55273
+ j++;
55274
+ while (isDigit2(s[j])) j++;
55275
+ }
55276
+ }
55277
+ if (s[j] === "." || isLetter2(s[j])) j++;
55278
+ return j;
55279
+ }
55280
+ function badlyDelimited(text) {
55281
+ const c = text[text.length - 1];
55282
+ const dot = text.indexOf(".");
55283
+ return !isDigit2(c) && c !== "." || c === "." && dot !== text.length - 1;
55284
+ }
55285
+ function lineEnd(s, i) {
55286
+ const nl = s.indexOf("\n", i);
55287
+ return nl === -1 ? s.length : nl;
55288
+ }
55289
+ function directiveLine(text) {
55290
+ const rest = text.slice(1).replace(/^line/, "");
55291
+ const m = /^\s*([+-]?\d+)/.exec(rest);
55292
+ if (m === null) return void 0;
55293
+ const lineno = Number.parseInt(m[1], 10);
55294
+ return lineno <= 0 ? void 0 : lineno - 1;
55295
+ }
55296
+ function qstringBuffer(body) {
55297
+ return body.replace(/\\\\|\\"|\\\n/g, (m) => m === '\\"' ? '"' : m === "\\\n" ? "" : m);
55298
+ }
55299
+ function lexQuoted(s, i) {
55300
+ for (let j = i + 1; j < s.length; j++) {
55301
+ if (s[j] === "\\" && j + 1 < s.length) j++;
55302
+ else if (s[j] === '"') return { kind: "token", end: j + 1, text: '"' };
55303
+ }
55304
+ return { kind: "open", state: "qstring", buffer: qstringBuffer(s.slice(i + 1)) };
55305
+ }
55306
+ function lexHtml(s, i) {
55307
+ let nest = 1;
55308
+ for (let j = i + 1; j < s.length; j++) {
55309
+ if (s[j] === "<") nest++;
55310
+ else if (s[j] === ">" && --nest === 0) return { kind: "token", end: j + 1, text: ">" };
55311
+ }
55312
+ return { kind: "open", state: "hstring", buffer: s.slice(i + 1) };
55313
+ }
55314
+ function lexComment(s, i) {
55315
+ const close = s.indexOf("*/", i + 2);
55316
+ if (close === -1) return { kind: "open", state: "comment", buffer: "" };
55317
+ return { kind: "skip", end: close + 2 };
55318
+ }
55319
+ function lexHash(s, i) {
55320
+ const end = lineEnd(s, i);
55321
+ const atLineStart = i === 0 || s[i - 1] === "\n";
55322
+ const line = atLineStart ? directiveLine(s.slice(i, end)) : void 0;
55323
+ return line === void 0 ? { kind: "skip", end } : { kind: "skip", end, line };
55324
+ }
55325
+ function lexAtom(s, i) {
55326
+ if (isLetter2(s[i])) {
55327
+ let j2 = i + 1;
55328
+ while (isLetter2(s[j2]) || isDigit2(s[j2])) j2++;
55329
+ const text = s.slice(i, j2);
55330
+ return text === "\uFEFF" ? { kind: "skip", end: j2 } : { kind: "token", end: j2, text };
55331
+ }
55332
+ if (s[i] === "-" && (s[i + 1] === "-" || s[i + 1] === ">")) {
55333
+ return { kind: "token", end: i + 2, text: s.slice(i, i + 2) };
55334
+ }
55335
+ if (!startsNumber2(s, i)) return { kind: "token", end: i + 1, text: s[i] };
55336
+ const j = matchNumber2(s, i);
55337
+ const end = badlyDelimited(s.slice(i, j)) ? j - 1 : j;
55338
+ return { kind: "token", end, text: s.slice(i, end) };
55339
+ }
55340
+ function lexTrivia(s, i) {
55341
+ const c = s[i];
55342
+ if (c === "\n" || c === " " || c === " " || c === "\r") return { kind: "skip", end: i + 1 };
55343
+ if (c === "#") return lexHash(s, i);
55344
+ if (c !== "/") return void 0;
55345
+ if (s[i + 1] === "*") return lexComment(s, i);
55346
+ if (s[i + 1] === "/") return { kind: "skip", end: lineEnd(s, i) };
55347
+ return void 0;
55348
+ }
55349
+ function lexStep(s, i) {
55350
+ const trivia = lexTrivia(s, i);
55351
+ if (trivia !== void 0) return trivia;
55352
+ if (s[i] === '"') return lexQuoted(s, i);
55353
+ if (s[i] === "<") return lexHtml(s, i);
55354
+ return lexAtom(s, i);
55355
+ }
55356
+ function countNewlines(s, from, to) {
55357
+ let n = 0;
55358
+ for (let i = s.indexOf("\n", from); i !== -1 && i < to; i = s.indexOf("\n", i + 1)) n++;
55359
+ return n;
55360
+ }
55361
+ var HEADER_KEYWORDS = ["strict", "graph", "digraph"];
55362
+ function isTruncatedHeaderKeyword(src, step, offset, seen) {
55363
+ if (offset !== src.length || step.end !== offset || seen.length > 1) return false;
55364
+ if (seen.length === 1 && seen[0].toLowerCase() !== "strict") return false;
55365
+ const word = step.text.toLowerCase();
55366
+ return HEADER_KEYWORDS.some((k) => k.length > word.length && k.startsWith(word));
55367
+ }
55368
+ function reachesOffset(src, step, offset, seen) {
55369
+ if (step.end > offset) return true;
55370
+ if (isTruncatedHeaderKeyword(src, step, offset, seen)) return true;
55371
+ if (step.text !== "-" && step.text !== ".") return false;
55372
+ return offset <= step.end + (step.text === "-" && src[step.end] === "." ? 1 : 0);
55373
+ }
55374
+ function scanAtError(src, offset) {
55375
+ let line = 1;
55376
+ let i = 0;
55377
+ const seen = [];
55378
+ while (i < src.length) {
55379
+ const step = lexStep(src, i);
55380
+ if (step.kind === "open") {
55381
+ line += countNewlines(src, i, src.length);
55382
+ return { state: step.state, text: "", line, buffer: step.buffer };
55383
+ }
55384
+ if (step.kind === "skip" && step.line !== void 0) line = step.line;
55385
+ line += countNewlines(src, i, step.end);
55386
+ if (step.kind === "token" && reachesOffset(src, step, offset, seen)) {
55387
+ return { state: "INITIAL", text: step.text, line, buffer: "" };
55388
+ }
55389
+ if (step.kind === "token") seen.push(step.text);
55390
+ i = step.end;
55391
+ }
55392
+ return { state: "INITIAL", text: "", line, buffer: "" };
55393
+ }
55394
+ function firstBytes(s) {
55395
+ const bytes = new TextEncoder().encode(s);
55396
+ if (bytes.length <= STRING_STARTING_BYTES) return s;
55397
+ return new TextDecoder().decode(bytes.subarray(0, STRING_STARTING_BYTES));
55398
+ }
55399
+ function stateNote(at) {
55400
+ const start = at.buffer.length > 0 ? firstBytes(at.buffer) : "";
55401
+ switch (at.state) {
55402
+ case "qstring":
55403
+ return ` scanning a quoted string (missing endquote? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
55404
+ String starting:"${start}`);
55405
+ case "hstring":
55406
+ return ` scanning a HTML string (missing '>'? bad nesting? longer than ${YY_BUF_SIZE}?)` + (start === "" ? "" : `
55407
+ String starting:<${start}`);
55408
+ case "comment":
55409
+ return ` scanning a /*...*/ comment (missing '*/? longer than ${YY_BUF_SIZE}?)`;
55410
+ case "INITIAL":
55411
+ return "";
55412
+ }
55413
+ }
55414
+ function syntaxErrorMessage(src, offset) {
55415
+ const at = scanAtError(src, offset);
55416
+ const where = `Error: syntax error in line ${at.line}`;
55417
+ return at.text === "" ? where + stateNote(at) : `${where} near '${at.text}'`;
55418
+ }
55419
+
54712
55420
  // src/parser/index.ts
54713
55421
  var ParseError = class extends DotEngineError {
54714
55422
  type = "syntax";
@@ -54772,9 +55480,9 @@ var Stripper = class _Stripper {
54772
55480
  */
54773
55481
  static blankLine(src, i, out) {
54774
55482
  const n = src.length;
54775
- const width = src[i] === "#" ? 1 : 2;
54776
- out.push(" ".repeat(width));
54777
- i += width;
55483
+ const width2 = src[i] === "#" ? 1 : 2;
55484
+ out.push(" ".repeat(width2));
55485
+ i += width2;
54778
55486
  while (i < n && src[i] !== "\n") {
54779
55487
  out.push(" ");
54780
55488
  i++;
@@ -54885,6 +55593,7 @@ function parse(src) {
54885
55593
  if (isPeggyError(err)) {
54886
55594
  const start = err.location.start;
54887
55595
  warnNumberAmbiguities(src, start.offset);
55596
+ console.error(syntaxErrorMessage(src, start.offset));
54888
55597
  const code = err.found === null ? "SYNTAX_UNEXPECTED_EOF" : "SYNTAX_ERROR";
54889
55598
  throw new ParseError(
54890
55599
  err instanceof Error ? err.message : String(err),
@@ -54902,8 +55611,17 @@ function parse(src) {
54902
55611
  }
54903
55612
  throw err;
54904
55613
  }
55614
+ try {
55615
+ validateEdgeOperators(src, ast.directed);
55616
+ } catch (err) {
55617
+ const offset = err instanceof ParseError ? err.location.offset : void 0;
55618
+ if (offset !== void 0) {
55619
+ warnNumberAmbiguities(src, offset);
55620
+ console.error(syntaxErrorMessage(src, offset));
55621
+ }
55622
+ throw err;
55623
+ }
54905
55624
  warnNumberAmbiguities(src, src.length);
54906
- validateEdgeOperators(src, ast.directed);
54907
55625
  return buildFromAst(ast);
54908
55626
  }
54909
55627