@knowvah/dot-engine 1.2.3 → 1.2.4
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/cdt/bag.d.ts +6 -4
- package/dist/cdt/bag.d.ts.map +1 -1
- package/dist/common/htmltable-lex.d.ts.map +1 -1
- package/dist/common/record.d.ts.map +1 -1
- package/dist/index.js +1986 -2006
- package/dist/index.js.map +4 -4
- package/dist/render.js +41 -61
- package/dist/render.js.map +3 -3
- package/dist/xdot/parse.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/cdt/bag.ts +30 -52
- package/src/common/htmltable-lex.ts +17 -4
- package/src/common/htmltable-parse.ts +1 -1
- package/src/common/record.ts +3 -5
- package/src/xdot/parse.ts +3 -1
- package/dist/gvc/textlayout.d.ts +0 -33
- package/dist/gvc/textlayout.d.ts.map +0 -1
- package/dist/layout/osage/layout.d.ts +0 -49
- package/dist/layout/osage/layout.d.ts.map +0 -1
- package/dist/layout/pack/test-helpers.d.ts +0 -7
- package/dist/layout/pack/test-helpers.d.ts.map +0 -1
- package/dist/layout/patchwork/tree-node.d.ts +0 -46
- package/dist/layout/patchwork/tree-node.d.ts.map +0 -1
- package/dist/xdot/lex.d.ts +0 -22
- package/dist/xdot/lex.d.ts.map +0 -1
- package/src/gvc/textlayout.ts +0 -44
- package/src/layout/osage/layout.ts +0 -254
- package/src/layout/pack/test-helpers.ts +0 -46
- package/src/layout/patchwork/tree-node.ts +0 -120
- package/src/xdot/lex.ts +0 -151
package/dist/index.js
CHANGED
|
@@ -10105,12 +10105,15 @@ function parseAttrs(raw) {
|
|
|
10105
10105
|
}
|
|
10106
10106
|
return out;
|
|
10107
10107
|
}
|
|
10108
|
+
function normalizeTag(tag) {
|
|
10109
|
+
return tag === "TH" ? "TR" : tag;
|
|
10110
|
+
}
|
|
10108
10111
|
function parseCloseToken(inner) {
|
|
10109
10112
|
const body = inner.slice(1).trim();
|
|
10110
10113
|
const sp = body.search(/\s/);
|
|
10111
10114
|
const tag = (sp === -1 ? body : body.slice(0, sp)).toUpperCase();
|
|
10112
10115
|
checkTag(tag);
|
|
10113
|
-
return { type: "close", tag };
|
|
10116
|
+
return { type: "close", tag: normalizeTag(tag) };
|
|
10114
10117
|
}
|
|
10115
10118
|
function cleanText(raw) {
|
|
10116
10119
|
const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
@@ -10144,12 +10147,13 @@ function scanTag(src, start, tokens) {
|
|
|
10144
10147
|
function parseOpenToken(inner) {
|
|
10145
10148
|
const sp = inner.search(/\s/);
|
|
10146
10149
|
if (sp === -1) {
|
|
10147
|
-
|
|
10148
|
-
|
|
10150
|
+
const tag2 = inner.toUpperCase();
|
|
10151
|
+
checkTag(tag2);
|
|
10152
|
+
return { type: "open", tag: normalizeTag(tag2), attrs: parseAttrs("") };
|
|
10149
10153
|
}
|
|
10150
10154
|
const tag = inner.slice(0, sp).toUpperCase();
|
|
10151
10155
|
checkTag(tag);
|
|
10152
|
-
return { type: "open", tag, attrs: parseAttrs(inner.slice(sp + 1)) };
|
|
10156
|
+
return { type: "open", tag: normalizeTag(tag), attrs: parseAttrs(inner.slice(sp + 1)) };
|
|
10153
10157
|
}
|
|
10154
10158
|
function tokenize(src) {
|
|
10155
10159
|
const tokens = [];
|
|
@@ -10374,7 +10378,7 @@ var buildCell = (content, a) => ({
|
|
|
10374
10378
|
});
|
|
10375
10379
|
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, attrs, fontStack), attrs);
|
|
10376
10380
|
var processRowToken = (s, t, cells, fontStack) => {
|
|
10377
|
-
if (t.type === "open" &&
|
|
10381
|
+
if (t.type === "open" && t.tag === "TD") {
|
|
10378
10382
|
consume(s);
|
|
10379
10383
|
cells.push(parseCell(s, t.attrs, fontStack));
|
|
10380
10384
|
return;
|
|
@@ -16880,1504 +16884,241 @@ function assembleResult(p, dimen, grown, fixedshape) {
|
|
|
16880
16884
|
};
|
|
16881
16885
|
}
|
|
16882
16886
|
|
|
16883
|
-
// src/
|
|
16884
|
-
var
|
|
16885
|
-
var
|
|
16886
|
-
var
|
|
16887
|
-
var
|
|
16888
|
-
var
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
var TOP2 = 4;
|
|
16892
|
-
var LEFT2 = 8;
|
|
16893
|
-
var PAD_X = 16;
|
|
16894
|
-
var PAD_Y = 8;
|
|
16895
|
-
function makeField() {
|
|
16896
|
-
return {
|
|
16897
|
-
size: { x: 0, y: 0 },
|
|
16898
|
-
b: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } },
|
|
16899
|
-
n_flds: 0,
|
|
16900
|
-
lp: null,
|
|
16901
|
-
fld: null,
|
|
16902
|
-
id: null,
|
|
16903
|
-
LR: 0,
|
|
16904
|
-
sides: 0
|
|
16905
|
-
};
|
|
16887
|
+
// src/layout/dot/fastgr.ts
|
|
16888
|
+
var VIRTUAL = 1;
|
|
16889
|
+
var NORMAL = 0;
|
|
16890
|
+
var FLATORDER = 4;
|
|
16891
|
+
var REVERSED = 3;
|
|
16892
|
+
var MC_SCALE = 256;
|
|
16893
|
+
function elistAppend(el, e) {
|
|
16894
|
+
el.list[el.size++] = e;
|
|
16906
16895
|
}
|
|
16907
|
-
function
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16896
|
+
function zapinlist(el, e) {
|
|
16897
|
+
let i = 0;
|
|
16898
|
+
while (i < el.size && el.list[i] !== e) i++;
|
|
16899
|
+
if (i < el.size) {
|
|
16900
|
+
el.list[i] = el.list[--el.size];
|
|
16901
|
+
el.list[el.size] = void 0;
|
|
16902
|
+
}
|
|
16911
16903
|
}
|
|
16912
|
-
function
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
|
|
16917
|
-
|
|
16918
|
-
|
|
16904
|
+
function deleteFastEdge(e) {
|
|
16905
|
+
if (e.tail.info.out) zapinlist(e.tail.info.out, e);
|
|
16906
|
+
if (e.head.info.in) zapinlist(e.head.info.in, e);
|
|
16907
|
+
}
|
|
16908
|
+
function fastEdge(e) {
|
|
16909
|
+
if (!e.tail.info.out) e.tail.info.out = { list: [], size: 0 };
|
|
16910
|
+
if (!e.head.info.in) e.head.info.in = { list: [], size: 0 };
|
|
16911
|
+
elistAppend(e.tail.info.out, e);
|
|
16912
|
+
elistAppend(e.head.info.in, e);
|
|
16913
|
+
}
|
|
16914
|
+
function findFastEdge(u, v) {
|
|
16915
|
+
const uOut = u.info.out;
|
|
16916
|
+
const vIn = v.info.in;
|
|
16917
|
+
if (uOut === void 0 || vIn === void 0) return void 0;
|
|
16918
|
+
if (uOut.size <= vIn.size) {
|
|
16919
|
+
for (let i = 0; i < uOut.size; i++) {
|
|
16920
|
+
if (uOut.list[i].head === v) return uOut.list[i];
|
|
16921
|
+
}
|
|
16922
|
+
} else {
|
|
16923
|
+
for (let i = 0; i < vIn.size; i++) {
|
|
16924
|
+
if (vIn.list[i].tail === u) return vIn.list[i];
|
|
16919
16925
|
}
|
|
16920
|
-
const c = p.s[j];
|
|
16921
|
-
if (c === "{") cnt++;
|
|
16922
|
-
else if (c === "}") cnt--;
|
|
16923
|
-
else if (c === "|" && cnt === 0) maxf++;
|
|
16924
|
-
if (cnt < 0) break;
|
|
16925
16926
|
}
|
|
16926
|
-
return
|
|
16927
|
+
return void 0;
|
|
16927
16928
|
}
|
|
16928
|
-
function
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
p.i++;
|
|
16932
|
-
st.pbuf = [];
|
|
16933
|
-
st.hspIdx = 0;
|
|
16934
|
-
return 0;
|
|
16929
|
+
function copyPort(p) {
|
|
16930
|
+
const bp = p.bp !== null ? { ll: { x: p.bp.ll.x, y: p.bp.ll.y }, ur: { x: p.bp.ur.x, y: p.bp.ur.y } } : null;
|
|
16931
|
+
return { p: { x: p.p.x, y: p.p.y }, theta: p.theta, bp, defined: p.defined, constrained: p.constrained, clip: p.clip, dyna: p.dyna, order: p.order, side: p.side, name: p.name };
|
|
16935
16932
|
}
|
|
16936
|
-
function
|
|
16937
|
-
if (
|
|
16938
|
-
|
|
16939
|
-
if (
|
|
16940
|
-
|
|
16941
|
-
st.mode &= ~INPORT;
|
|
16942
|
-
p.i++;
|
|
16943
|
-
return 0;
|
|
16933
|
+
function copyVirtualPorts(e, orig) {
|
|
16934
|
+
if (e.tail === orig.tail) e.info.tail_port = copyPort(orig.info.tail_port);
|
|
16935
|
+
else if (e.tail === orig.head) e.info.tail_port = copyPort(orig.info.head_port);
|
|
16936
|
+
if (e.head === orig.head) e.info.head_port = copyPort(orig.info.head_port);
|
|
16937
|
+
else if (e.head === orig.tail) e.info.head_port = copyPort(orig.info.tail_port);
|
|
16944
16938
|
}
|
|
16945
|
-
function
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16939
|
+
function copyVirtualEdgeInfo(e, orig) {
|
|
16940
|
+
e.info.count = orig.info.count;
|
|
16941
|
+
e.info.xpenalty = orig.info.xpenalty;
|
|
16942
|
+
e.info.weight = orig.info.weight;
|
|
16943
|
+
e.info.minlen = orig.info.minlen;
|
|
16944
|
+
copyVirtualPorts(e, orig);
|
|
16945
|
+
e.info.label = orig.info.label;
|
|
16946
|
+
e.info.head_label = orig.info.head_label;
|
|
16947
|
+
e.info.tail_label = orig.info.tail_label;
|
|
16948
|
+
e.info.xlabel = orig.info.xlabel;
|
|
16949
|
+
if (orig.info.to_virt === void 0) orig.info.to_virt = e;
|
|
16950
|
+
e.info.to_orig = orig;
|
|
16951
|
+
e.seq = orig.seq;
|
|
16954
16952
|
}
|
|
16955
|
-
function
|
|
16956
|
-
|
|
16957
|
-
|
|
16958
|
-
|
|
16959
|
-
|
|
16960
|
-
|
|
16961
|
-
|
|
16962
|
-
|
|
16963
|
-
|
|
16964
|
-
|
|
16965
|
-
false,
|
|
16966
|
-
{ fontname: p.lbl.fontname, fontsize: p.lbl.fontsize, fontcolor: p.lbl.fontcolor },
|
|
16967
|
-
p.measurer,
|
|
16968
|
-
p.obj
|
|
16969
|
-
);
|
|
16970
|
-
st.fp.LR = 1;
|
|
16971
|
-
st.tbuf = [];
|
|
16972
|
-
st.hstIdx = 0;
|
|
16953
|
+
function newVirtualEdge(u, v, orig) {
|
|
16954
|
+
const e = new Edge(u, v, "");
|
|
16955
|
+
e.info.edge_type = VIRTUAL;
|
|
16956
|
+
if (orig) {
|
|
16957
|
+
copyVirtualEdgeInfo(e, orig);
|
|
16958
|
+
} else {
|
|
16959
|
+
e.info.weight = 1;
|
|
16960
|
+
e.info.xpenalty = 1;
|
|
16961
|
+
e.info.count = 1;
|
|
16962
|
+
e.info.minlen = 1;
|
|
16973
16963
|
}
|
|
16964
|
+
return e;
|
|
16974
16965
|
}
|
|
16975
|
-
function
|
|
16976
|
-
const
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
st.fp = makeField();
|
|
16980
|
-
st.rv.fld[st.fi++] = st.fp;
|
|
16981
|
-
}
|
|
16982
|
-
if (st.tmpport !== null) {
|
|
16983
|
-
st.fp.id = st.tmpport;
|
|
16984
|
-
st.tmpport = null;
|
|
16985
|
-
}
|
|
16986
|
-
recFlushText(p, st);
|
|
16987
|
-
if (c !== "") {
|
|
16988
|
-
if (c === "}") {
|
|
16989
|
-
p.i++;
|
|
16990
|
-
st.rv.n_flds = st.fi;
|
|
16991
|
-
return 1;
|
|
16992
|
-
}
|
|
16993
|
-
st.mode = 0;
|
|
16994
|
-
p.i++;
|
|
16995
|
-
return 0;
|
|
16996
|
-
}
|
|
16997
|
-
st.rv.n_flds = st.fi;
|
|
16998
|
-
return 1;
|
|
16966
|
+
function virtualEdge(u, v, orig) {
|
|
16967
|
+
const e = newVirtualEdge(u, v, orig);
|
|
16968
|
+
fastEdge(e);
|
|
16969
|
+
return e;
|
|
16999
16970
|
}
|
|
17000
|
-
function
|
|
17001
|
-
|
|
17002
|
-
|
|
17003
|
-
|
|
17004
|
-
|
|
17005
|
-
st.ishardspace = true;
|
|
17006
|
-
} else {
|
|
17007
|
-
st.tbuf.push("\\");
|
|
17008
|
-
st.mode |= INTEXT | HASTEXT;
|
|
17009
|
-
}
|
|
17010
|
-
p.i++;
|
|
17011
|
-
}
|
|
16971
|
+
function mergeWeightsInto(f, ew, em, ex) {
|
|
16972
|
+
f.info.weight = (f.info.weight ?? 0) + ew;
|
|
16973
|
+
f.info.minlen = Math.max(f.info.minlen ?? 1, em);
|
|
16974
|
+
f.info.count = (f.info.count ?? 1) + 1;
|
|
16975
|
+
f.info.xpenalty = (f.info.xpenalty ?? 0) + ex;
|
|
17012
16976
|
}
|
|
17013
|
-
function
|
|
17014
|
-
const
|
|
17015
|
-
|
|
17016
|
-
|
|
16977
|
+
function basicMerge(e, rep) {
|
|
16978
|
+
const ew = e.info.weight ?? 1;
|
|
16979
|
+
const em = e.info.minlen ?? 1;
|
|
16980
|
+
const ex = e.info.xpenalty ?? 0;
|
|
16981
|
+
for (let f = rep; f !== void 0; f = f.info.to_virt) {
|
|
16982
|
+
mergeWeightsInto(f, ew, em, ex);
|
|
16983
|
+
}
|
|
17017
16984
|
}
|
|
17018
|
-
function
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
|
|
16985
|
+
function mergeOneway(e, rep) {
|
|
16986
|
+
if (e.info.to_virt !== void 0) return;
|
|
16987
|
+
e.info.to_virt = rep;
|
|
16988
|
+
basicMerge(e, rep);
|
|
17022
16989
|
}
|
|
17023
|
-
function
|
|
17024
|
-
|
|
17025
|
-
if (
|
|
17026
|
-
if (
|
|
17027
|
-
else if (st.mode & INPORT) recPushPort(st, c);
|
|
17028
|
-
p.i++;
|
|
17029
|
-
return 0;
|
|
16990
|
+
function deleteFlatEdge(e) {
|
|
16991
|
+
e.info.to_virt = void 0;
|
|
16992
|
+
if (e.tail.info.flat_out) zapinlist(e.tail.info.flat_out, e);
|
|
16993
|
+
if (e.head.info.flat_in) zapinlist(e.head.info.flat_in, e);
|
|
17030
16994
|
}
|
|
17031
|
-
function
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
|
|
17037
|
-
case ">":
|
|
17038
|
-
if (p.lbl.html) return recTextChar(p, st, c);
|
|
17039
|
-
return recClosePort(p, st);
|
|
17040
|
-
case "{":
|
|
17041
|
-
return recOpenTable(p, st, LR);
|
|
17042
|
-
case "}":
|
|
17043
|
-
case "|":
|
|
17044
|
-
case void 0:
|
|
17045
|
-
return recEndField(p, st, flag);
|
|
17046
|
-
case "\\":
|
|
17047
|
-
recBackslash(p, st);
|
|
17048
|
-
return recTextChar(p, st, p.s[p.i]);
|
|
17049
|
-
default:
|
|
17050
|
-
return recTextChar(p, st, c);
|
|
17051
|
-
}
|
|
16995
|
+
function flatEdge(g, e) {
|
|
16996
|
+
if (!e.tail.info.flat_out) e.tail.info.flat_out = { list: [], size: 0 };
|
|
16997
|
+
if (!e.head.info.flat_in) e.head.info.flat_in = { list: [], size: 0 };
|
|
16998
|
+
elistAppend(e.tail.info.flat_out, e);
|
|
16999
|
+
elistAppend(e.head.info.flat_in, e);
|
|
17000
|
+
g.info.has_flat_edges = true;
|
|
17052
17001
|
}
|
|
17053
|
-
function
|
|
17054
|
-
const
|
|
17055
|
-
|
|
17056
|
-
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
mode: 0,
|
|
17061
|
-
tbuf: [],
|
|
17062
|
-
hstIdx: 0,
|
|
17063
|
-
pbuf: [],
|
|
17064
|
-
hspIdx: 0,
|
|
17065
|
-
tmpport: null,
|
|
17066
|
-
ishardspace: false,
|
|
17067
|
-
fp: null
|
|
17068
|
-
};
|
|
17069
|
-
for (; ; ) {
|
|
17070
|
-
if (p.i < p.s.length && p.s[p.i] < " " && p.s[p.i] !== "") {
|
|
17071
|
-
p.i++;
|
|
17072
|
-
continue;
|
|
17002
|
+
function findFlatEdge(u, v) {
|
|
17003
|
+
const uOut = u.info.flat_out;
|
|
17004
|
+
const vIn = v.info.flat_in;
|
|
17005
|
+
if (uOut === void 0 || vIn === void 0) return void 0;
|
|
17006
|
+
if (uOut.size <= vIn.size) {
|
|
17007
|
+
for (let i = 0; i < uOut.size; i++) {
|
|
17008
|
+
if (uOut.list[i].head === v) return uOut.list[i];
|
|
17073
17009
|
}
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
if (p.i > p.s.length) break;
|
|
17078
|
-
}
|
|
17079
|
-
rv.n_flds = st.fi;
|
|
17080
|
-
return rv;
|
|
17081
|
-
}
|
|
17082
|
-
function recLabelDimen(n, g, f) {
|
|
17083
|
-
const dimen = { x: f.lp.dimen.x, y: f.lp.dimen.y };
|
|
17084
|
-
if (dimen.x > 0 || dimen.y > 0) {
|
|
17085
|
-
const m = nodeAttr(n, g, "margin");
|
|
17086
|
-
const parts = m !== void 0 ? m.split(",").map(parseFloat) : [];
|
|
17087
|
-
if (parts.length > 0 && !Number.isNaN(parts[0])) {
|
|
17088
|
-
dimen.x += 2 * parts[0] * 72;
|
|
17089
|
-
dimen.y += 2 * (parts.length > 1 && !Number.isNaN(parts[1]) ? parts[1] : parts[0]) * 72;
|
|
17090
|
-
} else {
|
|
17091
|
-
dimen.x += PAD_X;
|
|
17092
|
-
dimen.y += PAD_Y;
|
|
17010
|
+
} else {
|
|
17011
|
+
for (let i = 0; i < vIn.size; i++) {
|
|
17012
|
+
if (vIn.list[i].tail === u) return vIn.list[i];
|
|
17093
17013
|
}
|
|
17094
17014
|
}
|
|
17095
|
-
return
|
|
17015
|
+
return void 0;
|
|
17096
17016
|
}
|
|
17097
|
-
function
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17017
|
+
function reverseEdge(e) {
|
|
17018
|
+
deleteFastEdge(e);
|
|
17019
|
+
e.info.reversed = true;
|
|
17020
|
+
const f = findFastEdge(e.head, e.tail);
|
|
17021
|
+
if (f !== void 0) {
|
|
17022
|
+
mergeOneway(e, f);
|
|
17101
17023
|
} else {
|
|
17102
|
-
|
|
17103
|
-
for (let i = 0; i < f.n_flds; i++) {
|
|
17104
|
-
const d0 = sizeReclbl(n, g, f.fld[i]);
|
|
17105
|
-
if (f.LR) {
|
|
17106
|
-
d.x += d0.x;
|
|
17107
|
-
d.y = Math.max(d.y, d0.y);
|
|
17108
|
-
} else {
|
|
17109
|
-
d.y += d0.y;
|
|
17110
|
-
d.x = Math.max(d.x, d0.x);
|
|
17111
|
-
}
|
|
17112
|
-
}
|
|
17024
|
+
virtualEdge(e.head, e.tail, e);
|
|
17113
17025
|
}
|
|
17114
|
-
f.size = d;
|
|
17115
|
-
return d;
|
|
17116
17026
|
}
|
|
17117
|
-
function
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
|
|
17122
|
-
f.lp.space.y += d.y;
|
|
17123
|
-
}
|
|
17124
|
-
if (f.n_flds) {
|
|
17125
|
-
const inc2 = f.LR ? d.x / f.n_flds : d.y / f.n_flds;
|
|
17126
|
-
for (let i = 0; i < f.n_flds; i++) {
|
|
17127
|
-
const sf = f.fld[i];
|
|
17128
|
-
const amt = Math.trunc((i + 1) * inc2) - Math.trunc(i * inc2);
|
|
17129
|
-
const newsz = f.LR ? { x: sf.size.x + amt, y: sz.y } : { x: sz.x, y: sf.size.y + amt };
|
|
17130
|
-
resizeReclbl(sf, newsz, nojustify);
|
|
17131
|
-
}
|
|
17132
|
-
}
|
|
17027
|
+
function fastNode(g, n) {
|
|
17028
|
+
n.info.next = g.info.nlist;
|
|
17029
|
+
if (g.info.nlist !== void 0) g.info.nlist.info.prev = n;
|
|
17030
|
+
n.info.prev = void 0;
|
|
17031
|
+
g.info.nlist = n;
|
|
17133
17032
|
}
|
|
17134
|
-
function
|
|
17135
|
-
if (
|
|
17136
|
-
|
|
17137
|
-
|
|
17138
|
-
}
|
|
17139
|
-
if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
|
|
17140
|
-
return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
|
|
17033
|
+
function deleteFastNode(g, n) {
|
|
17034
|
+
if (n.info.prev !== void 0) n.info.prev.info.next = n.info.next;
|
|
17035
|
+
else g.info.nlist = n.info.next;
|
|
17036
|
+
if (n.info.next !== void 0) n.info.next.info.prev = n.info.prev;
|
|
17141
17037
|
}
|
|
17142
|
-
function
|
|
17143
|
-
|
|
17144
|
-
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17152
|
-
|
|
17153
|
-
|
|
17154
|
-
|
|
17038
|
+
function removeFromRank(g, n) {
|
|
17039
|
+
const r = n.info.rank !== void 0 ? n.info.rank : 0;
|
|
17040
|
+
const rank3 = g.info.rank;
|
|
17041
|
+
if (rank3 === void 0) return;
|
|
17042
|
+
const rk = rank3[r];
|
|
17043
|
+
for (let j = 0; j < rk.n; j++) {
|
|
17044
|
+
const v = rk.v[j];
|
|
17045
|
+
if (v === n) {
|
|
17046
|
+
for (j++; j < rk.n; j++) {
|
|
17047
|
+
rk.v[j - 1] = rk.v[j];
|
|
17048
|
+
}
|
|
17049
|
+
rk.n--;
|
|
17050
|
+
break;
|
|
17051
|
+
}
|
|
17155
17052
|
}
|
|
17156
17053
|
}
|
|
17157
|
-
function
|
|
17158
|
-
const
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17054
|
+
function virtualNode(g) {
|
|
17055
|
+
const n = new Node(0, "", g.root);
|
|
17056
|
+
n.info.node_type = VIRTUAL;
|
|
17057
|
+
n.info.lw = 1;
|
|
17058
|
+
n.info.rw = 1;
|
|
17059
|
+
n.info.ht = 1;
|
|
17060
|
+
n.info.UF_size = 1;
|
|
17061
|
+
n.info.in = { list: [], size: 0 };
|
|
17062
|
+
n.info.out = { list: [], size: 0 };
|
|
17063
|
+
fastNode(g, n);
|
|
17064
|
+
return n;
|
|
17162
17065
|
}
|
|
17163
|
-
function
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
return {
|
|
17167
|
-
x: (w !== void 0 ? parseFloat(w) : 0.75) * 72,
|
|
17168
|
-
y: (h !== void 0 ? parseFloat(h) : 0.5) * 72
|
|
17169
|
-
};
|
|
17066
|
+
function otherEdge(e) {
|
|
17067
|
+
if (!e.tail.info.other) e.tail.info.other = { list: [], size: 0 };
|
|
17068
|
+
elistAppend(e.tail.info.other, e);
|
|
17170
17069
|
}
|
|
17171
|
-
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
const
|
|
17176
|
-
return
|
|
17070
|
+
|
|
17071
|
+
// src/common/splines-geom.ts
|
|
17072
|
+
function approxEqPt(p, q, tol) {
|
|
17073
|
+
const dx = p.x - q.x;
|
|
17074
|
+
const dy = p.y - q.y;
|
|
17075
|
+
return dx * dx + dy * dy < tol * tol;
|
|
17177
17076
|
}
|
|
17178
|
-
function
|
|
17179
|
-
const
|
|
17180
|
-
const
|
|
17181
|
-
const
|
|
17182
|
-
|
|
17183
|
-
const
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17077
|
+
function evalBezier(sp, t, left, right) {
|
|
17078
|
+
const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
|
|
17079
|
+
const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
|
|
17080
|
+
const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
|
|
17081
|
+
const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
|
|
17082
|
+
const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
|
|
17083
|
+
const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
|
|
17084
|
+
if (left !== null) {
|
|
17085
|
+
left[0] = sp[0];
|
|
17086
|
+
left[1] = ab;
|
|
17087
|
+
left[2] = abbc;
|
|
17088
|
+
left[3] = pt;
|
|
17187
17089
|
}
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
n.info.ht = ns.ht;
|
|
17196
|
-
n.info.shape_info = info;
|
|
17090
|
+
if (right !== null) {
|
|
17091
|
+
right[0] = pt;
|
|
17092
|
+
right[1] = bccd;
|
|
17093
|
+
right[2] = cd;
|
|
17094
|
+
right[3] = sp[3];
|
|
17095
|
+
}
|
|
17096
|
+
return pt;
|
|
17197
17097
|
}
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17098
|
+
var HW = 2;
|
|
17099
|
+
var SMALL = 1e-10;
|
|
17100
|
+
function ptToLine2(a, b, p) {
|
|
17101
|
+
const dx = b.x - a.x;
|
|
17102
|
+
const dy = b.y - a.y;
|
|
17103
|
+
let a2 = (p.y - a.y) * dx - (p.x - a.x) * dy;
|
|
17104
|
+
a2 *= a2;
|
|
17105
|
+
if (a2 < SMALL) return 0;
|
|
17106
|
+
return a2 / (dx * dx + dy * dy);
|
|
17202
17107
|
}
|
|
17203
|
-
function
|
|
17204
|
-
|
|
17205
|
-
|
|
17108
|
+
function checkControlPoints(cp) {
|
|
17109
|
+
const dis1 = ptToLine2(cp[0], cp[3], cp[1]);
|
|
17110
|
+
const dis2 = ptToLine2(cp[0], cp[3], cp[2]);
|
|
17111
|
+
return dis1 < HW * HW && dis2 < HW * HW;
|
|
17206
17112
|
}
|
|
17207
|
-
function
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
}
|
|
17217
|
-
for (let i = 0; i < f.n_flds; i++) {
|
|
17218
|
-
if (i > 0) genFieldSeparator(job, coord, f, f.fld[i]);
|
|
17219
|
-
genFields(job, n, f.fld[i]);
|
|
17220
|
-
}
|
|
17221
|
-
}
|
|
17222
|
-
function genFieldSeparator(job, coord, f, child) {
|
|
17223
|
-
const a = { x: 0, y: 0 };
|
|
17224
|
-
const b = { x: 0, y: 0 };
|
|
17225
|
-
if (f.LR) {
|
|
17226
|
-
a.x = child.b.ll.x;
|
|
17227
|
-
a.y = child.b.ll.y;
|
|
17228
|
-
b.x = a.x;
|
|
17229
|
-
b.y = child.b.ur.y;
|
|
17230
|
-
} else {
|
|
17231
|
-
b.x = child.b.ur.x;
|
|
17232
|
-
b.y = child.b.ur.y;
|
|
17233
|
-
a.x = child.b.ll.x;
|
|
17234
|
-
a.y = b.y;
|
|
17235
|
-
}
|
|
17236
|
-
const pts = [
|
|
17237
|
-
transformPoint({ x: a.x + coord.x, y: a.y + coord.y }, job),
|
|
17238
|
-
transformPoint({ x: b.x + coord.x, y: b.y + coord.y }, job)
|
|
17239
|
-
];
|
|
17240
|
-
job.renderer.polyline(pts, job);
|
|
17241
|
-
}
|
|
17242
|
-
function recordGencode(rawJob, rawNode) {
|
|
17243
|
-
const job = rawJob;
|
|
17244
|
-
const n = rawNode;
|
|
17245
|
-
if (!job.renderer) return;
|
|
17246
|
-
const f = n.info.shape_info;
|
|
17247
|
-
if (!f) return;
|
|
17248
|
-
const coord = n.info.coord ?? { x: 0, y: 0 };
|
|
17249
|
-
const ll = { x: f.b.ll.x + coord.x, y: f.b.ll.y + coord.y };
|
|
17250
|
-
const ur = { x: f.b.ur.x + coord.x, y: f.b.ur.y + coord.y };
|
|
17251
|
-
const filled = job.obj !== null && applyNodeStyle(job.obj, n, job);
|
|
17252
|
-
drawRecordBox(job, n, ll, ur, filled);
|
|
17253
|
-
genFields(job, n, f);
|
|
17254
|
-
}
|
|
17255
|
-
function drawRecordBox(job, n, ll, ur, filled) {
|
|
17256
|
-
const isMrecord = nodeAttr(n, n.root, "shape") === "Mrecord";
|
|
17257
|
-
const rounded = isMrecord || parseStyleFlags(nodeAttr(n, n.root, "style")).rounded;
|
|
17258
|
-
if (rounded) {
|
|
17259
|
-
const af = [{ x: ll.x, y: ll.y }, { x: ur.x, y: ll.y }, { x: ur.x, y: ur.y }, { x: ll.x, y: ur.y }];
|
|
17260
|
-
emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer: job.renderer, job });
|
|
17261
|
-
return;
|
|
17262
|
-
}
|
|
17263
|
-
const pts = [{ x: ll.x, y: ll.y }, { x: ll.x, y: ur.y }, { x: ur.x, y: ur.y }, { x: ur.x, y: ll.y }].map((q) => transformPoint(q, job));
|
|
17264
|
-
job.renderer.polygon(pts, filled, job);
|
|
17265
|
-
}
|
|
17266
|
-
|
|
17267
|
-
// src/common/poly-init.ts
|
|
17268
|
-
var DEFAULT_LW = 27;
|
|
17269
|
-
var DEFAULT_RW = 27;
|
|
17270
|
-
var DEFAULT_HT = 36;
|
|
17271
|
-
function nodeAttr(n, g, key) {
|
|
17272
|
-
const own = n.attrs.get(key);
|
|
17273
|
-
if (own !== void 0) return own;
|
|
17274
|
-
if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
|
|
17275
|
-
return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
|
|
17276
|
-
}
|
|
17277
|
-
function readFontAttrs(n, g) {
|
|
17278
|
-
return {
|
|
17279
|
-
fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
|
|
17280
|
-
fontsize: parseFloat(nodeAttr(n, g, "fontsize") ?? String(DEFAULT_FONTSIZE2)),
|
|
17281
|
-
fontcolor: nodeAttr(n, g, "fontcolor") ?? DEFAULT_COLOR2
|
|
17282
|
-
};
|
|
17283
|
-
}
|
|
17284
|
-
function assignShapeInfo(n, polyDesc) {
|
|
17285
|
-
const w = n.info.width !== void 0 ? n.info.width * 72 : (n.info.lw || DEFAULT_LW) + (n.info.rw || DEFAULT_RW);
|
|
17286
|
-
const h = n.info.height !== void 0 ? n.info.height * 72 : n.info.ht || DEFAULT_HT;
|
|
17287
|
-
const base = n.info.base_width !== void 0 && n.info.base_height !== void 0 ? { w: n.info.base_width * 72, h: n.info.base_height * 72 } : void 0;
|
|
17288
|
-
n.info.shape_info = {
|
|
17289
|
-
...polyDesc,
|
|
17290
|
-
vertices: computeVertices(polyDesc, w, h, base)
|
|
17291
|
-
};
|
|
17292
|
-
}
|
|
17293
|
-
function buildNodeLabel(n, g, measurer) {
|
|
17294
|
-
if (n.info.label !== void 0) return;
|
|
17295
|
-
const labelAttr = nodeAttr(n, g, "label");
|
|
17296
|
-
const font = readFontAttrs(n, g);
|
|
17297
|
-
const isHtml = labelAttr !== void 0 && isHtmlValue(labelAttr);
|
|
17298
|
-
const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
|
|
17299
|
-
n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
|
|
17300
|
-
}
|
|
17301
|
-
function polyInit(n, g, measurer) {
|
|
17302
|
-
const shapeName = nodeAttr(n, g, "shape") ?? "ellipse";
|
|
17303
|
-
const shapefile = nodeAttr(n, g, "shapefile");
|
|
17304
|
-
n.info.shape = bindShape(shapeName, shapefile);
|
|
17305
|
-
if (shapefile !== void 0 && shapefile !== "" && shapeName !== "epsf") {
|
|
17306
|
-
console.error(`Warning: No or improper shapefile="${shapefile}" for node "${n.name}"`);
|
|
17307
|
-
}
|
|
17308
|
-
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
17309
|
-
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
17310
|
-
return;
|
|
17311
|
-
}
|
|
17312
|
-
buildNodeLabel(n, g, measurer);
|
|
17313
|
-
if (n.info.shape_info !== void 0) return;
|
|
17314
|
-
const polyDesc = n.info.shape.polygon;
|
|
17315
|
-
if (polyDesc !== null) assignShapeInfo(n, polyDesc);
|
|
17316
|
-
}
|
|
17317
|
-
|
|
17318
|
-
// src/render/svg-multicolor.ts
|
|
17319
|
-
var THIN_LINE = 0.5;
|
|
17320
|
-
function rationalFunction(x, c) {
|
|
17321
|
-
return (x * (x * c[0] + c[1]) + c[2]) / (x + c[3]);
|
|
17322
|
-
}
|
|
17323
|
-
var COEFFS3LOW = [
|
|
17324
|
-
[
|
|
17325
|
-
[3.85268, -21.229, -0.330434, 0.0127842],
|
|
17326
|
-
[-1.61486, 0.706564, 0.225945, 0.263682],
|
|
17327
|
-
[-0.910164, 0.388383, 551445e-8, 671814e-8],
|
|
17328
|
-
[-0.630184, 0.192402, 98871e-7, 0.0102527]
|
|
17329
|
-
],
|
|
17330
|
-
[
|
|
17331
|
-
[-0.162211, 9.94329, 0.13723, 0.0124084],
|
|
17332
|
-
[-0.253135, 187735e-8, 0.0230286, 0.01264],
|
|
17333
|
-
[-0.0695069, -0.0437594, 0.0120636, 0.0163087],
|
|
17334
|
-
[-0.0328856, -926032e-8, -173573e-8, 527385e-8]
|
|
17335
|
-
]
|
|
17336
|
-
];
|
|
17337
|
-
var COEFFS3HIGH = [
|
|
17338
|
-
[
|
|
17339
|
-
[0.0899116, -19.2349, -4.11711, 0.183362],
|
|
17340
|
-
[0.138148, -1.45804, 1.32044, 1.38474],
|
|
17341
|
-
[0.230903, -0.450262, 0.219963, 0.414038],
|
|
17342
|
-
[0.0590565, -0.101062, 0.0430592, 0.0204699]
|
|
17343
|
-
],
|
|
17344
|
-
[
|
|
17345
|
-
[0.0164649, 9.89394, 0.0919496, 760802e-8],
|
|
17346
|
-
[0.0191603, -0.0322058, 0.0134667, -0.0825018],
|
|
17347
|
-
[0.0156192, -0.017535, 326508e-8, -0.228157],
|
|
17348
|
-
[-0.0236752, 0.0405821, -0.0173086, 0.176187]
|
|
17349
|
-
]
|
|
17350
|
-
];
|
|
17351
|
-
var SAFETY3 = [1e-3, 4.98, 0.207, 67e-4];
|
|
17352
|
-
function estimateError(a, b, etaA, etaB) {
|
|
17353
|
-
const eta = 0.5 * (etaA + etaB);
|
|
17354
|
-
const x = b / a;
|
|
17355
|
-
const dEta = etaB - etaA;
|
|
17356
|
-
const cos2 = Math.cos(2 * eta);
|
|
17357
|
-
const cos4 = Math.cos(4 * eta);
|
|
17358
|
-
const cos6 = Math.cos(6 * eta);
|
|
17359
|
-
const c = x < 0.25 ? COEFFS3LOW : COEFFS3HIGH;
|
|
17360
|
-
const c0 = rationalFunction(x, c[0][0]) + cos2 * rationalFunction(x, c[0][1]) + cos4 * rationalFunction(x, c[0][2]) + cos6 * rationalFunction(x, c[0][3]);
|
|
17361
|
-
const c1 = rationalFunction(x, c[1][0]) + cos2 * rationalFunction(x, c[1][1]) + cos4 * rationalFunction(x, c[1][2]) + cos6 * rationalFunction(x, c[1][3]);
|
|
17362
|
-
return rationalFunction(x, SAFETY3) * a * Math.exp(c0 + c1 * dEta);
|
|
17363
|
-
}
|
|
17364
|
-
function allSubdivsBelowThreshold(a, b, eta1, n, dEta) {
|
|
17365
|
-
let etaA = eta1;
|
|
17366
|
-
for (let i = 0; i < n; i++) {
|
|
17367
|
-
if (estimateError(a, b, etaA, etaA + dEta) > 1e-5) return false;
|
|
17368
|
-
etaA += dEta;
|
|
17369
|
-
}
|
|
17370
|
-
return true;
|
|
17371
|
-
}
|
|
17372
|
-
function numSubdivisions(a, b, eta1, eta2) {
|
|
17373
|
-
let n = 1;
|
|
17374
|
-
while (n < 1024) {
|
|
17375
|
-
const dEta = (eta2 - eta1) / n;
|
|
17376
|
-
if (dEta <= 0.5 * Math.PI && allSubdivsBelowThreshold(a, b, eta1, n, dEta)) break;
|
|
17377
|
-
n <<= 1;
|
|
17378
|
-
}
|
|
17379
|
-
return n;
|
|
17380
|
-
}
|
|
17381
|
-
function initArcPath(pts, e, eta1) {
|
|
17382
|
-
const cosE = Math.cos(eta1);
|
|
17383
|
-
const sinE = Math.sin(eta1);
|
|
17384
|
-
const xB = e.cx + e.xsemi * cosE;
|
|
17385
|
-
const yB = e.cy + e.ysemi * sinE;
|
|
17386
|
-
pts.push(
|
|
17387
|
-
{ x: e.cx, y: e.cy },
|
|
17388
|
-
{ x: e.cx, y: e.cy },
|
|
17389
|
-
{ x: xB, y: yB },
|
|
17390
|
-
{ x: xB, y: yB }
|
|
17391
|
-
);
|
|
17392
|
-
return { xB, yB, xBDot: -e.xsemi * sinE, yBDot: e.ysemi * cosE };
|
|
17393
|
-
}
|
|
17394
|
-
function stepBezier(pts, state3, e, sp) {
|
|
17395
|
-
const xA = state3.xB;
|
|
17396
|
-
const yA = state3.yB;
|
|
17397
|
-
const xADot = state3.xBDot;
|
|
17398
|
-
const yADot = state3.yBDot;
|
|
17399
|
-
const newEta = sp.etaB + sp.dEta;
|
|
17400
|
-
const cosE = Math.cos(newEta);
|
|
17401
|
-
const sinE = Math.sin(newEta);
|
|
17402
|
-
state3.xB = e.cx + e.xsemi * cosE;
|
|
17403
|
-
state3.yB = e.cy + e.ysemi * sinE;
|
|
17404
|
-
state3.xBDot = -e.xsemi * sinE;
|
|
17405
|
-
state3.yBDot = e.ysemi * cosE;
|
|
17406
|
-
pts.push({ x: xA + sp.alpha * xADot, y: yA + sp.alpha * yADot });
|
|
17407
|
-
pts.push({ x: state3.xB - sp.alpha * state3.xBDot, y: state3.yB - sp.alpha * state3.yBDot });
|
|
17408
|
-
pts.push({ x: state3.xB, y: state3.yB });
|
|
17409
|
-
return newEta;
|
|
17410
|
-
}
|
|
17411
|
-
function ellipticWedge(e, angle0, angle1) {
|
|
17412
|
-
const TWOPI2 = 2 * Math.PI;
|
|
17413
|
-
const eta1 = Math.atan2(Math.sin(angle0) / e.ysemi, Math.cos(angle0) / e.xsemi);
|
|
17414
|
-
let eta2 = Math.atan2(Math.sin(angle1) / e.ysemi, Math.cos(angle1) / e.xsemi);
|
|
17415
|
-
eta2 -= TWOPI2 * Math.floor((eta2 - eta1) / TWOPI2);
|
|
17416
|
-
if (angle1 - angle0 > Math.PI && eta2 - eta1 < Math.PI) eta2 += TWOPI2;
|
|
17417
|
-
const n = numSubdivisions(e.xsemi, e.ysemi, eta1, eta2);
|
|
17418
|
-
const dEta = (eta2 - eta1) / n;
|
|
17419
|
-
const t = Math.tan(0.5 * dEta);
|
|
17420
|
-
const alpha = Math.sin(dEta) * (Math.sqrt(4 + 3 * t * t) - 1) / 3;
|
|
17421
|
-
const pts = [];
|
|
17422
|
-
const state3 = initArcPath(pts, e, eta1);
|
|
17423
|
-
let sp = { etaB: eta1, dEta, alpha };
|
|
17424
|
-
for (let i = 0; i < n; i++) sp = { ...sp, etaB: stepBezier(pts, state3, e, sp) };
|
|
17425
|
-
pts.push({ x: state3.xB, y: state3.yB }, { x: e.cx, y: e.cy }, { x: e.cx, y: e.cy });
|
|
17426
|
-
return pts;
|
|
17427
|
-
}
|
|
17428
|
-
function drawWedge(seg2, e, ctx) {
|
|
17429
|
-
const TWOPI2 = 2 * Math.PI;
|
|
17430
|
-
const angle1 = seg2.isLast ? TWOPI2 : seg2.angle0 + TWOPI2 * seg2.t;
|
|
17431
|
-
const obj = ctx.job.obj;
|
|
17432
|
-
if (obj !== null) obj.fillColor = resolveRenderColor(seg2.color);
|
|
17433
|
-
const ptsUp = ellipticWedge(e, seg2.angle0, angle1);
|
|
17434
|
-
ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
|
|
17435
|
-
return angle1;
|
|
17436
|
-
}
|
|
17437
|
-
function wedgedEllipse(job, pf, clrs, renderer) {
|
|
17438
|
-
const { segs, error } = parseSegs(clrs);
|
|
17439
|
-
if (error === 1 || error === 2) return error;
|
|
17440
|
-
const ctrX = (pf[0].x + pf[1].x) / 2;
|
|
17441
|
-
const ctrY = (pf[0].y + pf[1].y) / 2;
|
|
17442
|
-
const e = {
|
|
17443
|
-
cx: ctrX,
|
|
17444
|
-
cy: -ctrY,
|
|
17445
|
-
xsemi: pf[1].x - ctrX,
|
|
17446
|
-
ysemi: Math.abs(pf[1].y - ctrY)
|
|
17447
|
-
};
|
|
17448
|
-
const ctx = { job, renderer };
|
|
17449
|
-
const obj = job.obj;
|
|
17450
|
-
const saved = obj !== null ? obj.penWidth : 1;
|
|
17451
|
-
if (obj !== null && saved > THIN_LINE) obj.penWidth = THIN_LINE;
|
|
17452
|
-
let angle0 = 0;
|
|
17453
|
-
for (let i = 0; i < segs.length; i++) {
|
|
17454
|
-
const s = segs[i];
|
|
17455
|
-
if (s.color === null) break;
|
|
17456
|
-
if (s.t > 0) {
|
|
17457
|
-
angle0 = drawWedge({ angle0, t: s.t, isLast: i + 1 === segs.length, color: s.color }, e, ctx);
|
|
17458
|
-
}
|
|
17459
|
-
}
|
|
17460
|
-
if (obj !== null && saved > THIN_LINE) obj.penWidth = saved;
|
|
17461
|
-
return error;
|
|
17462
|
-
}
|
|
17463
|
-
function drawBand(p, seg2, ctx) {
|
|
17464
|
-
const obj = ctx.job.obj;
|
|
17465
|
-
if (obj !== null) obj.fillColor = resolveRenderColor(seg2.color);
|
|
17466
|
-
p[1].x = p[2].x = seg2.isLast ? seg2.lastx : p[0].x + seg2.segWidth;
|
|
17467
|
-
ctx.renderer.polygon([...p], true, ctx.job);
|
|
17468
|
-
p[0].x = p[3].x = p[1].x;
|
|
17469
|
-
}
|
|
17470
|
-
function stripedBox(job, pts, clrs, rotate, renderer) {
|
|
17471
|
-
const { segs, error } = parseSegs(clrs);
|
|
17472
|
-
if (error === 1 || error === 2) return error;
|
|
17473
|
-
const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
|
|
17474
|
-
const lastx = p[1].x;
|
|
17475
|
-
const xdelta = p[1].x - p[0].x;
|
|
17476
|
-
p[1].x = p[2].x = p[0].x;
|
|
17477
|
-
const ctx = { job, renderer };
|
|
17478
|
-
const obj = job.obj;
|
|
17479
|
-
const saved = obj !== null ? obj.penWidth : 1;
|
|
17480
|
-
if (obj !== null && saved > THIN_LINE) obj.penWidth = THIN_LINE;
|
|
17481
|
-
for (let i = 0; i < segs.length; i++) {
|
|
17482
|
-
const s = segs[i];
|
|
17483
|
-
if (s.color === null) break;
|
|
17484
|
-
if (s.t > 0) {
|
|
17485
|
-
drawBand(p, { color: s.color, isLast: i + 1 === segs.length, segWidth: xdelta * s.t, lastx }, ctx);
|
|
17486
|
-
}
|
|
17487
|
-
}
|
|
17488
|
-
if (obj !== null && saved > THIN_LINE) obj.penWidth = saved;
|
|
17489
|
-
return error;
|
|
17490
|
-
}
|
|
17491
|
-
|
|
17492
|
-
// src/render/xml-escape.ts
|
|
17493
|
-
var RE_DQUOTE = new RegExp('"', "g");
|
|
17494
|
-
var RE_SQUOTE = new RegExp("'", "g");
|
|
17495
|
-
var RE_AMP_NONENTITY = /&(?![A-Za-z]+;|#[0-9]+;|#x[0-9A-Fa-f]+;)/g;
|
|
17496
|
-
function escapeXml(s) {
|
|
17497
|
-
let r = s.replace(RE_AMP_NONENTITY, "&");
|
|
17498
|
-
r = r.replace(/</g, "<");
|
|
17499
|
-
r = r.replace(/>/g, ">");
|
|
17500
|
-
r = r.replace(RE_DQUOTE, """);
|
|
17501
|
-
r = r.replace(RE_SQUOTE, "'");
|
|
17502
|
-
return r;
|
|
17503
|
-
}
|
|
17504
|
-
function escapeXmlTitle(s) {
|
|
17505
|
-
let r = escapeXml(s);
|
|
17506
|
-
r = r.replace(/-/g, "-");
|
|
17507
|
-
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
17508
|
-
return r;
|
|
17509
|
-
}
|
|
17510
|
-
function escapeXmlText(s) {
|
|
17511
|
-
let r = escapeXml(s);
|
|
17512
|
-
r = r.replace(/-/g, "-");
|
|
17513
|
-
r = r.replace(/\n/g, " ");
|
|
17514
|
-
r = r.replace(/\r/g, " ");
|
|
17515
|
-
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
17516
|
-
return r;
|
|
17517
|
-
}
|
|
17518
|
-
|
|
17519
|
-
// src/gvc/device-cluster.ts
|
|
17520
|
-
function applyClusterGradient(obj, fill) {
|
|
17521
|
-
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
17522
|
-
obj.fillColor = resolveRenderColor(fill.fillColor);
|
|
17523
|
-
obj.stopColor = resolveRenderColor(fill.stopColor);
|
|
17524
|
-
obj.gradientFrac = fill.frac;
|
|
17525
|
-
obj.gradientAngle = fill.angle;
|
|
17526
|
-
}
|
|
17527
|
-
function clusterAttr(sg, key) {
|
|
17528
|
-
for (let g = sg; g !== null; g = g.parent) {
|
|
17529
|
-
const v = g.attrs.get(key);
|
|
17530
|
-
if (v !== void 0) return v;
|
|
17531
|
-
}
|
|
17532
|
-
return void 0;
|
|
17533
|
-
}
|
|
17534
|
-
function clusterStyle(sg) {
|
|
17535
|
-
return clusterAttr(sg, "style");
|
|
17536
|
-
}
|
|
17537
|
-
function clusterPeripheries(sg) {
|
|
17538
|
-
const raw = clusterAttr(sg, "peripheries");
|
|
17539
|
-
if (raw === void 0 || raw.length === 0) return 1;
|
|
17540
|
-
const v = parseInt(raw, 10);
|
|
17541
|
-
if (Number.isNaN(v)) return 1;
|
|
17542
|
-
return v < 0 ? 0 : v;
|
|
17543
|
-
}
|
|
17544
|
-
function applyClusterPenState(obj, sg) {
|
|
17545
|
-
const flags = parseStyleFlags(clusterStyle(sg));
|
|
17546
|
-
const pen = clusterAttr(sg, "pencolor") ?? clusterAttr(sg, "color");
|
|
17547
|
-
obj.penColor = clusterPeripheries(sg) === 0 ? resolveRenderColor("transparent") : resolveRenderColor(resolvePenColor(pen));
|
|
17548
|
-
obj.penWidth = resolvePenWidth(flags, clusterAttr(sg, "penwidth"));
|
|
17549
|
-
obj.pen = resolvePenType(flags);
|
|
17550
|
-
}
|
|
17551
|
-
function clusterAttrsOf(sg) {
|
|
17552
|
-
return {
|
|
17553
|
-
style: clusterStyle(sg),
|
|
17554
|
-
color: clusterAttr(sg, "color"),
|
|
17555
|
-
pencolor: clusterAttr(sg, "pencolor"),
|
|
17556
|
-
fillcolor: clusterAttr(sg, "fillcolor"),
|
|
17557
|
-
bgcolor: clusterAttr(sg, "bgcolor"),
|
|
17558
|
-
penwidth: clusterAttr(sg, "penwidth"),
|
|
17559
|
-
gradientangle: clusterAttr(sg, "gradientangle")
|
|
17560
|
-
};
|
|
17561
|
-
}
|
|
17562
|
-
function applyClusterObjState(sg, job) {
|
|
17563
|
-
const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
|
|
17564
|
-
if (job.obj === null) return false;
|
|
17565
|
-
const obj = job.obj;
|
|
17566
|
-
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
17567
|
-
applyClusterPenState(obj, sg);
|
|
17568
|
-
if (fillRes.kind === "none") {
|
|
17569
|
-
obj.fill = 0 /* None */;
|
|
17570
|
-
return false;
|
|
17571
|
-
}
|
|
17572
|
-
if (fillRes.kind === "solid") {
|
|
17573
|
-
obj.fill = 1 /* Solid */;
|
|
17574
|
-
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
17575
|
-
return true;
|
|
17576
|
-
}
|
|
17577
|
-
applyClusterGradient(obj, fillRes);
|
|
17578
|
-
return true;
|
|
17579
|
-
});
|
|
17580
|
-
}
|
|
17581
|
-
|
|
17582
|
-
// src/render/svg-id.ts
|
|
17583
|
-
function svgClass(kind, classAttr) {
|
|
17584
|
-
return classAttr !== void 0 && classAttr.length > 0 ? 'class="' + kind + " " + escapeXmlTitle(classAttr) + '"' : 'class="' + kind + '"';
|
|
17585
|
-
}
|
|
17586
|
-
function svgNodeId(n, job) {
|
|
17587
|
-
return job.objId(n.attrs.get("id"), "node" + (n.id + 1));
|
|
17588
|
-
}
|
|
17589
|
-
function svgEdgeId(e, job) {
|
|
17590
|
-
return job.objId(e.attrs.get("id"), "edge" + e.graphSeq);
|
|
17591
|
-
}
|
|
17592
|
-
function svgClusterId(sg, job) {
|
|
17593
|
-
return job.objId(sg.attrs.get("id"), "clust" + sg.seq);
|
|
17594
|
-
}
|
|
17595
|
-
function svgGraphId(g, job) {
|
|
17596
|
-
return job.objId(g.attrs.get("id"), "graph0", true);
|
|
17597
|
-
}
|
|
17598
|
-
function svgNodeClass(n) {
|
|
17599
|
-
return svgClass("node", nodeAttr(n, n.root, "class"));
|
|
17600
|
-
}
|
|
17601
|
-
function svgEdgeClass(e) {
|
|
17602
|
-
return svgClass("edge", e.attrs.get("class"));
|
|
17603
|
-
}
|
|
17604
|
-
function svgClusterClass(sg) {
|
|
17605
|
-
return svgClass("cluster", clusterAttr(sg, "class"));
|
|
17606
|
-
}
|
|
17607
|
-
function svgGraphClass(g) {
|
|
17608
|
-
return svgClass("graph", g.attrs.get("class"));
|
|
17609
|
-
}
|
|
17610
|
-
|
|
17611
|
-
// src/common/poly-gencode.ts
|
|
17612
|
-
function isMulticolor(fillcolor) {
|
|
17613
|
-
return fillcolor.includes(":");
|
|
17614
|
-
}
|
|
17615
|
-
function renderEllipse(ring, coord, renderer, job, filled) {
|
|
17616
|
-
const rx = Math.abs((ring[1].x - ring[0].x) / 2);
|
|
17617
|
-
const ry = Math.abs((ring[1].y - ring[0].y) / 2);
|
|
17618
|
-
const center = transformPoint(coord, job);
|
|
17619
|
-
renderer.ellipse(center, rx, ry, filled, job);
|
|
17620
|
-
}
|
|
17621
|
-
function renderPolygon(ring, coord, renderer, job, filled) {
|
|
17622
|
-
const pts = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, job));
|
|
17623
|
-
renderer.polygon(pts, filled, job);
|
|
17624
|
-
}
|
|
17625
|
-
function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
17626
|
-
if (ctx.style.wedged && j === 0 && isMulticolor(ctx.fillcolor)) {
|
|
17627
|
-
const pf = ring.map(
|
|
17628
|
-
(v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
|
|
17629
|
-
);
|
|
17630
|
-
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
|
|
17631
|
-
renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
|
|
17632
|
-
} else {
|
|
17633
|
-
renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
|
|
17634
|
-
}
|
|
17635
|
-
if (ctx.diagonals) mcircleHack(ring, coord, ctx);
|
|
17636
|
-
}
|
|
17637
|
-
function renderStripedRing(ring, coord, ctx) {
|
|
17638
|
-
const af = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job));
|
|
17639
|
-
stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer);
|
|
17640
|
-
renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
|
|
17641
|
-
}
|
|
17642
|
-
function renderPolyRing(ring, coord, filled, j, ctx) {
|
|
17643
|
-
if (ctx.style.striped && j === 0) renderStripedRing(ring, coord, ctx);
|
|
17644
|
-
else if (ctx.underline) underlineDraw(ring, coord, filled, ctx);
|
|
17645
|
-
else if (ctx.shape !== 0 && ctx.shape !== STAR || ctx.diagonals || ctx.rounded) {
|
|
17646
|
-
drawRoundCorners(ring, coord, filled, ctx);
|
|
17647
|
-
} else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
|
|
17648
|
-
}
|
|
17649
|
-
function renderPeripheries(poly, coord, filled, ctx) {
|
|
17650
|
-
const sides = poly.sides <= 2 ? 2 : poly.sides;
|
|
17651
|
-
const verts = poly.vertices;
|
|
17652
|
-
for (let j = 0; j < poly.peripheries; j++) {
|
|
17653
|
-
const ring = verts.slice(j * sides, (j + 1) * sides);
|
|
17654
|
-
if (ring.length < sides) break;
|
|
17655
|
-
const ringFilled = j === 0 ? filled : false;
|
|
17656
|
-
if (poly.sides <= 2) {
|
|
17657
|
-
renderEllipseRing(ring, coord, ringFilled, j, ctx);
|
|
17658
|
-
} else {
|
|
17659
|
-
renderPolyRing(ring, coord, ringFilled, j, ctx);
|
|
17660
|
-
}
|
|
17661
|
-
}
|
|
17662
|
-
}
|
|
17663
|
-
function renderLabel(label, coord, renderer, job) {
|
|
17664
|
-
if (label.u.kind !== "txt" || label.u.nspans < 1) return;
|
|
17665
|
-
label.pos = coord;
|
|
17666
|
-
label.set = true;
|
|
17667
|
-
const VALIGN_TOP2 = "t".charCodeAt(0);
|
|
17668
|
-
const VALIGN_BOTTOM2 = "b".charCodeAt(0);
|
|
17669
|
-
let py = label.valign === VALIGN_TOP2 ? coord.y + label.space.y / 2 - label.fontsize : label.valign === VALIGN_BOTTOM2 ? coord.y - label.space.y / 2 + label.dimen.y - label.fontsize : coord.y + label.dimen.y / 2 - label.fontsize;
|
|
17670
|
-
for (let i = 0; i < label.u.nspans; i++) {
|
|
17671
|
-
const span = label.u.span[i];
|
|
17672
|
-
const px = span.just === "l" ? coord.x - label.space.x / 2 : span.just === "r" ? coord.x + label.space.x / 2 : coord.x;
|
|
17673
|
-
gvrenderTextspan(renderer, { x: px, y: py }, span, job);
|
|
17674
|
-
py -= span.size.y;
|
|
17675
|
-
}
|
|
17676
|
-
}
|
|
17677
|
-
function renderNodeLabel(n, coord, renderer, job) {
|
|
17678
|
-
const label = n.info.label;
|
|
17679
|
-
if (label === void 0) return;
|
|
17680
|
-
if (label.html && label.u.kind === "html") {
|
|
17681
|
-
label.pos = coord;
|
|
17682
|
-
label.set = true;
|
|
17683
|
-
const html = label.u.html;
|
|
17684
|
-
withLabelEmitState(job, () => emitHtmlLabel(html, coord, renderer, job));
|
|
17685
|
-
} else {
|
|
17686
|
-
renderLabel(label, coord, renderer, job);
|
|
17687
|
-
}
|
|
17688
|
-
}
|
|
17689
|
-
function anchorAttr2(n, key) {
|
|
17690
|
-
const v = nodeAttr(n, n.root, key);
|
|
17691
|
-
return v !== void 0 && v !== "" ? v : void 0;
|
|
17692
|
-
}
|
|
17693
|
-
function resolveTooltip(n, tooltip) {
|
|
17694
|
-
if (tooltip !== void 0) return substObjAnchor(interpretCRNL(tooltip), n);
|
|
17695
|
-
const label = n.info.label;
|
|
17696
|
-
return label?.text ?? "";
|
|
17697
|
-
}
|
|
17698
|
-
function beginNodeAnchor(n, renderer, job) {
|
|
17699
|
-
const url = anchorAttr2(n, "href") ?? anchorAttr2(n, "URL");
|
|
17700
|
-
const tooltip = anchorAttr2(n, "tooltip");
|
|
17701
|
-
if (url === void 0 && tooltip === void 0) return false;
|
|
17702
|
-
renderer.beginAnchor?.(
|
|
17703
|
-
url !== void 0 ? substObjAnchor(url, n) : "",
|
|
17704
|
-
resolveTooltip(n, tooltip),
|
|
17705
|
-
anchorAttr2(n, "target") ?? "",
|
|
17706
|
-
svgNodeId(n, job),
|
|
17707
|
-
job
|
|
17708
|
-
);
|
|
17709
|
-
return true;
|
|
17710
|
-
}
|
|
17711
|
-
function applyGradientFields(obj, fill) {
|
|
17712
|
-
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
17713
|
-
obj.fillColor = resolveRenderColor(fill.fillColor);
|
|
17714
|
-
obj.stopColor = resolveRenderColor(fill.stopColor);
|
|
17715
|
-
obj.gradientFrac = fill.frac;
|
|
17716
|
-
obj.gradientAngle = fill.angle;
|
|
17717
|
-
}
|
|
17718
|
-
function isPointNode(n) {
|
|
17719
|
-
return n.info.shape?.kind === 3 /* SH_POINT */;
|
|
17720
|
-
}
|
|
17721
|
-
function findFillDflt(n) {
|
|
17722
|
-
const fillcolor = nodeAttr(n, n.root, "fillcolor");
|
|
17723
|
-
if (fillcolor !== void 0 && fillcolor !== "") return fillcolor;
|
|
17724
|
-
const color = nodeAttr(n, n.root, "color");
|
|
17725
|
-
if (color !== void 0 && color !== "") return color;
|
|
17726
|
-
return "black";
|
|
17727
|
-
}
|
|
17728
|
-
function applyFillState(obj, n, job) {
|
|
17729
|
-
obj.id = svgNodeId(n, job);
|
|
17730
|
-
if (isPointNode(n)) {
|
|
17731
|
-
obj.fill = 1 /* Solid */;
|
|
17732
|
-
obj.fillColor = resolveRenderColor(findFillDflt(n));
|
|
17733
|
-
return true;
|
|
17734
|
-
}
|
|
17735
|
-
const fillRes = resolveNodeFillEx({
|
|
17736
|
-
style: nodeAttr(n, n.root, "style"),
|
|
17737
|
-
fillcolor: nodeAttr(n, n.root, "fillcolor"),
|
|
17738
|
-
color: nodeAttr(n, n.root, "color"),
|
|
17739
|
-
gradientangle: nodeAttr(n, n.root, "gradientangle")
|
|
17740
|
-
});
|
|
17741
|
-
if (fillRes.kind === "none") {
|
|
17742
|
-
obj.fill = 0 /* None */;
|
|
17743
|
-
return false;
|
|
17744
|
-
}
|
|
17745
|
-
if (fillRes.kind === "solid") {
|
|
17746
|
-
obj.fill = 1 /* Solid */;
|
|
17747
|
-
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
17748
|
-
return true;
|
|
17749
|
-
}
|
|
17750
|
-
applyGradientFields(obj, fillRes);
|
|
17751
|
-
return true;
|
|
17752
|
-
}
|
|
17753
|
-
function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
17754
|
-
const flags = parseStyleFlags(styleAttr);
|
|
17755
|
-
obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
|
|
17756
|
-
obj.pen = resolvePenType(flags);
|
|
17757
|
-
obj.penWidth = resolvePenWidth(flags, penwidthAttr);
|
|
17758
|
-
obj.rawStyle = styleTokens(styleAttr);
|
|
17759
|
-
}
|
|
17760
|
-
function applyNodeStyle(obj, n, job) {
|
|
17761
|
-
const styleAttr = nodeAttr(n, n.root, "style");
|
|
17762
|
-
const colorAttr = nodeAttr(n, n.root, "color");
|
|
17763
|
-
const filled = applyFillState(obj, n, job);
|
|
17764
|
-
applyPenState(obj, styleAttr, colorAttr, nodeAttr(n, n.root, "penwidth"));
|
|
17765
|
-
return filled;
|
|
17766
|
-
}
|
|
17767
|
-
function prepareDrawPoly(poly, filled, obj) {
|
|
17768
|
-
if (poly.peripheries !== 0 || !filled) return poly;
|
|
17769
|
-
obj.penColor = { type: "string", s: "transparent" };
|
|
17770
|
-
return { ...poly, peripheries: 1 };
|
|
17771
|
-
}
|
|
17772
|
-
function vertexScale(n, poly) {
|
|
17773
|
-
const info = n.info;
|
|
17774
|
-
if (poly.vertices == null || info.width === void 0 || info.height === void 0) {
|
|
17775
|
-
return poly;
|
|
17776
|
-
}
|
|
17777
|
-
const xsize = (info.lw + info.rw) / (info.width * 72);
|
|
17778
|
-
const ysize = info.ht / (info.height * 72);
|
|
17779
|
-
if (Math.abs(xsize - 1) < 1e-9 && Math.abs(ysize - 1) < 1e-9) return poly;
|
|
17780
|
-
return {
|
|
17781
|
-
...poly,
|
|
17782
|
-
vertices: poly.vertices.map((v) => ({ x: v.x * xsize, y: v.y * ysize }))
|
|
17783
|
-
};
|
|
17784
|
-
}
|
|
17785
|
-
function resolveNodeDrawCtx(job, n) {
|
|
17786
|
-
const rawPoly = n.info.shape_info;
|
|
17787
|
-
if (rawPoly === void 0 || rawPoly.vertices === void 0) return null;
|
|
17788
|
-
const poly = vertexScale(n, rawPoly);
|
|
17789
|
-
const coord = n.info.coord ?? { x: 0, y: 0 };
|
|
17790
|
-
const obj = job.obj;
|
|
17791
|
-
const filled = obj !== null && applyNodeStyle(obj, n, job);
|
|
17792
|
-
const drawPoly = obj !== null ? prepareDrawPoly(poly, filled, obj) : poly;
|
|
17793
|
-
const styleFlags = parseStyleFlags(nodeAttr(n, n.root, "style"));
|
|
17794
|
-
const ringCtx = {
|
|
17795
|
-
renderer: job.renderer,
|
|
17796
|
-
job,
|
|
17797
|
-
style: styleFlags,
|
|
17798
|
-
fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
|
|
17799
|
-
...specialCornerFlags(drawPoly.option, styleFlags)
|
|
17800
|
-
};
|
|
17801
|
-
return { poly: drawPoly, coord, filled, ringCtx };
|
|
17802
|
-
}
|
|
17803
|
-
function specialCornerFlags(opt, style) {
|
|
17804
|
-
return {
|
|
17805
|
-
shape: opt.shape,
|
|
17806
|
-
diagonals: opt.diagonals || style.diagonals,
|
|
17807
|
-
rounded: opt.rounded || style.rounded,
|
|
17808
|
-
underline: opt.underline || style.underline
|
|
17809
|
-
};
|
|
17810
|
-
}
|
|
17811
|
-
function polyGencode(rawJob, rawNode) {
|
|
17812
|
-
const job = rawJob;
|
|
17813
|
-
const n = rawNode;
|
|
17814
|
-
const renderer = job.renderer;
|
|
17815
|
-
if (!renderer) return;
|
|
17816
|
-
const ctx = resolveNodeDrawCtx(job, n);
|
|
17817
|
-
if (ctx === null) return;
|
|
17818
|
-
const clustersLast = (job.flags & EMIT_CLUSTERS_LAST) !== 0;
|
|
17819
|
-
const savedShape = job.obj?.urlMapShape;
|
|
17820
|
-
const savedPts = job.obj?.urlMapPts;
|
|
17821
|
-
let inAnchor = clustersLast ? false : beginNodeAnchor(n, renderer, job);
|
|
17822
|
-
renderPeripheries(ctx.poly, ctx.coord, ctx.filled, ctx.ringCtx);
|
|
17823
|
-
if (!isPointNode(n)) renderNodeLabel(n, ctx.coord, renderer, job);
|
|
17824
|
-
if (clustersLast) {
|
|
17825
|
-
if (job.obj && savedPts !== void 0 && savedShape !== void 0) {
|
|
17826
|
-
job.obj.urlMapShape = savedShape;
|
|
17827
|
-
job.obj.urlMapPts = savedPts;
|
|
17828
|
-
}
|
|
17829
|
-
inAnchor = beginNodeAnchor(n, renderer, job);
|
|
17830
|
-
}
|
|
17831
|
-
if (inAnchor) renderer.endAnchor?.(job);
|
|
17832
|
-
}
|
|
17833
|
-
|
|
17834
|
-
// src/common/poly-inside.ts
|
|
17835
|
-
function sameSide(p0, p1, L0, L1) {
|
|
17836
|
-
const a = -(L1.y - L0.y);
|
|
17837
|
-
const b = L1.x - L0.x;
|
|
17838
|
-
const c = a * L0.x + b * L0.y;
|
|
17839
|
-
const s0 = a * p0.x + b * p0.y - c >= 0;
|
|
17840
|
-
const s1 = a * p1.x + b * p1.y - c >= 0;
|
|
17841
|
-
return s0 === s1;
|
|
17842
|
-
}
|
|
17843
|
-
function fixedShapeSize(poly) {
|
|
17844
|
-
let xmax = 0;
|
|
17845
|
-
let ymax = 0;
|
|
17846
|
-
for (const v of poly.vertices ?? []) {
|
|
17847
|
-
xmax = Math.max(xmax, Math.abs(v.x));
|
|
17848
|
-
ymax = Math.max(ymax, Math.abs(v.y));
|
|
17849
|
-
}
|
|
17850
|
-
return { w: 2 * xmax, h: 2 * ymax };
|
|
17851
|
-
}
|
|
17852
|
-
function insideDims(n, xsize, ysize) {
|
|
17853
|
-
const w = 72 * (n.info.width || xsize / 72);
|
|
17854
|
-
const h = 72 * (n.info.height || ysize / 72);
|
|
17855
|
-
return { w, h, ow: 72 * n.info.outline_width || w, oh: 72 * n.info.outline_height || h };
|
|
17856
|
-
}
|
|
17857
|
-
function insideScale(n, poly) {
|
|
17858
|
-
const flip = n.root.info.flip === true;
|
|
17859
|
-
if (poly.option.fixedshape) {
|
|
17860
|
-
const { w: w2, h: h2 } = fixedShapeSize(poly);
|
|
17861
|
-
const xsize2 = flip ? h2 : w2;
|
|
17862
|
-
const ysize2 = flip ? w2 : h2;
|
|
17863
|
-
return {
|
|
17864
|
-
scalex: xsize2 !== 0 ? w2 / xsize2 : w2,
|
|
17865
|
-
scaley: ysize2 !== 0 ? h2 / ysize2 : h2,
|
|
17866
|
-
boxURx: w2 / 2,
|
|
17867
|
-
boxURy: h2 / 2
|
|
17868
|
-
};
|
|
17869
|
-
}
|
|
17870
|
-
const lwrw = n.info.lw + n.info.rw;
|
|
17871
|
-
const xsize = flip ? n.info.ht : lwrw;
|
|
17872
|
-
const ysize = flip ? lwrw : n.info.ht;
|
|
17873
|
-
const { w, h, ow, oh } = insideDims(n, xsize, ysize);
|
|
17874
|
-
return {
|
|
17875
|
-
scalex: xsize !== 0 ? w / xsize : w,
|
|
17876
|
-
scaley: ysize !== 0 ? h / ysize : h,
|
|
17877
|
-
boxURx: ow / 2,
|
|
17878
|
-
boxURy: oh / 2
|
|
17879
|
-
};
|
|
17880
|
-
}
|
|
17881
|
-
function polygonWalk(P, vertex, sides) {
|
|
17882
|
-
const O = { x: 0, y: 0 };
|
|
17883
|
-
let i = 0;
|
|
17884
|
-
let i1 = 1 % sides;
|
|
17885
|
-
const Q = vertex[i];
|
|
17886
|
-
const R2 = vertex[i1];
|
|
17887
|
-
if (!sameSide(P, O, Q, R2)) return false;
|
|
17888
|
-
const s = sameSide(P, Q, R2, O);
|
|
17889
|
-
if (s && sameSide(P, R2, O, Q)) return true;
|
|
17890
|
-
for (let j = 1; j < sides; j++) {
|
|
17891
|
-
if (s) {
|
|
17892
|
-
i = i1;
|
|
17893
|
-
i1 = (i + 1) % sides;
|
|
17894
|
-
} else {
|
|
17895
|
-
i1 = i;
|
|
17896
|
-
i = (i + sides - 1) % sides;
|
|
17897
|
-
}
|
|
17898
|
-
if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
|
|
17899
|
-
}
|
|
17900
|
-
return true;
|
|
17901
|
-
}
|
|
17902
|
-
function insideShape(n, poly, p) {
|
|
17903
|
-
const sc = insideScale(n, poly);
|
|
17904
|
-
const P = { x: p.x * sc.scalex, y: p.y * sc.scaley };
|
|
17905
|
-
if (Math.abs(P.x) > sc.boxURx || Math.abs(P.y) > sc.boxURy) return false;
|
|
17906
|
-
if (poly.sides <= 2) {
|
|
17907
|
-
return Math.hypot(P.x / sc.boxURx, P.y / sc.boxURy) < 1;
|
|
17908
|
-
}
|
|
17909
|
-
const outerStart = (Math.max(poly.peripheries, 1) - 1) * poly.sides;
|
|
17910
|
-
const outer = poly.vertices.slice(outerStart, outerStart + poly.sides);
|
|
17911
|
-
const ring = polygonOutlineRing(outer, poly.sides, poly.penwidth ?? 1);
|
|
17912
|
-
return polygonWalk(P, ring, poly.sides);
|
|
17913
|
-
}
|
|
17914
|
-
function polyInside(ctx, p) {
|
|
17915
|
-
const n = ctx.node;
|
|
17916
|
-
if (n === void 0) return false;
|
|
17917
|
-
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
17918
|
-
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
17919
|
-
if (ctx.bp) {
|
|
17920
|
-
const b = ctx.bp;
|
|
17921
|
-
return P.x >= b.ll.x && P.x <= b.ur.x && P.y >= b.ll.y && P.y <= b.ur.y;
|
|
17922
|
-
}
|
|
17923
|
-
const poly = n.info.shape_info;
|
|
17924
|
-
if (poly === void 0 || poly.vertices === null) return false;
|
|
17925
|
-
return insideShape(n, poly, P);
|
|
17926
|
-
}
|
|
17927
|
-
function starInside(ctx, p) {
|
|
17928
|
-
const n = ctx.node;
|
|
17929
|
-
if (n === void 0) return false;
|
|
17930
|
-
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
17931
|
-
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
17932
|
-
if (ctx.bp) {
|
|
17933
|
-
const b = ctx.bp;
|
|
17934
|
-
return P.x >= b.ll.x && P.x <= b.ur.x && P.y >= b.ll.y && P.y <= b.ur.y;
|
|
17935
|
-
}
|
|
17936
|
-
const poly = n.info.shape_info;
|
|
17937
|
-
if (poly === void 0 || poly.vertices === null) return false;
|
|
17938
|
-
const sides = poly.sides;
|
|
17939
|
-
const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides;
|
|
17940
|
-
const outer = poly.vertices.slice(outerStart, outerStart + sides);
|
|
17941
|
-
const ring = polygonOutlineRing(outer, sides, poly.penwidth ?? 1);
|
|
17942
|
-
const O = { x: 0, y: 0 };
|
|
17943
|
-
let outcnt = 0;
|
|
17944
|
-
for (let i = 0; i < sides; i += 2) {
|
|
17945
|
-
const Q = ring[i];
|
|
17946
|
-
const R2 = ring[(i + 4) % sides];
|
|
17947
|
-
if (!sameSide(P, O, Q, R2)) outcnt++;
|
|
17948
|
-
if (outcnt === 2) return false;
|
|
17949
|
-
}
|
|
17950
|
-
return true;
|
|
17951
|
-
}
|
|
17952
|
-
function recordInside(ctx, p) {
|
|
17953
|
-
const n = ctx.node;
|
|
17954
|
-
if (n === void 0) return false;
|
|
17955
|
-
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
17956
|
-
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
17957
|
-
let bb;
|
|
17958
|
-
if (ctx.bp) {
|
|
17959
|
-
bb = ctx.bp;
|
|
17960
|
-
} else {
|
|
17961
|
-
const fld = n.info.shape_info;
|
|
17962
|
-
if (!fld?.b) return false;
|
|
17963
|
-
bb = fld.b;
|
|
17964
|
-
}
|
|
17965
|
-
const pw = 0.5;
|
|
17966
|
-
return P.x >= bb.ll.x - pw && P.x <= bb.ur.x + pw && P.y >= bb.ll.y - pw && P.y <= bb.ur.y + pw;
|
|
17967
|
-
}
|
|
17968
|
-
|
|
17969
|
-
// src/layout/dot/fastgr.ts
|
|
17970
|
-
var VIRTUAL = 1;
|
|
17971
|
-
var NORMAL = 0;
|
|
17972
|
-
var FLATORDER = 4;
|
|
17973
|
-
var REVERSED = 3;
|
|
17974
|
-
var MC_SCALE = 256;
|
|
17975
|
-
function elistAppend(el, e) {
|
|
17976
|
-
el.list[el.size++] = e;
|
|
17977
|
-
}
|
|
17978
|
-
function zapinlist(el, e) {
|
|
17979
|
-
let i = 0;
|
|
17980
|
-
while (i < el.size && el.list[i] !== e) i++;
|
|
17981
|
-
if (i < el.size) {
|
|
17982
|
-
el.list[i] = el.list[--el.size];
|
|
17983
|
-
el.list[el.size] = void 0;
|
|
17984
|
-
}
|
|
17985
|
-
}
|
|
17986
|
-
function deleteFastEdge(e) {
|
|
17987
|
-
if (e.tail.info.out) zapinlist(e.tail.info.out, e);
|
|
17988
|
-
if (e.head.info.in) zapinlist(e.head.info.in, e);
|
|
17989
|
-
}
|
|
17990
|
-
function fastEdge(e) {
|
|
17991
|
-
if (!e.tail.info.out) e.tail.info.out = { list: [], size: 0 };
|
|
17992
|
-
if (!e.head.info.in) e.head.info.in = { list: [], size: 0 };
|
|
17993
|
-
elistAppend(e.tail.info.out, e);
|
|
17994
|
-
elistAppend(e.head.info.in, e);
|
|
17995
|
-
}
|
|
17996
|
-
function findFastEdge(u, v) {
|
|
17997
|
-
const uOut = u.info.out;
|
|
17998
|
-
const vIn = v.info.in;
|
|
17999
|
-
if (uOut === void 0 || vIn === void 0) return void 0;
|
|
18000
|
-
if (uOut.size <= vIn.size) {
|
|
18001
|
-
for (let i = 0; i < uOut.size; i++) {
|
|
18002
|
-
if (uOut.list[i].head === v) return uOut.list[i];
|
|
18003
|
-
}
|
|
18004
|
-
} else {
|
|
18005
|
-
for (let i = 0; i < vIn.size; i++) {
|
|
18006
|
-
if (vIn.list[i].tail === u) return vIn.list[i];
|
|
18007
|
-
}
|
|
18008
|
-
}
|
|
18009
|
-
return void 0;
|
|
18010
|
-
}
|
|
18011
|
-
function copyPort(p) {
|
|
18012
|
-
const bp = p.bp !== null ? { ll: { x: p.bp.ll.x, y: p.bp.ll.y }, ur: { x: p.bp.ur.x, y: p.bp.ur.y } } : null;
|
|
18013
|
-
return { p: { x: p.p.x, y: p.p.y }, theta: p.theta, bp, defined: p.defined, constrained: p.constrained, clip: p.clip, dyna: p.dyna, order: p.order, side: p.side, name: p.name };
|
|
18014
|
-
}
|
|
18015
|
-
function copyVirtualPorts(e, orig) {
|
|
18016
|
-
if (e.tail === orig.tail) e.info.tail_port = copyPort(orig.info.tail_port);
|
|
18017
|
-
else if (e.tail === orig.head) e.info.tail_port = copyPort(orig.info.head_port);
|
|
18018
|
-
if (e.head === orig.head) e.info.head_port = copyPort(orig.info.head_port);
|
|
18019
|
-
else if (e.head === orig.tail) e.info.head_port = copyPort(orig.info.tail_port);
|
|
18020
|
-
}
|
|
18021
|
-
function copyVirtualEdgeInfo(e, orig) {
|
|
18022
|
-
e.info.count = orig.info.count;
|
|
18023
|
-
e.info.xpenalty = orig.info.xpenalty;
|
|
18024
|
-
e.info.weight = orig.info.weight;
|
|
18025
|
-
e.info.minlen = orig.info.minlen;
|
|
18026
|
-
copyVirtualPorts(e, orig);
|
|
18027
|
-
e.info.label = orig.info.label;
|
|
18028
|
-
e.info.head_label = orig.info.head_label;
|
|
18029
|
-
e.info.tail_label = orig.info.tail_label;
|
|
18030
|
-
e.info.xlabel = orig.info.xlabel;
|
|
18031
|
-
if (orig.info.to_virt === void 0) orig.info.to_virt = e;
|
|
18032
|
-
e.info.to_orig = orig;
|
|
18033
|
-
e.seq = orig.seq;
|
|
18034
|
-
}
|
|
18035
|
-
function newVirtualEdge(u, v, orig) {
|
|
18036
|
-
const e = new Edge(u, v, "");
|
|
18037
|
-
e.info.edge_type = VIRTUAL;
|
|
18038
|
-
if (orig) {
|
|
18039
|
-
copyVirtualEdgeInfo(e, orig);
|
|
18040
|
-
} else {
|
|
18041
|
-
e.info.weight = 1;
|
|
18042
|
-
e.info.xpenalty = 1;
|
|
18043
|
-
e.info.count = 1;
|
|
18044
|
-
e.info.minlen = 1;
|
|
18045
|
-
}
|
|
18046
|
-
return e;
|
|
18047
|
-
}
|
|
18048
|
-
function virtualEdge(u, v, orig) {
|
|
18049
|
-
const e = newVirtualEdge(u, v, orig);
|
|
18050
|
-
fastEdge(e);
|
|
18051
|
-
return e;
|
|
18052
|
-
}
|
|
18053
|
-
function mergeWeightsInto(f, ew, em, ex) {
|
|
18054
|
-
f.info.weight = (f.info.weight ?? 0) + ew;
|
|
18055
|
-
f.info.minlen = Math.max(f.info.minlen ?? 1, em);
|
|
18056
|
-
f.info.count = (f.info.count ?? 1) + 1;
|
|
18057
|
-
f.info.xpenalty = (f.info.xpenalty ?? 0) + ex;
|
|
18058
|
-
}
|
|
18059
|
-
function basicMerge(e, rep) {
|
|
18060
|
-
const ew = e.info.weight ?? 1;
|
|
18061
|
-
const em = e.info.minlen ?? 1;
|
|
18062
|
-
const ex = e.info.xpenalty ?? 0;
|
|
18063
|
-
for (let f = rep; f !== void 0; f = f.info.to_virt) {
|
|
18064
|
-
mergeWeightsInto(f, ew, em, ex);
|
|
18065
|
-
}
|
|
18066
|
-
}
|
|
18067
|
-
function mergeOneway(e, rep) {
|
|
18068
|
-
if (e.info.to_virt !== void 0) return;
|
|
18069
|
-
e.info.to_virt = rep;
|
|
18070
|
-
basicMerge(e, rep);
|
|
18071
|
-
}
|
|
18072
|
-
function deleteFlatEdge(e) {
|
|
18073
|
-
e.info.to_virt = void 0;
|
|
18074
|
-
if (e.tail.info.flat_out) zapinlist(e.tail.info.flat_out, e);
|
|
18075
|
-
if (e.head.info.flat_in) zapinlist(e.head.info.flat_in, e);
|
|
18076
|
-
}
|
|
18077
|
-
function flatEdge(g, e) {
|
|
18078
|
-
if (!e.tail.info.flat_out) e.tail.info.flat_out = { list: [], size: 0 };
|
|
18079
|
-
if (!e.head.info.flat_in) e.head.info.flat_in = { list: [], size: 0 };
|
|
18080
|
-
elistAppend(e.tail.info.flat_out, e);
|
|
18081
|
-
elistAppend(e.head.info.flat_in, e);
|
|
18082
|
-
g.info.has_flat_edges = true;
|
|
18083
|
-
}
|
|
18084
|
-
function findFlatEdge(u, v) {
|
|
18085
|
-
const uOut = u.info.flat_out;
|
|
18086
|
-
const vIn = v.info.flat_in;
|
|
18087
|
-
if (uOut === void 0 || vIn === void 0) return void 0;
|
|
18088
|
-
if (uOut.size <= vIn.size) {
|
|
18089
|
-
for (let i = 0; i < uOut.size; i++) {
|
|
18090
|
-
if (uOut.list[i].head === v) return uOut.list[i];
|
|
18091
|
-
}
|
|
18092
|
-
} else {
|
|
18093
|
-
for (let i = 0; i < vIn.size; i++) {
|
|
18094
|
-
if (vIn.list[i].tail === u) return vIn.list[i];
|
|
18095
|
-
}
|
|
18096
|
-
}
|
|
18097
|
-
return void 0;
|
|
18098
|
-
}
|
|
18099
|
-
function reverseEdge(e) {
|
|
18100
|
-
deleteFastEdge(e);
|
|
18101
|
-
e.info.reversed = true;
|
|
18102
|
-
const f = findFastEdge(e.head, e.tail);
|
|
18103
|
-
if (f !== void 0) {
|
|
18104
|
-
mergeOneway(e, f);
|
|
18105
|
-
} else {
|
|
18106
|
-
virtualEdge(e.head, e.tail, e);
|
|
18107
|
-
}
|
|
18108
|
-
}
|
|
18109
|
-
function fastNode(g, n) {
|
|
18110
|
-
n.info.next = g.info.nlist;
|
|
18111
|
-
if (g.info.nlist !== void 0) g.info.nlist.info.prev = n;
|
|
18112
|
-
n.info.prev = void 0;
|
|
18113
|
-
g.info.nlist = n;
|
|
18114
|
-
}
|
|
18115
|
-
function deleteFastNode(g, n) {
|
|
18116
|
-
if (n.info.prev !== void 0) n.info.prev.info.next = n.info.next;
|
|
18117
|
-
else g.info.nlist = n.info.next;
|
|
18118
|
-
if (n.info.next !== void 0) n.info.next.info.prev = n.info.prev;
|
|
18119
|
-
}
|
|
18120
|
-
function removeFromRank(g, n) {
|
|
18121
|
-
const r = n.info.rank !== void 0 ? n.info.rank : 0;
|
|
18122
|
-
const rank3 = g.info.rank;
|
|
18123
|
-
if (rank3 === void 0) return;
|
|
18124
|
-
const rk = rank3[r];
|
|
18125
|
-
for (let j = 0; j < rk.n; j++) {
|
|
18126
|
-
const v = rk.v[j];
|
|
18127
|
-
if (v === n) {
|
|
18128
|
-
for (j++; j < rk.n; j++) {
|
|
18129
|
-
rk.v[j - 1] = rk.v[j];
|
|
18130
|
-
}
|
|
18131
|
-
rk.n--;
|
|
18132
|
-
break;
|
|
18133
|
-
}
|
|
18134
|
-
}
|
|
18135
|
-
}
|
|
18136
|
-
function virtualNode(g) {
|
|
18137
|
-
const n = new Node(0, "", g.root);
|
|
18138
|
-
n.info.node_type = VIRTUAL;
|
|
18139
|
-
n.info.lw = 1;
|
|
18140
|
-
n.info.rw = 1;
|
|
18141
|
-
n.info.ht = 1;
|
|
18142
|
-
n.info.UF_size = 1;
|
|
18143
|
-
n.info.in = { list: [], size: 0 };
|
|
18144
|
-
n.info.out = { list: [], size: 0 };
|
|
18145
|
-
fastNode(g, n);
|
|
18146
|
-
return n;
|
|
18147
|
-
}
|
|
18148
|
-
function otherEdge(e) {
|
|
18149
|
-
if (!e.tail.info.other) e.tail.info.other = { list: [], size: 0 };
|
|
18150
|
-
elistAppend(e.tail.info.other, e);
|
|
18151
|
-
}
|
|
18152
|
-
|
|
18153
|
-
// src/layout/dot/decomp.ts
|
|
18154
|
-
function nodesInSeq(g) {
|
|
18155
|
-
return [...g.nodes.values()].sort((a, b) => a.id - b.id);
|
|
18156
|
-
}
|
|
18157
|
-
function ufFind(n) {
|
|
18158
|
-
while (n.info.UF_parent !== void 0 && n.info.UF_parent !== n) {
|
|
18159
|
-
const gp = n.info.UF_parent.info.UF_parent;
|
|
18160
|
-
if (gp !== void 0) n.info.UF_parent = gp;
|
|
18161
|
-
n = n.info.UF_parent;
|
|
18162
|
-
}
|
|
18163
|
-
return n;
|
|
18164
|
-
}
|
|
18165
|
-
function ufUnion(u, v) {
|
|
18166
|
-
if (u === v) return u;
|
|
18167
|
-
if (u.info.UF_parent === void 0) {
|
|
18168
|
-
u.info.UF_parent = u;
|
|
18169
|
-
u.info.UF_size = 1;
|
|
18170
|
-
} else u = ufFind(u);
|
|
18171
|
-
if (v.info.UF_parent === void 0) {
|
|
18172
|
-
v.info.UF_parent = v;
|
|
18173
|
-
v.info.UF_size = 1;
|
|
18174
|
-
} else v = ufFind(v);
|
|
18175
|
-
if (u === v) return u;
|
|
18176
|
-
const us = u.info.UF_size ?? 0;
|
|
18177
|
-
const vs = v.info.UF_size ?? 0;
|
|
18178
|
-
v.info.UF_parent = u;
|
|
18179
|
-
u.info.UF_size = us + vs;
|
|
18180
|
-
return u;
|
|
18181
|
-
}
|
|
18182
|
-
function ufSingleton(u) {
|
|
18183
|
-
u.info.UF_size = 1;
|
|
18184
|
-
u.info.UF_parent = void 0;
|
|
18185
|
-
u.info.ranktype = 0;
|
|
18186
|
-
}
|
|
18187
|
-
function ufSetname(u, v) {
|
|
18188
|
-
u.info.UF_parent = v;
|
|
18189
|
-
v.info.UF_size = (v.info.UF_size ?? 0) + (u.info.UF_size ?? 0);
|
|
18190
|
-
}
|
|
18191
|
-
function decompPushNeighbors(stk, el, n, cmark) {
|
|
18192
|
-
if (!el || el.size === 0) return;
|
|
18193
|
-
for (let i = el.size - 1; i >= 0; i--) {
|
|
18194
|
-
const e = el.list[i];
|
|
18195
|
-
const other = e.head === n ? e.tail : e.head;
|
|
18196
|
-
if (other.info.mark !== cmark && other === ufFind(other)) {
|
|
18197
|
-
other.info.mark = cmark + 1;
|
|
18198
|
-
stk.push(other);
|
|
18199
|
-
}
|
|
18200
|
-
}
|
|
18201
|
-
}
|
|
18202
|
-
function decompSearch(g, start, cmark) {
|
|
18203
|
-
const stk = [];
|
|
18204
|
-
let lastNode;
|
|
18205
|
-
start.info.mark = cmark + 1;
|
|
18206
|
-
stk.push(start);
|
|
18207
|
-
g.info.nlist = void 0;
|
|
18208
|
-
let top;
|
|
18209
|
-
while ((top = stk.pop()) !== void 0) {
|
|
18210
|
-
if (top.info.mark === cmark) continue;
|
|
18211
|
-
top.info.mark = cmark;
|
|
18212
|
-
if (lastNode !== void 0) {
|
|
18213
|
-
top.info.prev = lastNode;
|
|
18214
|
-
lastNode.info.next = top;
|
|
18215
|
-
} else {
|
|
18216
|
-
top.info.prev = void 0;
|
|
18217
|
-
g.info.nlist = top;
|
|
18218
|
-
}
|
|
18219
|
-
lastNode = top;
|
|
18220
|
-
top.info.next = void 0;
|
|
18221
|
-
decompPushNeighbors(stk, top.info.flat_in, top, cmark);
|
|
18222
|
-
decompPushNeighbors(stk, top.info.flat_out, top, cmark);
|
|
18223
|
-
decompPushNeighbors(stk, top.info.in, top, cmark);
|
|
18224
|
-
decompPushNeighbors(stk, top.info.out, top, cmark);
|
|
18225
|
-
}
|
|
18226
|
-
}
|
|
18227
|
-
var _dc = { cmark: 0 };
|
|
18228
|
-
function resolveNode(n, pass) {
|
|
18229
|
-
if (pass > 0) {
|
|
18230
|
-
const subg = n.info.clust;
|
|
18231
|
-
if (subg) return subg.info.rankleader?.[n.info.rank ?? 0];
|
|
18232
|
-
}
|
|
18233
|
-
return n === ufFind(n) ? n : void 0;
|
|
18234
|
-
}
|
|
18235
|
-
function decompose(g, pass) {
|
|
18236
|
-
if (++_dc.cmark === 0) _dc.cmark = 1;
|
|
18237
|
-
const cmark = _dc.cmark;
|
|
18238
|
-
g.info.comp = [];
|
|
18239
|
-
for (const n of nodesInSeq(g)) {
|
|
18240
|
-
const v = resolveNode(n, pass);
|
|
18241
|
-
if (v !== void 0 && v.info.mark !== cmark) {
|
|
18242
|
-
decompSearch(g, v, cmark);
|
|
18243
|
-
g.info.comp.push(g.info.nlist);
|
|
18244
|
-
}
|
|
18245
|
-
}
|
|
18246
|
-
}
|
|
18247
|
-
|
|
18248
|
-
// src/layout/dot/mincross-utils.ts
|
|
18249
|
-
var CONVERGENCE = 0.995;
|
|
18250
|
-
function matrixGet(m, row, col) {
|
|
18251
|
-
if (row >= m.nrows || col >= m.ncols) return false;
|
|
18252
|
-
const idx = row * m.ncols + col;
|
|
18253
|
-
return (m.data[idx >> 3] >> (idx & 7) & 1) === 1;
|
|
18254
|
-
}
|
|
18255
|
-
function matrixSet(m, row, col) {
|
|
18256
|
-
if (row >= m.nrows || col >= m.ncols) matrixExpand(m, row, col);
|
|
18257
|
-
const idx = row * m.ncols + col;
|
|
18258
|
-
m.data[idx >> 3] |= 1 << (idx & 7);
|
|
18259
|
-
}
|
|
18260
|
-
function matrixCopyBits(m, data, ncols) {
|
|
18261
|
-
for (let r = 0; r < m.nrows; r++) {
|
|
18262
|
-
for (let c = 0; c < m.ncols; c++) {
|
|
18263
|
-
if (!matrixGet(m, r, c)) continue;
|
|
18264
|
-
const idx = r * ncols + c;
|
|
18265
|
-
data[idx >> 3] |= 1 << (idx & 7);
|
|
18266
|
-
}
|
|
18267
|
-
}
|
|
18268
|
-
}
|
|
18269
|
-
function matrixExpand(m, row, col) {
|
|
18270
|
-
const nrows = Math.max(m.nrows, row + 1);
|
|
18271
|
-
const ncols = Math.max(m.ncols, col + 1);
|
|
18272
|
-
const bits = nrows * ncols;
|
|
18273
|
-
const bytes = (bits >> 3) + (bits & 7 ? 1 : 0);
|
|
18274
|
-
const data = new Uint8Array(bytes);
|
|
18275
|
-
matrixCopyBits(m, data, ncols);
|
|
18276
|
-
m.nrows = nrows;
|
|
18277
|
-
m.ncols = ncols;
|
|
18278
|
-
m.data = data;
|
|
18279
|
-
}
|
|
18280
|
-
function newMatrix(rows, cols) {
|
|
18281
|
-
const bits = rows * cols;
|
|
18282
|
-
const bytes = (bits >> 3) + (bits & 7 ? 1 : 0);
|
|
18283
|
-
return { nrows: rows, ncols: cols, data: new Uint8Array(bytes) };
|
|
18284
|
-
}
|
|
18285
|
-
function dotRoot(g) {
|
|
18286
|
-
return g.info.dotroot ?? g.root;
|
|
18287
|
-
}
|
|
18288
|
-
function agContainsNode(g, n) {
|
|
18289
|
-
return g.nodes.get(n.name) === n;
|
|
18290
|
-
}
|
|
18291
|
-
function agContainsEdge(g, e) {
|
|
18292
|
-
return g.edges.includes(e);
|
|
18293
|
-
}
|
|
18294
|
-
function rankGet(rank3, i) {
|
|
18295
|
-
return rank3.v[(rank3.vStart ?? 0) + i];
|
|
18296
|
-
}
|
|
18297
|
-
function rankSet(rank3, i, n) {
|
|
18298
|
-
rank3.v[(rank3.vStart ?? 0) + i] = n;
|
|
18299
|
-
}
|
|
18300
|
-
function isNormalNodeOf(g, v) {
|
|
18301
|
-
return v.info.node_type === NORMAL && agContainsNode(g, v);
|
|
18302
|
-
}
|
|
18303
|
-
function isVnodeOfEdgeOf(g, v) {
|
|
18304
|
-
if (v.info.node_type !== VIRTUAL) return false;
|
|
18305
|
-
const inSz = v.info.in ? v.info.in.size : 0;
|
|
18306
|
-
const outSz = v.info.out ? v.info.out.size : 0;
|
|
18307
|
-
if (inSz !== 1 || outSz !== 1) return false;
|
|
18308
|
-
let e = v.info.out.list[0];
|
|
18309
|
-
while (e.info.edge_type !== NORMAL && e.info.to_orig) e = e.info.to_orig;
|
|
18310
|
-
return agContainsEdge(g, e);
|
|
18311
|
-
}
|
|
18312
|
-
function insideCluster(g, v) {
|
|
18313
|
-
return isNormalNodeOf(g, v) || isVnodeOfEdgeOf(g, v);
|
|
18314
|
-
}
|
|
18315
|
-
function neighborNode(ctx, v, dir) {
|
|
18316
|
-
const rk = ctx.root.info.rank?.[v.info.rank ?? 0];
|
|
18317
|
-
if (!rk) return void 0;
|
|
18318
|
-
const order = v.info.order ?? 0;
|
|
18319
|
-
return (dir < 0 ? order > 0 ? rk.v[order - 1] : void 0 : rk.v[order + 1]) ?? void 0;
|
|
18320
|
-
}
|
|
18321
|
-
function furthestNode(ctx, g, v, dir) {
|
|
18322
|
-
let rv = v;
|
|
18323
|
-
let u = v;
|
|
18324
|
-
while ((u = neighborNode(ctx, u, dir)) !== void 0) {
|
|
18325
|
-
if (isNormalNodeOf(g, u) || isVnodeOfEdgeOf(g, u)) rv = u;
|
|
18326
|
-
}
|
|
18327
|
-
return rv;
|
|
18328
|
-
}
|
|
18329
|
-
|
|
18330
|
-
// src/common/splines-geom.ts
|
|
18331
|
-
function approxEqPt(p, q, tol) {
|
|
18332
|
-
const dx = p.x - q.x;
|
|
18333
|
-
const dy = p.y - q.y;
|
|
18334
|
-
return dx * dx + dy * dy < tol * tol;
|
|
18335
|
-
}
|
|
18336
|
-
function evalBezier(sp, t, left, right) {
|
|
18337
|
-
const ab = { x: sp[0].x + t * (sp[1].x - sp[0].x), y: sp[0].y + t * (sp[1].y - sp[0].y) };
|
|
18338
|
-
const bc = { x: sp[1].x + t * (sp[2].x - sp[1].x), y: sp[1].y + t * (sp[2].y - sp[1].y) };
|
|
18339
|
-
const cd = { x: sp[2].x + t * (sp[3].x - sp[2].x), y: sp[2].y + t * (sp[3].y - sp[2].y) };
|
|
18340
|
-
const abbc = { x: ab.x + t * (bc.x - ab.x), y: ab.y + t * (bc.y - ab.y) };
|
|
18341
|
-
const bccd = { x: bc.x + t * (cd.x - bc.x), y: bc.y + t * (cd.y - bc.y) };
|
|
18342
|
-
const pt = { x: abbc.x + t * (bccd.x - abbc.x), y: abbc.y + t * (bccd.y - abbc.y) };
|
|
18343
|
-
if (left !== null) {
|
|
18344
|
-
left[0] = sp[0];
|
|
18345
|
-
left[1] = ab;
|
|
18346
|
-
left[2] = abbc;
|
|
18347
|
-
left[3] = pt;
|
|
18348
|
-
}
|
|
18349
|
-
if (right !== null) {
|
|
18350
|
-
right[0] = pt;
|
|
18351
|
-
right[1] = bccd;
|
|
18352
|
-
right[2] = cd;
|
|
18353
|
-
right[3] = sp[3];
|
|
18354
|
-
}
|
|
18355
|
-
return pt;
|
|
18356
|
-
}
|
|
18357
|
-
var HW = 2;
|
|
18358
|
-
var SMALL = 1e-10;
|
|
18359
|
-
function ptToLine2(a, b, p) {
|
|
18360
|
-
const dx = b.x - a.x;
|
|
18361
|
-
const dy = b.y - a.y;
|
|
18362
|
-
let a2 = (p.y - a.y) * dx - (p.x - a.x) * dy;
|
|
18363
|
-
a2 *= a2;
|
|
18364
|
-
if (a2 < SMALL) return 0;
|
|
18365
|
-
return a2 / (dx * dx + dy * dy);
|
|
18366
|
-
}
|
|
18367
|
-
function checkControlPoints(cp) {
|
|
18368
|
-
const dis1 = ptToLine2(cp[0], cp[3], cp[1]);
|
|
18369
|
-
const dis2 = ptToLine2(cp[0], cp[3], cp[2]);
|
|
18370
|
-
return dis1 < HW * HW && dis2 < HW * HW;
|
|
18371
|
-
}
|
|
18372
|
-
function anyOutside(bb, cp) {
|
|
18373
|
-
return cp.some((p) => p.x > bb.ur.x || p.x < bb.ll.x || p.y > bb.ur.y || p.y < bb.ll.y);
|
|
18374
|
-
}
|
|
18375
|
-
function expandByPoints(bb, cp) {
|
|
18376
|
-
for (const p of cp) {
|
|
18377
|
-
if (p.x > bb.ur.x) bb.ur.x = p.x;
|
|
18378
|
-
else if (p.x < bb.ll.x) bb.ll.x = p.x;
|
|
18379
|
-
if (p.y > bb.ur.y) bb.ur.y = p.y;
|
|
18380
|
-
else if (p.y < bb.ll.y) bb.ll.y = p.y;
|
|
17113
|
+
function anyOutside(bb, cp) {
|
|
17114
|
+
return cp.some((p) => p.x > bb.ur.x || p.x < bb.ll.x || p.y > bb.ur.y || p.y < bb.ll.y);
|
|
17115
|
+
}
|
|
17116
|
+
function expandByPoints(bb, cp) {
|
|
17117
|
+
for (const p of cp) {
|
|
17118
|
+
if (p.x > bb.ur.x) bb.ur.x = p.x;
|
|
17119
|
+
else if (p.x < bb.ll.x) bb.ll.x = p.x;
|
|
17120
|
+
if (p.y > bb.ur.y) bb.ur.y = p.y;
|
|
17121
|
+
else if (p.y < bb.ll.y) bb.ll.y = p.y;
|
|
18381
17122
|
}
|
|
18382
17123
|
}
|
|
18383
17124
|
function updateBbBz(bb, cp) {
|
|
@@ -20284,6 +19025,101 @@ function doGraphLabel(sg, measurer) {
|
|
|
20284
19025
|
applyLabelBorder(sg, { x: label.dimen.x + 4 * GAP2, y: label.dimen.y + 2 * GAP2 });
|
|
20285
19026
|
}
|
|
20286
19027
|
|
|
19028
|
+
// src/layout/dot/decomp.ts
|
|
19029
|
+
function nodesInSeq(g) {
|
|
19030
|
+
return [...g.nodes.values()].sort((a, b) => a.id - b.id);
|
|
19031
|
+
}
|
|
19032
|
+
function ufFind(n) {
|
|
19033
|
+
while (n.info.UF_parent !== void 0 && n.info.UF_parent !== n) {
|
|
19034
|
+
const gp = n.info.UF_parent.info.UF_parent;
|
|
19035
|
+
if (gp !== void 0) n.info.UF_parent = gp;
|
|
19036
|
+
n = n.info.UF_parent;
|
|
19037
|
+
}
|
|
19038
|
+
return n;
|
|
19039
|
+
}
|
|
19040
|
+
function ufUnion(u, v) {
|
|
19041
|
+
if (u === v) return u;
|
|
19042
|
+
if (u.info.UF_parent === void 0) {
|
|
19043
|
+
u.info.UF_parent = u;
|
|
19044
|
+
u.info.UF_size = 1;
|
|
19045
|
+
} else u = ufFind(u);
|
|
19046
|
+
if (v.info.UF_parent === void 0) {
|
|
19047
|
+
v.info.UF_parent = v;
|
|
19048
|
+
v.info.UF_size = 1;
|
|
19049
|
+
} else v = ufFind(v);
|
|
19050
|
+
if (u === v) return u;
|
|
19051
|
+
const us = u.info.UF_size ?? 0;
|
|
19052
|
+
const vs = v.info.UF_size ?? 0;
|
|
19053
|
+
v.info.UF_parent = u;
|
|
19054
|
+
u.info.UF_size = us + vs;
|
|
19055
|
+
return u;
|
|
19056
|
+
}
|
|
19057
|
+
function ufSingleton(u) {
|
|
19058
|
+
u.info.UF_size = 1;
|
|
19059
|
+
u.info.UF_parent = void 0;
|
|
19060
|
+
u.info.ranktype = 0;
|
|
19061
|
+
}
|
|
19062
|
+
function ufSetname(u, v) {
|
|
19063
|
+
u.info.UF_parent = v;
|
|
19064
|
+
v.info.UF_size = (v.info.UF_size ?? 0) + (u.info.UF_size ?? 0);
|
|
19065
|
+
}
|
|
19066
|
+
function decompPushNeighbors(stk, el, n, cmark) {
|
|
19067
|
+
if (!el || el.size === 0) return;
|
|
19068
|
+
for (let i = el.size - 1; i >= 0; i--) {
|
|
19069
|
+
const e = el.list[i];
|
|
19070
|
+
const other = e.head === n ? e.tail : e.head;
|
|
19071
|
+
if (other.info.mark !== cmark && other === ufFind(other)) {
|
|
19072
|
+
other.info.mark = cmark + 1;
|
|
19073
|
+
stk.push(other);
|
|
19074
|
+
}
|
|
19075
|
+
}
|
|
19076
|
+
}
|
|
19077
|
+
function decompSearch(g, start, cmark) {
|
|
19078
|
+
const stk = [];
|
|
19079
|
+
let lastNode;
|
|
19080
|
+
start.info.mark = cmark + 1;
|
|
19081
|
+
stk.push(start);
|
|
19082
|
+
g.info.nlist = void 0;
|
|
19083
|
+
let top;
|
|
19084
|
+
while ((top = stk.pop()) !== void 0) {
|
|
19085
|
+
if (top.info.mark === cmark) continue;
|
|
19086
|
+
top.info.mark = cmark;
|
|
19087
|
+
if (lastNode !== void 0) {
|
|
19088
|
+
top.info.prev = lastNode;
|
|
19089
|
+
lastNode.info.next = top;
|
|
19090
|
+
} else {
|
|
19091
|
+
top.info.prev = void 0;
|
|
19092
|
+
g.info.nlist = top;
|
|
19093
|
+
}
|
|
19094
|
+
lastNode = top;
|
|
19095
|
+
top.info.next = void 0;
|
|
19096
|
+
decompPushNeighbors(stk, top.info.flat_in, top, cmark);
|
|
19097
|
+
decompPushNeighbors(stk, top.info.flat_out, top, cmark);
|
|
19098
|
+
decompPushNeighbors(stk, top.info.in, top, cmark);
|
|
19099
|
+
decompPushNeighbors(stk, top.info.out, top, cmark);
|
|
19100
|
+
}
|
|
19101
|
+
}
|
|
19102
|
+
var _dc = { cmark: 0 };
|
|
19103
|
+
function resolveNode(n, pass) {
|
|
19104
|
+
if (pass > 0) {
|
|
19105
|
+
const subg = n.info.clust;
|
|
19106
|
+
if (subg) return subg.info.rankleader?.[n.info.rank ?? 0];
|
|
19107
|
+
}
|
|
19108
|
+
return n === ufFind(n) ? n : void 0;
|
|
19109
|
+
}
|
|
19110
|
+
function decompose(g, pass) {
|
|
19111
|
+
if (++_dc.cmark === 0) _dc.cmark = 1;
|
|
19112
|
+
const cmark = _dc.cmark;
|
|
19113
|
+
g.info.comp = [];
|
|
19114
|
+
for (const n of nodesInSeq(g)) {
|
|
19115
|
+
const v = resolveNode(n, pass);
|
|
19116
|
+
if (v !== void 0 && v.info.mark !== cmark) {
|
|
19117
|
+
decompSearch(g, v, cmark);
|
|
19118
|
+
g.info.comp.push(g.info.nlist);
|
|
19119
|
+
}
|
|
19120
|
+
}
|
|
19121
|
+
}
|
|
19122
|
+
|
|
20287
19123
|
// src/layout/dot/acyclic.ts
|
|
20288
19124
|
function dfsStep(stack) {
|
|
20289
19125
|
const f = stack[stack.length - 1];
|
|
@@ -21826,6 +20662,216 @@ function dot2Rank(g) {
|
|
|
21826
20662
|
readoutLevels(g, Xg, ncc);
|
|
21827
20663
|
}
|
|
21828
20664
|
|
|
20665
|
+
// src/layout/dot/mincross-utils.ts
|
|
20666
|
+
var CONVERGENCE = 0.995;
|
|
20667
|
+
function matrixGet(m, row, col) {
|
|
20668
|
+
if (row >= m.nrows || col >= m.ncols) return false;
|
|
20669
|
+
const idx = row * m.ncols + col;
|
|
20670
|
+
return (m.data[idx >> 3] >> (idx & 7) & 1) === 1;
|
|
20671
|
+
}
|
|
20672
|
+
function matrixSet(m, row, col) {
|
|
20673
|
+
if (row >= m.nrows || col >= m.ncols) matrixExpand(m, row, col);
|
|
20674
|
+
const idx = row * m.ncols + col;
|
|
20675
|
+
m.data[idx >> 3] |= 1 << (idx & 7);
|
|
20676
|
+
}
|
|
20677
|
+
function matrixCopyBits(m, data, ncols) {
|
|
20678
|
+
for (let r = 0; r < m.nrows; r++) {
|
|
20679
|
+
for (let c = 0; c < m.ncols; c++) {
|
|
20680
|
+
if (!matrixGet(m, r, c)) continue;
|
|
20681
|
+
const idx = r * ncols + c;
|
|
20682
|
+
data[idx >> 3] |= 1 << (idx & 7);
|
|
20683
|
+
}
|
|
20684
|
+
}
|
|
20685
|
+
}
|
|
20686
|
+
function matrixExpand(m, row, col) {
|
|
20687
|
+
const nrows = Math.max(m.nrows, row + 1);
|
|
20688
|
+
const ncols = Math.max(m.ncols, col + 1);
|
|
20689
|
+
const bits = nrows * ncols;
|
|
20690
|
+
const bytes = (bits >> 3) + (bits & 7 ? 1 : 0);
|
|
20691
|
+
const data = new Uint8Array(bytes);
|
|
20692
|
+
matrixCopyBits(m, data, ncols);
|
|
20693
|
+
m.nrows = nrows;
|
|
20694
|
+
m.ncols = ncols;
|
|
20695
|
+
m.data = data;
|
|
20696
|
+
}
|
|
20697
|
+
function newMatrix(rows, cols) {
|
|
20698
|
+
const bits = rows * cols;
|
|
20699
|
+
const bytes = (bits >> 3) + (bits & 7 ? 1 : 0);
|
|
20700
|
+
return { nrows: rows, ncols: cols, data: new Uint8Array(bytes) };
|
|
20701
|
+
}
|
|
20702
|
+
function dotRoot(g) {
|
|
20703
|
+
return g.info.dotroot ?? g.root;
|
|
20704
|
+
}
|
|
20705
|
+
function agContainsNode(g, n) {
|
|
20706
|
+
return g.nodes.get(n.name) === n;
|
|
20707
|
+
}
|
|
20708
|
+
function agContainsEdge(g, e) {
|
|
20709
|
+
return g.edges.includes(e);
|
|
20710
|
+
}
|
|
20711
|
+
function rankGet(rank3, i) {
|
|
20712
|
+
return rank3.v[(rank3.vStart ?? 0) + i];
|
|
20713
|
+
}
|
|
20714
|
+
function rankSet(rank3, i, n) {
|
|
20715
|
+
rank3.v[(rank3.vStart ?? 0) + i] = n;
|
|
20716
|
+
}
|
|
20717
|
+
function isNormalNodeOf(g, v) {
|
|
20718
|
+
return v.info.node_type === NORMAL && agContainsNode(g, v);
|
|
20719
|
+
}
|
|
20720
|
+
function isVnodeOfEdgeOf(g, v) {
|
|
20721
|
+
if (v.info.node_type !== VIRTUAL) return false;
|
|
20722
|
+
const inSz = v.info.in ? v.info.in.size : 0;
|
|
20723
|
+
const outSz = v.info.out ? v.info.out.size : 0;
|
|
20724
|
+
if (inSz !== 1 || outSz !== 1) return false;
|
|
20725
|
+
let e = v.info.out.list[0];
|
|
20726
|
+
while (e.info.edge_type !== NORMAL && e.info.to_orig) e = e.info.to_orig;
|
|
20727
|
+
return agContainsEdge(g, e);
|
|
20728
|
+
}
|
|
20729
|
+
function insideCluster(g, v) {
|
|
20730
|
+
return isNormalNodeOf(g, v) || isVnodeOfEdgeOf(g, v);
|
|
20731
|
+
}
|
|
20732
|
+
function neighborNode(ctx, v, dir) {
|
|
20733
|
+
const rk = ctx.root.info.rank?.[v.info.rank ?? 0];
|
|
20734
|
+
if (!rk) return void 0;
|
|
20735
|
+
const order = v.info.order ?? 0;
|
|
20736
|
+
return (dir < 0 ? order > 0 ? rk.v[order - 1] : void 0 : rk.v[order + 1]) ?? void 0;
|
|
20737
|
+
}
|
|
20738
|
+
function furthestNode(ctx, g, v, dir) {
|
|
20739
|
+
let rv = v;
|
|
20740
|
+
let u = v;
|
|
20741
|
+
while ((u = neighborNode(ctx, u, dir)) !== void 0) {
|
|
20742
|
+
if (isNormalNodeOf(g, u) || isVnodeOfEdgeOf(g, u)) rv = u;
|
|
20743
|
+
}
|
|
20744
|
+
return rv;
|
|
20745
|
+
}
|
|
20746
|
+
|
|
20747
|
+
// src/layout/dot/cluster-path.ts
|
|
20748
|
+
var CLUSTER_EDGE = 5;
|
|
20749
|
+
function mapInterclustNode(n) {
|
|
20750
|
+
const clust = n.info.clust;
|
|
20751
|
+
if (clust === void 0 || clust.info.expanded) return n;
|
|
20752
|
+
return clust.info.rankleader[n.info.rank ?? 0];
|
|
20753
|
+
}
|
|
20754
|
+
function makeSlotsContract(root, r, pos, d) {
|
|
20755
|
+
const rk = root.info.rank[r];
|
|
20756
|
+
for (let i = pos - d + 1; i < rk.n; i++) {
|
|
20757
|
+
const v = rk.v[i];
|
|
20758
|
+
v.info.order = i + d - 1;
|
|
20759
|
+
rk.v[v.info.order] = v;
|
|
20760
|
+
}
|
|
20761
|
+
for (let i = rk.n + d - 1; i < rk.n; i++) rk.v[i] = null;
|
|
20762
|
+
}
|
|
20763
|
+
function makeSlotsExpand(root, r, pos, d) {
|
|
20764
|
+
const rk = root.info.rank[r];
|
|
20765
|
+
for (let i = rk.n - 1; i > pos; i--) {
|
|
20766
|
+
const v = rk.v[i];
|
|
20767
|
+
v.info.order = i + d - 1;
|
|
20768
|
+
rk.v[v.info.order] = v;
|
|
20769
|
+
}
|
|
20770
|
+
for (let i = pos + 1; i < pos + d; i++) rk.v[i] = null;
|
|
20771
|
+
}
|
|
20772
|
+
function makeSlots(root, r, pos, d) {
|
|
20773
|
+
if (d <= 0) makeSlotsContract(root, r, pos, d);
|
|
20774
|
+
else makeSlotsExpand(root, r, pos, d);
|
|
20775
|
+
root.info.rank[r].n += d - 1;
|
|
20776
|
+
}
|
|
20777
|
+
function cloneVn(g, vn) {
|
|
20778
|
+
const r = vn.info.rank ?? 0;
|
|
20779
|
+
makeSlots(g, r, vn.info.order, 2);
|
|
20780
|
+
const rv = virtualNode(g);
|
|
20781
|
+
rv.info.lw = vn.info.lw;
|
|
20782
|
+
rv.info.rw = vn.info.rw;
|
|
20783
|
+
rv.info.rank = r;
|
|
20784
|
+
rv.info.order = (vn.info.order ?? 0) + 1;
|
|
20785
|
+
g.info.rank[r].v[rv.info.order] = rv;
|
|
20786
|
+
return rv;
|
|
20787
|
+
}
|
|
20788
|
+
function safeOtherEdge(e) {
|
|
20789
|
+
if (!e.tail.info.other) e.tail.info.other = { list: [], size: 0 };
|
|
20790
|
+
const other = e.tail.info.other;
|
|
20791
|
+
for (let i = 0; i < other.size; i++) if (other.list[i] === e) return;
|
|
20792
|
+
other.list[other.size++] = e;
|
|
20793
|
+
}
|
|
20794
|
+
function portsEqSimple(orig, e) {
|
|
20795
|
+
const hp = orig.info.head_port;
|
|
20796
|
+
const tp = orig.info.tail_port;
|
|
20797
|
+
const ehp = e.info.head_port;
|
|
20798
|
+
const etp = e.info.tail_port;
|
|
20799
|
+
return hp.defined === ehp.defined && tp.defined === etp.defined && (!hp.defined || hp.p.x === ehp.p.x && hp.p.y === ehp.p.y) && (!tp.defined || tp.p.x === etp.p.x && tp.p.y === etp.p.y);
|
|
20800
|
+
}
|
|
20801
|
+
function mapPathAdjacentMulti(from, to, orig, ve, type) {
|
|
20802
|
+
const root = dotRoot(from.root);
|
|
20803
|
+
let u = from;
|
|
20804
|
+
for (let r = from.info.rank ?? 0; r < (to.info.rank ?? 0); r++) {
|
|
20805
|
+
const v = r < (to.info.rank ?? 0) - 1 ? cloneVn(root, ve.head) : to;
|
|
20806
|
+
const e = virtualEdge(u, v, orig);
|
|
20807
|
+
e.info.edge_type = type;
|
|
20808
|
+
u = v;
|
|
20809
|
+
ve.info.count = (ve.info.count ?? 1) - 1;
|
|
20810
|
+
ve = ve.head.info.out.list[0];
|
|
20811
|
+
}
|
|
20812
|
+
}
|
|
20813
|
+
function mapPathAdjacentSingle(from, to, orig, ve, type) {
|
|
20814
|
+
const existing = findFastEdge(from, to);
|
|
20815
|
+
if (existing !== void 0 && portsEqSimple(orig, existing)) {
|
|
20816
|
+
orig.info.to_virt = existing;
|
|
20817
|
+
existing.info.edge_type = type;
|
|
20818
|
+
existing.info.count = (existing.info.count ?? 1) + 1;
|
|
20819
|
+
if (from.info.node_type === NORMAL && to.info.node_type === NORMAL)
|
|
20820
|
+
safeOtherEdge(orig);
|
|
20821
|
+
} else {
|
|
20822
|
+
orig.info.to_virt = void 0;
|
|
20823
|
+
const e = virtualEdge(from, to, orig);
|
|
20824
|
+
e.info.edge_type = type;
|
|
20825
|
+
ve.info.count = (ve.info.count ?? 1) - 1;
|
|
20826
|
+
}
|
|
20827
|
+
}
|
|
20828
|
+
function mapPathLongSingle(from, to, orig, ve, type) {
|
|
20829
|
+
let e;
|
|
20830
|
+
if (ve.tail !== from) {
|
|
20831
|
+
orig.info.to_virt = void 0;
|
|
20832
|
+
e = orig.info.to_virt = virtualEdge(from, ve.head, orig);
|
|
20833
|
+
deleteFastEdge(ve);
|
|
20834
|
+
} else {
|
|
20835
|
+
e = ve;
|
|
20836
|
+
}
|
|
20837
|
+
while ((e.head.info.rank ?? 0) !== (to.info.rank ?? 0))
|
|
20838
|
+
e = e.head.info.out.list[0];
|
|
20839
|
+
if (e.head !== to) {
|
|
20840
|
+
const old = e;
|
|
20841
|
+
e = virtualEdge(e.tail, to, orig);
|
|
20842
|
+
e.info.edge_type = type;
|
|
20843
|
+
deleteFastEdge(old);
|
|
20844
|
+
}
|
|
20845
|
+
}
|
|
20846
|
+
function mapPathMultiEdge(from, to, orig, ve, type) {
|
|
20847
|
+
orig.info.to_virt = void 0;
|
|
20848
|
+
const span = (to.info.rank ?? 0) - (from.info.rank ?? 0);
|
|
20849
|
+
if (span === 1) {
|
|
20850
|
+
const ex = findFastEdge(from, to);
|
|
20851
|
+
if (ex !== void 0 && portsEqSimple(orig, ex)) {
|
|
20852
|
+
mergeOneway(orig, ex);
|
|
20853
|
+
if (from.info.node_type === NORMAL && to.info.node_type === NORMAL)
|
|
20854
|
+
safeOtherEdge(orig);
|
|
20855
|
+
return;
|
|
20856
|
+
}
|
|
20857
|
+
}
|
|
20858
|
+
mapPathAdjacentMulti(from, to, orig, ve, type);
|
|
20859
|
+
}
|
|
20860
|
+
function mapPath(from, to, orig, ve, type) {
|
|
20861
|
+
if (ve.tail === from && ve.head === to) return;
|
|
20862
|
+
const span = (to.info.rank ?? 0) - (from.info.rank ?? 0);
|
|
20863
|
+
const cnt = ve.info.count ?? 1;
|
|
20864
|
+
if (cnt > 1) mapPathMultiEdge(from, to, orig, ve, type);
|
|
20865
|
+
else if (span === 1) mapPathAdjacentSingle(from, to, orig, ve, type);
|
|
20866
|
+
else mapPathLongSingle(from, to, orig, ve, type);
|
|
20867
|
+
}
|
|
20868
|
+
function makeInterclustChain(from, to, orig) {
|
|
20869
|
+
const u = mapInterclustNode(from);
|
|
20870
|
+
const v = mapInterclustNode(to);
|
|
20871
|
+
const type = u === from && v === to ? VIRTUAL : CLUSTER_EDGE;
|
|
20872
|
+
mapPath(u, v, orig, orig.info.to_virt, type);
|
|
20873
|
+
}
|
|
20874
|
+
|
|
21829
20875
|
// src/layout/dot/mincross-cross.ts
|
|
21830
20876
|
var reMincross = false;
|
|
21831
20877
|
function setReMincross(b) {
|
|
@@ -22476,134 +21522,6 @@ function orderedEdges(ctx, g) {
|
|
|
22476
21522
|
doOrderingForNodes(ctx, g);
|
|
22477
21523
|
}
|
|
22478
21524
|
|
|
22479
|
-
// src/layout/dot/cluster-path.ts
|
|
22480
|
-
var CLUSTER_EDGE = 5;
|
|
22481
|
-
function mapInterclustNode(n) {
|
|
22482
|
-
const clust = n.info.clust;
|
|
22483
|
-
if (clust === void 0 || clust.info.expanded) return n;
|
|
22484
|
-
return clust.info.rankleader[n.info.rank ?? 0];
|
|
22485
|
-
}
|
|
22486
|
-
function makeSlotsContract(root, r, pos, d) {
|
|
22487
|
-
const rk = root.info.rank[r];
|
|
22488
|
-
for (let i = pos - d + 1; i < rk.n; i++) {
|
|
22489
|
-
const v = rk.v[i];
|
|
22490
|
-
v.info.order = i + d - 1;
|
|
22491
|
-
rk.v[v.info.order] = v;
|
|
22492
|
-
}
|
|
22493
|
-
for (let i = rk.n + d - 1; i < rk.n; i++) rk.v[i] = null;
|
|
22494
|
-
}
|
|
22495
|
-
function makeSlotsExpand(root, r, pos, d) {
|
|
22496
|
-
const rk = root.info.rank[r];
|
|
22497
|
-
for (let i = rk.n - 1; i > pos; i--) {
|
|
22498
|
-
const v = rk.v[i];
|
|
22499
|
-
v.info.order = i + d - 1;
|
|
22500
|
-
rk.v[v.info.order] = v;
|
|
22501
|
-
}
|
|
22502
|
-
for (let i = pos + 1; i < pos + d; i++) rk.v[i] = null;
|
|
22503
|
-
}
|
|
22504
|
-
function makeSlots(root, r, pos, d) {
|
|
22505
|
-
if (d <= 0) makeSlotsContract(root, r, pos, d);
|
|
22506
|
-
else makeSlotsExpand(root, r, pos, d);
|
|
22507
|
-
root.info.rank[r].n += d - 1;
|
|
22508
|
-
}
|
|
22509
|
-
function cloneVn(g, vn) {
|
|
22510
|
-
const r = vn.info.rank ?? 0;
|
|
22511
|
-
makeSlots(g, r, vn.info.order, 2);
|
|
22512
|
-
const rv = virtualNode(g);
|
|
22513
|
-
rv.info.lw = vn.info.lw;
|
|
22514
|
-
rv.info.rw = vn.info.rw;
|
|
22515
|
-
rv.info.rank = r;
|
|
22516
|
-
rv.info.order = (vn.info.order ?? 0) + 1;
|
|
22517
|
-
g.info.rank[r].v[rv.info.order] = rv;
|
|
22518
|
-
return rv;
|
|
22519
|
-
}
|
|
22520
|
-
function safeOtherEdge(e) {
|
|
22521
|
-
if (!e.tail.info.other) e.tail.info.other = { list: [], size: 0 };
|
|
22522
|
-
const other = e.tail.info.other;
|
|
22523
|
-
for (let i = 0; i < other.size; i++) if (other.list[i] === e) return;
|
|
22524
|
-
other.list[other.size++] = e;
|
|
22525
|
-
}
|
|
22526
|
-
function portsEqSimple(orig, e) {
|
|
22527
|
-
const hp = orig.info.head_port;
|
|
22528
|
-
const tp = orig.info.tail_port;
|
|
22529
|
-
const ehp = e.info.head_port;
|
|
22530
|
-
const etp = e.info.tail_port;
|
|
22531
|
-
return hp.defined === ehp.defined && tp.defined === etp.defined && (!hp.defined || hp.p.x === ehp.p.x && hp.p.y === ehp.p.y) && (!tp.defined || tp.p.x === etp.p.x && tp.p.y === etp.p.y);
|
|
22532
|
-
}
|
|
22533
|
-
function mapPathAdjacentMulti(from, to, orig, ve, type) {
|
|
22534
|
-
const root = dotRoot(from.root);
|
|
22535
|
-
let u = from;
|
|
22536
|
-
for (let r = from.info.rank ?? 0; r < (to.info.rank ?? 0); r++) {
|
|
22537
|
-
const v = r < (to.info.rank ?? 0) - 1 ? cloneVn(root, ve.head) : to;
|
|
22538
|
-
const e = virtualEdge(u, v, orig);
|
|
22539
|
-
e.info.edge_type = type;
|
|
22540
|
-
u = v;
|
|
22541
|
-
ve.info.count = (ve.info.count ?? 1) - 1;
|
|
22542
|
-
ve = ve.head.info.out.list[0];
|
|
22543
|
-
}
|
|
22544
|
-
}
|
|
22545
|
-
function mapPathAdjacentSingle(from, to, orig, ve, type) {
|
|
22546
|
-
const existing = findFastEdge(from, to);
|
|
22547
|
-
if (existing !== void 0 && portsEqSimple(orig, existing)) {
|
|
22548
|
-
orig.info.to_virt = existing;
|
|
22549
|
-
existing.info.edge_type = type;
|
|
22550
|
-
existing.info.count = (existing.info.count ?? 1) + 1;
|
|
22551
|
-
if (from.info.node_type === NORMAL && to.info.node_type === NORMAL)
|
|
22552
|
-
safeOtherEdge(orig);
|
|
22553
|
-
} else {
|
|
22554
|
-
orig.info.to_virt = void 0;
|
|
22555
|
-
const e = virtualEdge(from, to, orig);
|
|
22556
|
-
e.info.edge_type = type;
|
|
22557
|
-
ve.info.count = (ve.info.count ?? 1) - 1;
|
|
22558
|
-
}
|
|
22559
|
-
}
|
|
22560
|
-
function mapPathLongSingle(from, to, orig, ve, type) {
|
|
22561
|
-
let e;
|
|
22562
|
-
if (ve.tail !== from) {
|
|
22563
|
-
orig.info.to_virt = void 0;
|
|
22564
|
-
e = orig.info.to_virt = virtualEdge(from, ve.head, orig);
|
|
22565
|
-
deleteFastEdge(ve);
|
|
22566
|
-
} else {
|
|
22567
|
-
e = ve;
|
|
22568
|
-
}
|
|
22569
|
-
while ((e.head.info.rank ?? 0) !== (to.info.rank ?? 0))
|
|
22570
|
-
e = e.head.info.out.list[0];
|
|
22571
|
-
if (e.head !== to) {
|
|
22572
|
-
const old = e;
|
|
22573
|
-
e = virtualEdge(e.tail, to, orig);
|
|
22574
|
-
e.info.edge_type = type;
|
|
22575
|
-
deleteFastEdge(old);
|
|
22576
|
-
}
|
|
22577
|
-
}
|
|
22578
|
-
function mapPathMultiEdge(from, to, orig, ve, type) {
|
|
22579
|
-
orig.info.to_virt = void 0;
|
|
22580
|
-
const span = (to.info.rank ?? 0) - (from.info.rank ?? 0);
|
|
22581
|
-
if (span === 1) {
|
|
22582
|
-
const ex = findFastEdge(from, to);
|
|
22583
|
-
if (ex !== void 0 && portsEqSimple(orig, ex)) {
|
|
22584
|
-
mergeOneway(orig, ex);
|
|
22585
|
-
if (from.info.node_type === NORMAL && to.info.node_type === NORMAL)
|
|
22586
|
-
safeOtherEdge(orig);
|
|
22587
|
-
return;
|
|
22588
|
-
}
|
|
22589
|
-
}
|
|
22590
|
-
mapPathAdjacentMulti(from, to, orig, ve, type);
|
|
22591
|
-
}
|
|
22592
|
-
function mapPath(from, to, orig, ve, type) {
|
|
22593
|
-
if (ve.tail === from && ve.head === to) return;
|
|
22594
|
-
const span = (to.info.rank ?? 0) - (from.info.rank ?? 0);
|
|
22595
|
-
const cnt = ve.info.count ?? 1;
|
|
22596
|
-
if (cnt > 1) mapPathMultiEdge(from, to, orig, ve, type);
|
|
22597
|
-
else if (span === 1) mapPathAdjacentSingle(from, to, orig, ve, type);
|
|
22598
|
-
else mapPathLongSingle(from, to, orig, ve, type);
|
|
22599
|
-
}
|
|
22600
|
-
function makeInterclustChain(from, to, orig) {
|
|
22601
|
-
const u = mapInterclustNode(from);
|
|
22602
|
-
const v = mapInterclustNode(to);
|
|
22603
|
-
const type = u === from && v === to ? VIRTUAL : CLUSTER_EDGE;
|
|
22604
|
-
mapPath(u, v, orig, orig.info.to_virt, type);
|
|
22605
|
-
}
|
|
22606
|
-
|
|
22607
21525
|
// src/layout/dot/cluster.ts
|
|
22608
21526
|
function interclexpMergeable(prev, e) {
|
|
22609
21527
|
if (!prev) return false;
|
|
@@ -22883,15 +21801,325 @@ function markLowclusterBasic(g) {
|
|
|
22883
21801
|
for (let c = 1; c <= nClust; c++) markLowclusterBasic(g.info.clust[c - 1]);
|
|
22884
21802
|
const outByTail = outEdgesByTail(g.edges);
|
|
22885
21803
|
for (const n of nodesInSeq(g)) {
|
|
22886
|
-
if (n.info.clust === void 0) n.info.clust = g;
|
|
22887
|
-
const oes = outByTail.get(n);
|
|
22888
|
-
if (oes === void 0) continue;
|
|
22889
|
-
for (const orig of oes) markLowclusterChain(orig, g);
|
|
21804
|
+
if (n.info.clust === void 0) n.info.clust = g;
|
|
21805
|
+
const oes = outByTail.get(n);
|
|
21806
|
+
if (oes === void 0) continue;
|
|
21807
|
+
for (const orig of oes) markLowclusterChain(orig, g);
|
|
21808
|
+
}
|
|
21809
|
+
}
|
|
21810
|
+
function markLowclusters(root) {
|
|
21811
|
+
markLowclustersZap(root);
|
|
21812
|
+
markLowclusterBasic(root);
|
|
21813
|
+
}
|
|
21814
|
+
|
|
21815
|
+
// src/layout/dot/classify.ts
|
|
21816
|
+
function portsEq(e, f) {
|
|
21817
|
+
const ehp = e.info.head_port;
|
|
21818
|
+
const fhp = f.info.head_port;
|
|
21819
|
+
const etp = e.info.tail_port;
|
|
21820
|
+
const ftp = f.info.tail_port;
|
|
21821
|
+
const headMatch = ehp.p.x === fhp.p.x && ehp.p.y === fhp.p.y || !ehp.defined;
|
|
21822
|
+
const tailMatch = etp.p.x === ftp.p.x && etp.p.y === ftp.p.y || !etp.defined;
|
|
21823
|
+
return ehp.defined === fhp.defined && headMatch && tailMatch;
|
|
21824
|
+
}
|
|
21825
|
+
function nonconstraintEdge(e) {
|
|
21826
|
+
return e.info.constraint === false;
|
|
21827
|
+
}
|
|
21828
|
+
var WNODE_ORDINARY = 0;
|
|
21829
|
+
var WNODE_SINGLETON = 1;
|
|
21830
|
+
var WNODE_VIRTUAL = 2;
|
|
21831
|
+
var CLASSIFY_WEIGHT_TABLE = [[1, 1, 1], [1, 2, 2], [1, 2, 4]];
|
|
21832
|
+
function epClass(n) {
|
|
21833
|
+
if (n.info.node_type === VIRTUAL) return WNODE_VIRTUAL;
|
|
21834
|
+
if ((n.info.weight_class ?? 2) <= 1) return WNODE_SINGLETON;
|
|
21835
|
+
return WNODE_ORDINARY;
|
|
21836
|
+
}
|
|
21837
|
+
function applyVirtualWeight(e) {
|
|
21838
|
+
const t = CLASSIFY_WEIGHT_TABLE[epClass(e.tail)][epClass(e.head)];
|
|
21839
|
+
e.info.weight = (e.info.weight ?? 1) * t;
|
|
21840
|
+
}
|
|
21841
|
+
function interclust1TRank(e) {
|
|
21842
|
+
const clust = e.tail.info.clust;
|
|
21843
|
+
return clust ? (e.tail.info.rank ?? 0) - (clust.info.leader?.info.rank ?? 0) : 0;
|
|
21844
|
+
}
|
|
21845
|
+
function interclust1HRank(e) {
|
|
21846
|
+
const clust = e.head.info.clust;
|
|
21847
|
+
return clust ? (e.head.info.rank ?? 0) - (clust.info.leader?.info.rank ?? 0) : 0;
|
|
21848
|
+
}
|
|
21849
|
+
function interclust1Lengths(e) {
|
|
21850
|
+
const offset = (e.info.minlen ?? 1) + interclust1TRank(e) - interclust1HRank(e);
|
|
21851
|
+
return offset > 0 ? [0, offset] : [-offset, 0];
|
|
21852
|
+
}
|
|
21853
|
+
function interclust1(g, t, h, e) {
|
|
21854
|
+
const [tLen, hLen] = interclust1Lengths(e);
|
|
21855
|
+
const v = virtualNode(g);
|
|
21856
|
+
v.info.node_type = SLACKNODE;
|
|
21857
|
+
const t0 = ufFind(t);
|
|
21858
|
+
const h0 = ufFind(h);
|
|
21859
|
+
const w = e.info.weight ?? 1;
|
|
21860
|
+
const rt = makeAuxEdge(v, t0, tLen, CL_BACK * w);
|
|
21861
|
+
const rh = makeAuxEdge(v, h0, hLen, w);
|
|
21862
|
+
rt.info.to_orig = e;
|
|
21863
|
+
rh.info.to_orig = e;
|
|
21864
|
+
}
|
|
21865
|
+
function class1Edge(g, e) {
|
|
21866
|
+
if (e.info.to_virt !== void 0) return;
|
|
21867
|
+
if (nonconstraintEdge(e)) return;
|
|
21868
|
+
const t = ufFind(e.tail);
|
|
21869
|
+
const h = ufFind(e.head);
|
|
21870
|
+
if (t === h) return;
|
|
21871
|
+
if (t.info.clust || h.info.clust) {
|
|
21872
|
+
interclust1(g, e.tail, e.head, e);
|
|
21873
|
+
return;
|
|
21874
|
+
}
|
|
21875
|
+
const rep = findFastEdge(t, h);
|
|
21876
|
+
if (rep !== void 0) mergeOneway(e, rep);
|
|
21877
|
+
else virtualEdge(t, h, e);
|
|
21878
|
+
}
|
|
21879
|
+
function class1(g) {
|
|
21880
|
+
markClusters(g);
|
|
21881
|
+
for (const n of nodesInSeq(g)) {
|
|
21882
|
+
for (const e of n.outEdges(g)) class1Edge(g, e);
|
|
21883
|
+
}
|
|
21884
|
+
}
|
|
21885
|
+
function labelVnodeDimen(orig) {
|
|
21886
|
+
const lbl = orig.info.label;
|
|
21887
|
+
return lbl?.dimen;
|
|
21888
|
+
}
|
|
21889
|
+
function labelVnode(g, orig) {
|
|
21890
|
+
const dimen = labelVnodeDimen(orig);
|
|
21891
|
+
const v = virtualNode(g);
|
|
21892
|
+
v.info.label = orig.info.label;
|
|
21893
|
+
v.info.lw = dotRoot(g).info.nodesep ?? 0;
|
|
21894
|
+
if (!orig.info.label_ontop && dimen) {
|
|
21895
|
+
const flip = dotRoot(g).info.flip === true;
|
|
21896
|
+
v.info.ht = flip ? dimen.x : dimen.y;
|
|
21897
|
+
v.info.rw = flip ? dimen.y : dimen.x;
|
|
21898
|
+
}
|
|
21899
|
+
return v;
|
|
21900
|
+
}
|
|
21901
|
+
function incrWidth(g, v) {
|
|
21902
|
+
const width = Math.floor((g.info.nodesep ?? 0) / 2);
|
|
21903
|
+
v.info.lw = (v.info.lw ?? 0) + width;
|
|
21904
|
+
v.info.rw = (v.info.rw ?? 0) + width;
|
|
21905
|
+
}
|
|
21906
|
+
function plainVnode(g) {
|
|
21907
|
+
const v = virtualNode(g);
|
|
21908
|
+
incrWidth(g, v);
|
|
21909
|
+
return v;
|
|
21910
|
+
}
|
|
21911
|
+
function leaderOf(v) {
|
|
21912
|
+
if (v.info.ranktype !== CLUSTER) return ufFind(v);
|
|
21913
|
+
return v.info.clust.info.rankleader[v.info.rank ?? 0];
|
|
21914
|
+
}
|
|
21915
|
+
function chainVnode(g, orig, r, labelRank) {
|
|
21916
|
+
if (r === labelRank) return labelVnode(g, orig);
|
|
21917
|
+
return plainVnode(g);
|
|
21918
|
+
}
|
|
21919
|
+
function makeChain(g, from, to, orig) {
|
|
21920
|
+
const labelRank = orig.info.label !== void 0 ? Math.floor(((from.info.rank ?? 0) + (to.info.rank ?? 0)) / 2) : -1;
|
|
21921
|
+
let u = from;
|
|
21922
|
+
const toRank = to.info.rank ?? 0;
|
|
21923
|
+
for (let r = (from.info.rank ?? 0) + 1; r <= toRank; r++) {
|
|
21924
|
+
const v = r < toRank ? (() => {
|
|
21925
|
+
const n = chainVnode(g, orig, r, labelRank);
|
|
21926
|
+
n.info.rank = r;
|
|
21927
|
+
return n;
|
|
21928
|
+
})() : to;
|
|
21929
|
+
const e = virtualEdge(u, v, orig);
|
|
21930
|
+
applyVirtualWeight(e);
|
|
21931
|
+
u = v;
|
|
21932
|
+
}
|
|
21933
|
+
}
|
|
21934
|
+
function nodeRank3(n) {
|
|
21935
|
+
return n.info.rank ?? 0;
|
|
21936
|
+
}
|
|
21937
|
+
function edgeCount(e) {
|
|
21938
|
+
return e.info.count ?? 1;
|
|
21939
|
+
}
|
|
21940
|
+
function edgeXpenalty(e) {
|
|
21941
|
+
return e.info.xpenalty ?? 0;
|
|
21942
|
+
}
|
|
21943
|
+
function edgeWeight3(e) {
|
|
21944
|
+
return e.info.weight ?? 1;
|
|
21945
|
+
}
|
|
21946
|
+
function nextVirtEdge(e) {
|
|
21947
|
+
return e.head.info.out?.list[0];
|
|
21948
|
+
}
|
|
21949
|
+
function mergeChainStep(rep, e, updateCount) {
|
|
21950
|
+
if (updateCount) rep.info.count = edgeCount(rep) + edgeCount(e);
|
|
21951
|
+
rep.info.xpenalty = edgeXpenalty(rep) + edgeXpenalty(e);
|
|
21952
|
+
rep.info.weight = edgeWeight3(rep) + edgeWeight3(e);
|
|
21953
|
+
return nextVirtEdge(rep);
|
|
21954
|
+
}
|
|
21955
|
+
function mergeChain(g, e, f, updateCount) {
|
|
21956
|
+
const lastrank = Math.max(e.tail.info.rank ?? 0, e.head.info.rank ?? 0);
|
|
21957
|
+
e.info.to_virt = f;
|
|
21958
|
+
let rep = f;
|
|
21959
|
+
while (rep !== void 0) {
|
|
21960
|
+
if ((rep.head.info.rank ?? 0) === lastrank) {
|
|
21961
|
+
mergeChainStep(rep, e, updateCount);
|
|
21962
|
+
break;
|
|
21963
|
+
}
|
|
21964
|
+
incrWidth(g, rep.head);
|
|
21965
|
+
rep = mergeChainStep(rep, e, updateCount);
|
|
21966
|
+
}
|
|
21967
|
+
}
|
|
21968
|
+
function mergeable(e, f) {
|
|
21969
|
+
if (!e || !f) return false;
|
|
21970
|
+
return e.tail === f.tail && e.head === f.head && e.info.label === f.info.label && portsEq(e, f);
|
|
21971
|
+
}
|
|
21972
|
+
function interclrepChain(g, e, t, h) {
|
|
21973
|
+
makeChain(g, t, h, e);
|
|
21974
|
+
let cur = e.info.to_virt;
|
|
21975
|
+
while (cur !== void 0 && nodeRank3(cur.head) <= nodeRank3(h)) {
|
|
21976
|
+
cur.info.edge_type = CLUSTER_EDGE;
|
|
21977
|
+
cur = cur.head.info.out?.list[0];
|
|
21978
|
+
}
|
|
21979
|
+
}
|
|
21980
|
+
function interclrep(g, e) {
|
|
21981
|
+
let t = leaderOf(e.tail);
|
|
21982
|
+
let h = leaderOf(e.head);
|
|
21983
|
+
if (nodeRank3(t) > nodeRank3(h)) {
|
|
21984
|
+
const tmp = t;
|
|
21985
|
+
t = h;
|
|
21986
|
+
h = tmp;
|
|
21987
|
+
}
|
|
21988
|
+
if (t.info.clust === h.info.clust) return;
|
|
21989
|
+
const ve = findFastEdge(t, h);
|
|
21990
|
+
if (ve !== void 0) {
|
|
21991
|
+
mergeChain(g, e, ve, true);
|
|
21992
|
+
return;
|
|
21993
|
+
}
|
|
21994
|
+
if (nodeRank3(t) === nodeRank3(h)) return;
|
|
21995
|
+
interclrepChain(g, e, t, h);
|
|
21996
|
+
}
|
|
21997
|
+
function isClusterEdge(e) {
|
|
21998
|
+
return e.tail.info.ranktype === CLUSTER || e.head.info.ranktype === CLUSTER;
|
|
21999
|
+
}
|
|
22000
|
+
function handleClusterMergeable(g, e, prev) {
|
|
22001
|
+
if (prev.info.to_virt !== void 0) {
|
|
22002
|
+
mergeChain(g, e, prev.info.to_virt, false);
|
|
22003
|
+
otherEdge(e);
|
|
22004
|
+
} else if ((e.tail.info.rank ?? 0) === (e.head.info.rank ?? 0)) {
|
|
22005
|
+
mergeOneway(e, prev);
|
|
22006
|
+
otherEdge(e);
|
|
22007
|
+
}
|
|
22008
|
+
return prev;
|
|
22009
|
+
}
|
|
22010
|
+
function handleClusterEdge(g, e, prev) {
|
|
22011
|
+
if (mergeable(prev, e)) return handleClusterMergeable(g, e, prev);
|
|
22012
|
+
interclrep(g, e);
|
|
22013
|
+
return e;
|
|
22014
|
+
}
|
|
22015
|
+
function concentrateOrMerge(g, e, prev) {
|
|
22016
|
+
if (dotRoot(g).info.concentrate ?? false) {
|
|
22017
|
+
e.info.edge_type = IGNORED;
|
|
22018
|
+
} else if (prev.info.to_virt !== void 0) {
|
|
22019
|
+
mergeChain(g, e, prev.info.to_virt, true);
|
|
22020
|
+
otherEdge(e);
|
|
22021
|
+
}
|
|
22022
|
+
}
|
|
22023
|
+
function handleMultiSameRank(e, prev) {
|
|
22024
|
+
if ((e.tail.info.rank ?? 0) !== (e.head.info.rank ?? 0)) return false;
|
|
22025
|
+
mergeOneway(e, prev);
|
|
22026
|
+
otherEdge(e);
|
|
22027
|
+
return true;
|
|
22028
|
+
}
|
|
22029
|
+
function handleMultiParallel(g, e, prev) {
|
|
22030
|
+
if (e.info.label !== void 0 || prev.info.label !== void 0) return false;
|
|
22031
|
+
if (!portsEq(e, prev)) return false;
|
|
22032
|
+
concentrateOrMerge(g, e, prev);
|
|
22033
|
+
return true;
|
|
22034
|
+
}
|
|
22035
|
+
function handleMultiEdge(g, e, prev) {
|
|
22036
|
+
if (!prev || e.tail !== prev.tail || e.head !== prev.head) return false;
|
|
22037
|
+
if (handleMultiSameRank(e, prev)) return true;
|
|
22038
|
+
return handleMultiParallel(g, e, prev);
|
|
22039
|
+
}
|
|
22040
|
+
function oppEdgeConcOrMerge(g, e, opp) {
|
|
22041
|
+
if (e.info.label !== void 0 || opp.info.label !== void 0) return false;
|
|
22042
|
+
if (!portsEq(e, opp)) return false;
|
|
22043
|
+
if (dotRoot(g).info.concentrate ?? false) {
|
|
22044
|
+
e.info.edge_type = IGNORED;
|
|
22045
|
+
opp.info.conc_opp_flag = true;
|
|
22046
|
+
} else {
|
|
22047
|
+
otherEdge(e);
|
|
22048
|
+
mergeChain(g, e, opp.info.to_virt, true);
|
|
22049
|
+
}
|
|
22050
|
+
return true;
|
|
22051
|
+
}
|
|
22052
|
+
function tryOppEdge(g, e, opp) {
|
|
22053
|
+
if (opp.head !== e.tail) return false;
|
|
22054
|
+
if (opp.info.edge_type === IGNORED) return false;
|
|
22055
|
+
if (opp.info.to_virt === void 0) makeChain(g, opp.tail, opp.head, opp);
|
|
22056
|
+
return oppEdgeConcOrMerge(g, e, opp);
|
|
22057
|
+
}
|
|
22058
|
+
function handleBackEdge(g, e) {
|
|
22059
|
+
for (const opp of e.head.outEdges(g)) {
|
|
22060
|
+
if (tryOppEdge(g, e, opp)) return void 0;
|
|
22061
|
+
}
|
|
22062
|
+
makeChain(g, e.head, e.tail, e);
|
|
22063
|
+
return e;
|
|
22064
|
+
}
|
|
22065
|
+
function class2EdgeSameRep(g, e) {
|
|
22066
|
+
if (nodeRank3(e.tail) === nodeRank3(e.head)) {
|
|
22067
|
+
flatEdge(g, e);
|
|
22068
|
+
return e;
|
|
22069
|
+
}
|
|
22070
|
+
if (nodeRank3(e.head) > nodeRank3(e.tail)) {
|
|
22071
|
+
makeChain(g, e.tail, e.head, e);
|
|
22072
|
+
return e;
|
|
22073
|
+
}
|
|
22074
|
+
return handleBackEdge(g, e);
|
|
22075
|
+
}
|
|
22076
|
+
function class2OneEdge(g, e, prev) {
|
|
22077
|
+
if (e.info.to_virt !== void 0) return e;
|
|
22078
|
+
if (isClusterEdge(e)) return handleClusterEdge(g, e, prev);
|
|
22079
|
+
if (handleMultiEdge(g, e, prev)) return prev;
|
|
22080
|
+
if (e.tail === e.head) {
|
|
22081
|
+
otherEdge(e);
|
|
22082
|
+
return e;
|
|
22083
|
+
}
|
|
22084
|
+
const t = ufFind(e.tail);
|
|
22085
|
+
const h = ufFind(e.head);
|
|
22086
|
+
if (e.tail !== t || e.head !== h) return prev;
|
|
22087
|
+
return class2EdgeSameRep(g, e);
|
|
22088
|
+
}
|
|
22089
|
+
function class2ProcessNodeEdges(g, oes) {
|
|
22090
|
+
let prev;
|
|
22091
|
+
for (const e of oes) {
|
|
22092
|
+
const next = class2OneEdge(g, e, prev);
|
|
22093
|
+
prev = next !== void 0 ? next : prev;
|
|
22094
|
+
}
|
|
22095
|
+
}
|
|
22096
|
+
function weightClass(n) {
|
|
22097
|
+
return n.info.weight_class ?? 0;
|
|
22098
|
+
}
|
|
22099
|
+
function incrWeightClass(n) {
|
|
22100
|
+
if (weightClass(n) <= 2) n.info.weight_class = weightClass(n) + 1;
|
|
22101
|
+
}
|
|
22102
|
+
function class2WeightClasses(g) {
|
|
22103
|
+
for (const e of g.edges) {
|
|
22104
|
+
incrWeightClass(e.head);
|
|
22105
|
+
incrWeightClass(e.tail);
|
|
22106
|
+
}
|
|
22107
|
+
}
|
|
22108
|
+
function class2ProcessNodes(g) {
|
|
22109
|
+
const outIdx = buildOutEdgeIndex(g);
|
|
22110
|
+
for (const n of nodesInSeq(g)) {
|
|
22111
|
+
if (n.info.clust === void 0 && n === ufFind(n)) fastNode(g, n);
|
|
22112
|
+
class2ProcessNodeEdges(g, outIdx.get(n) ?? []);
|
|
22890
22113
|
}
|
|
22891
22114
|
}
|
|
22892
|
-
function
|
|
22893
|
-
|
|
22894
|
-
|
|
22115
|
+
function class2(g) {
|
|
22116
|
+
g.info.nlist = void 0;
|
|
22117
|
+
markClusters(g);
|
|
22118
|
+
const nClust = g.info.n_cluster ?? 0;
|
|
22119
|
+
for (let c = 1; c <= nClust; c++) buildSkeleton(g, g.info.clust[c - 1]);
|
|
22120
|
+
class2WeightClasses(g);
|
|
22121
|
+
class2ProcessNodes(g);
|
|
22122
|
+
if (g !== dotRoot(g)) g.info.comp = [g.info.nlist ?? null];
|
|
22895
22123
|
}
|
|
22896
22124
|
|
|
22897
22125
|
// src/layout/dot/rank.ts
|
|
@@ -23154,450 +22382,1223 @@ function gMaxrankVal(g) {
|
|
|
23154
22382
|
function gNCluster(g) {
|
|
23155
22383
|
return g.info.n_cluster ?? 0;
|
|
23156
22384
|
}
|
|
23157
|
-
function gClust(g) {
|
|
23158
|
-
return g.info.clust ?? [];
|
|
22385
|
+
function gClust(g) {
|
|
22386
|
+
return g.info.clust ?? [];
|
|
22387
|
+
}
|
|
22388
|
+
function nRank(n) {
|
|
22389
|
+
return n.info.rank ?? 0;
|
|
22390
|
+
}
|
|
22391
|
+
function nRanktype(n) {
|
|
22392
|
+
return n.info.ranktype ?? 0;
|
|
22393
|
+
}
|
|
22394
|
+
function gMaxrankDef(g) {
|
|
22395
|
+
return g.info.maxrank ?? -1;
|
|
22396
|
+
}
|
|
22397
|
+
function gMinrankDef(g) {
|
|
22398
|
+
return g.info.minrank ?? Number.MAX_SAFE_INTEGER;
|
|
22399
|
+
}
|
|
22400
|
+
function setMinmax(g) {
|
|
22401
|
+
const lr = gLeaderRank(g);
|
|
22402
|
+
g.info.minrank = gMinrankVal(g) + lr;
|
|
22403
|
+
g.info.maxrank = gMaxrankVal(g) + lr;
|
|
22404
|
+
const cl = gClust(g);
|
|
22405
|
+
const nc = gNCluster(g);
|
|
22406
|
+
for (let c = 1; c <= nc; c++) setMinmax(cl[c - 1]);
|
|
22407
|
+
}
|
|
22408
|
+
function minmaxEdgesReverse(n, isOut) {
|
|
22409
|
+
const rt = n.info.ranktype ?? 0;
|
|
22410
|
+
const flag = isOut ? rt === SINKRANK : rt === SOURCERANK;
|
|
22411
|
+
const list = isOut ? n.info.out : n.info.in;
|
|
22412
|
+
if (list) {
|
|
22413
|
+
while (list.size > 0) reverseEdge(list.list[0]);
|
|
22414
|
+
}
|
|
22415
|
+
return flag ? 1 : 0;
|
|
22416
|
+
}
|
|
22417
|
+
function minmaxEdges(g) {
|
|
22418
|
+
if (!g.info.maxset && !g.info.minset) return [0, 0];
|
|
22419
|
+
if (g.info.minset) g.info.minset = ufFind(g.info.minset);
|
|
22420
|
+
if (g.info.maxset) g.info.maxset = ufFind(g.info.maxset);
|
|
22421
|
+
const slenY = g.info.maxset ? minmaxEdgesReverse(g.info.maxset, true) : 0;
|
|
22422
|
+
const slenX = g.info.minset ? minmaxEdgesReverse(g.info.minset, false) : 0;
|
|
22423
|
+
return [slenX, slenY];
|
|
22424
|
+
}
|
|
22425
|
+
function nOutEdge0(n) {
|
|
22426
|
+
return n.info.out?.list[0];
|
|
22427
|
+
}
|
|
22428
|
+
function nInEdge0(n) {
|
|
22429
|
+
return n.info.in?.list[0];
|
|
22430
|
+
}
|
|
22431
|
+
function mmEdges2CheckMax(g, n, slen1) {
|
|
22432
|
+
const out = n.info.out;
|
|
22433
|
+
if ((!out || out.size === 0) && g.info.maxset && n !== g.info.maxset) {
|
|
22434
|
+
const ref = nOutEdge0(n) ?? nInEdge0(n);
|
|
22435
|
+
const e = virtualEdge(n, g.info.maxset, ref);
|
|
22436
|
+
e.info.minlen = slen1;
|
|
22437
|
+
e.info.weight = 0;
|
|
22438
|
+
return true;
|
|
22439
|
+
}
|
|
22440
|
+
return false;
|
|
22441
|
+
}
|
|
22442
|
+
function mmEdges2CheckMin(g, n, slen0) {
|
|
22443
|
+
const inp = n.info.in;
|
|
22444
|
+
if ((!inp || inp.size === 0) && g.info.minset && n !== g.info.minset) {
|
|
22445
|
+
const ref = nInEdge0(n) ?? nOutEdge0(n);
|
|
22446
|
+
const e = virtualEdge(g.info.minset, n, ref);
|
|
22447
|
+
e.info.minlen = slen0;
|
|
22448
|
+
e.info.weight = 0;
|
|
22449
|
+
return true;
|
|
22450
|
+
}
|
|
22451
|
+
return false;
|
|
22452
|
+
}
|
|
22453
|
+
function minmaxEdges2(g, slen) {
|
|
22454
|
+
if (!g.info.maxset && !g.info.minset) return false;
|
|
22455
|
+
let added = false;
|
|
22456
|
+
for (const n of nodesInSeq(g)) {
|
|
22457
|
+
if (n !== ufFind(n)) continue;
|
|
22458
|
+
if (mmEdges2CheckMax(g, n, slen[1])) added = true;
|
|
22459
|
+
if (mmEdges2CheckMin(g, n, slen[0])) added = true;
|
|
22460
|
+
}
|
|
22461
|
+
return added;
|
|
22462
|
+
}
|
|
22463
|
+
function rank1(g) {
|
|
22464
|
+
const nslimit1 = g.attrs.get("nslimit1") ?? g.graphDefaultsSnapshot?.get("nslimit1") ?? g.root.attrs.get("nslimit1");
|
|
22465
|
+
const maxiter = nslimit1 ? scaleClamp(g.nodes.size, parseFloat(nslimit1)) : Number.MAX_SAFE_INTEGER;
|
|
22466
|
+
const comp = g.info.comp ?? [];
|
|
22467
|
+
const hasClusters = (g.info.n_cluster ?? 0) > 0;
|
|
22468
|
+
for (let c = 0; c < comp.length; c++) {
|
|
22469
|
+
g.info.nlist = comp[c];
|
|
22470
|
+
rank(g, hasClusters ? 0 : 1, maxiter);
|
|
22471
|
+
}
|
|
22472
|
+
}
|
|
22473
|
+
function expandNode(g, n) {
|
|
22474
|
+
const leader = ufFind(n);
|
|
22475
|
+
if (leader !== n) n.info.rank = nRank(n) + nRank(leader);
|
|
22476
|
+
if (gMaxrankDef(g) < nRank(n)) g.info.maxrank = n.info.rank;
|
|
22477
|
+
if (gMinrankDef(g) > nRank(n)) g.info.minrank = n.info.rank;
|
|
22478
|
+
if (nRanktype(n) !== 0 && nRanktype(n) !== LEAFSET) ufSingleton(n);
|
|
22479
|
+
}
|
|
22480
|
+
function expandRankPostprocess(g) {
|
|
22481
|
+
if (clType === LOCAL) {
|
|
22482
|
+
const cl = gClust(g);
|
|
22483
|
+
for (let c = 1; c <= gNCluster(g); c++) setMinmax(cl[c - 1]);
|
|
22484
|
+
} else {
|
|
22485
|
+
findClusters(g);
|
|
22486
|
+
}
|
|
22487
|
+
}
|
|
22488
|
+
function expandRanksets(g) {
|
|
22489
|
+
const first = g.nodes.values().next().value;
|
|
22490
|
+
if (!first) {
|
|
22491
|
+
g.info.minrank = 0;
|
|
22492
|
+
g.info.maxrank = 0;
|
|
22493
|
+
return;
|
|
22494
|
+
}
|
|
22495
|
+
g.info.minrank = Number.MAX_SAFE_INTEGER;
|
|
22496
|
+
g.info.maxrank = -1;
|
|
22497
|
+
for (const n of nodesInSeq(g)) expandNode(g, n);
|
|
22498
|
+
if (g === (g.info.dotroot ?? g.root)) expandRankPostprocess(g);
|
|
22499
|
+
}
|
|
22500
|
+
function dot1Rank(g) {
|
|
22501
|
+
edgelabelRanks(g);
|
|
22502
|
+
collapseSets(g, g);
|
|
22503
|
+
class1(g);
|
|
22504
|
+
const slen = minmaxEdges(g);
|
|
22505
|
+
decompose(g, 0);
|
|
22506
|
+
acyclic(g);
|
|
22507
|
+
if (minmaxEdges2(g, slen)) decompose(g, 0);
|
|
22508
|
+
rank1(g);
|
|
22509
|
+
expandRanksets(g);
|
|
22510
|
+
cleanup1(g);
|
|
22511
|
+
}
|
|
22512
|
+
function dotRank(g) {
|
|
22513
|
+
if (mapbool2(g.attrs.get("newrank"))) {
|
|
22514
|
+
g.info.flags = (g.info.flags ?? 0) | NEW_RANK;
|
|
22515
|
+
dot2Rank(g);
|
|
22516
|
+
} else {
|
|
22517
|
+
dot1Rank(g);
|
|
22518
|
+
}
|
|
22519
|
+
}
|
|
22520
|
+
|
|
22521
|
+
// src/common/record.ts
|
|
22522
|
+
var HASTEXT = 1;
|
|
22523
|
+
var HASPORT = 2;
|
|
22524
|
+
var HASTABLE = 4;
|
|
22525
|
+
var INTEXT = 8;
|
|
22526
|
+
var INPORT = 16;
|
|
22527
|
+
var BOTTOM2 = 1;
|
|
22528
|
+
var RIGHT2 = 2;
|
|
22529
|
+
var TOP2 = 4;
|
|
22530
|
+
var LEFT2 = 8;
|
|
22531
|
+
var PAD_X = 16;
|
|
22532
|
+
var PAD_Y = 8;
|
|
22533
|
+
function makeField() {
|
|
22534
|
+
return {
|
|
22535
|
+
size: { x: 0, y: 0 },
|
|
22536
|
+
b: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } },
|
|
22537
|
+
n_flds: 0,
|
|
22538
|
+
lp: null,
|
|
22539
|
+
fld: null,
|
|
22540
|
+
id: null,
|
|
22541
|
+
LR: 0,
|
|
22542
|
+
sides: 0
|
|
22543
|
+
};
|
|
22544
|
+
}
|
|
22545
|
+
function recIsEscapedDelim(s, j) {
|
|
22546
|
+
if (s[j] !== "\\") return false;
|
|
22547
|
+
const nx = s[j + 1];
|
|
22548
|
+
return nx === "{" || nx === "}" || nx === "|" || nx === "\\";
|
|
22549
|
+
}
|
|
22550
|
+
function recCountFields(p) {
|
|
22551
|
+
let maxf = 1;
|
|
22552
|
+
let cnt = 0;
|
|
22553
|
+
for (let j = p.i; j < p.s.length; j++) {
|
|
22554
|
+
if (recIsEscapedDelim(p.s, j)) {
|
|
22555
|
+
j++;
|
|
22556
|
+
continue;
|
|
22557
|
+
}
|
|
22558
|
+
const c = p.s[j];
|
|
22559
|
+
if (c === "{") cnt++;
|
|
22560
|
+
else if (c === "}") cnt--;
|
|
22561
|
+
else if (c === "|" && cnt === 0) maxf++;
|
|
22562
|
+
if (cnt < 0) break;
|
|
22563
|
+
}
|
|
22564
|
+
return maxf;
|
|
22565
|
+
}
|
|
22566
|
+
function recOpenPort(p, st) {
|
|
22567
|
+
if (st.mode & (HASTABLE | HASPORT)) return -1;
|
|
22568
|
+
st.mode |= HASPORT | INPORT;
|
|
22569
|
+
p.i++;
|
|
22570
|
+
st.pbuf = [];
|
|
22571
|
+
st.hspIdx = 0;
|
|
22572
|
+
return 0;
|
|
22573
|
+
}
|
|
22574
|
+
function recClosePort(p, st) {
|
|
22575
|
+
if (!(st.mode & INPORT)) return -1;
|
|
22576
|
+
const t = st.pbuf;
|
|
22577
|
+
if (t.length > 1 && st.hspIdx !== t.length - 1 && t[t.length - 1] === " ") t.pop();
|
|
22578
|
+
st.tmpport = t.join("");
|
|
22579
|
+
st.mode &= ~INPORT;
|
|
22580
|
+
p.i++;
|
|
22581
|
+
return 0;
|
|
22582
|
+
}
|
|
22583
|
+
function recOpenTable(p, st, LR) {
|
|
22584
|
+
p.i++;
|
|
22585
|
+
if (st.mode !== 0 || p.i >= p.s.length) return -1;
|
|
22586
|
+
st.mode = HASTABLE;
|
|
22587
|
+
const sub = parseReclbl(p, LR ? 0 : 1, false);
|
|
22588
|
+
if (sub === null) return -1;
|
|
22589
|
+
st.rv.fld[st.fi++] = sub;
|
|
22590
|
+
st.fp = sub;
|
|
22591
|
+
return 0;
|
|
22592
|
+
}
|
|
22593
|
+
function recFlushText(p, st) {
|
|
22594
|
+
if (!(st.mode & (HASTEXT | HASTABLE))) {
|
|
22595
|
+
st.mode |= HASTEXT;
|
|
22596
|
+
st.tbuf.push(" ");
|
|
22597
|
+
}
|
|
22598
|
+
if (st.mode & HASTEXT) {
|
|
22599
|
+
const t = st.tbuf;
|
|
22600
|
+
if (t.length > 1 && st.hstIdx !== t.length - 1 && t[t.length - 1] === " ") t.pop();
|
|
22601
|
+
st.fp.lp = makeAnyLabel(
|
|
22602
|
+
t.join(""),
|
|
22603
|
+
false,
|
|
22604
|
+
{ fontname: p.lbl.fontname, fontsize: p.lbl.fontsize, fontcolor: p.lbl.fontcolor },
|
|
22605
|
+
p.measurer,
|
|
22606
|
+
p.obj
|
|
22607
|
+
);
|
|
22608
|
+
st.fp.LR = 1;
|
|
22609
|
+
st.tbuf = [];
|
|
22610
|
+
st.hstIdx = 0;
|
|
22611
|
+
}
|
|
22612
|
+
}
|
|
22613
|
+
function recEndField(p, st, flag) {
|
|
22614
|
+
const c = p.i < p.s.length ? p.s[p.i] : "";
|
|
22615
|
+
if (c === "" && !flag || st.mode & INPORT) return -1;
|
|
22616
|
+
if (!(st.mode & HASTABLE)) {
|
|
22617
|
+
st.fp = makeField();
|
|
22618
|
+
st.rv.fld[st.fi++] = st.fp;
|
|
22619
|
+
}
|
|
22620
|
+
if (st.tmpport !== null) {
|
|
22621
|
+
st.fp.id = st.tmpport;
|
|
22622
|
+
st.tmpport = null;
|
|
22623
|
+
}
|
|
22624
|
+
recFlushText(p, st);
|
|
22625
|
+
if (c !== "") {
|
|
22626
|
+
if (c === "}") {
|
|
22627
|
+
p.i++;
|
|
22628
|
+
st.rv.n_flds = st.fi;
|
|
22629
|
+
return 1;
|
|
22630
|
+
}
|
|
22631
|
+
st.mode = 0;
|
|
22632
|
+
p.i++;
|
|
22633
|
+
return 0;
|
|
22634
|
+
}
|
|
22635
|
+
st.rv.n_flds = st.fi;
|
|
22636
|
+
return 1;
|
|
22637
|
+
}
|
|
22638
|
+
function recBackslash(p, st) {
|
|
22639
|
+
const nx = p.s[p.i + 1];
|
|
22640
|
+
if (nx !== void 0) {
|
|
22641
|
+
if (nx < " ") {
|
|
22642
|
+
} else if (nx === " " && !p.lbl.html) {
|
|
22643
|
+
st.ishardspace = true;
|
|
22644
|
+
} else {
|
|
22645
|
+
st.tbuf.push("\\");
|
|
22646
|
+
st.mode |= INTEXT | HASTEXT;
|
|
22647
|
+
}
|
|
22648
|
+
p.i++;
|
|
22649
|
+
}
|
|
22650
|
+
}
|
|
22651
|
+
function recPushText(st, c, html) {
|
|
22652
|
+
const afterSpace = st.tbuf[st.tbuf.length - 1] === " ";
|
|
22653
|
+
if (!(c === " " && !st.ishardspace && afterSpace && !html)) st.tbuf.push(c);
|
|
22654
|
+
if (st.ishardspace) st.hstIdx = st.tbuf.length - 1;
|
|
22655
|
+
}
|
|
22656
|
+
function recPushPort(st, c) {
|
|
22657
|
+
const atStartOrSpace = st.pbuf.length === 0 || st.pbuf[st.pbuf.length - 1] === " ";
|
|
22658
|
+
if (!(c === " " && !st.ishardspace && atStartOrSpace)) st.pbuf.push(c);
|
|
22659
|
+
if (st.ishardspace) st.hspIdx = st.pbuf.length - 1;
|
|
22660
|
+
}
|
|
22661
|
+
function recTextChar(p, st, c) {
|
|
22662
|
+
if (st.mode & HASTABLE && c !== " ") return -1;
|
|
22663
|
+
if (!(st.mode & (INTEXT | INPORT)) && c !== " ") st.mode |= INTEXT | HASTEXT;
|
|
22664
|
+
if (st.mode & INTEXT) recPushText(st, c, p.lbl.html);
|
|
22665
|
+
else if (st.mode & INPORT) recPushPort(st, c);
|
|
22666
|
+
p.i++;
|
|
22667
|
+
return 0;
|
|
22668
|
+
}
|
|
22669
|
+
function recDispatch(p, st, LR, flag) {
|
|
22670
|
+
const c = p.s[p.i];
|
|
22671
|
+
switch (c) {
|
|
22672
|
+
case "<":
|
|
22673
|
+
if (p.lbl.html) return recTextChar(p, st, c);
|
|
22674
|
+
return recOpenPort(p, st);
|
|
22675
|
+
case ">":
|
|
22676
|
+
if (p.lbl.html) return recTextChar(p, st, c);
|
|
22677
|
+
return recClosePort(p, st);
|
|
22678
|
+
case "{":
|
|
22679
|
+
return recOpenTable(p, st, LR);
|
|
22680
|
+
case "}":
|
|
22681
|
+
case "|":
|
|
22682
|
+
case void 0:
|
|
22683
|
+
return recEndField(p, st, flag);
|
|
22684
|
+
case "\\":
|
|
22685
|
+
recBackslash(p, st);
|
|
22686
|
+
return recTextChar(p, st, p.s[p.i]);
|
|
22687
|
+
default:
|
|
22688
|
+
return recTextChar(p, st, c);
|
|
22689
|
+
}
|
|
22690
|
+
}
|
|
22691
|
+
function parseReclbl(p, LR, flag) {
|
|
22692
|
+
const rv = makeField();
|
|
22693
|
+
rv.fld = new Array(recCountFields(p));
|
|
22694
|
+
rv.LR = LR;
|
|
22695
|
+
const st = {
|
|
22696
|
+
rv,
|
|
22697
|
+
fi: 0,
|
|
22698
|
+
mode: 0,
|
|
22699
|
+
tbuf: [],
|
|
22700
|
+
hstIdx: 0,
|
|
22701
|
+
pbuf: [],
|
|
22702
|
+
hspIdx: 0,
|
|
22703
|
+
tmpport: null,
|
|
22704
|
+
ishardspace: false,
|
|
22705
|
+
fp: null
|
|
22706
|
+
};
|
|
22707
|
+
for (; ; ) {
|
|
22708
|
+
if (p.i < p.s.length && p.s[p.i] < " " && p.s[p.i] !== "") {
|
|
22709
|
+
p.i++;
|
|
22710
|
+
continue;
|
|
22711
|
+
}
|
|
22712
|
+
const r = recDispatch(p, st, LR, flag);
|
|
22713
|
+
if (r === -1) return null;
|
|
22714
|
+
if (r === 1) break;
|
|
22715
|
+
if (p.i > p.s.length) break;
|
|
22716
|
+
}
|
|
22717
|
+
rv.n_flds = st.fi;
|
|
22718
|
+
return rv;
|
|
22719
|
+
}
|
|
22720
|
+
function recLabelDimen(n, g, f) {
|
|
22721
|
+
const dimen = { x: f.lp.dimen.x, y: f.lp.dimen.y };
|
|
22722
|
+
if (dimen.x > 0 || dimen.y > 0) {
|
|
22723
|
+
const m = nodeAttr(n, g, "margin");
|
|
22724
|
+
const parts = m !== void 0 ? m.split(",").map(parseFloat) : [];
|
|
22725
|
+
if (parts.length > 0 && !Number.isNaN(parts[0])) {
|
|
22726
|
+
dimen.x += 2 * parts[0] * 72;
|
|
22727
|
+
dimen.y += 2 * (parts.length > 1 && !Number.isNaN(parts[1]) ? parts[1] : parts[0]) * 72;
|
|
22728
|
+
} else {
|
|
22729
|
+
dimen.x += PAD_X;
|
|
22730
|
+
dimen.y += PAD_Y;
|
|
22731
|
+
}
|
|
22732
|
+
}
|
|
22733
|
+
return dimen;
|
|
22734
|
+
}
|
|
22735
|
+
function sizeReclbl(n, g, f) {
|
|
22736
|
+
let d;
|
|
22737
|
+
if (f.lp) {
|
|
22738
|
+
d = recLabelDimen(n, g, f);
|
|
22739
|
+
} else {
|
|
22740
|
+
d = { x: 0, y: 0 };
|
|
22741
|
+
for (let i = 0; i < f.n_flds; i++) {
|
|
22742
|
+
const d0 = sizeReclbl(n, g, f.fld[i]);
|
|
22743
|
+
if (f.LR) {
|
|
22744
|
+
d.x += d0.x;
|
|
22745
|
+
d.y = Math.max(d.y, d0.y);
|
|
22746
|
+
} else {
|
|
22747
|
+
d.y += d0.y;
|
|
22748
|
+
d.x = Math.max(d.x, d0.x);
|
|
22749
|
+
}
|
|
22750
|
+
}
|
|
22751
|
+
}
|
|
22752
|
+
f.size = d;
|
|
22753
|
+
return d;
|
|
22754
|
+
}
|
|
22755
|
+
function resizeReclbl(f, sz, nojustify) {
|
|
22756
|
+
const d = { x: sz.x - f.size.x, y: sz.y - f.size.y };
|
|
22757
|
+
f.size = sz;
|
|
22758
|
+
if (f.lp && !nojustify) {
|
|
22759
|
+
f.lp.space.x += d.x;
|
|
22760
|
+
f.lp.space.y += d.y;
|
|
22761
|
+
}
|
|
22762
|
+
if (f.n_flds) {
|
|
22763
|
+
const inc2 = f.LR ? d.x / f.n_flds : d.y / f.n_flds;
|
|
22764
|
+
for (let i = 0; i < f.n_flds; i++) {
|
|
22765
|
+
const sf = f.fld[i];
|
|
22766
|
+
const amt = Math.trunc((i + 1) * inc2) - Math.trunc(i * inc2);
|
|
22767
|
+
const newsz = f.LR ? { x: sf.size.x + amt, y: sz.y } : { x: sz.x, y: sf.size.y + amt };
|
|
22768
|
+
resizeReclbl(sf, newsz, nojustify);
|
|
22769
|
+
}
|
|
22770
|
+
}
|
|
22771
|
+
}
|
|
22772
|
+
function recSideMask(f, i, last) {
|
|
22773
|
+
if (f.LR) {
|
|
22774
|
+
if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | BOTTOM2 | LEFT2;
|
|
22775
|
+
return i === last ? TOP2 | BOTTOM2 | RIGHT2 : TOP2 | BOTTOM2;
|
|
22776
|
+
}
|
|
22777
|
+
if (i === 0) return i === last ? TOP2 | BOTTOM2 | RIGHT2 | LEFT2 : TOP2 | RIGHT2 | LEFT2;
|
|
22778
|
+
return i === last ? LEFT2 | BOTTOM2 | RIGHT2 : LEFT2 | RIGHT2;
|
|
22779
|
+
}
|
|
22780
|
+
function posReclbl(f, ul, sides) {
|
|
22781
|
+
f.sides = sides;
|
|
22782
|
+
f.b = {
|
|
22783
|
+
ll: { x: ul.x, y: ul.y - f.size.y },
|
|
22784
|
+
ur: { x: ul.x + f.size.x, y: ul.y }
|
|
22785
|
+
};
|
|
22786
|
+
const last = f.n_flds - 1;
|
|
22787
|
+
const pos = { x: ul.x, y: ul.y };
|
|
22788
|
+
for (let i = 0; i <= last; i++) {
|
|
22789
|
+
const mask = sides ? recSideMask(f, i, last) : 0;
|
|
22790
|
+
posReclbl(f.fld[i], { x: pos.x, y: pos.y }, sides & mask);
|
|
22791
|
+
if (f.LR) pos.x += f.fld[i].size.x;
|
|
22792
|
+
else pos.y -= f.fld[i].size.y;
|
|
22793
|
+
}
|
|
22794
|
+
}
|
|
22795
|
+
function attrBool(n, g, key) {
|
|
22796
|
+
return mapbool2(nodeAttr(n, g, key));
|
|
22797
|
+
}
|
|
22798
|
+
function recAttrSize(n, g) {
|
|
22799
|
+
const w = nodeAttr(n, g, "width");
|
|
22800
|
+
const h = nodeAttr(n, g, "height");
|
|
22801
|
+
return {
|
|
22802
|
+
x: (w !== void 0 ? parseFloat(w) : 0.75) * 72,
|
|
22803
|
+
y: (h !== void 0 ? parseFloat(h) : 0.5) * 72
|
|
22804
|
+
};
|
|
22805
|
+
}
|
|
22806
|
+
function recParseOrFallback(lbl, measurer, flip, obj) {
|
|
22807
|
+
const p = { s: lbl.text, i: 0, lbl, measurer, obj };
|
|
22808
|
+
const info = parseReclbl(p, flip, true);
|
|
22809
|
+
if (info !== null) return info;
|
|
22810
|
+
const fb = { s: "\\N", i: 0, lbl, measurer, obj };
|
|
22811
|
+
return parseReclbl(fb, flip, true);
|
|
22812
|
+
}
|
|
22813
|
+
function recordInit(n, g, measurer) {
|
|
22814
|
+
const lbl = n.info.label;
|
|
22815
|
+
const flip = ((g.root.info.rankdir ?? 0) >> 2 & 1) === 1 ? 0 : 1;
|
|
22816
|
+
const info = recParseOrFallback(lbl, measurer, flip, n);
|
|
22817
|
+
sizeReclbl(n, g, info);
|
|
22818
|
+
const sz = recAttrSize(n, g);
|
|
22819
|
+
if (!attrBool(n, g, "fixedsize")) {
|
|
22820
|
+
sz.x = Math.max(info.size.x, sz.x);
|
|
22821
|
+
sz.y = Math.max(info.size.y, sz.y);
|
|
22822
|
+
}
|
|
22823
|
+
resizeReclbl(info, sz, attrBool(n, g, "nojustify"));
|
|
22824
|
+
posReclbl(info, { x: -sz.x / 2, y: sz.y / 2 }, BOTTOM2 | RIGHT2 | TOP2 | LEFT2);
|
|
22825
|
+
n.info.width = info.size.x / 72;
|
|
22826
|
+
n.info.height = (info.size.y + 1) / 72;
|
|
22827
|
+
const ns = gvNodesize(info.size.x, info.size.y + 1, g.root.info.flip === true);
|
|
22828
|
+
n.info.lw = ns.lw;
|
|
22829
|
+
n.info.rw = ns.rw;
|
|
22830
|
+
n.info.ht = ns.ht;
|
|
22831
|
+
n.info.shape_info = info;
|
|
22832
|
+
}
|
|
22833
|
+
function recordMakeLabel(n, g, measurer) {
|
|
22834
|
+
const labelText = nodeAttr(n, g, "label") ?? n.name;
|
|
22835
|
+
const { fontname, fontsize, fontcolor } = readFontAttrs(n, g);
|
|
22836
|
+
n.info.label = makeLabel(labelText, fontname, fontsize, fontcolor, measurer);
|
|
22837
|
+
}
|
|
22838
|
+
function recordNodeInit(n, g, measurer) {
|
|
22839
|
+
recordMakeLabel(n, g, measurer);
|
|
22840
|
+
recordInit(n, g, measurer);
|
|
22841
|
+
}
|
|
22842
|
+
function genFields(job, n, f) {
|
|
22843
|
+
const renderer = job.renderer;
|
|
22844
|
+
const coord = n.info.coord ?? { x: 0, y: 0 };
|
|
22845
|
+
if (f.lp) {
|
|
22846
|
+
const mid = {
|
|
22847
|
+
x: (f.b.ll.x + f.b.ur.x) / 2 + coord.x,
|
|
22848
|
+
y: (f.b.ll.y + f.b.ur.y) / 2 + coord.y
|
|
22849
|
+
};
|
|
22850
|
+
renderLabel(f.lp, mid, renderer, job);
|
|
22851
|
+
}
|
|
22852
|
+
for (let i = 0; i < f.n_flds; i++) {
|
|
22853
|
+
if (i > 0) genFieldSeparator(job, coord, f, f.fld[i]);
|
|
22854
|
+
genFields(job, n, f.fld[i]);
|
|
22855
|
+
}
|
|
22856
|
+
}
|
|
22857
|
+
function genFieldSeparator(job, coord, f, child) {
|
|
22858
|
+
const a = { x: 0, y: 0 };
|
|
22859
|
+
const b = { x: 0, y: 0 };
|
|
22860
|
+
if (f.LR) {
|
|
22861
|
+
a.x = child.b.ll.x;
|
|
22862
|
+
a.y = child.b.ll.y;
|
|
22863
|
+
b.x = a.x;
|
|
22864
|
+
b.y = child.b.ur.y;
|
|
22865
|
+
} else {
|
|
22866
|
+
b.x = child.b.ur.x;
|
|
22867
|
+
b.y = child.b.ur.y;
|
|
22868
|
+
a.x = child.b.ll.x;
|
|
22869
|
+
a.y = b.y;
|
|
22870
|
+
}
|
|
22871
|
+
const pts = [
|
|
22872
|
+
transformPoint({ x: a.x + coord.x, y: a.y + coord.y }, job),
|
|
22873
|
+
transformPoint({ x: b.x + coord.x, y: b.y + coord.y }, job)
|
|
22874
|
+
];
|
|
22875
|
+
job.renderer.polyline(pts, job);
|
|
22876
|
+
}
|
|
22877
|
+
function recordGencode(rawJob, rawNode) {
|
|
22878
|
+
const job = rawJob;
|
|
22879
|
+
const n = rawNode;
|
|
22880
|
+
if (!job.renderer) return;
|
|
22881
|
+
const f = n.info.shape_info;
|
|
22882
|
+
if (!f) return;
|
|
22883
|
+
const coord = n.info.coord ?? { x: 0, y: 0 };
|
|
22884
|
+
const ll = { x: f.b.ll.x + coord.x, y: f.b.ll.y + coord.y };
|
|
22885
|
+
const ur = { x: f.b.ur.x + coord.x, y: f.b.ur.y + coord.y };
|
|
22886
|
+
const filled = job.obj !== null && applyNodeStyle(job.obj, n, job);
|
|
22887
|
+
drawRecordBox(job, n, ll, ur, filled);
|
|
22888
|
+
genFields(job, n, f);
|
|
23159
22889
|
}
|
|
23160
|
-
function
|
|
23161
|
-
|
|
22890
|
+
function drawRecordBox(job, n, ll, ur, filled) {
|
|
22891
|
+
const isMrecord = nodeAttr(n, n.root, "shape") === "Mrecord";
|
|
22892
|
+
const rounded = isMrecord || parseStyleFlags(nodeAttr(n, n.root, "style")).rounded;
|
|
22893
|
+
if (rounded) {
|
|
22894
|
+
const af = [{ x: ll.x, y: ll.y }, { x: ur.x, y: ll.y }, { x: ur.x, y: ur.y }, { x: ll.x, y: ur.y }];
|
|
22895
|
+
emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer: job.renderer, job });
|
|
22896
|
+
return;
|
|
22897
|
+
}
|
|
22898
|
+
const pts = [{ x: ll.x, y: ll.y }, { x: ll.x, y: ur.y }, { x: ur.x, y: ur.y }, { x: ur.x, y: ll.y }].map((q) => transformPoint(q, job));
|
|
22899
|
+
job.renderer.polygon(pts, filled, job);
|
|
23162
22900
|
}
|
|
23163
|
-
|
|
23164
|
-
|
|
22901
|
+
|
|
22902
|
+
// src/common/poly-init.ts
|
|
22903
|
+
var DEFAULT_LW = 27;
|
|
22904
|
+
var DEFAULT_RW = 27;
|
|
22905
|
+
var DEFAULT_HT = 36;
|
|
22906
|
+
function nodeAttr(n, g, key) {
|
|
22907
|
+
const own = n.attrs.get(key);
|
|
22908
|
+
if (own !== void 0) return own;
|
|
22909
|
+
if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
|
|
22910
|
+
return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
|
|
23165
22911
|
}
|
|
23166
|
-
function
|
|
23167
|
-
return
|
|
22912
|
+
function readFontAttrs(n, g) {
|
|
22913
|
+
return {
|
|
22914
|
+
fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
|
|
22915
|
+
fontsize: parseFloat(nodeAttr(n, g, "fontsize") ?? String(DEFAULT_FONTSIZE2)),
|
|
22916
|
+
fontcolor: nodeAttr(n, g, "fontcolor") ?? DEFAULT_COLOR2
|
|
22917
|
+
};
|
|
23168
22918
|
}
|
|
23169
|
-
function
|
|
23170
|
-
|
|
22919
|
+
function assignShapeInfo(n, polyDesc) {
|
|
22920
|
+
const w = n.info.width !== void 0 ? n.info.width * 72 : (n.info.lw || DEFAULT_LW) + (n.info.rw || DEFAULT_RW);
|
|
22921
|
+
const h = n.info.height !== void 0 ? n.info.height * 72 : n.info.ht || DEFAULT_HT;
|
|
22922
|
+
const base = n.info.base_width !== void 0 && n.info.base_height !== void 0 ? { w: n.info.base_width * 72, h: n.info.base_height * 72 } : void 0;
|
|
22923
|
+
n.info.shape_info = {
|
|
22924
|
+
...polyDesc,
|
|
22925
|
+
vertices: computeVertices(polyDesc, w, h, base)
|
|
22926
|
+
};
|
|
23171
22927
|
}
|
|
23172
|
-
function
|
|
23173
|
-
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
const
|
|
23177
|
-
const
|
|
23178
|
-
|
|
22928
|
+
function buildNodeLabel(n, g, measurer) {
|
|
22929
|
+
if (n.info.label !== void 0) return;
|
|
22930
|
+
const labelAttr = nodeAttr(n, g, "label");
|
|
22931
|
+
const font = readFontAttrs(n, g);
|
|
22932
|
+
const isHtml = labelAttr !== void 0 && isHtmlValue(labelAttr);
|
|
22933
|
+
const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
|
|
22934
|
+
n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
|
|
23179
22935
|
}
|
|
23180
|
-
function
|
|
23181
|
-
const
|
|
23182
|
-
const
|
|
23183
|
-
|
|
23184
|
-
if (
|
|
23185
|
-
|
|
22936
|
+
function polyInit(n, g, measurer) {
|
|
22937
|
+
const shapeName = nodeAttr(n, g, "shape") ?? "ellipse";
|
|
22938
|
+
const shapefile = nodeAttr(n, g, "shapefile");
|
|
22939
|
+
n.info.shape = bindShape(shapeName, shapefile);
|
|
22940
|
+
if (shapefile !== void 0 && shapefile !== "" && shapeName !== "epsf") {
|
|
22941
|
+
console.error(`Warning: No or improper shapefile="${shapefile}" for node "${n.name}"`);
|
|
23186
22942
|
}
|
|
23187
|
-
|
|
23188
|
-
|
|
23189
|
-
|
|
23190
|
-
|
|
23191
|
-
|
|
23192
|
-
if (
|
|
23193
|
-
const
|
|
23194
|
-
|
|
23195
|
-
return [slenX, slenY];
|
|
22943
|
+
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
22944
|
+
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
22945
|
+
return;
|
|
22946
|
+
}
|
|
22947
|
+
buildNodeLabel(n, g, measurer);
|
|
22948
|
+
if (n.info.shape_info !== void 0) return;
|
|
22949
|
+
const polyDesc = n.info.shape.polygon;
|
|
22950
|
+
if (polyDesc !== null) assignShapeInfo(n, polyDesc);
|
|
23196
22951
|
}
|
|
23197
|
-
|
|
23198
|
-
|
|
22952
|
+
|
|
22953
|
+
// src/render/svg-multicolor.ts
|
|
22954
|
+
var THIN_LINE = 0.5;
|
|
22955
|
+
function rationalFunction(x, c) {
|
|
22956
|
+
return (x * (x * c[0] + c[1]) + c[2]) / (x + c[3]);
|
|
23199
22957
|
}
|
|
23200
|
-
|
|
23201
|
-
|
|
22958
|
+
var COEFFS3LOW = [
|
|
22959
|
+
[
|
|
22960
|
+
[3.85268, -21.229, -0.330434, 0.0127842],
|
|
22961
|
+
[-1.61486, 0.706564, 0.225945, 0.263682],
|
|
22962
|
+
[-0.910164, 0.388383, 551445e-8, 671814e-8],
|
|
22963
|
+
[-0.630184, 0.192402, 98871e-7, 0.0102527]
|
|
22964
|
+
],
|
|
22965
|
+
[
|
|
22966
|
+
[-0.162211, 9.94329, 0.13723, 0.0124084],
|
|
22967
|
+
[-0.253135, 187735e-8, 0.0230286, 0.01264],
|
|
22968
|
+
[-0.0695069, -0.0437594, 0.0120636, 0.0163087],
|
|
22969
|
+
[-0.0328856, -926032e-8, -173573e-8, 527385e-8]
|
|
22970
|
+
]
|
|
22971
|
+
];
|
|
22972
|
+
var COEFFS3HIGH = [
|
|
22973
|
+
[
|
|
22974
|
+
[0.0899116, -19.2349, -4.11711, 0.183362],
|
|
22975
|
+
[0.138148, -1.45804, 1.32044, 1.38474],
|
|
22976
|
+
[0.230903, -0.450262, 0.219963, 0.414038],
|
|
22977
|
+
[0.0590565, -0.101062, 0.0430592, 0.0204699]
|
|
22978
|
+
],
|
|
22979
|
+
[
|
|
22980
|
+
[0.0164649, 9.89394, 0.0919496, 760802e-8],
|
|
22981
|
+
[0.0191603, -0.0322058, 0.0134667, -0.0825018],
|
|
22982
|
+
[0.0156192, -0.017535, 326508e-8, -0.228157],
|
|
22983
|
+
[-0.0236752, 0.0405821, -0.0173086, 0.176187]
|
|
22984
|
+
]
|
|
22985
|
+
];
|
|
22986
|
+
var SAFETY3 = [1e-3, 4.98, 0.207, 67e-4];
|
|
22987
|
+
function estimateError(a, b, etaA, etaB) {
|
|
22988
|
+
const eta = 0.5 * (etaA + etaB);
|
|
22989
|
+
const x = b / a;
|
|
22990
|
+
const dEta = etaB - etaA;
|
|
22991
|
+
const cos2 = Math.cos(2 * eta);
|
|
22992
|
+
const cos4 = Math.cos(4 * eta);
|
|
22993
|
+
const cos6 = Math.cos(6 * eta);
|
|
22994
|
+
const c = x < 0.25 ? COEFFS3LOW : COEFFS3HIGH;
|
|
22995
|
+
const c0 = rationalFunction(x, c[0][0]) + cos2 * rationalFunction(x, c[0][1]) + cos4 * rationalFunction(x, c[0][2]) + cos6 * rationalFunction(x, c[0][3]);
|
|
22996
|
+
const c1 = rationalFunction(x, c[1][0]) + cos2 * rationalFunction(x, c[1][1]) + cos4 * rationalFunction(x, c[1][2]) + cos6 * rationalFunction(x, c[1][3]);
|
|
22997
|
+
return rationalFunction(x, SAFETY3) * a * Math.exp(c0 + c1 * dEta);
|
|
23202
22998
|
}
|
|
23203
|
-
function
|
|
23204
|
-
|
|
23205
|
-
|
|
23206
|
-
|
|
23207
|
-
|
|
23208
|
-
e.info.minlen = slen1;
|
|
23209
|
-
e.info.weight = 0;
|
|
23210
|
-
return true;
|
|
22999
|
+
function allSubdivsBelowThreshold(a, b, eta1, n, dEta) {
|
|
23000
|
+
let etaA = eta1;
|
|
23001
|
+
for (let i = 0; i < n; i++) {
|
|
23002
|
+
if (estimateError(a, b, etaA, etaA + dEta) > 1e-5) return false;
|
|
23003
|
+
etaA += dEta;
|
|
23211
23004
|
}
|
|
23212
|
-
return
|
|
23005
|
+
return true;
|
|
23213
23006
|
}
|
|
23214
|
-
function
|
|
23215
|
-
|
|
23216
|
-
|
|
23217
|
-
const
|
|
23218
|
-
|
|
23219
|
-
|
|
23220
|
-
e.info.weight = 0;
|
|
23221
|
-
return true;
|
|
23007
|
+
function numSubdivisions(a, b, eta1, eta2) {
|
|
23008
|
+
let n = 1;
|
|
23009
|
+
while (n < 1024) {
|
|
23010
|
+
const dEta = (eta2 - eta1) / n;
|
|
23011
|
+
if (dEta <= 0.5 * Math.PI && allSubdivsBelowThreshold(a, b, eta1, n, dEta)) break;
|
|
23012
|
+
n <<= 1;
|
|
23222
23013
|
}
|
|
23223
|
-
return
|
|
23014
|
+
return n;
|
|
23224
23015
|
}
|
|
23225
|
-
function
|
|
23226
|
-
|
|
23227
|
-
|
|
23228
|
-
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
|
|
23232
|
-
|
|
23233
|
-
|
|
23016
|
+
function initArcPath(pts, e, eta1) {
|
|
23017
|
+
const cosE = Math.cos(eta1);
|
|
23018
|
+
const sinE = Math.sin(eta1);
|
|
23019
|
+
const xB = e.cx + e.xsemi * cosE;
|
|
23020
|
+
const yB = e.cy + e.ysemi * sinE;
|
|
23021
|
+
pts.push(
|
|
23022
|
+
{ x: e.cx, y: e.cy },
|
|
23023
|
+
{ x: e.cx, y: e.cy },
|
|
23024
|
+
{ x: xB, y: yB },
|
|
23025
|
+
{ x: xB, y: yB }
|
|
23026
|
+
);
|
|
23027
|
+
return { xB, yB, xBDot: -e.xsemi * sinE, yBDot: e.ysemi * cosE };
|
|
23234
23028
|
}
|
|
23235
|
-
function
|
|
23236
|
-
const
|
|
23237
|
-
const
|
|
23238
|
-
const
|
|
23239
|
-
const
|
|
23240
|
-
|
|
23241
|
-
|
|
23242
|
-
|
|
23243
|
-
|
|
23029
|
+
function stepBezier(pts, state3, e, sp) {
|
|
23030
|
+
const xA = state3.xB;
|
|
23031
|
+
const yA = state3.yB;
|
|
23032
|
+
const xADot = state3.xBDot;
|
|
23033
|
+
const yADot = state3.yBDot;
|
|
23034
|
+
const newEta = sp.etaB + sp.dEta;
|
|
23035
|
+
const cosE = Math.cos(newEta);
|
|
23036
|
+
const sinE = Math.sin(newEta);
|
|
23037
|
+
state3.xB = e.cx + e.xsemi * cosE;
|
|
23038
|
+
state3.yB = e.cy + e.ysemi * sinE;
|
|
23039
|
+
state3.xBDot = -e.xsemi * sinE;
|
|
23040
|
+
state3.yBDot = e.ysemi * cosE;
|
|
23041
|
+
pts.push({ x: xA + sp.alpha * xADot, y: yA + sp.alpha * yADot });
|
|
23042
|
+
pts.push({ x: state3.xB - sp.alpha * state3.xBDot, y: state3.yB - sp.alpha * state3.yBDot });
|
|
23043
|
+
pts.push({ x: state3.xB, y: state3.yB });
|
|
23044
|
+
return newEta;
|
|
23244
23045
|
}
|
|
23245
|
-
function
|
|
23246
|
-
const
|
|
23247
|
-
|
|
23248
|
-
|
|
23249
|
-
|
|
23250
|
-
if (
|
|
23046
|
+
function ellipticWedge(e, angle0, angle1) {
|
|
23047
|
+
const TWOPI2 = 2 * Math.PI;
|
|
23048
|
+
const eta1 = Math.atan2(Math.sin(angle0) / e.ysemi, Math.cos(angle0) / e.xsemi);
|
|
23049
|
+
let eta2 = Math.atan2(Math.sin(angle1) / e.ysemi, Math.cos(angle1) / e.xsemi);
|
|
23050
|
+
eta2 -= TWOPI2 * Math.floor((eta2 - eta1) / TWOPI2);
|
|
23051
|
+
if (angle1 - angle0 > Math.PI && eta2 - eta1 < Math.PI) eta2 += TWOPI2;
|
|
23052
|
+
const n = numSubdivisions(e.xsemi, e.ysemi, eta1, eta2);
|
|
23053
|
+
const dEta = (eta2 - eta1) / n;
|
|
23054
|
+
const t = Math.tan(0.5 * dEta);
|
|
23055
|
+
const alpha = Math.sin(dEta) * (Math.sqrt(4 + 3 * t * t) - 1) / 3;
|
|
23056
|
+
const pts = [];
|
|
23057
|
+
const state3 = initArcPath(pts, e, eta1);
|
|
23058
|
+
let sp = { etaB: eta1, dEta, alpha };
|
|
23059
|
+
for (let i = 0; i < n; i++) sp = { ...sp, etaB: stepBezier(pts, state3, e, sp) };
|
|
23060
|
+
pts.push({ x: state3.xB, y: state3.yB }, { x: e.cx, y: e.cy }, { x: e.cx, y: e.cy });
|
|
23061
|
+
return pts;
|
|
23251
23062
|
}
|
|
23252
|
-
function
|
|
23253
|
-
|
|
23254
|
-
|
|
23255
|
-
|
|
23256
|
-
|
|
23257
|
-
|
|
23258
|
-
}
|
|
23063
|
+
function drawWedge(seg2, e, ctx) {
|
|
23064
|
+
const TWOPI2 = 2 * Math.PI;
|
|
23065
|
+
const angle1 = seg2.isLast ? TWOPI2 : seg2.angle0 + TWOPI2 * seg2.t;
|
|
23066
|
+
const obj = ctx.job.obj;
|
|
23067
|
+
if (obj !== null) obj.fillColor = resolveRenderColor(seg2.color);
|
|
23068
|
+
const ptsUp = ellipticWedge(e, seg2.angle0, angle1);
|
|
23069
|
+
ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
|
|
23070
|
+
return angle1;
|
|
23259
23071
|
}
|
|
23260
|
-
function
|
|
23261
|
-
const
|
|
23262
|
-
if (
|
|
23263
|
-
|
|
23264
|
-
|
|
23265
|
-
|
|
23072
|
+
function wedgedEllipse(job, pf, clrs, renderer) {
|
|
23073
|
+
const { segs, error } = parseSegs(clrs);
|
|
23074
|
+
if (error === 1 || error === 2) return error;
|
|
23075
|
+
const ctrX = (pf[0].x + pf[1].x) / 2;
|
|
23076
|
+
const ctrY = (pf[0].y + pf[1].y) / 2;
|
|
23077
|
+
const e = {
|
|
23078
|
+
cx: ctrX,
|
|
23079
|
+
cy: -ctrY,
|
|
23080
|
+
xsemi: pf[1].x - ctrX,
|
|
23081
|
+
ysemi: Math.abs(pf[1].y - ctrY)
|
|
23082
|
+
};
|
|
23083
|
+
const ctx = { job, renderer };
|
|
23084
|
+
const obj = job.obj;
|
|
23085
|
+
const saved = obj !== null ? obj.penWidth : 1;
|
|
23086
|
+
if (obj !== null && saved > THIN_LINE) obj.penWidth = THIN_LINE;
|
|
23087
|
+
let angle0 = 0;
|
|
23088
|
+
for (let i = 0; i < segs.length; i++) {
|
|
23089
|
+
const s = segs[i];
|
|
23090
|
+
if (s.color === null) break;
|
|
23091
|
+
if (s.t > 0) {
|
|
23092
|
+
angle0 = drawWedge({ angle0, t: s.t, isLast: i + 1 === segs.length, color: s.color }, e, ctx);
|
|
23093
|
+
}
|
|
23266
23094
|
}
|
|
23267
|
-
|
|
23268
|
-
|
|
23269
|
-
for (const n of nodesInSeq(g)) expandNode(g, n);
|
|
23270
|
-
if (g === (g.info.dotroot ?? g.root)) expandRankPostprocess(g);
|
|
23095
|
+
if (obj !== null && saved > THIN_LINE) obj.penWidth = saved;
|
|
23096
|
+
return error;
|
|
23271
23097
|
}
|
|
23272
|
-
function
|
|
23273
|
-
|
|
23274
|
-
|
|
23275
|
-
|
|
23276
|
-
|
|
23277
|
-
|
|
23278
|
-
acyclic(g);
|
|
23279
|
-
if (minmaxEdges2(g, slen)) decompose(g, 0);
|
|
23280
|
-
rank1(g);
|
|
23281
|
-
expandRanksets(g);
|
|
23282
|
-
cleanup1(g);
|
|
23098
|
+
function drawBand(p, seg2, ctx) {
|
|
23099
|
+
const obj = ctx.job.obj;
|
|
23100
|
+
if (obj !== null) obj.fillColor = resolveRenderColor(seg2.color);
|
|
23101
|
+
p[1].x = p[2].x = seg2.isLast ? seg2.lastx : p[0].x + seg2.segWidth;
|
|
23102
|
+
ctx.renderer.polygon([...p], true, ctx.job);
|
|
23103
|
+
p[0].x = p[3].x = p[1].x;
|
|
23283
23104
|
}
|
|
23284
|
-
function
|
|
23285
|
-
|
|
23286
|
-
|
|
23287
|
-
|
|
23288
|
-
|
|
23289
|
-
|
|
23105
|
+
function stripedBox(job, pts, clrs, rotate, renderer) {
|
|
23106
|
+
const { segs, error } = parseSegs(clrs);
|
|
23107
|
+
if (error === 1 || error === 2) return error;
|
|
23108
|
+
const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
|
|
23109
|
+
const lastx = p[1].x;
|
|
23110
|
+
const xdelta = p[1].x - p[0].x;
|
|
23111
|
+
p[1].x = p[2].x = p[0].x;
|
|
23112
|
+
const ctx = { job, renderer };
|
|
23113
|
+
const obj = job.obj;
|
|
23114
|
+
const saved = obj !== null ? obj.penWidth : 1;
|
|
23115
|
+
if (obj !== null && saved > THIN_LINE) obj.penWidth = THIN_LINE;
|
|
23116
|
+
for (let i = 0; i < segs.length; i++) {
|
|
23117
|
+
const s = segs[i];
|
|
23118
|
+
if (s.color === null) break;
|
|
23119
|
+
if (s.t > 0) {
|
|
23120
|
+
drawBand(p, { color: s.color, isLast: i + 1 === segs.length, segWidth: xdelta * s.t, lastx }, ctx);
|
|
23121
|
+
}
|
|
23290
23122
|
}
|
|
23123
|
+
if (obj !== null && saved > THIN_LINE) obj.penWidth = saved;
|
|
23124
|
+
return error;
|
|
23291
23125
|
}
|
|
23292
23126
|
|
|
23293
|
-
// src/
|
|
23294
|
-
|
|
23295
|
-
|
|
23296
|
-
|
|
23297
|
-
|
|
23298
|
-
|
|
23299
|
-
|
|
23300
|
-
|
|
23301
|
-
|
|
23302
|
-
|
|
23303
|
-
|
|
23304
|
-
return e.info.constraint === false;
|
|
23305
|
-
}
|
|
23306
|
-
var WNODE_ORDINARY = 0;
|
|
23307
|
-
var WNODE_SINGLETON = 1;
|
|
23308
|
-
var WNODE_VIRTUAL = 2;
|
|
23309
|
-
var CLASSIFY_WEIGHT_TABLE = [[1, 1, 1], [1, 2, 2], [1, 2, 4]];
|
|
23310
|
-
function epClass(n) {
|
|
23311
|
-
if (n.info.node_type === VIRTUAL) return WNODE_VIRTUAL;
|
|
23312
|
-
if ((n.info.weight_class ?? 2) <= 1) return WNODE_SINGLETON;
|
|
23313
|
-
return WNODE_ORDINARY;
|
|
23127
|
+
// src/render/xml-escape.ts
|
|
23128
|
+
var RE_DQUOTE = new RegExp('"', "g");
|
|
23129
|
+
var RE_SQUOTE = new RegExp("'", "g");
|
|
23130
|
+
var RE_AMP_NONENTITY = /&(?![A-Za-z]+;|#[0-9]+;|#x[0-9A-Fa-f]+;)/g;
|
|
23131
|
+
function escapeXml(s) {
|
|
23132
|
+
let r = s.replace(RE_AMP_NONENTITY, "&");
|
|
23133
|
+
r = r.replace(/</g, "<");
|
|
23134
|
+
r = r.replace(/>/g, ">");
|
|
23135
|
+
r = r.replace(RE_DQUOTE, """);
|
|
23136
|
+
r = r.replace(RE_SQUOTE, "'");
|
|
23137
|
+
return r;
|
|
23314
23138
|
}
|
|
23315
|
-
function
|
|
23316
|
-
|
|
23317
|
-
|
|
23139
|
+
function escapeXmlTitle(s) {
|
|
23140
|
+
let r = escapeXml(s);
|
|
23141
|
+
r = r.replace(/-/g, "-");
|
|
23142
|
+
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
23143
|
+
return r;
|
|
23318
23144
|
}
|
|
23319
|
-
function
|
|
23320
|
-
|
|
23321
|
-
|
|
23145
|
+
function escapeXmlText(s) {
|
|
23146
|
+
let r = escapeXml(s);
|
|
23147
|
+
r = r.replace(/-/g, "-");
|
|
23148
|
+
r = r.replace(/\n/g, " ");
|
|
23149
|
+
r = r.replace(/\r/g, " ");
|
|
23150
|
+
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
23151
|
+
return r;
|
|
23322
23152
|
}
|
|
23323
|
-
|
|
23324
|
-
|
|
23325
|
-
|
|
23153
|
+
|
|
23154
|
+
// src/gvc/device-cluster.ts
|
|
23155
|
+
function applyClusterGradient(obj, fill) {
|
|
23156
|
+
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
23157
|
+
obj.fillColor = resolveRenderColor(fill.fillColor);
|
|
23158
|
+
obj.stopColor = resolveRenderColor(fill.stopColor);
|
|
23159
|
+
obj.gradientFrac = fill.frac;
|
|
23160
|
+
obj.gradientAngle = fill.angle;
|
|
23326
23161
|
}
|
|
23327
|
-
function
|
|
23328
|
-
|
|
23329
|
-
|
|
23162
|
+
function clusterAttr(sg, key) {
|
|
23163
|
+
for (let g = sg; g !== null; g = g.parent) {
|
|
23164
|
+
const v = g.attrs.get(key);
|
|
23165
|
+
if (v !== void 0) return v;
|
|
23166
|
+
}
|
|
23167
|
+
return void 0;
|
|
23330
23168
|
}
|
|
23331
|
-
function
|
|
23332
|
-
|
|
23333
|
-
const v = virtualNode(g);
|
|
23334
|
-
v.info.node_type = SLACKNODE;
|
|
23335
|
-
const t0 = ufFind(t);
|
|
23336
|
-
const h0 = ufFind(h);
|
|
23337
|
-
const w = e.info.weight ?? 1;
|
|
23338
|
-
const rt = makeAuxEdge(v, t0, tLen, CL_BACK * w);
|
|
23339
|
-
const rh = makeAuxEdge(v, h0, hLen, w);
|
|
23340
|
-
rt.info.to_orig = e;
|
|
23341
|
-
rh.info.to_orig = e;
|
|
23169
|
+
function clusterStyle(sg) {
|
|
23170
|
+
return clusterAttr(sg, "style");
|
|
23342
23171
|
}
|
|
23343
|
-
function
|
|
23344
|
-
|
|
23345
|
-
if (
|
|
23346
|
-
const
|
|
23347
|
-
|
|
23348
|
-
|
|
23349
|
-
if (t.info.clust || h.info.clust) {
|
|
23350
|
-
interclust1(g, e.tail, e.head, e);
|
|
23351
|
-
return;
|
|
23352
|
-
}
|
|
23353
|
-
const rep = findFastEdge(t, h);
|
|
23354
|
-
if (rep !== void 0) mergeOneway(e, rep);
|
|
23355
|
-
else virtualEdge(t, h, e);
|
|
23172
|
+
function clusterPeripheries(sg) {
|
|
23173
|
+
const raw = clusterAttr(sg, "peripheries");
|
|
23174
|
+
if (raw === void 0 || raw.length === 0) return 1;
|
|
23175
|
+
const v = parseInt(raw, 10);
|
|
23176
|
+
if (Number.isNaN(v)) return 1;
|
|
23177
|
+
return v < 0 ? 0 : v;
|
|
23356
23178
|
}
|
|
23357
|
-
function
|
|
23358
|
-
|
|
23359
|
-
|
|
23360
|
-
|
|
23361
|
-
|
|
23179
|
+
function applyClusterPenState(obj, sg) {
|
|
23180
|
+
const flags = parseStyleFlags(clusterStyle(sg));
|
|
23181
|
+
const pen = clusterAttr(sg, "pencolor") ?? clusterAttr(sg, "color");
|
|
23182
|
+
obj.penColor = clusterPeripheries(sg) === 0 ? resolveRenderColor("transparent") : resolveRenderColor(resolvePenColor(pen));
|
|
23183
|
+
obj.penWidth = resolvePenWidth(flags, clusterAttr(sg, "penwidth"));
|
|
23184
|
+
obj.pen = resolvePenType(flags);
|
|
23362
23185
|
}
|
|
23363
|
-
function
|
|
23364
|
-
|
|
23365
|
-
|
|
23186
|
+
function clusterAttrsOf(sg) {
|
|
23187
|
+
return {
|
|
23188
|
+
style: clusterStyle(sg),
|
|
23189
|
+
color: clusterAttr(sg, "color"),
|
|
23190
|
+
pencolor: clusterAttr(sg, "pencolor"),
|
|
23191
|
+
fillcolor: clusterAttr(sg, "fillcolor"),
|
|
23192
|
+
bgcolor: clusterAttr(sg, "bgcolor"),
|
|
23193
|
+
penwidth: clusterAttr(sg, "penwidth"),
|
|
23194
|
+
gradientangle: clusterAttr(sg, "gradientangle")
|
|
23195
|
+
};
|
|
23366
23196
|
}
|
|
23367
|
-
function
|
|
23368
|
-
const
|
|
23369
|
-
|
|
23370
|
-
|
|
23371
|
-
|
|
23372
|
-
|
|
23373
|
-
|
|
23374
|
-
|
|
23375
|
-
|
|
23376
|
-
|
|
23377
|
-
|
|
23197
|
+
function applyClusterObjState(sg, job) {
|
|
23198
|
+
const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
|
|
23199
|
+
if (job.obj === null) return false;
|
|
23200
|
+
const obj = job.obj;
|
|
23201
|
+
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
23202
|
+
applyClusterPenState(obj, sg);
|
|
23203
|
+
if (fillRes.kind === "none") {
|
|
23204
|
+
obj.fill = 0 /* None */;
|
|
23205
|
+
return false;
|
|
23206
|
+
}
|
|
23207
|
+
if (fillRes.kind === "solid") {
|
|
23208
|
+
obj.fill = 1 /* Solid */;
|
|
23209
|
+
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
23210
|
+
return true;
|
|
23211
|
+
}
|
|
23212
|
+
applyClusterGradient(obj, fillRes);
|
|
23213
|
+
return true;
|
|
23214
|
+
});
|
|
23378
23215
|
}
|
|
23379
|
-
|
|
23380
|
-
|
|
23381
|
-
|
|
23382
|
-
|
|
23216
|
+
|
|
23217
|
+
// src/render/svg-id.ts
|
|
23218
|
+
function svgClass(kind, classAttr) {
|
|
23219
|
+
return classAttr !== void 0 && classAttr.length > 0 ? 'class="' + kind + " " + escapeXmlTitle(classAttr) + '"' : 'class="' + kind + '"';
|
|
23383
23220
|
}
|
|
23384
|
-
function
|
|
23385
|
-
|
|
23386
|
-
incrWidth(g, v);
|
|
23387
|
-
return v;
|
|
23221
|
+
function svgNodeId(n, job) {
|
|
23222
|
+
return job.objId(n.attrs.get("id"), "node" + (n.id + 1));
|
|
23388
23223
|
}
|
|
23389
|
-
function
|
|
23390
|
-
|
|
23391
|
-
return v.info.clust.info.rankleader[v.info.rank ?? 0];
|
|
23224
|
+
function svgEdgeId(e, job) {
|
|
23225
|
+
return job.objId(e.attrs.get("id"), "edge" + e.graphSeq);
|
|
23392
23226
|
}
|
|
23393
|
-
function
|
|
23394
|
-
|
|
23395
|
-
return plainVnode(g);
|
|
23227
|
+
function svgClusterId(sg, job) {
|
|
23228
|
+
return job.objId(sg.attrs.get("id"), "clust" + sg.seq);
|
|
23396
23229
|
}
|
|
23397
|
-
function
|
|
23398
|
-
|
|
23399
|
-
let u = from;
|
|
23400
|
-
const toRank = to.info.rank ?? 0;
|
|
23401
|
-
for (let r = (from.info.rank ?? 0) + 1; r <= toRank; r++) {
|
|
23402
|
-
const v = r < toRank ? (() => {
|
|
23403
|
-
const n = chainVnode(g, orig, r, labelRank);
|
|
23404
|
-
n.info.rank = r;
|
|
23405
|
-
return n;
|
|
23406
|
-
})() : to;
|
|
23407
|
-
const e = virtualEdge(u, v, orig);
|
|
23408
|
-
applyVirtualWeight(e);
|
|
23409
|
-
u = v;
|
|
23410
|
-
}
|
|
23230
|
+
function svgGraphId(g, job) {
|
|
23231
|
+
return job.objId(g.attrs.get("id"), "graph0", true);
|
|
23411
23232
|
}
|
|
23412
|
-
function
|
|
23413
|
-
return n.
|
|
23233
|
+
function svgNodeClass(n) {
|
|
23234
|
+
return svgClass("node", nodeAttr(n, n.root, "class"));
|
|
23414
23235
|
}
|
|
23415
|
-
function
|
|
23416
|
-
return e.
|
|
23236
|
+
function svgEdgeClass(e) {
|
|
23237
|
+
return svgClass("edge", e.attrs.get("class"));
|
|
23417
23238
|
}
|
|
23418
|
-
function
|
|
23419
|
-
return
|
|
23239
|
+
function svgClusterClass(sg) {
|
|
23240
|
+
return svgClass("cluster", clusterAttr(sg, "class"));
|
|
23420
23241
|
}
|
|
23421
|
-
function
|
|
23422
|
-
return
|
|
23242
|
+
function svgGraphClass(g) {
|
|
23243
|
+
return svgClass("graph", g.attrs.get("class"));
|
|
23423
23244
|
}
|
|
23424
|
-
|
|
23425
|
-
|
|
23245
|
+
|
|
23246
|
+
// src/common/poly-gencode.ts
|
|
23247
|
+
function isMulticolor(fillcolor) {
|
|
23248
|
+
return fillcolor.includes(":");
|
|
23426
23249
|
}
|
|
23427
|
-
function
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23250
|
+
function renderEllipse(ring, coord, renderer, job, filled) {
|
|
23251
|
+
const rx = Math.abs((ring[1].x - ring[0].x) / 2);
|
|
23252
|
+
const ry = Math.abs((ring[1].y - ring[0].y) / 2);
|
|
23253
|
+
const center = transformPoint(coord, job);
|
|
23254
|
+
renderer.ellipse(center, rx, ry, filled, job);
|
|
23432
23255
|
}
|
|
23433
|
-
function
|
|
23434
|
-
const
|
|
23435
|
-
|
|
23436
|
-
|
|
23437
|
-
|
|
23438
|
-
|
|
23439
|
-
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
|
|
23443
|
-
|
|
23256
|
+
function renderPolygon(ring, coord, renderer, job, filled) {
|
|
23257
|
+
const pts = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, job));
|
|
23258
|
+
renderer.polygon(pts, filled, job);
|
|
23259
|
+
}
|
|
23260
|
+
function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
23261
|
+
if (ctx.style.wedged && j === 0 && isMulticolor(ctx.fillcolor)) {
|
|
23262
|
+
const pf = ring.map(
|
|
23263
|
+
(v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
|
|
23264
|
+
);
|
|
23265
|
+
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
|
|
23266
|
+
renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
|
|
23267
|
+
} else {
|
|
23268
|
+
renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
|
|
23444
23269
|
}
|
|
23270
|
+
if (ctx.diagonals) mcircleHack(ring, coord, ctx);
|
|
23445
23271
|
}
|
|
23446
|
-
function
|
|
23447
|
-
|
|
23448
|
-
|
|
23272
|
+
function renderStripedRing(ring, coord, ctx) {
|
|
23273
|
+
const af = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job));
|
|
23274
|
+
stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer);
|
|
23275
|
+
renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
|
|
23449
23276
|
}
|
|
23450
|
-
function
|
|
23451
|
-
|
|
23452
|
-
|
|
23453
|
-
|
|
23454
|
-
|
|
23455
|
-
|
|
23456
|
-
}
|
|
23277
|
+
function renderPolyRing(ring, coord, filled, j, ctx) {
|
|
23278
|
+
if (ctx.style.striped && j === 0) renderStripedRing(ring, coord, ctx);
|
|
23279
|
+
else if (ctx.underline) underlineDraw(ring, coord, filled, ctx);
|
|
23280
|
+
else if (ctx.shape !== 0 && ctx.shape !== STAR || ctx.diagonals || ctx.rounded) {
|
|
23281
|
+
drawRoundCorners(ring, coord, filled, ctx);
|
|
23282
|
+
} else renderPolygon(ring, coord, ctx.renderer, ctx.job, filled);
|
|
23457
23283
|
}
|
|
23458
|
-
function
|
|
23459
|
-
|
|
23460
|
-
|
|
23461
|
-
|
|
23462
|
-
const
|
|
23463
|
-
|
|
23464
|
-
|
|
23465
|
-
|
|
23466
|
-
|
|
23467
|
-
|
|
23468
|
-
|
|
23469
|
-
|
|
23470
|
-
return;
|
|
23284
|
+
function renderPeripheries(poly, coord, filled, ctx) {
|
|
23285
|
+
const sides = poly.sides <= 2 ? 2 : poly.sides;
|
|
23286
|
+
const verts = poly.vertices;
|
|
23287
|
+
for (let j = 0; j < poly.peripheries; j++) {
|
|
23288
|
+
const ring = verts.slice(j * sides, (j + 1) * sides);
|
|
23289
|
+
if (ring.length < sides) break;
|
|
23290
|
+
const ringFilled = j === 0 ? filled : false;
|
|
23291
|
+
if (poly.sides <= 2) {
|
|
23292
|
+
renderEllipseRing(ring, coord, ringFilled, j, ctx);
|
|
23293
|
+
} else {
|
|
23294
|
+
renderPolyRing(ring, coord, ringFilled, j, ctx);
|
|
23295
|
+
}
|
|
23471
23296
|
}
|
|
23472
|
-
if (nodeRank3(t) === nodeRank3(h)) return;
|
|
23473
|
-
interclrepChain(g, e, t, h);
|
|
23474
23297
|
}
|
|
23475
|
-
function
|
|
23476
|
-
|
|
23298
|
+
function renderLabel(label, coord, renderer, job) {
|
|
23299
|
+
if (label.u.kind !== "txt" || label.u.nspans < 1) return;
|
|
23300
|
+
label.pos = coord;
|
|
23301
|
+
label.set = true;
|
|
23302
|
+
const VALIGN_TOP2 = "t".charCodeAt(0);
|
|
23303
|
+
const VALIGN_BOTTOM2 = "b".charCodeAt(0);
|
|
23304
|
+
let py = label.valign === VALIGN_TOP2 ? coord.y + label.space.y / 2 - label.fontsize : label.valign === VALIGN_BOTTOM2 ? coord.y - label.space.y / 2 + label.dimen.y - label.fontsize : coord.y + label.dimen.y / 2 - label.fontsize;
|
|
23305
|
+
for (let i = 0; i < label.u.nspans; i++) {
|
|
23306
|
+
const span = label.u.span[i];
|
|
23307
|
+
const px = span.just === "l" ? coord.x - label.space.x / 2 : span.just === "r" ? coord.x + label.space.x / 2 : coord.x;
|
|
23308
|
+
gvrenderTextspan(renderer, { x: px, y: py }, span, job);
|
|
23309
|
+
py -= span.size.y;
|
|
23310
|
+
}
|
|
23477
23311
|
}
|
|
23478
|
-
function
|
|
23479
|
-
|
|
23480
|
-
|
|
23481
|
-
|
|
23482
|
-
|
|
23483
|
-
|
|
23484
|
-
|
|
23312
|
+
function renderNodeLabel(n, coord, renderer, job) {
|
|
23313
|
+
const label = n.info.label;
|
|
23314
|
+
if (label === void 0) return;
|
|
23315
|
+
if (label.html && label.u.kind === "html") {
|
|
23316
|
+
label.pos = coord;
|
|
23317
|
+
label.set = true;
|
|
23318
|
+
const html = label.u.html;
|
|
23319
|
+
withLabelEmitState(job, () => emitHtmlLabel(html, coord, renderer, job));
|
|
23320
|
+
} else {
|
|
23321
|
+
renderLabel(label, coord, renderer, job);
|
|
23485
23322
|
}
|
|
23486
|
-
return prev;
|
|
23487
23323
|
}
|
|
23488
|
-
function
|
|
23489
|
-
|
|
23490
|
-
|
|
23491
|
-
return e;
|
|
23324
|
+
function anchorAttr2(n, key) {
|
|
23325
|
+
const v = nodeAttr(n, n.root, key);
|
|
23326
|
+
return v !== void 0 && v !== "" ? v : void 0;
|
|
23492
23327
|
}
|
|
23493
|
-
function
|
|
23494
|
-
if (
|
|
23495
|
-
|
|
23496
|
-
|
|
23497
|
-
mergeChain(g, e, prev.info.to_virt, true);
|
|
23498
|
-
otherEdge(e);
|
|
23499
|
-
}
|
|
23328
|
+
function resolveTooltip(n, tooltip) {
|
|
23329
|
+
if (tooltip !== void 0) return substObjAnchor(interpretCRNL(tooltip), n);
|
|
23330
|
+
const label = n.info.label;
|
|
23331
|
+
return label?.text ?? "";
|
|
23500
23332
|
}
|
|
23501
|
-
function
|
|
23502
|
-
|
|
23503
|
-
|
|
23504
|
-
|
|
23333
|
+
function beginNodeAnchor(n, renderer, job) {
|
|
23334
|
+
const url = anchorAttr2(n, "href") ?? anchorAttr2(n, "URL");
|
|
23335
|
+
const tooltip = anchorAttr2(n, "tooltip");
|
|
23336
|
+
if (url === void 0 && tooltip === void 0) return false;
|
|
23337
|
+
renderer.beginAnchor?.(
|
|
23338
|
+
url !== void 0 ? substObjAnchor(url, n) : "",
|
|
23339
|
+
resolveTooltip(n, tooltip),
|
|
23340
|
+
anchorAttr2(n, "target") ?? "",
|
|
23341
|
+
svgNodeId(n, job),
|
|
23342
|
+
job
|
|
23343
|
+
);
|
|
23505
23344
|
return true;
|
|
23506
23345
|
}
|
|
23507
|
-
function
|
|
23508
|
-
|
|
23509
|
-
|
|
23510
|
-
|
|
23511
|
-
|
|
23346
|
+
function applyGradientFields(obj, fill) {
|
|
23347
|
+
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
23348
|
+
obj.fillColor = resolveRenderColor(fill.fillColor);
|
|
23349
|
+
obj.stopColor = resolveRenderColor(fill.stopColor);
|
|
23350
|
+
obj.gradientFrac = fill.frac;
|
|
23351
|
+
obj.gradientAngle = fill.angle;
|
|
23512
23352
|
}
|
|
23513
|
-
function
|
|
23514
|
-
|
|
23515
|
-
if (handleMultiSameRank(e, prev)) return true;
|
|
23516
|
-
return handleMultiParallel(g, e, prev);
|
|
23353
|
+
function isPointNode(n) {
|
|
23354
|
+
return n.info.shape?.kind === 3 /* SH_POINT */;
|
|
23517
23355
|
}
|
|
23518
|
-
function
|
|
23519
|
-
|
|
23520
|
-
if (
|
|
23521
|
-
|
|
23522
|
-
|
|
23523
|
-
|
|
23524
|
-
|
|
23525
|
-
|
|
23526
|
-
|
|
23356
|
+
function findFillDflt(n) {
|
|
23357
|
+
const fillcolor = nodeAttr(n, n.root, "fillcolor");
|
|
23358
|
+
if (fillcolor !== void 0 && fillcolor !== "") return fillcolor;
|
|
23359
|
+
const color = nodeAttr(n, n.root, "color");
|
|
23360
|
+
if (color !== void 0 && color !== "") return color;
|
|
23361
|
+
return "black";
|
|
23362
|
+
}
|
|
23363
|
+
function applyFillState(obj, n, job) {
|
|
23364
|
+
obj.id = svgNodeId(n, job);
|
|
23365
|
+
if (isPointNode(n)) {
|
|
23366
|
+
obj.fill = 1 /* Solid */;
|
|
23367
|
+
obj.fillColor = resolveRenderColor(findFillDflt(n));
|
|
23368
|
+
return true;
|
|
23369
|
+
}
|
|
23370
|
+
const fillRes = resolveNodeFillEx({
|
|
23371
|
+
style: nodeAttr(n, n.root, "style"),
|
|
23372
|
+
fillcolor: nodeAttr(n, n.root, "fillcolor"),
|
|
23373
|
+
color: nodeAttr(n, n.root, "color"),
|
|
23374
|
+
gradientangle: nodeAttr(n, n.root, "gradientangle")
|
|
23375
|
+
});
|
|
23376
|
+
if (fillRes.kind === "none") {
|
|
23377
|
+
obj.fill = 0 /* None */;
|
|
23378
|
+
return false;
|
|
23379
|
+
}
|
|
23380
|
+
if (fillRes.kind === "solid") {
|
|
23381
|
+
obj.fill = 1 /* Solid */;
|
|
23382
|
+
obj.fillColor = resolveRenderColor(fillRes.color);
|
|
23383
|
+
return true;
|
|
23527
23384
|
}
|
|
23385
|
+
applyGradientFields(obj, fillRes);
|
|
23528
23386
|
return true;
|
|
23529
23387
|
}
|
|
23530
|
-
function
|
|
23531
|
-
|
|
23532
|
-
|
|
23533
|
-
|
|
23534
|
-
|
|
23388
|
+
function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
23389
|
+
const flags = parseStyleFlags(styleAttr);
|
|
23390
|
+
obj.penColor = resolveRenderColor(resolvePenColor(colorAttr));
|
|
23391
|
+
obj.pen = resolvePenType(flags);
|
|
23392
|
+
obj.penWidth = resolvePenWidth(flags, penwidthAttr);
|
|
23393
|
+
obj.rawStyle = styleTokens(styleAttr);
|
|
23535
23394
|
}
|
|
23536
|
-
function
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23541
|
-
return
|
|
23395
|
+
function applyNodeStyle(obj, n, job) {
|
|
23396
|
+
const styleAttr = nodeAttr(n, n.root, "style");
|
|
23397
|
+
const colorAttr = nodeAttr(n, n.root, "color");
|
|
23398
|
+
const filled = applyFillState(obj, n, job);
|
|
23399
|
+
applyPenState(obj, styleAttr, colorAttr, nodeAttr(n, n.root, "penwidth"));
|
|
23400
|
+
return filled;
|
|
23542
23401
|
}
|
|
23543
|
-
function
|
|
23544
|
-
if (
|
|
23545
|
-
|
|
23546
|
-
|
|
23402
|
+
function prepareDrawPoly(poly, filled, obj) {
|
|
23403
|
+
if (poly.peripheries !== 0 || !filled) return poly;
|
|
23404
|
+
obj.penColor = { type: "string", s: "transparent" };
|
|
23405
|
+
return { ...poly, peripheries: 1 };
|
|
23406
|
+
}
|
|
23407
|
+
function vertexScale(n, poly) {
|
|
23408
|
+
const info = n.info;
|
|
23409
|
+
if (poly.vertices == null || info.width === void 0 || info.height === void 0) {
|
|
23410
|
+
return poly;
|
|
23547
23411
|
}
|
|
23548
|
-
|
|
23549
|
-
|
|
23550
|
-
|
|
23412
|
+
const xsize = (info.lw + info.rw) / (info.width * 72);
|
|
23413
|
+
const ysize = info.ht / (info.height * 72);
|
|
23414
|
+
if (Math.abs(xsize - 1) < 1e-9 && Math.abs(ysize - 1) < 1e-9) return poly;
|
|
23415
|
+
return {
|
|
23416
|
+
...poly,
|
|
23417
|
+
vertices: poly.vertices.map((v) => ({ x: v.x * xsize, y: v.y * ysize }))
|
|
23418
|
+
};
|
|
23419
|
+
}
|
|
23420
|
+
function resolveNodeDrawCtx(job, n) {
|
|
23421
|
+
const rawPoly = n.info.shape_info;
|
|
23422
|
+
if (rawPoly === void 0 || rawPoly.vertices === void 0) return null;
|
|
23423
|
+
const poly = vertexScale(n, rawPoly);
|
|
23424
|
+
const coord = n.info.coord ?? { x: 0, y: 0 };
|
|
23425
|
+
const obj = job.obj;
|
|
23426
|
+
const filled = obj !== null && applyNodeStyle(obj, n, job);
|
|
23427
|
+
const drawPoly = obj !== null ? prepareDrawPoly(poly, filled, obj) : poly;
|
|
23428
|
+
const styleFlags = parseStyleFlags(nodeAttr(n, n.root, "style"));
|
|
23429
|
+
const ringCtx = {
|
|
23430
|
+
renderer: job.renderer,
|
|
23431
|
+
job,
|
|
23432
|
+
style: styleFlags,
|
|
23433
|
+
fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
|
|
23434
|
+
...specialCornerFlags(drawPoly.option, styleFlags)
|
|
23435
|
+
};
|
|
23436
|
+
return { poly: drawPoly, coord, filled, ringCtx };
|
|
23437
|
+
}
|
|
23438
|
+
function specialCornerFlags(opt, style) {
|
|
23439
|
+
return {
|
|
23440
|
+
shape: opt.shape,
|
|
23441
|
+
diagonals: opt.diagonals || style.diagonals,
|
|
23442
|
+
rounded: opt.rounded || style.rounded,
|
|
23443
|
+
underline: opt.underline || style.underline
|
|
23444
|
+
};
|
|
23445
|
+
}
|
|
23446
|
+
function polyGencode(rawJob, rawNode) {
|
|
23447
|
+
const job = rawJob;
|
|
23448
|
+
const n = rawNode;
|
|
23449
|
+
const renderer = job.renderer;
|
|
23450
|
+
if (!renderer) return;
|
|
23451
|
+
const ctx = resolveNodeDrawCtx(job, n);
|
|
23452
|
+
if (ctx === null) return;
|
|
23453
|
+
const clustersLast = (job.flags & EMIT_CLUSTERS_LAST) !== 0;
|
|
23454
|
+
const savedShape = job.obj?.urlMapShape;
|
|
23455
|
+
const savedPts = job.obj?.urlMapPts;
|
|
23456
|
+
let inAnchor = clustersLast ? false : beginNodeAnchor(n, renderer, job);
|
|
23457
|
+
renderPeripheries(ctx.poly, ctx.coord, ctx.filled, ctx.ringCtx);
|
|
23458
|
+
if (!isPointNode(n)) renderNodeLabel(n, ctx.coord, renderer, job);
|
|
23459
|
+
if (clustersLast) {
|
|
23460
|
+
if (job.obj && savedPts !== void 0 && savedShape !== void 0) {
|
|
23461
|
+
job.obj.urlMapShape = savedShape;
|
|
23462
|
+
job.obj.urlMapPts = savedPts;
|
|
23463
|
+
}
|
|
23464
|
+
inAnchor = beginNodeAnchor(n, renderer, job);
|
|
23551
23465
|
}
|
|
23552
|
-
|
|
23466
|
+
if (inAnchor) renderer.endAnchor?.(job);
|
|
23553
23467
|
}
|
|
23554
|
-
|
|
23555
|
-
|
|
23556
|
-
|
|
23557
|
-
|
|
23558
|
-
|
|
23559
|
-
|
|
23560
|
-
|
|
23468
|
+
|
|
23469
|
+
// src/common/poly-inside.ts
|
|
23470
|
+
function sameSide(p0, p1, L0, L1) {
|
|
23471
|
+
const a = -(L1.y - L0.y);
|
|
23472
|
+
const b = L1.x - L0.x;
|
|
23473
|
+
const c = a * L0.x + b * L0.y;
|
|
23474
|
+
const s0 = a * p0.x + b * p0.y - c >= 0;
|
|
23475
|
+
const s1 = a * p1.x + b * p1.y - c >= 0;
|
|
23476
|
+
return s0 === s1;
|
|
23477
|
+
}
|
|
23478
|
+
function fixedShapeSize(poly) {
|
|
23479
|
+
let xmax = 0;
|
|
23480
|
+
let ymax = 0;
|
|
23481
|
+
for (const v of poly.vertices ?? []) {
|
|
23482
|
+
xmax = Math.max(xmax, Math.abs(v.x));
|
|
23483
|
+
ymax = Math.max(ymax, Math.abs(v.y));
|
|
23561
23484
|
}
|
|
23562
|
-
|
|
23563
|
-
const h = ufFind(e.head);
|
|
23564
|
-
if (e.tail !== t || e.head !== h) return prev;
|
|
23565
|
-
return class2EdgeSameRep(g, e);
|
|
23485
|
+
return { w: 2 * xmax, h: 2 * ymax };
|
|
23566
23486
|
}
|
|
23567
|
-
function
|
|
23568
|
-
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
|
|
23487
|
+
function insideDims(n, xsize, ysize) {
|
|
23488
|
+
const w = 72 * (n.info.width || xsize / 72);
|
|
23489
|
+
const h = 72 * (n.info.height || ysize / 72);
|
|
23490
|
+
return { w, h, ow: 72 * n.info.outline_width || w, oh: 72 * n.info.outline_height || h };
|
|
23491
|
+
}
|
|
23492
|
+
function insideScale(n, poly) {
|
|
23493
|
+
const flip = n.root.info.flip === true;
|
|
23494
|
+
if (poly.option.fixedshape) {
|
|
23495
|
+
const { w: w2, h: h2 } = fixedShapeSize(poly);
|
|
23496
|
+
const xsize2 = flip ? h2 : w2;
|
|
23497
|
+
const ysize2 = flip ? w2 : h2;
|
|
23498
|
+
return {
|
|
23499
|
+
scalex: xsize2 !== 0 ? w2 / xsize2 : w2,
|
|
23500
|
+
scaley: ysize2 !== 0 ? h2 / ysize2 : h2,
|
|
23501
|
+
boxURx: w2 / 2,
|
|
23502
|
+
boxURy: h2 / 2
|
|
23503
|
+
};
|
|
23572
23504
|
}
|
|
23505
|
+
const lwrw = n.info.lw + n.info.rw;
|
|
23506
|
+
const xsize = flip ? n.info.ht : lwrw;
|
|
23507
|
+
const ysize = flip ? lwrw : n.info.ht;
|
|
23508
|
+
const { w, h, ow, oh } = insideDims(n, xsize, ysize);
|
|
23509
|
+
return {
|
|
23510
|
+
scalex: xsize !== 0 ? w / xsize : w,
|
|
23511
|
+
scaley: ysize !== 0 ? h / ysize : h,
|
|
23512
|
+
boxURx: ow / 2,
|
|
23513
|
+
boxURy: oh / 2
|
|
23514
|
+
};
|
|
23573
23515
|
}
|
|
23574
|
-
function
|
|
23575
|
-
|
|
23516
|
+
function polygonWalk(P, vertex, sides) {
|
|
23517
|
+
const O = { x: 0, y: 0 };
|
|
23518
|
+
let i = 0;
|
|
23519
|
+
let i1 = 1 % sides;
|
|
23520
|
+
const Q = vertex[i];
|
|
23521
|
+
const R2 = vertex[i1];
|
|
23522
|
+
if (!sameSide(P, O, Q, R2)) return false;
|
|
23523
|
+
const s = sameSide(P, Q, R2, O);
|
|
23524
|
+
if (s && sameSide(P, R2, O, Q)) return true;
|
|
23525
|
+
for (let j = 1; j < sides; j++) {
|
|
23526
|
+
if (s) {
|
|
23527
|
+
i = i1;
|
|
23528
|
+
i1 = (i + 1) % sides;
|
|
23529
|
+
} else {
|
|
23530
|
+
i1 = i;
|
|
23531
|
+
i = (i + sides - 1) % sides;
|
|
23532
|
+
}
|
|
23533
|
+
if (!sameSide(P, O, vertex[i], vertex[i1])) return false;
|
|
23534
|
+
}
|
|
23535
|
+
return true;
|
|
23576
23536
|
}
|
|
23577
|
-
function
|
|
23578
|
-
|
|
23537
|
+
function insideShape(n, poly, p) {
|
|
23538
|
+
const sc = insideScale(n, poly);
|
|
23539
|
+
const P = { x: p.x * sc.scalex, y: p.y * sc.scaley };
|
|
23540
|
+
if (Math.abs(P.x) > sc.boxURx || Math.abs(P.y) > sc.boxURy) return false;
|
|
23541
|
+
if (poly.sides <= 2) {
|
|
23542
|
+
return Math.hypot(P.x / sc.boxURx, P.y / sc.boxURy) < 1;
|
|
23543
|
+
}
|
|
23544
|
+
const outerStart = (Math.max(poly.peripheries, 1) - 1) * poly.sides;
|
|
23545
|
+
const outer = poly.vertices.slice(outerStart, outerStart + poly.sides);
|
|
23546
|
+
const ring = polygonOutlineRing(outer, poly.sides, poly.penwidth ?? 1);
|
|
23547
|
+
return polygonWalk(P, ring, poly.sides);
|
|
23579
23548
|
}
|
|
23580
|
-
function
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23549
|
+
function polyInside(ctx, p) {
|
|
23550
|
+
const n = ctx.node;
|
|
23551
|
+
if (n === void 0) return false;
|
|
23552
|
+
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
23553
|
+
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
23554
|
+
if (ctx.bp) {
|
|
23555
|
+
const b = ctx.bp;
|
|
23556
|
+
return P.x >= b.ll.x && P.x <= b.ur.x && P.y >= b.ll.y && P.y <= b.ur.y;
|
|
23584
23557
|
}
|
|
23558
|
+
const poly = n.info.shape_info;
|
|
23559
|
+
if (poly === void 0 || poly.vertices === null) return false;
|
|
23560
|
+
return insideShape(n, poly, P);
|
|
23585
23561
|
}
|
|
23586
|
-
function
|
|
23587
|
-
const
|
|
23588
|
-
|
|
23589
|
-
|
|
23590
|
-
|
|
23562
|
+
function starInside(ctx, p) {
|
|
23563
|
+
const n = ctx.node;
|
|
23564
|
+
if (n === void 0) return false;
|
|
23565
|
+
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
23566
|
+
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
23567
|
+
if (ctx.bp) {
|
|
23568
|
+
const b = ctx.bp;
|
|
23569
|
+
return P.x >= b.ll.x && P.x <= b.ur.x && P.y >= b.ll.y && P.y <= b.ur.y;
|
|
23591
23570
|
}
|
|
23571
|
+
const poly = n.info.shape_info;
|
|
23572
|
+
if (poly === void 0 || poly.vertices === null) return false;
|
|
23573
|
+
const sides = poly.sides;
|
|
23574
|
+
const outerStart = (Math.max(poly.peripheries, 1) - 1) * sides;
|
|
23575
|
+
const outer = poly.vertices.slice(outerStart, outerStart + sides);
|
|
23576
|
+
const ring = polygonOutlineRing(outer, sides, poly.penwidth ?? 1);
|
|
23577
|
+
const O = { x: 0, y: 0 };
|
|
23578
|
+
let outcnt = 0;
|
|
23579
|
+
for (let i = 0; i < sides; i += 2) {
|
|
23580
|
+
const Q = ring[i];
|
|
23581
|
+
const R2 = ring[(i + 4) % sides];
|
|
23582
|
+
if (!sameSide(P, O, Q, R2)) outcnt++;
|
|
23583
|
+
if (outcnt === 2) return false;
|
|
23584
|
+
}
|
|
23585
|
+
return true;
|
|
23592
23586
|
}
|
|
23593
|
-
function
|
|
23594
|
-
|
|
23595
|
-
|
|
23596
|
-
const
|
|
23597
|
-
|
|
23598
|
-
|
|
23599
|
-
|
|
23600
|
-
|
|
23587
|
+
function recordInside(ctx, p) {
|
|
23588
|
+
const n = ctx.node;
|
|
23589
|
+
if (n === void 0) return false;
|
|
23590
|
+
const rankdir = (n.root.info.rankdir ?? 0) & 3;
|
|
23591
|
+
const P = rankdir === 0 ? p : ccwrotatepf(p, rankdir * 90);
|
|
23592
|
+
let bb;
|
|
23593
|
+
if (ctx.bp) {
|
|
23594
|
+
bb = ctx.bp;
|
|
23595
|
+
} else {
|
|
23596
|
+
const fld = n.info.shape_info;
|
|
23597
|
+
if (!fld?.b) return false;
|
|
23598
|
+
bb = fld.b;
|
|
23599
|
+
}
|
|
23600
|
+
const pw = 0.5;
|
|
23601
|
+
return P.x >= bb.ll.x - pw && P.x <= bb.ur.x + pw && P.y >= bb.ll.y - pw && P.y <= bb.ur.y + pw;
|
|
23601
23602
|
}
|
|
23602
23603
|
|
|
23603
23604
|
// src/common/edge-label-init.ts
|
|
@@ -32134,31 +32135,13 @@ function splay(root, key, keyOf, compare) {
|
|
|
32134
32135
|
}
|
|
32135
32136
|
|
|
32136
32137
|
// src/cdt/bag.ts
|
|
32137
|
-
function
|
|
32138
|
-
|
|
32139
|
-
|
|
32140
|
-
|
|
32141
|
-
|
|
32142
|
-
|
|
32143
|
-
|
|
32144
|
-
cur = cur.left;
|
|
32145
|
-
}
|
|
32146
|
-
return [null, null];
|
|
32147
|
-
}
|
|
32148
|
-
function unlinkNode(root, cur, parent) {
|
|
32149
|
-
const left = cur.left;
|
|
32150
|
-
const right = cur.right;
|
|
32151
|
-
let replacement;
|
|
32152
|
-
if (left === null) {
|
|
32153
|
-
replacement = right;
|
|
32154
|
-
} else {
|
|
32155
|
-
const maxLeft = splayMax(left);
|
|
32156
|
-
maxLeft.right = right;
|
|
32157
|
-
replacement = maxLeft;
|
|
32158
|
-
}
|
|
32159
|
-
if (parent === null) return replacement;
|
|
32160
|
-
parent.left = replacement;
|
|
32161
|
-
return root;
|
|
32138
|
+
function removeRoot(root) {
|
|
32139
|
+
const left = root.left;
|
|
32140
|
+
const right = root.right;
|
|
32141
|
+
if (left === null) return right;
|
|
32142
|
+
const maxLeft = splayMax(left);
|
|
32143
|
+
maxLeft.right = right;
|
|
32144
|
+
return maxLeft;
|
|
32162
32145
|
}
|
|
32163
32146
|
var DtBag = class {
|
|
32164
32147
|
_root = null;
|
|
@@ -32197,16 +32180,13 @@ var DtBag = class {
|
|
|
32197
32180
|
const key = this._keyOf(obj);
|
|
32198
32181
|
this._root = splay(this._root, key, this._keyOf, this._compare);
|
|
32199
32182
|
if (this._compare(key, this._keyOf(this._root.obj)) !== 0) return false;
|
|
32200
|
-
|
|
32201
|
-
this._root
|
|
32202
|
-
|
|
32203
|
-
|
|
32204
|
-
|
|
32205
|
-
|
|
32206
|
-
);
|
|
32207
|
-
if (cur === null) return false;
|
|
32208
|
-
const newRoot = unlinkNode(this._root, cur, parent);
|
|
32209
|
-
this._root = newRoot;
|
|
32183
|
+
while (this._root.obj !== obj) {
|
|
32184
|
+
const nxt = this.next(this._root.obj);
|
|
32185
|
+
if (nxt === void 0 || this._compare(key, this._keyOf(nxt)) !== 0) {
|
|
32186
|
+
return false;
|
|
32187
|
+
}
|
|
32188
|
+
}
|
|
32189
|
+
this._root = removeRoot(this._root);
|
|
32210
32190
|
this._size--;
|
|
32211
32191
|
return true;
|
|
32212
32192
|
}
|
|
@@ -52489,7 +52469,7 @@ var XdotParser = class _XdotParser {
|
|
|
52489
52469
|
let accounted = 0;
|
|
52490
52470
|
let j = 0;
|
|
52491
52471
|
while (accounted < len) {
|
|
52492
|
-
if (cur + j >= s.length)
|
|
52472
|
+
if (cur + j >= s.length) return null;
|
|
52493
52473
|
const ch = s[cur + j];
|
|
52494
52474
|
const prev = j > 0 ? s[cur + j - 1] : "";
|
|
52495
52475
|
out += ch;
|