@knowvah/dot-engine 2.6.1 → 2.6.3
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.
- package/dist/common/htmltable-lex.d.ts +38 -0
- package/dist/common/htmltable-lex.d.ts.map +1 -1
- package/dist/common/htmltable-parse-attrs.d.ts +41 -0
- package/dist/common/htmltable-parse-attrs.d.ts.map +1 -0
- package/dist/common/htmltable-parse.d.ts +3 -0
- package/dist/common/htmltable-parse.d.ts.map +1 -1
- package/dist/common/htmltable-pos.d.ts +17 -0
- package/dist/common/htmltable-pos.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +13 -1
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/make-label.d.ts.map +1 -1
- package/dist/common/pointset.d.ts +35 -0
- package/dist/common/pointset.d.ts.map +1 -0
- package/dist/common/spline-midpoint.d.ts +8 -0
- package/dist/common/spline-midpoint.d.ts.map +1 -1
- package/dist/index.js +639 -315
- package/dist/index.js.map +4 -4
- package/dist/label/node.d.ts +7 -1
- package/dist/label/node.d.ts.map +1 -1
- package/dist/layout/circo/position-helpers.d.ts +15 -3
- package/dist/layout/circo/position-helpers.d.ts.map +1 -1
- package/dist/layout/circo/position.d.ts +17 -1
- package/dist/layout/circo/position.d.ts.map +1 -1
- package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
- package/dist/layout/neato/multispline.d.ts.map +1 -1
- package/dist/layout/pack/poly-pack.d.ts +2 -18
- package/dist/layout/pack/poly-pack.d.ts.map +1 -1
- package/dist/layout/pack/poly-place.d.ts.map +1 -1
- package/dist/pathplan/shortest.d.ts.map +1 -1
- package/dist/render.js +792 -468
- package/dist/render.js.map +4 -4
- package/package.json +2 -2
- package/src/common/htmltable-lex.ts +265 -5
- package/src/common/htmltable-parse-attrs.ts +166 -0
- package/src/common/htmltable-parse.ts +262 -242
- package/src/common/htmltable-pos.ts +37 -38
- package/src/common/htmltable.ts +139 -45
- package/src/common/make-label.ts +19 -3
- package/src/common/pointset.ts +73 -0
- package/src/common/spline-midpoint.ts +30 -9
- package/src/label/node.ts +8 -2
- package/src/layout/circo/position-helpers.ts +28 -17
- package/src/layout/circo/position.ts +28 -7
- package/src/layout/dot/ortho-adapter.ts +20 -9
- package/src/layout/neato/multispline.ts +17 -5
- package/src/layout/pack/poly-pack.ts +5 -31
- package/src/layout/pack/poly-place.ts +42 -47
- package/src/pathplan/shortest.ts +15 -2
package/dist/index.js
CHANGED
|
@@ -4302,11 +4302,11 @@ function lexToken(s, i) {
|
|
|
4302
4302
|
function scanNumberAmbiguities(src, stripped) {
|
|
4303
4303
|
const out = [];
|
|
4304
4304
|
let line = 1;
|
|
4305
|
-
let
|
|
4305
|
+
let lineAt2 = 0;
|
|
4306
4306
|
for (let i = 0; i < stripped.length; ) {
|
|
4307
4307
|
const { next, bad } = lexToken(stripped, i);
|
|
4308
4308
|
if (bad !== null) {
|
|
4309
|
-
for (;
|
|
4309
|
+
for (; lineAt2 < i; lineAt2++) if (src[lineAt2] === "\n") line++;
|
|
4310
4310
|
out.push({ text: bad, line, offset: i });
|
|
4311
4311
|
}
|
|
4312
4312
|
i = next;
|
|
@@ -10341,16 +10341,152 @@ function parseOpenToken(inner) {
|
|
|
10341
10341
|
checkTag(tag);
|
|
10342
10342
|
return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
|
|
10343
10343
|
}
|
|
10344
|
-
|
|
10344
|
+
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
10345
|
+
var XML_ERROR_TAG_MISMATCH = "mismatched tag";
|
|
10346
|
+
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
10347
|
+
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
10348
|
+
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
10349
|
+
var XML_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
10350
|
+
var HtmlLexError = class extends HtmlParseError {
|
|
10351
|
+
diagnostics;
|
|
10352
|
+
constructor(tag, message, diagnostics) {
|
|
10353
|
+
super(tag);
|
|
10354
|
+
this.message = message;
|
|
10355
|
+
this.diagnostics = diagnostics;
|
|
10356
|
+
}
|
|
10357
|
+
};
|
|
10358
|
+
function htmlErrorInLine(message, line, context) {
|
|
10359
|
+
const text = `${message} in line ${line} `;
|
|
10360
|
+
return new HtmlLexError(message, text, [`Error: ${text}`, `... ${context} ...`]);
|
|
10361
|
+
}
|
|
10362
|
+
var chunkInfo = /* @__PURE__ */ new WeakMap();
|
|
10363
|
+
function lineAt(src, pos) {
|
|
10364
|
+
let line = 1;
|
|
10365
|
+
for (let k = 0; k < pos; k++) {
|
|
10366
|
+
if (src[k] === "\n" || src[k] === "\r" && src[k + 1] !== "\n") line++;
|
|
10367
|
+
}
|
|
10368
|
+
return line;
|
|
10369
|
+
}
|
|
10370
|
+
function chunkLine(info) {
|
|
10371
|
+
if (info.src[info.pos] === "<") return lineAt(info.src, info.pos);
|
|
10372
|
+
const last = info.src.lastIndexOf("\n", info.end - 1);
|
|
10373
|
+
if (last < info.pos) return lineAt(info.src, info.pos);
|
|
10374
|
+
return lineAt(info.src, last === info.end - 1 ? last : last + 1);
|
|
10375
|
+
}
|
|
10376
|
+
function htmlErrorAtToken(message, tok) {
|
|
10377
|
+
const info = tok === void 0 ? void 0 : chunkInfo.get(tok);
|
|
10378
|
+
if (info === void 0) return void 0;
|
|
10379
|
+
return htmlErrorInLine(message, chunkLine(info), info.context);
|
|
10380
|
+
}
|
|
10381
|
+
function chunkEnd(src, i) {
|
|
10382
|
+
const j = src[i] === "<" ? src.indexOf(">", i + 1) : src.indexOf("<", i);
|
|
10383
|
+
if (j < 0) return src.length;
|
|
10384
|
+
return src[i] === "<" ? j + 1 : j;
|
|
10385
|
+
}
|
|
10386
|
+
function findUndefinedEntity(text) {
|
|
10387
|
+
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
10388
|
+
if (text[t + 1] === "#") continue;
|
|
10389
|
+
const semi = text.indexOf(";", t + 1);
|
|
10390
|
+
if (semi < 0) continue;
|
|
10391
|
+
const key = text.slice(t + 1, semi);
|
|
10392
|
+
if (XML_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
10393
|
+
return t;
|
|
10394
|
+
}
|
|
10395
|
+
}
|
|
10396
|
+
return -1;
|
|
10397
|
+
}
|
|
10398
|
+
function parseTagChunk(chunk) {
|
|
10399
|
+
if (!chunk.endsWith(">")) return void 0;
|
|
10400
|
+
const body = chunk.slice(1, -1);
|
|
10401
|
+
if (body.startsWith("!")) return void 0;
|
|
10402
|
+
const close = body.startsWith("/");
|
|
10403
|
+
const name = /^[^\s/>]*/.exec(close ? body.slice(1) : body)?.[0] ?? "";
|
|
10404
|
+
return { close, selfClose: !close && body.endsWith("/"), name };
|
|
10405
|
+
}
|
|
10406
|
+
var ATTR_NAME = /^[A-Za-z_:][\w.:-]*/;
|
|
10407
|
+
var isSpace = (c) => c !== void 0 && /\s/.test(c);
|
|
10408
|
+
var invalidToken = (offset) => ({ message: XML_ERROR_INVALID_TOKEN, offset });
|
|
10409
|
+
function skipSpace(chunk, i) {
|
|
10410
|
+
let j = i;
|
|
10411
|
+
while (isSpace(chunk[j])) j++;
|
|
10412
|
+
return j;
|
|
10413
|
+
}
|
|
10414
|
+
function readAttrPair(chunk, i) {
|
|
10415
|
+
const name = ATTR_NAME.exec(chunk.slice(i))?.[0];
|
|
10416
|
+
if (name === void 0) return invalidToken(i);
|
|
10417
|
+
let j = skipSpace(chunk, i + name.length);
|
|
10418
|
+
if (chunk[j] !== "=") return invalidToken(j);
|
|
10419
|
+
j = skipSpace(chunk, j + 1);
|
|
10420
|
+
const q = chunk[j];
|
|
10421
|
+
if (q !== '"' && q !== "'") return invalidToken(j);
|
|
10422
|
+
const end = chunk.indexOf(q, j + 1);
|
|
10423
|
+
return end < 0 ? void 0 : { name, next: end + 1 };
|
|
10424
|
+
}
|
|
10425
|
+
function findAttrError(chunk, from) {
|
|
10426
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10427
|
+
let dup;
|
|
10428
|
+
let i = skipSpace(chunk, from);
|
|
10429
|
+
while (chunk[i] !== ">" && !(chunk[i] === "/" && chunk[i + 1] === ">")) {
|
|
10430
|
+
const pair = readAttrPair(chunk, i);
|
|
10431
|
+
if (pair === void 0) return void 0;
|
|
10432
|
+
if ("message" in pair) return pair;
|
|
10433
|
+
if (seen.has(pair.name) && dup === void 0) dup = { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: i };
|
|
10434
|
+
seen.add(pair.name);
|
|
10435
|
+
i = skipSpace(chunk, pair.next);
|
|
10436
|
+
}
|
|
10437
|
+
return dup;
|
|
10438
|
+
}
|
|
10439
|
+
function checkTagChunk(src, start, st) {
|
|
10440
|
+
const tag = parseTagChunk(st.curr);
|
|
10441
|
+
if (tag === void 0) return;
|
|
10442
|
+
if (tag.close) {
|
|
10443
|
+
if (st.stack.length > 0 && st.stack.pop() !== tag.name) {
|
|
10444
|
+
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, start), st.prev + st.curr);
|
|
10445
|
+
}
|
|
10446
|
+
} else {
|
|
10447
|
+
const bad = findAttrError(st.curr, 1 + tag.name.length);
|
|
10448
|
+
if (bad !== void 0) {
|
|
10449
|
+
throw htmlErrorInLine(bad.message, lineAt(src, start + bad.offset), st.prev + st.curr);
|
|
10450
|
+
}
|
|
10451
|
+
if (!tag.selfClose) st.stack.push(tag.name);
|
|
10452
|
+
}
|
|
10453
|
+
if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
|
|
10454
|
+
const text = `Unknown HTML element <${tag.name}> on line ${lineAt(src, start)} `;
|
|
10455
|
+
throw new HtmlLexError(tag.name.toUpperCase(), text, [`Error: ${text}`]);
|
|
10456
|
+
}
|
|
10457
|
+
function checkChunk(src, start, st) {
|
|
10458
|
+
if (st.curr.startsWith("<")) {
|
|
10459
|
+
checkTagChunk(src, start, st);
|
|
10460
|
+
return;
|
|
10461
|
+
}
|
|
10462
|
+
const off = findUndefinedEntity(st.curr);
|
|
10463
|
+
if (off >= 0) {
|
|
10464
|
+
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, start + off), st.prev + st.curr);
|
|
10465
|
+
}
|
|
10466
|
+
}
|
|
10467
|
+
function tokenizeDeferred(src) {
|
|
10345
10468
|
const tokens = [];
|
|
10469
|
+
const st = { stack: [], prev: "", curr: "" };
|
|
10346
10470
|
let i = 0;
|
|
10347
|
-
|
|
10348
|
-
|
|
10471
|
+
try {
|
|
10472
|
+
while (i < src.length) {
|
|
10473
|
+
const first = tokens.length;
|
|
10474
|
+
const start = i;
|
|
10475
|
+
st.prev = st.curr;
|
|
10476
|
+
st.curr = src.slice(i, chunkEnd(src, i));
|
|
10477
|
+
checkChunk(src, i, st);
|
|
10478
|
+
i = src[i] === "<" ? scanTag(src, i, tokens) : scanText(src, i, tokens);
|
|
10479
|
+
const info = { src, pos: start, end: i, context: st.prev + st.curr };
|
|
10480
|
+
for (let k = first; k < tokens.length; k++) chunkInfo.set(tokens[k], info);
|
|
10481
|
+
}
|
|
10482
|
+
} catch (e) {
|
|
10483
|
+
if (e instanceof HtmlParseError) return { tokens, error: e };
|
|
10484
|
+
throw e;
|
|
10349
10485
|
}
|
|
10350
|
-
return tokens;
|
|
10486
|
+
return { tokens };
|
|
10351
10487
|
}
|
|
10352
10488
|
|
|
10353
|
-
// src/common/htmltable-parse.ts
|
|
10489
|
+
// src/common/htmltable-parse-attrs.ts
|
|
10354
10490
|
function anchorAttr(v) {
|
|
10355
10491
|
return v === void 0 ? void 0 : htmlEntityUTF8(v);
|
|
10356
10492
|
}
|
|
@@ -10373,6 +10509,81 @@ var num = (s) => {
|
|
|
10373
10509
|
const n = parseInt(s, 10);
|
|
10374
10510
|
return isNaN(n) ? void 0 : n;
|
|
10375
10511
|
};
|
|
10512
|
+
var parseFixedSize = (a) => a["fixedsize"]?.toUpperCase() === "TRUE" ? true : void 0;
|
|
10513
|
+
var parseTitle = (a) => a["title"] !== void 0 ? a["title"] : a["tooltip"];
|
|
10514
|
+
var parseSides = (v) => {
|
|
10515
|
+
if (v === void 0) return void 0;
|
|
10516
|
+
let flags = 0;
|
|
10517
|
+
for (const c of v.toLowerCase()) {
|
|
10518
|
+
if (c === "l") flags |= BORDER_LEFT;
|
|
10519
|
+
else if (c === "t") flags |= BORDER_TOP;
|
|
10520
|
+
else if (c === "r") flags |= BORDER_RIGHT;
|
|
10521
|
+
else if (c === "b") flags |= BORDER_BOTTOM;
|
|
10522
|
+
}
|
|
10523
|
+
if (flags === 0 || flags === BORDER_MASK) return void 0;
|
|
10524
|
+
return flags;
|
|
10525
|
+
};
|
|
10526
|
+
var parseGradientAngle = (v) => {
|
|
10527
|
+
if (v === void 0) return void 0;
|
|
10528
|
+
const n = parseInt(v, 10);
|
|
10529
|
+
if (isNaN(n) || String(n) !== v.trim()) return void 0;
|
|
10530
|
+
if (n < 0 || n > 360) return void 0;
|
|
10531
|
+
return n;
|
|
10532
|
+
};
|
|
10533
|
+
var parseColumns = (v) => v === "*" ? true : void 0;
|
|
10534
|
+
var parseRows = (v) => v === "*" ? true : void 0;
|
|
10535
|
+
var buildCell = (content, a) => ({
|
|
10536
|
+
kind: "cell",
|
|
10537
|
+
content,
|
|
10538
|
+
port: a["port"],
|
|
10539
|
+
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10540
|
+
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10541
|
+
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
10542
|
+
bgcolor: a["bgcolor"],
|
|
10543
|
+
color: a["color"],
|
|
10544
|
+
border: num(a["border"]),
|
|
10545
|
+
cellpadding: num(a["cellpadding"]),
|
|
10546
|
+
cellspacing: num(a["cellspacing"]),
|
|
10547
|
+
sides: parseSides(a["sides"]),
|
|
10548
|
+
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10549
|
+
style: a["style"],
|
|
10550
|
+
width: num(a["width"]),
|
|
10551
|
+
height: num(a["height"]),
|
|
10552
|
+
fixedsize: parseFixedSize(a),
|
|
10553
|
+
colspan: num(a["colspan"]),
|
|
10554
|
+
rowspan: num(a["rowspan"]),
|
|
10555
|
+
href: anchorAttr(a["href"]),
|
|
10556
|
+
title: parseTitle(a),
|
|
10557
|
+
target: anchorAttr(a["target"]),
|
|
10558
|
+
id: a["id"]
|
|
10559
|
+
});
|
|
10560
|
+
var buildTable = (rows, a) => ({
|
|
10561
|
+
kind: "table",
|
|
10562
|
+
rows,
|
|
10563
|
+
border: num(a["border"]),
|
|
10564
|
+
cellborder: num(a["cellborder"]),
|
|
10565
|
+
cellspacing: num(a["cellspacing"]),
|
|
10566
|
+
cellpadding: num(a["cellpadding"]),
|
|
10567
|
+
bgcolor: a["bgcolor"],
|
|
10568
|
+
color: a["color"],
|
|
10569
|
+
style: a["style"],
|
|
10570
|
+
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10571
|
+
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10572
|
+
fixedsize: parseFixedSize(a),
|
|
10573
|
+
width: num(a["width"]),
|
|
10574
|
+
height: num(a["height"]),
|
|
10575
|
+
href: anchorAttr(a["href"]),
|
|
10576
|
+
title: parseTitle(a),
|
|
10577
|
+
target: anchorAttr(a["target"]),
|
|
10578
|
+
id: a["id"],
|
|
10579
|
+
port: a["port"],
|
|
10580
|
+
sides: parseSides(a["sides"]),
|
|
10581
|
+
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10582
|
+
vrule: parseColumns(a["columns"]),
|
|
10583
|
+
hrule: parseRows(a["rows"])
|
|
10584
|
+
});
|
|
10585
|
+
|
|
10586
|
+
// src/common/htmltable-parse.ts
|
|
10376
10587
|
var definedOf = (s) => Object.fromEntries(
|
|
10377
10588
|
Object.entries(s).filter(([, v]) => v !== void 0)
|
|
10378
10589
|
);
|
|
@@ -10396,6 +10607,11 @@ var fontItemProps = (f) => {
|
|
|
10396
10607
|
if (f.fontSize !== void 0) out.fontSize = f.fontSize;
|
|
10397
10608
|
return out;
|
|
10398
10609
|
};
|
|
10610
|
+
var MSG_SYNTAX_ERROR = "syntax error";
|
|
10611
|
+
var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
|
|
10612
|
+
var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
|
|
10613
|
+
var nonSpace = (text) => /[^ \t\n\r]/.test(text);
|
|
10614
|
+
var parseError = (s, tok, message) => (tok === void 0 ? s.pending : htmlErrorAtToken(message, tok)) ?? new HtmlParseError(message);
|
|
10399
10615
|
var peek = (s) => s.tokens[s.pos];
|
|
10400
10616
|
var consume = (s) => {
|
|
10401
10617
|
const t = s.tokens[s.pos];
|
|
@@ -10414,12 +10630,20 @@ var inlineFontState = (tag, _attrs) => {
|
|
|
10414
10630
|
if (tag === "SUP") fs.superscript = true;
|
|
10415
10631
|
return fs;
|
|
10416
10632
|
};
|
|
10633
|
+
var consumeClose = (s, tag) => {
|
|
10634
|
+
const nxt = peek(s);
|
|
10635
|
+
if (nxt === void 0) return;
|
|
10636
|
+
if (nxt.type === "close" && nxt.tag === tag) {
|
|
10637
|
+
consume(s);
|
|
10638
|
+
return;
|
|
10639
|
+
}
|
|
10640
|
+
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10641
|
+
};
|
|
10417
10642
|
var applyBrTag = (s, t, fontStack, items) => {
|
|
10418
10643
|
consume(s);
|
|
10419
10644
|
const font = fontStack[fontStack.length - 1] ?? {};
|
|
10420
10645
|
items.push({ br: true, brAlign: parseAlign(t.attrs["align"] ?? ""), ...fontItemProps(font) });
|
|
10421
|
-
|
|
10422
|
-
if (nxt?.type === "close" && nxt.tag === "BR") consume(s);
|
|
10646
|
+
consumeClose(s, "BR");
|
|
10423
10647
|
};
|
|
10424
10648
|
var applyFontTag = (s, t, fontStack, items) => {
|
|
10425
10649
|
consume(s);
|
|
@@ -10476,12 +10700,6 @@ var parseText = (s, fontStack) => {
|
|
|
10476
10700
|
}
|
|
10477
10701
|
return { kind: "text", items };
|
|
10478
10702
|
};
|
|
10479
|
-
var parseHrContent = (s) => {
|
|
10480
|
-
consume(s);
|
|
10481
|
-
const nxt = peek(s);
|
|
10482
|
-
if (nxt?.type === "close" && nxt.tag === "HR") consume(s);
|
|
10483
|
-
return { kind: "hr" };
|
|
10484
|
-
};
|
|
10485
10703
|
var parseImgContent = (s, t, cellAttrs) => {
|
|
10486
10704
|
consume(s);
|
|
10487
10705
|
const img = {
|
|
@@ -10489,24 +10707,54 @@ var parseImgContent = (s, t, cellAttrs) => {
|
|
|
10489
10707
|
src: cellAttrs["src"] ?? t.attrs["src"] ?? "",
|
|
10490
10708
|
scale: t.attrs["scale"]
|
|
10491
10709
|
};
|
|
10492
|
-
|
|
10493
|
-
if (nxt?.type === "close" && nxt.tag === "IMG") consume(s);
|
|
10710
|
+
consumeClose(s, "IMG");
|
|
10494
10711
|
return img;
|
|
10495
10712
|
};
|
|
10496
|
-
var
|
|
10497
|
-
if (
|
|
10498
|
-
if (
|
|
10499
|
-
|
|
10713
|
+
var scanCellTable = (s, t, fontStack, st) => {
|
|
10714
|
+
if (st.kind === "image" || st.kind === "table") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10715
|
+
if (st.textNonSpace) throw parseError(s, t, MSG_TEXT_BEFORE_TABLE);
|
|
10716
|
+
const tbl = parseTable(s, fontStack);
|
|
10717
|
+
st.kind = "table";
|
|
10718
|
+
return [tbl];
|
|
10719
|
+
};
|
|
10720
|
+
var scanCellText = (s, t, fontStack, st) => {
|
|
10721
|
+
const start = s.pos;
|
|
10500
10722
|
const txt = parseText(s, fontStack);
|
|
10723
|
+
if (s.pos === start) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10724
|
+
if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) st.textNonSpace = true;
|
|
10725
|
+
st.kind = "text";
|
|
10501
10726
|
return txt.items.length > 0 ? [txt] : [];
|
|
10502
10727
|
};
|
|
10728
|
+
var scanAfterTable = (s, t, st) => {
|
|
10729
|
+
if (t.type !== "text") throw parseError(s, t, st.afterNonSpace ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
10730
|
+
consume(s);
|
|
10731
|
+
if (nonSpace(t.value)) st.afterNonSpace = true;
|
|
10732
|
+
return [];
|
|
10733
|
+
};
|
|
10734
|
+
var scanCellImage = (s, t, cellAttrs, st) => {
|
|
10735
|
+
if (st.kind !== "none") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10736
|
+
st.kind = "image";
|
|
10737
|
+
return [parseImgContent(s, t, cellAttrs)];
|
|
10738
|
+
};
|
|
10739
|
+
var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
|
|
10740
|
+
if (st.kind === "table") return scanAfterTable(s, t, st);
|
|
10741
|
+
if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
|
|
10742
|
+
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, cellAttrs, st);
|
|
10743
|
+
if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10744
|
+
return scanCellText(s, t, fontStack, st);
|
|
10745
|
+
};
|
|
10746
|
+
var endsCell = (s, t, st) => {
|
|
10747
|
+
if (t.type !== "close") return false;
|
|
10748
|
+
const afterText = st.kind === "table" && st.afterNonSpace;
|
|
10749
|
+
if (t.tag === "TD" && !afterText) return true;
|
|
10750
|
+
throw parseError(s, t, afterText ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
10751
|
+
};
|
|
10503
10752
|
var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
10504
10753
|
const content = [];
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
if (
|
|
10508
|
-
|
|
10509
|
-
content.push(...parseCellItem(s, t, cellAttrs, fontStack));
|
|
10754
|
+
const st = { kind: "none", textNonSpace: false, afterNonSpace: false };
|
|
10755
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10756
|
+
if (endsCell(s, t, st)) break;
|
|
10757
|
+
content.push(...scanCellItem(s, t, cellAttrs, fontStack, st));
|
|
10510
10758
|
}
|
|
10511
10759
|
const nxt = peek(s);
|
|
10512
10760
|
if (nxt?.type === "close" && nxt.tag === "TD") consume(s);
|
|
@@ -10514,134 +10762,85 @@ var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
|
10514
10762
|
if (tbl !== void 0) return [tbl];
|
|
10515
10763
|
return content;
|
|
10516
10764
|
};
|
|
10517
|
-
var parseFixedSize = (a) => a["fixedsize"]?.toUpperCase() === "TRUE" ? true : void 0;
|
|
10518
|
-
var parseTitle = (a) => a["title"] !== void 0 ? a["title"] : a["tooltip"];
|
|
10519
|
-
var parseSides = (v) => {
|
|
10520
|
-
if (v === void 0) return void 0;
|
|
10521
|
-
let flags = 0;
|
|
10522
|
-
for (const c of v.toLowerCase()) {
|
|
10523
|
-
if (c === "l") flags |= BORDER_LEFT;
|
|
10524
|
-
else if (c === "t") flags |= BORDER_TOP;
|
|
10525
|
-
else if (c === "r") flags |= BORDER_RIGHT;
|
|
10526
|
-
else if (c === "b") flags |= BORDER_BOTTOM;
|
|
10527
|
-
}
|
|
10528
|
-
if (flags === 0 || flags === BORDER_MASK) return void 0;
|
|
10529
|
-
return flags;
|
|
10530
|
-
};
|
|
10531
|
-
var parseGradientAngle = (v) => {
|
|
10532
|
-
if (v === void 0) return void 0;
|
|
10533
|
-
const n = parseInt(v, 10);
|
|
10534
|
-
if (isNaN(n) || String(n) !== v.trim()) return void 0;
|
|
10535
|
-
if (n < 0 || n > 360) return void 0;
|
|
10536
|
-
return n;
|
|
10537
|
-
};
|
|
10538
|
-
var parseColumns = (v) => v === "*" ? true : void 0;
|
|
10539
|
-
var parseRows = (v) => v === "*" ? true : void 0;
|
|
10540
|
-
var buildCell = (content, a) => ({
|
|
10541
|
-
kind: "cell",
|
|
10542
|
-
content,
|
|
10543
|
-
port: a["port"],
|
|
10544
|
-
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10545
|
-
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10546
|
-
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
10547
|
-
bgcolor: a["bgcolor"],
|
|
10548
|
-
color: a["color"],
|
|
10549
|
-
border: num(a["border"]),
|
|
10550
|
-
cellpadding: num(a["cellpadding"]),
|
|
10551
|
-
cellspacing: num(a["cellspacing"]),
|
|
10552
|
-
sides: parseSides(a["sides"]),
|
|
10553
|
-
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10554
|
-
style: a["style"],
|
|
10555
|
-
width: num(a["width"]),
|
|
10556
|
-
height: num(a["height"]),
|
|
10557
|
-
fixedsize: parseFixedSize(a),
|
|
10558
|
-
colspan: num(a["colspan"]),
|
|
10559
|
-
rowspan: num(a["rowspan"]),
|
|
10560
|
-
href: anchorAttr(a["href"]),
|
|
10561
|
-
title: parseTitle(a),
|
|
10562
|
-
target: anchorAttr(a["target"]),
|
|
10563
|
-
id: a["id"]
|
|
10564
|
-
});
|
|
10565
10765
|
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, attrs, fontStack), attrs);
|
|
10566
|
-
var
|
|
10766
|
+
var parseRowVr = (s, t, cells) => {
|
|
10767
|
+
const prev = cells[cells.length - 1];
|
|
10768
|
+
if (prev === void 0) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10769
|
+
consume(s);
|
|
10770
|
+
consumeClose(s, "VR");
|
|
10771
|
+
prev.vruled = true;
|
|
10772
|
+
};
|
|
10773
|
+
var scanRowCell = (s, t, fontStack, rs) => {
|
|
10567
10774
|
if (t.type === "open" && t.tag === "TD") {
|
|
10568
10775
|
consume(s);
|
|
10569
|
-
cells.push(parseCell(s, t.attrs, fontStack));
|
|
10570
|
-
|
|
10776
|
+
rs.cells.push(parseCell(s, t.attrs, fontStack));
|
|
10777
|
+
rs.needCell = false;
|
|
10778
|
+
} else if (t.type === "open" && t.tag === "VR" && !rs.needCell) {
|
|
10779
|
+
parseRowVr(s, t, rs.cells);
|
|
10780
|
+
rs.needCell = true;
|
|
10781
|
+
} else {
|
|
10782
|
+
throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10571
10783
|
}
|
|
10572
|
-
|
|
10784
|
+
};
|
|
10785
|
+
var scanRowToken = (s, t, fontStack, rs) => {
|
|
10786
|
+
if (t.type === "text") {
|
|
10573
10787
|
consume(s);
|
|
10574
|
-
|
|
10575
|
-
if (nxt?.type === "close" && nxt.tag === "VR") consume(s);
|
|
10576
|
-
const prev = cells[cells.length - 1];
|
|
10577
|
-
if (prev === void 0) throw new HtmlParseError("VR");
|
|
10578
|
-
prev.vruled = true;
|
|
10579
|
-
return;
|
|
10788
|
+
return false;
|
|
10580
10789
|
}
|
|
10581
|
-
|
|
10790
|
+
if (t.type !== "close" || t.tag !== "TR") {
|
|
10791
|
+
scanRowCell(s, t, fontStack, rs);
|
|
10792
|
+
return false;
|
|
10793
|
+
}
|
|
10794
|
+
if (rs.cells.length === 0 || rs.needCell) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10795
|
+
return true;
|
|
10582
10796
|
};
|
|
10583
10797
|
var parseRow = (s, fontStack) => {
|
|
10584
|
-
const
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
if (!t) break;
|
|
10588
|
-
if (t.type === "close" && t.tag === "TR") break;
|
|
10589
|
-
processRowToken(s, t, cells, fontStack);
|
|
10798
|
+
const rs = { cells: [], needCell: false };
|
|
10799
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10800
|
+
if (scanRowToken(s, t, fontStack, rs)) break;
|
|
10590
10801
|
}
|
|
10591
10802
|
const nxt = peek(s);
|
|
10592
10803
|
if (nxt?.type === "close" && nxt.tag === "TR") consume(s);
|
|
10593
|
-
return { cells };
|
|
10804
|
+
return { cells: rs.cells };
|
|
10805
|
+
};
|
|
10806
|
+
var scanTableRow = (s, t, fontStack, ts) => {
|
|
10807
|
+
if (t.type === "open" && t.tag === "TR") {
|
|
10808
|
+
consume(s);
|
|
10809
|
+
ts.rows.push(parseTableRow(s, fontStack, ts));
|
|
10810
|
+
ts.needRow = false;
|
|
10811
|
+
} else if (t.type === "open" && t.tag === "HR" && ts.rows.length > 0 && !ts.needRow) {
|
|
10812
|
+
consumeRowHr(s, ts.rows);
|
|
10813
|
+
ts.needRow = true;
|
|
10814
|
+
} else {
|
|
10815
|
+
throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10816
|
+
}
|
|
10817
|
+
};
|
|
10818
|
+
var scanTableToken = (s, t, fontStack, ts) => {
|
|
10819
|
+
if (t.type === "text") {
|
|
10820
|
+
consume(s);
|
|
10821
|
+
return false;
|
|
10822
|
+
}
|
|
10823
|
+
if (t.type !== "close" || t.tag !== "TABLE") {
|
|
10824
|
+
scanTableRow(s, t, fontStack, ts);
|
|
10825
|
+
return false;
|
|
10826
|
+
}
|
|
10827
|
+
if (ts.rows.length === 0 || ts.needRow) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
10828
|
+
consume(s);
|
|
10829
|
+
return true;
|
|
10594
10830
|
};
|
|
10595
|
-
var buildTable = (rows, a) => ({
|
|
10596
|
-
kind: "table",
|
|
10597
|
-
rows,
|
|
10598
|
-
border: num(a["border"]),
|
|
10599
|
-
cellborder: num(a["cellborder"]),
|
|
10600
|
-
cellspacing: num(a["cellspacing"]),
|
|
10601
|
-
cellpadding: num(a["cellpadding"]),
|
|
10602
|
-
bgcolor: a["bgcolor"],
|
|
10603
|
-
color: a["color"],
|
|
10604
|
-
style: a["style"],
|
|
10605
|
-
align: parseAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
10606
|
-
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
10607
|
-
fixedsize: parseFixedSize(a),
|
|
10608
|
-
width: num(a["width"]),
|
|
10609
|
-
height: num(a["height"]),
|
|
10610
|
-
href: anchorAttr(a["href"]),
|
|
10611
|
-
title: parseTitle(a),
|
|
10612
|
-
target: anchorAttr(a["target"]),
|
|
10613
|
-
id: a["id"],
|
|
10614
|
-
port: a["port"],
|
|
10615
|
-
sides: parseSides(a["sides"]),
|
|
10616
|
-
gradientangle: parseGradientAngle(a["gradientangle"]),
|
|
10617
|
-
vrule: parseColumns(a["columns"]),
|
|
10618
|
-
hrule: parseRows(a["rows"])
|
|
10619
|
-
});
|
|
10620
10831
|
var parseTable = (s, fontStack) => {
|
|
10621
10832
|
const open = consume(s);
|
|
10622
10833
|
if (open.type !== "open" || open.tag !== "TABLE") throw new HtmlParseError("TABLE");
|
|
10623
|
-
const
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
break;
|
|
10632
|
-
}
|
|
10633
|
-
if (t.type === "open" && t.tag === "TR") {
|
|
10634
|
-
consume(s);
|
|
10635
|
-
rows.push(parseTableRow(s, fontStack, { hrule, vrule }));
|
|
10636
|
-
continue;
|
|
10637
|
-
}
|
|
10638
|
-
if (t.type === "open" && t.tag === "HR") {
|
|
10639
|
-
consumeRowHr(s, rows);
|
|
10640
|
-
continue;
|
|
10641
|
-
}
|
|
10642
|
-
consume(s);
|
|
10834
|
+
const ts = {
|
|
10835
|
+
rows: [],
|
|
10836
|
+
needRow: false,
|
|
10837
|
+
hrule: parseRows(open.attrs["rows"]) === true,
|
|
10838
|
+
vrule: parseColumns(open.attrs["columns"]) === true
|
|
10839
|
+
};
|
|
10840
|
+
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
10841
|
+
if (scanTableToken(s, t, fontStack, ts)) break;
|
|
10643
10842
|
}
|
|
10644
|
-
return buildTable(rows, open.attrs);
|
|
10843
|
+
return buildTable(ts.rows, open.attrs);
|
|
10645
10844
|
};
|
|
10646
10845
|
var parseTableRow = (s, fontStack, opts) => {
|
|
10647
10846
|
const row = parseRow(s, fontStack);
|
|
@@ -10651,11 +10850,9 @@ var parseTableRow = (s, fontStack, opts) => {
|
|
|
10651
10850
|
};
|
|
10652
10851
|
var consumeRowHr = (s, rows) => {
|
|
10653
10852
|
consume(s);
|
|
10654
|
-
|
|
10655
|
-
if (nxt?.type === "close" && nxt.tag === "HR") consume(s);
|
|
10853
|
+
consumeClose(s, "HR");
|
|
10656
10854
|
const prev = rows[rows.length - 1];
|
|
10657
|
-
if (prev
|
|
10658
|
-
prev.ruled = true;
|
|
10855
|
+
if (prev !== void 0) prev.ruled = true;
|
|
10659
10856
|
};
|
|
10660
10857
|
var findFirstRealToken = (tokens, start) => {
|
|
10661
10858
|
for (let i = start; i < tokens.length; i++) {
|
|
@@ -10671,34 +10868,61 @@ var skipLeadingWs = (s) => {
|
|
|
10671
10868
|
consume(s);
|
|
10672
10869
|
}
|
|
10673
10870
|
};
|
|
10871
|
+
var finishTableLabel = (s) => {
|
|
10872
|
+
let afterNonSpace = false;
|
|
10873
|
+
for (let t = peek(s); t?.type === "text"; t = peek(s)) {
|
|
10874
|
+
consume(s);
|
|
10875
|
+
if (nonSpace(t.value)) afterNonSpace = true;
|
|
10876
|
+
}
|
|
10877
|
+
const nxt = peek(s);
|
|
10878
|
+
if (nxt === void 0) return;
|
|
10879
|
+
if (afterNonSpace) throw parseError(s, nxt, MSG_TEXT_AFTER_TABLE);
|
|
10880
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10881
|
+
consume(s);
|
|
10882
|
+
};
|
|
10674
10883
|
var parseTableLabel = (s, fontStack) => {
|
|
10675
10884
|
skipLeadingWs(s);
|
|
10676
10885
|
const table = parseTable(s, fontStack);
|
|
10677
|
-
|
|
10678
|
-
if (nxt?.type === "close" && nxt.tag === "HTML") consume(s);
|
|
10886
|
+
finishTableLabel(s);
|
|
10679
10887
|
return { kind: "table", table };
|
|
10680
10888
|
};
|
|
10681
|
-
var
|
|
10682
|
-
const wrapped = `<HTML>${src}</HTML>`;
|
|
10683
|
-
const tokens = tokenize(wrapped);
|
|
10684
|
-
const s = { tokens, pos: 0 };
|
|
10685
|
-
const fontStack = [{}];
|
|
10686
|
-
const htmlOpen = consume(s);
|
|
10687
|
-
if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
|
|
10688
|
-
const firstReal = findFirstRealToken(tokens, s.pos);
|
|
10689
|
-
if (firstReal?.type === "open" && firstReal.tag === "TABLE") {
|
|
10690
|
-
return parseTableLabel(s, fontStack);
|
|
10691
|
-
}
|
|
10889
|
+
var parseTextLabel = (s, fontStack) => {
|
|
10692
10890
|
const texts = [];
|
|
10693
10891
|
const txt = parseText(s, fontStack);
|
|
10694
10892
|
if (txt.items.length > 0) texts.push(txt);
|
|
10695
10893
|
const nxt = peek(s);
|
|
10696
|
-
if (nxt
|
|
10697
|
-
|
|
10894
|
+
if (nxt === void 0) return { kind: "text", texts };
|
|
10895
|
+
if (nxt.type === "open" && nxt.tag === "TABLE") {
|
|
10896
|
+
if (txt.items.some((i) => i.text !== void 0 && nonSpace(i.text))) {
|
|
10897
|
+
throw parseError(s, nxt, MSG_TEXT_BEFORE_TABLE);
|
|
10898
|
+
}
|
|
10899
|
+
throw new HtmlParseError("TABLE");
|
|
10698
10900
|
}
|
|
10699
|
-
if (nxt
|
|
10901
|
+
if (nxt.type !== "close" || nxt.tag !== "HTML") throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
10902
|
+
consume(s);
|
|
10700
10903
|
return { kind: "text", texts };
|
|
10701
10904
|
};
|
|
10905
|
+
var parseTokens = (s) => {
|
|
10906
|
+
const fontStack = [{}];
|
|
10907
|
+
const htmlOpen = consume(s);
|
|
10908
|
+
if (htmlOpen.type !== "open" || htmlOpen.tag !== "HTML") throw new HtmlParseError("HTML");
|
|
10909
|
+
const firstReal = findFirstRealToken(s.tokens, s.pos);
|
|
10910
|
+
if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
|
|
10911
|
+
return parseTextLabel(s, fontStack);
|
|
10912
|
+
};
|
|
10913
|
+
var parseHtmlLabel = (src) => {
|
|
10914
|
+
const { tokens, error } = tokenizeDeferred(`<HTML>${src}</HTML>`);
|
|
10915
|
+
const s = { tokens, pos: 0, pending: error };
|
|
10916
|
+
let label;
|
|
10917
|
+
try {
|
|
10918
|
+
label = parseTokens(s);
|
|
10919
|
+
} catch (e) {
|
|
10920
|
+
if (error !== void 0 && s.pos >= tokens.length) throw error;
|
|
10921
|
+
throw e;
|
|
10922
|
+
}
|
|
10923
|
+
if (error !== void 0) throw error;
|
|
10924
|
+
return label;
|
|
10925
|
+
};
|
|
10702
10926
|
|
|
10703
10927
|
// src/gvc/usershape.ts
|
|
10704
10928
|
var activeSizer = null;
|
|
@@ -10712,28 +10936,80 @@ function findImageSize(src) {
|
|
|
10712
10936
|
return activeSizer !== null ? activeSizer(src) : null;
|
|
10713
10937
|
}
|
|
10714
10938
|
|
|
10939
|
+
// src/common/pointset.ts
|
|
10940
|
+
function cmpPair(a, b) {
|
|
10941
|
+
if (a.x > b.x) return 1;
|
|
10942
|
+
if (a.x < b.x) return -1;
|
|
10943
|
+
if (a.y > b.y) return 1;
|
|
10944
|
+
if (a.y < b.y) return -1;
|
|
10945
|
+
return 0;
|
|
10946
|
+
}
|
|
10947
|
+
var PointSet = class {
|
|
10948
|
+
byX = /* @__PURE__ */ new Map();
|
|
10949
|
+
n = 0;
|
|
10950
|
+
/**
|
|
10951
|
+
* Insert (x, y). A duplicate keeps the point inserted first, as `dtinsert`
|
|
10952
|
+
* returns the existing object and the new one is freed.
|
|
10953
|
+
* @see lib/common/pointset.c:addPS
|
|
10954
|
+
*/
|
|
10955
|
+
addPS(x, y) {
|
|
10956
|
+
let col = this.byX.get(x);
|
|
10957
|
+
if (col === void 0) {
|
|
10958
|
+
col = /* @__PURE__ */ new Map();
|
|
10959
|
+
this.byX.set(x, col);
|
|
10960
|
+
}
|
|
10961
|
+
if (col.has(y)) return;
|
|
10962
|
+
col.set(y, { x, y });
|
|
10963
|
+
this.n++;
|
|
10964
|
+
}
|
|
10965
|
+
/** @see lib/common/pointset.c:inPS */
|
|
10966
|
+
inPS(pt) {
|
|
10967
|
+
return this.byX.get(pt.x)?.has(pt.y) ?? false;
|
|
10968
|
+
}
|
|
10969
|
+
/** @see lib/common/pointset.c:isInPS */
|
|
10970
|
+
isInPS(x, y) {
|
|
10971
|
+
return this.byX.get(x)?.has(y) ?? false;
|
|
10972
|
+
}
|
|
10973
|
+
/** @see lib/common/pointset.c:sizeOf */
|
|
10974
|
+
sizeOf() {
|
|
10975
|
+
return this.n;
|
|
10976
|
+
}
|
|
10977
|
+
/**
|
|
10978
|
+
* The points in dictionary order (`dtflatten` walks the ordered set).
|
|
10979
|
+
* @see lib/common/pointset.c:pointsOf
|
|
10980
|
+
*/
|
|
10981
|
+
pointsOf() {
|
|
10982
|
+
const pts = [];
|
|
10983
|
+
for (const col of this.byX.values()) {
|
|
10984
|
+
for (const p of col.values()) pts.push({ x: p.x, y: p.y });
|
|
10985
|
+
}
|
|
10986
|
+
return pts.sort(cmpPair);
|
|
10987
|
+
}
|
|
10988
|
+
};
|
|
10989
|
+
|
|
10715
10990
|
// src/common/htmltable.ts
|
|
10716
10991
|
var DEFAULT_BORDER = 1;
|
|
10717
10992
|
var DEFAULT_CELLPADDING = 2;
|
|
10718
10993
|
var DEFAULT_CELLSPACING = 2;
|
|
10719
10994
|
var DEFAULT_FONTSIZE = 14;
|
|
10720
|
-
var findCol = (
|
|
10995
|
+
var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
10721
10996
|
let col = startCol;
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10997
|
+
let notFound = true;
|
|
10998
|
+
const end = colspan - 1;
|
|
10999
|
+
while (notFound) {
|
|
11000
|
+
const lastc = col + end;
|
|
11001
|
+
let c;
|
|
11002
|
+
for (c = lastc; c >= col; c--) {
|
|
11003
|
+
if (ps.isInPS(c, row)) break;
|
|
11004
|
+
}
|
|
11005
|
+
if (c >= col) col = c + 1;
|
|
11006
|
+
else notFound = false;
|
|
11007
|
+
}
|
|
11008
|
+
for (let j = col; j < col + colspan; j++) {
|
|
11009
|
+
for (let i = row; i < row + rowspan; i++) {
|
|
11010
|
+
ps.addPS(j, i);
|
|
10731
11011
|
}
|
|
10732
|
-
if (!conflict) break;
|
|
10733
11012
|
}
|
|
10734
|
-
for (let c = col; c < col + colspan; c++)
|
|
10735
|
-
for (let r = row; r < row + rowspan; r++)
|
|
10736
|
-
used.add(`${c},${r}`);
|
|
10737
11013
|
return col;
|
|
10738
11014
|
};
|
|
10739
11015
|
var DEFAULT_SIZE_ENV = { fontsize: DEFAULT_FONTSIZE, fontname: "" };
|
|
@@ -10812,29 +11088,32 @@ var sizeTextContent = (texts, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
|
10812
11088
|
if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].mxysize : DEFAULT_FONTSIZE;
|
|
10813
11089
|
return { w, h };
|
|
10814
11090
|
};
|
|
11091
|
+
var missingImages = /* @__PURE__ */ new WeakSet();
|
|
10815
11092
|
var sizeHtmlImg = (img, imageSizer) => {
|
|
10816
|
-
if (img.width !== void 0 && img.height !== void 0) return;
|
|
11093
|
+
if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
|
|
10817
11094
|
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
10818
11095
|
if (sz !== null) {
|
|
10819
11096
|
img.width = sz.w;
|
|
10820
11097
|
img.height = sz.h;
|
|
10821
|
-
return;
|
|
11098
|
+
return 0;
|
|
10822
11099
|
}
|
|
10823
11100
|
console.error(`Error: No or improper image file="${img.src}"`);
|
|
10824
11101
|
img.width = 0;
|
|
10825
11102
|
img.height = 0;
|
|
11103
|
+
missingImages.add(img);
|
|
11104
|
+
return 1;
|
|
10826
11105
|
};
|
|
10827
11106
|
var sizeContentItem = (item, measurer, env) => {
|
|
10828
|
-
if (item.kind === "text") return sizeTextContent([item], measurer, env);
|
|
11107
|
+
if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
|
|
10829
11108
|
if (item.kind === "table") {
|
|
10830
|
-
sizeTableInner(item, measurer, env);
|
|
10831
|
-
return item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 };
|
|
11109
|
+
const rv = sizeTableInner(item, measurer, env);
|
|
11110
|
+
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
10832
11111
|
}
|
|
10833
11112
|
if (item.kind === "image") {
|
|
10834
|
-
sizeHtmlImg(item, env.imageSizer);
|
|
10835
|
-
return { w: item.width ?? 0, h: item.height ?? 0 };
|
|
11113
|
+
const rv = sizeHtmlImg(item, env.imageSizer);
|
|
11114
|
+
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
10836
11115
|
}
|
|
10837
|
-
return { w: 0, h: 0 };
|
|
11116
|
+
return { w: 0, h: 0, rv: 0 };
|
|
10838
11117
|
};
|
|
10839
11118
|
var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
|
|
10840
11119
|
var cellBorder = (cell2, tbl) => {
|
|
@@ -10844,27 +11123,60 @@ var cellBorder = (cell2, tbl) => {
|
|
|
10844
11123
|
if (tbl.border !== void 0) return tbl.border;
|
|
10845
11124
|
return DEFAULT_BORDER;
|
|
10846
11125
|
};
|
|
11126
|
+
function inheritTablePenColor(tbl, parentColor) {
|
|
11127
|
+
if (tbl.color === void 0) tbl.color = parentColor;
|
|
11128
|
+
const tblColor = tbl.color;
|
|
11129
|
+
for (const row of tbl.rows) {
|
|
11130
|
+
for (const cell2 of row.cells) {
|
|
11131
|
+
if (cell2.color === void 0) cell2.color = tblColor;
|
|
11132
|
+
for (const item of cell2.content) {
|
|
11133
|
+
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
11136
|
+
}
|
|
11137
|
+
}
|
|
11138
|
+
var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
|
|
11139
|
+
var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
|
|
11140
|
+
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
11141
|
+
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
11142
|
+
var sizeWarned = /* @__PURE__ */ new WeakSet();
|
|
11143
|
+
var fixedCellCheck = (cell2, sz, warn) => {
|
|
11144
|
+
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
11145
|
+
if (cell2.width && cell2.height) {
|
|
11146
|
+
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
11147
|
+
if (small && warn) console.warn(WARN_CELL_TOO_SMALL);
|
|
11148
|
+
return { rv: small ? 1 : 0, zero: true };
|
|
11149
|
+
}
|
|
11150
|
+
if (warn) console.warn(WARN_CELL_UNSPECIFIED);
|
|
11151
|
+
return { rv: 1, zero: false };
|
|
11152
|
+
};
|
|
10847
11153
|
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
10848
11154
|
const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
|
|
10849
|
-
let cw = 0, ch = 0;
|
|
11155
|
+
let cw = 0, ch = 0, rv = 0;
|
|
10850
11156
|
for (const item of cell2.content) {
|
|
10851
11157
|
const s = sizeContentItem(item, measurer, env);
|
|
10852
11158
|
cw = Math.max(cw, s.w);
|
|
10853
11159
|
ch += s.h;
|
|
11160
|
+
rv |= s.rv;
|
|
10854
11161
|
}
|
|
10855
11162
|
let szx = cw + margin;
|
|
10856
11163
|
let szy = ch + margin;
|
|
10857
|
-
|
|
11164
|
+
const warn = !sizeWarned.has(cell2);
|
|
11165
|
+
sizeWarned.add(cell2);
|
|
11166
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn);
|
|
11167
|
+
rv |= fixed.rv;
|
|
11168
|
+
if (fixed.zero) {
|
|
10858
11169
|
szx = 0;
|
|
10859
11170
|
szy = 0;
|
|
10860
11171
|
}
|
|
10861
11172
|
const bw = cell2.width !== void 0 ? cell2.width : 0;
|
|
10862
11173
|
const bh = cell2.height !== void 0 ? cell2.height : 0;
|
|
10863
|
-
return { w: Math.max(szx, bw), h: Math.max(szy, bh) };
|
|
11174
|
+
return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
|
|
10864
11175
|
};
|
|
10865
11176
|
var buildLayouts = (tbl, measurer, env) => {
|
|
10866
11177
|
const entries = [];
|
|
10867
|
-
|
|
11178
|
+
let rv = 0;
|
|
11179
|
+
const ps = new PointSet();
|
|
10868
11180
|
let rowIdx = 0;
|
|
10869
11181
|
for (const row of tbl.rows) {
|
|
10870
11182
|
let col = 0;
|
|
@@ -10874,14 +11186,15 @@ var buildLayouts = (tbl, measurer, env) => {
|
|
|
10874
11186
|
}
|
|
10875
11187
|
const colspan = c.colspan !== void 0 ? c.colspan : 1;
|
|
10876
11188
|
const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
|
|
10877
|
-
const { w, h } = getCellSize(c, tbl, measurer, env);
|
|
10878
|
-
|
|
11189
|
+
const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
|
|
11190
|
+
rv |= cellRv;
|
|
11191
|
+
col = findCol(ps, rowIdx, col, colspan, rowspan);
|
|
10879
11192
|
entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
|
|
10880
11193
|
col += colspan;
|
|
10881
11194
|
}
|
|
10882
11195
|
rowIdx++;
|
|
10883
11196
|
}
|
|
10884
|
-
return entries;
|
|
11197
|
+
return { entries, rv };
|
|
10885
11198
|
};
|
|
10886
11199
|
var setColWidths = (entries, ncols, spacing) => {
|
|
10887
11200
|
const widths = new Array(ncols + 1).fill(0);
|
|
@@ -10934,21 +11247,34 @@ var sumTableDims = (a) => {
|
|
|
10934
11247
|
var layoutHtmlTable = (tbl, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
10935
11248
|
const spacing = getSpacing(tbl);
|
|
10936
11249
|
const border = getBorder(tbl);
|
|
10937
|
-
const entries = buildLayouts(tbl, measurer, env);
|
|
11250
|
+
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
10938
11251
|
if (entries.length === 0) {
|
|
10939
|
-
return { entries, widths: [], heights: [], spacing, border };
|
|
11252
|
+
return { entries, widths: [], heights: [], spacing, border, rv };
|
|
10940
11253
|
}
|
|
10941
11254
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
10942
11255
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
10943
11256
|
const widths = setColWidths(entries, ncols, spacing);
|
|
10944
11257
|
const heights = setRowHeights(entries, nrows, spacing);
|
|
10945
|
-
return { entries, widths, heights, spacing, border };
|
|
11258
|
+
return { entries, widths, heights, spacing, border, rv };
|
|
11259
|
+
};
|
|
11260
|
+
var warnFixedTable = (tbl, dims) => {
|
|
11261
|
+
const warn = !sizeWarned.has(tbl);
|
|
11262
|
+
sizeWarned.add(tbl);
|
|
11263
|
+
if (tbl.fixedsize !== true) return 0;
|
|
11264
|
+
if (tbl.width && tbl.height) {
|
|
11265
|
+
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
11266
|
+
if (warn) console.warn(WARN_TABLE_TOO_SMALL);
|
|
11267
|
+
return 1;
|
|
11268
|
+
}
|
|
11269
|
+
if (warn) console.warn(WARN_TABLE_UNSPECIFIED);
|
|
11270
|
+
return 1;
|
|
10946
11271
|
};
|
|
10947
11272
|
var sizeTableInner = (tbl, measurer, env) => {
|
|
10948
|
-
const { entries, widths, heights, spacing, border } = layoutHtmlTable(tbl, measurer, env);
|
|
11273
|
+
const { entries, widths, heights, spacing, border, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
10949
11274
|
if (entries.length === 0) {
|
|
11275
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border }));
|
|
10950
11276
|
tbl.dimen = { w: 0, h: 0 };
|
|
10951
|
-
return;
|
|
11277
|
+
return rv | fixed2;
|
|
10952
11278
|
}
|
|
10953
11279
|
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
10954
11280
|
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
@@ -10956,19 +11282,22 @@ var sizeTableInner = (tbl, measurer, env) => {
|
|
|
10956
11282
|
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border });
|
|
10957
11283
|
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
10958
11284
|
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
11285
|
+
const fixed = warnFixedTable(tbl, { wd, ht });
|
|
10959
11286
|
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
10960
11287
|
tbl.dimen = {
|
|
10961
11288
|
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
10962
11289
|
h: Math.max(zeroContent ? 0 : ht, baseHt)
|
|
10963
11290
|
};
|
|
11291
|
+
return rv | fixed;
|
|
10964
11292
|
};
|
|
10965
11293
|
var sizeHtmlLabel = (label, measurer, env = DEFAULT_SIZE_ENV) => {
|
|
10966
11294
|
if (label.kind === "table") {
|
|
10967
|
-
sizeTableInner(label.table, measurer, env);
|
|
11295
|
+
const rv = sizeTableInner(label.table, measurer, env);
|
|
10968
11296
|
label.dimen = label.table.dimen;
|
|
10969
|
-
|
|
10970
|
-
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
11297
|
+
return rv;
|
|
10971
11298
|
}
|
|
11299
|
+
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
11300
|
+
return 0;
|
|
10972
11301
|
};
|
|
10973
11302
|
|
|
10974
11303
|
// src/common/splines-constants.ts
|
|
@@ -16538,28 +16867,18 @@ function posHtmlLabel(label, finfo, measurer) {
|
|
|
16538
16867
|
if (label.kind === "table") return posHtmlTable(label.table, finfo, measurer);
|
|
16539
16868
|
return posTextLabel(label, finfo, measurer);
|
|
16540
16869
|
}
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
const tblColor = tbl.color;
|
|
16544
|
-
for (const row of tbl.rows) {
|
|
16545
|
-
for (const cell2 of row.cells) {
|
|
16546
|
-
if (cell2.color === void 0) cell2.color = tblColor;
|
|
16547
|
-
for (const item of cell2.content) {
|
|
16548
|
-
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
16549
|
-
}
|
|
16550
|
-
}
|
|
16551
|
-
}
|
|
16552
|
-
}
|
|
16553
|
-
function makeHtmlLabel(content, finfo, measurer) {
|
|
16870
|
+
var HTML_PARSE_FATAL = 3;
|
|
16871
|
+
function makeHtmlLabelRv(content, finfo, measurer) {
|
|
16554
16872
|
const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
|
|
16555
16873
|
let lbl;
|
|
16556
16874
|
try {
|
|
16557
16875
|
lbl = parseHtmlLabel(content);
|
|
16558
|
-
} catch {
|
|
16559
|
-
|
|
16876
|
+
} catch (e) {
|
|
16877
|
+
if (e instanceof HtmlLexError) for (const line of e.diagnostics) console.error(line);
|
|
16878
|
+
return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
|
|
16560
16879
|
}
|
|
16561
16880
|
if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
|
|
16562
|
-
sizeHtmlLabel(lbl, measurer, {
|
|
16881
|
+
const rv = sizeHtmlLabel(lbl, measurer, {
|
|
16563
16882
|
fontsize,
|
|
16564
16883
|
fontname,
|
|
16565
16884
|
imageSizer
|
|
@@ -16567,7 +16886,7 @@ function makeHtmlLabel(content, finfo, measurer) {
|
|
|
16567
16886
|
const placed = posHtmlLabel(lbl, { fontname, fontsize, fontcolor }, measurer);
|
|
16568
16887
|
const dim = lbl.dimen ?? { w: 0, h: 0 };
|
|
16569
16888
|
const text = lbl.kind === "table" ? "<TABLE>" : content;
|
|
16570
|
-
return htmlTextLabel(text, { fontname, fontsize, fontcolor }, placed, dim);
|
|
16889
|
+
return { label: htmlTextLabel(text, { fontname, fontsize, fontcolor }, placed, dim), rv };
|
|
16571
16890
|
}
|
|
16572
16891
|
function htmlTextLabel(text, finfo, placed, dim) {
|
|
16573
16892
|
return {
|
|
@@ -16686,6 +17005,14 @@ function getPenColor(obj) {
|
|
|
16686
17005
|
function rootOf(obj) {
|
|
16687
17006
|
return obj instanceof Edge ? obj.tail.root : obj.root;
|
|
16688
17007
|
}
|
|
17008
|
+
function inLabelOf(obj) {
|
|
17009
|
+
if (obj instanceof Edge) {
|
|
17010
|
+
const sep = obj.head.root.kind.endsWith("undirected") ? "--" : "->";
|
|
17011
|
+
return `in label of edge ${obj.tail.name} ${sep} ${obj.head.name}`;
|
|
17012
|
+
}
|
|
17013
|
+
if (obj instanceof Graph) return `in label of graph ${obj.name}`;
|
|
17014
|
+
return `in label of node ${obj.name}`;
|
|
17015
|
+
}
|
|
16689
17016
|
function buildSpan(text, font, measured) {
|
|
16690
17017
|
return {
|
|
16691
17018
|
str: text,
|
|
@@ -16753,7 +17080,9 @@ function makeLabel(text, fontname, fontsize, fontcolor, measurer) {
|
|
|
16753
17080
|
function makeAnyLabel(content, isHtml, font, measurer, obj) {
|
|
16754
17081
|
if (isHtml && content !== "") {
|
|
16755
17082
|
const imageSizer = obj !== void 0 ? rootOf(obj).info.gvc?.imageSizer : void 0;
|
|
16756
|
-
|
|
17083
|
+
const { label, rv } = makeHtmlLabelRv(content, { ...font, pencolor: getPenColor(obj), imageSizer }, measurer);
|
|
17084
|
+
if (rv !== 0 && obj !== void 0) console.error(inLabelOf(obj));
|
|
17085
|
+
return label;
|
|
16757
17086
|
}
|
|
16758
17087
|
const subst2 = obj !== void 0 ? substObj(content, obj, false) : content;
|
|
16759
17088
|
const text = htmlEntityUTF8(subst2);
|
|
@@ -29053,18 +29382,22 @@ function dotSameports(g) {
|
|
|
29053
29382
|
function dist2(p, q) {
|
|
29054
29383
|
const dx = p.x - q.x;
|
|
29055
29384
|
const dy = p.y - q.y;
|
|
29056
|
-
return dx
|
|
29385
|
+
return fma(dx, dx, dy * dy);
|
|
29057
29386
|
}
|
|
29058
29387
|
function distPt(p, q) {
|
|
29059
29388
|
return Math.sqrt(dist2(p, q));
|
|
29060
29389
|
}
|
|
29061
|
-
function
|
|
29390
|
+
function bezier(v, t) {
|
|
29062
29391
|
const u = 1 - t;
|
|
29063
|
-
const [
|
|
29064
|
-
|
|
29065
|
-
|
|
29066
|
-
|
|
29067
|
-
|
|
29392
|
+
const x = [v[0].x, v[1].x, v[2].x, v[3].x];
|
|
29393
|
+
const y = [v[0].y, v[1].y, v[2].y, v[3].y];
|
|
29394
|
+
for (let i = 1; i <= 3; i++) {
|
|
29395
|
+
for (let j = 0; j <= 3 - i; j++) {
|
|
29396
|
+
x[j] = fma(x[j], u, t * x[j + 1]);
|
|
29397
|
+
y[j] = fma(y[j], u, t * y[j + 1]);
|
|
29398
|
+
}
|
|
29399
|
+
}
|
|
29400
|
+
return { x: x[0], y: y[0] };
|
|
29068
29401
|
}
|
|
29069
29402
|
function dotneatoClosest(spl, pt) {
|
|
29070
29403
|
let besti = 0;
|
|
@@ -29094,7 +29427,7 @@ function dotneatoClosest(spl, pt) {
|
|
|
29094
29427
|
let pt2;
|
|
29095
29428
|
for (; ; ) {
|
|
29096
29429
|
const t = (lo + hi) / 2;
|
|
29097
|
-
pt2 =
|
|
29430
|
+
pt2 = bezier(c, t);
|
|
29098
29431
|
if (Math.abs(dlo2 - dhi2) < 1 || Math.abs(hi - lo) < 1e-5) break;
|
|
29099
29432
|
if (dlo2 < dhi2) {
|
|
29100
29433
|
hi = t;
|
|
@@ -30006,9 +30339,19 @@ var ShortestHelper = class _ShortestHelper {
|
|
|
30006
30339
|
_ShortestHelper.connectAll(tris);
|
|
30007
30340
|
const ftrii = _ShortestHelper.findTri(tris, eps[0]);
|
|
30008
30341
|
const ltrii = _ShortestHelper.findTri(tris, eps[1]);
|
|
30009
|
-
if (ftrii === NO_TRI
|
|
30342
|
+
if (ftrii === NO_TRI) {
|
|
30343
|
+
console.warn("source point not in any triangle");
|
|
30344
|
+
return null;
|
|
30345
|
+
}
|
|
30346
|
+
if (ltrii === NO_TRI) {
|
|
30347
|
+
console.warn("destination point not in any triangle");
|
|
30348
|
+
return null;
|
|
30349
|
+
}
|
|
30010
30350
|
if (ftrii === ltrii) return [eps[0], eps[1]];
|
|
30011
|
-
if (!_ShortestHelper.markPath(tris, ftrii, ltrii))
|
|
30351
|
+
if (!_ShortestHelper.markPath(tris, ftrii, ltrii)) {
|
|
30352
|
+
console.warn("cannot find triangle path");
|
|
30353
|
+
return [eps[0], eps[1]];
|
|
30354
|
+
}
|
|
30012
30355
|
const epnls = [{ pp: eps[0], link: null }, { pp: eps[1], link: null }];
|
|
30013
30356
|
const dq = _ShortestHelper.initDeque(pnlps.length);
|
|
30014
30357
|
_ShortestHelper.add2dq(dq, DQ_FRONT, epnls[0]);
|
|
@@ -31990,7 +32333,7 @@ function nodeCover(n) {
|
|
|
31990
32333
|
for (let i = 0; i < NODECARD; i++) {
|
|
31991
32334
|
if (n.branch[i].child !== null) {
|
|
31992
32335
|
if (flag) {
|
|
31993
|
-
r = n.branch[i].rect;
|
|
32336
|
+
r = { boundary: [...n.branch[i].rect.boundary] };
|
|
31994
32337
|
flag = false;
|
|
31995
32338
|
} else {
|
|
31996
32339
|
r = combineRect(r, n.branch[i].rect);
|
|
@@ -34256,8 +34599,8 @@ function nodeInsideFn2(box) {
|
|
|
34256
34599
|
const pw = box.penwidth ?? DEFAULT_NODEPENWIDTH;
|
|
34257
34600
|
return box.isEllipse ? makeEllipseInsideFn(halfW, halfH, pw) : makeBoxInsideFn(halfW, halfH, pw);
|
|
34258
34601
|
}
|
|
34259
|
-
function clipToNodes(
|
|
34260
|
-
const step1 = clip.tail ? bezierClipNode(
|
|
34602
|
+
function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
|
|
34603
|
+
const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
|
|
34261
34604
|
const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
|
|
34262
34605
|
const arrowTip = step2[3];
|
|
34263
34606
|
const elen = normalArrowLen(penwidth);
|
|
@@ -34271,9 +34614,9 @@ function clipToNodes(bezier, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH,
|
|
|
34271
34614
|
function routeWithRank(tailBox, headBox, rank3, penwidth = DEFAULT_NODEPENWIDTH, port) {
|
|
34272
34615
|
const corridor = port ? { tailP: port.tailP, headP: port.headP } : void 0;
|
|
34273
34616
|
const { startPt, endPt, boxes } = buildRankCorridor(tailBox, headBox, rank3, corridor);
|
|
34274
|
-
const
|
|
34617
|
+
const bezier2 = computeSpline(boxes, startPt, endPt);
|
|
34275
34618
|
const clip = port ? { tail: port.clipTail, head: port.clipHead } : CLIP_BOTH;
|
|
34276
|
-
const { clipped, arrowTip, arrowDir } = clipToNodes(
|
|
34619
|
+
const { clipped, arrowTip, arrowDir } = clipToNodes(bezier2, tailBox, headBox, penwidth, clip);
|
|
34277
34620
|
return { bezierPts: clipped, arrowTip, arrowDir };
|
|
34278
34621
|
}
|
|
34279
34622
|
function routeSimple(tailBox, headBox, routeBezierFn) {
|
|
@@ -36866,24 +37209,27 @@ function buildNodes(nodeArr) {
|
|
|
36866
37209
|
ysize: n.info.ht
|
|
36867
37210
|
}));
|
|
36868
37211
|
}
|
|
37212
|
+
function isConcentrateDup(ps, e) {
|
|
37213
|
+
const ti = e.tail.id;
|
|
37214
|
+
const hi = e.head.id;
|
|
37215
|
+
const lo = ti <= hi ? ti : hi;
|
|
37216
|
+
const up = ti <= hi ? hi : ti;
|
|
37217
|
+
if (ps.isInPS(lo, up)) return true;
|
|
37218
|
+
ps.addPS(lo, up);
|
|
37219
|
+
return false;
|
|
37220
|
+
}
|
|
36869
37221
|
function buildEdges(g, nodeArr, orthoNodes) {
|
|
36870
37222
|
const concentrate = dotRoot(g).info.concentrate ?? false;
|
|
36871
37223
|
const nodeIndex = /* @__PURE__ */ new Map();
|
|
36872
37224
|
nodeArr.forEach((n, i) => nodeIndex.set(n, i));
|
|
36873
37225
|
const outIndex = buildOutEdgeIndex(g);
|
|
36874
|
-
const
|
|
37226
|
+
const ps = concentrate ? new PointSet() : null;
|
|
36875
37227
|
const result = [];
|
|
36876
37228
|
for (const n of nodeArr) {
|
|
36877
37229
|
const oes = outIndex.get(n);
|
|
36878
37230
|
if (oes === void 0) continue;
|
|
36879
37231
|
for (const e of oes) {
|
|
36880
|
-
if (
|
|
36881
|
-
const ti = e.tail.id;
|
|
36882
|
-
const hi = e.head.id;
|
|
36883
|
-
const key = ti <= hi ? `${ti},${hi}` : `${hi},${ti}`;
|
|
36884
|
-
if (seen.has(key)) continue;
|
|
36885
|
-
seen.add(key);
|
|
36886
|
-
}
|
|
37232
|
+
if (ps !== null && isConcentrateDup(ps, e)) continue;
|
|
36887
37233
|
result.push({
|
|
36888
37234
|
tail: orthoNodes[nodeIndex.get(e.tail)],
|
|
36889
37235
|
head: orthoNodes[nodeIndex.get(e.head)],
|
|
@@ -37971,15 +38317,6 @@ function spiralSearch(info, ctx, wide) {
|
|
|
37971
38317
|
|
|
37972
38318
|
// src/layout/pack/poly-pack.ts
|
|
37973
38319
|
var C2 = 100;
|
|
37974
|
-
function psKey(x, y) {
|
|
37975
|
-
return `${cround(x)},${cround(y)}`;
|
|
37976
|
-
}
|
|
37977
|
-
function inPS(ps, p) {
|
|
37978
|
-
return ps.has(psKey(p.x, p.y));
|
|
37979
|
-
}
|
|
37980
|
-
function insertPS(ps, p) {
|
|
37981
|
-
ps.add(psKey(p.x, p.y));
|
|
37982
|
-
}
|
|
37983
38320
|
function computeStep(ng, bbs, margin) {
|
|
37984
38321
|
let b = 0;
|
|
37985
38322
|
let c = 0;
|
|
@@ -38026,14 +38363,14 @@ function genBox2(p) {
|
|
|
38026
38363
|
function hasCollision(cells, dx, dy, ps) {
|
|
38027
38364
|
for (let i = 0; i < cells.length; i++) {
|
|
38028
38365
|
const cell2 = cells[i];
|
|
38029
|
-
if (cell2 !== void 0 && inPS(
|
|
38366
|
+
if (cell2 !== void 0 && ps.inPS({ x: cell2.x + dx, y: cell2.y + dy })) return true;
|
|
38030
38367
|
}
|
|
38031
38368
|
return false;
|
|
38032
38369
|
}
|
|
38033
38370
|
function markCells(cells, dx, dy, ps) {
|
|
38034
38371
|
for (let i = 0; i < cells.length; i++) {
|
|
38035
38372
|
const cell2 = cells[i];
|
|
38036
|
-
if (cell2 !== void 0)
|
|
38373
|
+
if (cell2 !== void 0) ps.addPS(cell2.x + dx, cell2.y + dy);
|
|
38037
38374
|
}
|
|
38038
38375
|
}
|
|
38039
38376
|
function fits(x, y, info, ctx) {
|
|
@@ -38078,7 +38415,7 @@ function polyRects(ng, bbs, pinfo) {
|
|
|
38078
38415
|
infos.push(genBox2({ bb, ssize: step, margin: pinfo.margin, idx: i }));
|
|
38079
38416
|
}
|
|
38080
38417
|
const sorted = gvQsort([...infos], cmpByGPerimeter);
|
|
38081
|
-
const ctx = { ps:
|
|
38418
|
+
const ctx = { ps: new PointSet(), step, bbs };
|
|
38082
38419
|
const places = new Array(ng).fill({ x: 0, y: 0 });
|
|
38083
38420
|
for (let i = 0; i < sorted.length; i++) {
|
|
38084
38421
|
const info = sorted[i];
|
|
@@ -38099,21 +38436,6 @@ function cval2(v, s) {
|
|
|
38099
38436
|
function cell(p, s) {
|
|
38100
38437
|
return { x: cval2(p.x, s), y: cval2(p.y, s) };
|
|
38101
38438
|
}
|
|
38102
|
-
var PointSet = class {
|
|
38103
|
-
m = /* @__PURE__ */ new Map();
|
|
38104
|
-
add(x, y) {
|
|
38105
|
-
this.m.set(`${x},${y}`, { x, y });
|
|
38106
|
-
}
|
|
38107
|
-
has(p) {
|
|
38108
|
-
return this.m.has(`${p.x},${p.y}`);
|
|
38109
|
-
}
|
|
38110
|
-
points() {
|
|
38111
|
-
return [...this.m.values()];
|
|
38112
|
-
}
|
|
38113
|
-
get size() {
|
|
38114
|
-
return this.m.size;
|
|
38115
|
-
}
|
|
38116
|
-
};
|
|
38117
38439
|
function computeStep2(bbs, margin) {
|
|
38118
38440
|
const a = C_AVG * bbs.length - 1;
|
|
38119
38441
|
let b = 0;
|
|
@@ -38131,7 +38453,7 @@ function computeStep2(bbs, margin) {
|
|
|
38131
38453
|
function lineXDominant(st, ps) {
|
|
38132
38454
|
let d = st.ay - (st.ax >> 1);
|
|
38133
38455
|
for (; ; ) {
|
|
38134
|
-
ps.
|
|
38456
|
+
ps.addPS(st.x, st.y);
|
|
38135
38457
|
if (st.x === st.x2) return;
|
|
38136
38458
|
if (d >= 0) {
|
|
38137
38459
|
st.y += st.sy;
|
|
@@ -38144,7 +38466,7 @@ function lineXDominant(st, ps) {
|
|
|
38144
38466
|
function lineYDominant(st, ps) {
|
|
38145
38467
|
let d = st.ax - (st.ay >> 1);
|
|
38146
38468
|
for (; ; ) {
|
|
38147
|
-
ps.
|
|
38469
|
+
ps.addPS(st.x, st.y);
|
|
38148
38470
|
if (st.y === st.y2) return;
|
|
38149
38471
|
if (d >= 0) {
|
|
38150
38472
|
st.x += st.sx;
|
|
@@ -38176,7 +38498,7 @@ function fillLine(p, q, ps) {
|
|
|
38176
38498
|
}
|
|
38177
38499
|
function fillRect(LL, UR, ps) {
|
|
38178
38500
|
for (let x = LL.x; x <= UR.x; x++) {
|
|
38179
|
-
for (let y = LL.y; y <= UR.y; y++) ps.
|
|
38501
|
+
for (let y = LL.y; y <= UR.y; y++) ps.addPS(x, y);
|
|
38180
38502
|
}
|
|
38181
38503
|
}
|
|
38182
38504
|
function roundedCell(p, ssize) {
|
|
@@ -38228,7 +38550,7 @@ function genBox3(bb0, ssize, margin, center) {
|
|
|
38228
38550
|
const UR = roundedCell({ x: center.x + bbW + margin, y: center.y + bbH + margin }, ssize);
|
|
38229
38551
|
fillRect(LL, UR, ps);
|
|
38230
38552
|
return {
|
|
38231
|
-
cells: ps.
|
|
38553
|
+
cells: ps.pointsOf(),
|
|
38232
38554
|
perim: grid(bb0.ur.x - bb0.ll.x + 2 * margin, ssize) + grid(bb0.ur.y - bb0.ll.y + 2 * margin, ssize),
|
|
38233
38555
|
index: 0
|
|
38234
38556
|
};
|
|
@@ -38260,42 +38582,38 @@ function genPoly(root, g, bb, ssize, pinfo, center) {
|
|
|
38260
38582
|
};
|
|
38261
38583
|
for (const n of g.nodes.values()) coverNode(n, ctx);
|
|
38262
38584
|
return {
|
|
38263
|
-
cells: ps.
|
|
38585
|
+
cells: ps.pointsOf(),
|
|
38264
38586
|
perim: grid(bb.ur.x - bb.ll.x + 2 * pinfo.margin, ssize) + grid(bb.ur.y - bb.ll.y + 2 * pinfo.margin, ssize),
|
|
38265
38587
|
index: 0
|
|
38266
38588
|
};
|
|
38267
38589
|
}
|
|
38268
38590
|
function fits2(x, y, info, ctx) {
|
|
38269
38591
|
for (const c of info.cells) {
|
|
38270
|
-
if (ctx.ps.
|
|
38592
|
+
if (ctx.ps.isInPS(c.x + x, c.y + y)) return false;
|
|
38271
38593
|
}
|
|
38272
38594
|
const bb = ctx.bbs[info.index];
|
|
38273
38595
|
const LL = { x: cround(bb.ll.x), y: cround(bb.ll.y) };
|
|
38274
38596
|
ctx.places[info.index] = { x: Math.imul(ctx.step, x) - LL.x, y: Math.imul(ctx.step, y) - LL.y };
|
|
38275
|
-
for (const c of info.cells) ctx.ps.
|
|
38597
|
+
for (const c of info.cells) ctx.ps.addPS(c.x + x, c.y + y);
|
|
38276
38598
|
return true;
|
|
38277
38599
|
}
|
|
38278
|
-
function
|
|
38279
|
-
|
|
38280
|
-
|
|
38281
|
-
|
|
38282
|
-
|
|
38283
|
-
|
|
38284
|
-
|
|
38285
|
-
|
|
38286
|
-
|
|
38287
|
-
|
|
38288
|
-
|
|
38289
|
-
|
|
38290
|
-
|
|
38291
|
-
for (; x < bnd; x++) yield [x, y];
|
|
38292
|
-
for (; y < bnd; y++) yield [x, y];
|
|
38293
|
-
for (; x > -bnd; x--) yield [x, y];
|
|
38294
|
-
for (; y > 0; y--) yield [x, y];
|
|
38600
|
+
function leg(c, dx, dy, end, info, ctx) {
|
|
38601
|
+
for (; (dx !== 0 ? c.x : c.y) !== end; c.x += dx, c.y += dy) {
|
|
38602
|
+
if (fits2(c.x, c.y, info, ctx)) return true;
|
|
38603
|
+
}
|
|
38604
|
+
return false;
|
|
38605
|
+
}
|
|
38606
|
+
function ringWide(bnd, info, ctx) {
|
|
38607
|
+
const c = { x: 0, y: -bnd };
|
|
38608
|
+
return leg(c, 1, 0, bnd, info, ctx) || leg(c, 0, 1, bnd, info, ctx) || leg(c, -1, 0, -bnd, info, ctx) || leg(c, 0, -1, -bnd, info, ctx) || leg(c, 1, 0, 0, info, ctx);
|
|
38609
|
+
}
|
|
38610
|
+
function ringTall(bnd, info, ctx) {
|
|
38611
|
+
const c = { x: -bnd, y: 0 };
|
|
38612
|
+
return leg(c, 0, -1, -bnd, info, ctx) || leg(c, 1, 0, bnd, info, ctx) || leg(c, 0, 1, bnd, info, ctx) || leg(c, -1, 0, -bnd, info, ctx) || leg(c, 0, -1, 0, info, ctx);
|
|
38295
38613
|
}
|
|
38296
38614
|
function placeFixed(info, ctx, center) {
|
|
38297
38615
|
ctx.places[info.index] = { x: -center.x, y: -center.y };
|
|
38298
|
-
for (const c of info.cells) ctx.ps.
|
|
38616
|
+
for (const c of info.cells) ctx.ps.addPS(c.x, c.y);
|
|
38299
38617
|
}
|
|
38300
38618
|
function placeGraph2(i, info, ctx) {
|
|
38301
38619
|
const bb = ctx.bbs[info.index];
|
|
@@ -38307,10 +38625,7 @@ function placeGraph2(i, info, ctx) {
|
|
|
38307
38625
|
if (fits2(0, 0, info, ctx)) return;
|
|
38308
38626
|
const wide = Math.ceil(bb.ur.x - bb.ll.x) >= Math.ceil(bb.ur.y - bb.ll.y);
|
|
38309
38627
|
for (let bnd = 1; ; bnd++) {
|
|
38310
|
-
|
|
38311
|
-
for (const [x, y] of ring) {
|
|
38312
|
-
if (fits2(x, y, info, ctx)) return;
|
|
38313
|
-
}
|
|
38628
|
+
if (wide ? ringWide(bnd, info, ctx) : ringTall(bnd, info, ctx)) return;
|
|
38314
38629
|
}
|
|
38315
38630
|
}
|
|
38316
38631
|
function polyGraphs(gs, root, pinfo, bbs) {
|
|
@@ -41950,6 +42265,12 @@ function chainOf(e) {
|
|
|
41950
42265
|
}
|
|
41951
42266
|
return list;
|
|
41952
42267
|
}
|
|
42268
|
+
function warnNoControlPoints(e) {
|
|
42269
|
+
console.warn(
|
|
42270
|
+
`Warning: Could not create control points for multiple spline for edge (${e.tail.name},${e.head.name})`
|
|
42271
|
+
);
|
|
42272
|
+
return 1;
|
|
42273
|
+
}
|
|
41953
42274
|
function genroute(g, trip, t, e, doPolyline) {
|
|
41954
42275
|
const eps = [
|
|
41955
42276
|
{ x: trip.ps[0].x, y: trip.ps[0].y },
|
|
@@ -41959,7 +42280,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41959
42280
|
const mult = e.info.count ?? 1;
|
|
41960
42281
|
const head = e.head;
|
|
41961
42282
|
const pl = shortestPath({ ps: trip.ps }, eps);
|
|
41962
|
-
if (pl === null) return
|
|
42283
|
+
if (pl === null) return warnNoControlPoints(e);
|
|
41963
42284
|
if (pl.length === 2) {
|
|
41964
42285
|
const chain = chainOf(e);
|
|
41965
42286
|
makeStraightEdges(g, chain, chain.length, doPolyline ? 1 : 0, MSINFO);
|
|
@@ -41967,7 +42288,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41967
42288
|
}
|
|
41968
42289
|
if (mult === 1 || concentrate) {
|
|
41969
42290
|
const spl = routeMember(trip.ps, t, pl, doPolyline);
|
|
41970
|
-
if (spl === null) return
|
|
42291
|
+
if (spl === null) return warnNoControlPoints(e);
|
|
41971
42292
|
finishEdge(e, spl, e.head !== head);
|
|
41972
42293
|
return 0;
|
|
41973
42294
|
}
|
|
@@ -41975,7 +42296,7 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41975
42296
|
const cpts = [];
|
|
41976
42297
|
for (let i = 0; i + 2 < pl.length; i++) {
|
|
41977
42298
|
const cp = mkCtrlPts(t, mult + 1, pl[i], pl[i + 1], pl[i + 2], trip);
|
|
41978
|
-
if (cp === null) return
|
|
42299
|
+
if (cp === null) return warnNoControlPoints(e);
|
|
41979
42300
|
cpts.push(cp);
|
|
41980
42301
|
}
|
|
41981
42302
|
let cur = e;
|
|
@@ -41990,9 +42311,9 @@ function genroute(g, trip, t, e, doPolyline) {
|
|
|
41990
42311
|
poly[pn - j] = cpts[j - 1][i + 1];
|
|
41991
42312
|
}
|
|
41992
42313
|
const mmpl = shortestPath({ ps: poly }, eps);
|
|
41993
|
-
if (mmpl === null) return
|
|
42314
|
+
if (mmpl === null) return warnNoControlPoints(cur);
|
|
41994
42315
|
const spl = routeMember(poly, pl.length - 1, mmpl, doPolyline);
|
|
41995
|
-
if (spl === null) return
|
|
42316
|
+
if (spl === null) return warnNoControlPoints(cur);
|
|
41996
42317
|
finishEdge(cur, spl, cur.head !== head);
|
|
41997
42318
|
cur = cur.info.to_virt;
|
|
41998
42319
|
}
|
|
@@ -51216,22 +51537,22 @@ function freeBlocktree(bp) {
|
|
|
51216
51537
|
|
|
51217
51538
|
// src/layout/circo/position-helpers.ts
|
|
51218
51539
|
function rotatePoint(x, y, cosR, sinR) {
|
|
51219
|
-
return [x
|
|
51540
|
+
return [fma(x, cosR, -sinR * y), fma(x, sinR, cosR * y)];
|
|
51220
51541
|
}
|
|
51221
51542
|
function nodePsi(n) {
|
|
51222
51543
|
return n.info.alg?.psi ?? 0;
|
|
51223
51544
|
}
|
|
51224
51545
|
function rotFromParentPos(sn, theta) {
|
|
51225
|
-
let r = theta + Math.PI - sn.parentPos;
|
|
51546
|
+
let r = theta + (Math.PI - sn.parentPos);
|
|
51226
51547
|
if (r < 0) r += 2 * Math.PI;
|
|
51227
51548
|
return r;
|
|
51228
51549
|
}
|
|
51229
51550
|
function closestNode(sn, x, y, skip) {
|
|
51230
51551
|
let best = skip;
|
|
51231
|
-
let bestDist =
|
|
51552
|
+
let bestDist = libmHypot(skip.info.pos[0] + x, skip.info.pos[1] + y);
|
|
51232
51553
|
for (const dn of sn.subGraph.nodes) {
|
|
51233
51554
|
if (dn.orig === skip) continue;
|
|
51234
|
-
const d =
|
|
51555
|
+
const d = libmHypot(dn.orig.info.pos[0] + x, dn.orig.info.pos[1] + y);
|
|
51235
51556
|
if (d < bestDist) {
|
|
51236
51557
|
bestDist = d;
|
|
51237
51558
|
best = dn.orig;
|
|
@@ -51244,22 +51565,19 @@ function rotCoalesced(sn, x, y, nbr, theta) {
|
|
|
51244
51565
|
const r = sn.radius - rho;
|
|
51245
51566
|
const nx = nbr.info.pos[0];
|
|
51246
51567
|
const ny = nbr.info.pos[1];
|
|
51247
|
-
|
|
51248
|
-
const phi2 = Math.atan2(ny, nx);
|
|
51249
|
-
return theta + Math.PI - phi2 - nodePsi(nbr);
|
|
51250
|
-
}
|
|
51251
|
-
const R2 = Math.hypot(x, y);
|
|
51568
|
+
const R2 = libmHypot(x, y);
|
|
51252
51569
|
const phi = Math.atan2(ny, nx + r);
|
|
51253
51570
|
const l = r - rho / Math.cos(phi);
|
|
51254
|
-
return theta + Math.PI / 2 - phi - Math.asin(l / R2 * Math.cos(phi));
|
|
51571
|
+
return theta + (Math.PI / 2 - phi - Math.asin(l / R2 * Math.cos(phi)));
|
|
51255
51572
|
}
|
|
51256
51573
|
function rotGeneral(sn, x, y, nbr, theta) {
|
|
51257
51574
|
if (closestNode(sn, x, y, nbr) === nbr) return 0;
|
|
51258
|
-
|
|
51575
|
+
const r = sn.radius - sn.rad0;
|
|
51576
|
+
if (isCoalesced(sn) && -r < nbr.info.pos[0]) return rotCoalesced(sn, x, y, nbr, theta);
|
|
51259
51577
|
const phi = Math.atan2(nbr.info.pos[1], nbr.info.pos[0]);
|
|
51260
|
-
let
|
|
51261
|
-
if (
|
|
51262
|
-
return
|
|
51578
|
+
let t = theta + (Math.PI - phi - nodePsi(nbr));
|
|
51579
|
+
if (t > 2 * Math.PI) t -= 2 * Math.PI;
|
|
51580
|
+
return t;
|
|
51263
51581
|
}
|
|
51264
51582
|
function applyDelta(sn, x, y, rotate) {
|
|
51265
51583
|
const cosR = Math.cos(rotate);
|
|
@@ -51302,7 +51620,7 @@ function getInfo(pi, stp, minDist) {
|
|
|
51302
51620
|
}
|
|
51303
51621
|
function setInfo(p0, p1, delta2) {
|
|
51304
51622
|
const t = Math.max(
|
|
51305
|
-
(p0.diameter
|
|
51623
|
+
fma(p0.diameter, p1.minRadius, p1.diameter * p0.minRadius) / (2 * delta2 * p0.minRadius * p1.minRadius),
|
|
51306
51624
|
1
|
|
51307
51625
|
);
|
|
51308
51626
|
p0.scale = Math.max(p0.scale, t);
|
|
@@ -51312,7 +51630,13 @@ function placeChild(child, ca, ctx) {
|
|
|
51312
51630
|
const dx = ctx.childRadius * Math.cos(ca);
|
|
51313
51631
|
const dy = ctx.childRadius * Math.sin(ca);
|
|
51314
51632
|
applyDelta(child, dx, dy, getRotation(child, dx, dy, ca));
|
|
51315
|
-
return
|
|
51633
|
+
return nextChildAngle(ca, ctx.incAngle, ctx.mindistAngle, ctx.length);
|
|
51634
|
+
}
|
|
51635
|
+
function nextChildAngle(ca, inc2, mda, length) {
|
|
51636
|
+
return length === 1 ? ca + (inc2 + mda) : ca + (inc2 + mda / 2);
|
|
51637
|
+
}
|
|
51638
|
+
function leftoverArc(childRadius, diameter) {
|
|
51639
|
+
return fma(2 * Math.PI, childRadius, -diameter);
|
|
51316
51640
|
}
|
|
51317
51641
|
function advanceAngleL1(ca, inc2, total, cnt, stp) {
|
|
51318
51642
|
const next = cnt === 0 ? 0 : total === 2 ? Math.PI : ca + inc2;
|
|
@@ -51322,7 +51646,7 @@ function advanceAngleL1(ca, inc2, total, cnt, stp) {
|
|
|
51322
51646
|
}
|
|
51323
51647
|
function advanceAngleLN(ca, inc2, mda, total, theta) {
|
|
51324
51648
|
if (total === 1) return theta;
|
|
51325
|
-
return ca + inc2 + mda / 2;
|
|
51649
|
+
return ca + (inc2 + mda / 2);
|
|
51326
51650
|
}
|
|
51327
51651
|
function maybeWritePsi(n, stp, ca, isMid) {
|
|
51328
51652
|
if (isMid && n === stp.neighbor) {
|
|
@@ -51337,7 +51661,7 @@ function positionChildren(pi, stp, length, minDist) {
|
|
|
51337
51661
|
let md = minDist;
|
|
51338
51662
|
if (length === 1) {
|
|
51339
51663
|
cr = Math.max(cr, pi.diameter / (2 * Math.PI));
|
|
51340
|
-
const d =
|
|
51664
|
+
const d = leftoverArc(cr, pi.diameter);
|
|
51341
51665
|
if (d > 0) md += d / pi.childCount;
|
|
51342
51666
|
}
|
|
51343
51667
|
stp.subtreeR = Math.max(stp.subtreeR, cr + pi.maxRadius);
|