@knowvah/dot-engine 2.6.12 → 2.7.1
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/README.md +1 -1
- package/dist/api.js +18 -4
- package/dist/api.js.map +3 -3
- package/dist/common/attr-get.d.ts +30 -0
- package/dist/common/attr-get.d.ts.map +1 -0
- package/dist/common/htmltable-emit-fill.d.ts +20 -2
- package/dist/common/htmltable-emit-fill.d.ts.map +1 -1
- package/dist/common/htmltable-emit.d.ts.map +1 -1
- package/dist/common/htmltable-lex-expat.d.ts.map +1 -1
- package/dist/common/htmltable-pos-runs.d.ts +7 -4
- package/dist/common/htmltable-pos-runs.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/libm-trig.d.ts +5 -0
- package/dist/common/libm-trig.d.ts.map +1 -0
- package/dist/common/make-label.d.ts.map +1 -1
- package/dist/common/multicolor.d.ts +21 -13
- package/dist/common/multicolor.d.ts.map +1 -1
- package/dist/common/poly-gencode.d.ts +1 -2
- package/dist/common/poly-gencode.d.ts.map +1 -1
- package/dist/common/poly-init.d.ts +2 -12
- package/dist/common/poly-init.d.ts.map +1 -1
- package/dist/common/splines-clip.d.ts +7 -0
- package/dist/common/splines-clip.d.ts.map +1 -1
- package/dist/gvc/context.d.ts +6 -0
- package/dist/gvc/context.d.ts.map +1 -1
- package/dist/gvc/device-cluster.d.ts +15 -0
- package/dist/gvc/device-cluster.d.ts.map +1 -1
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/gvc/first-layer.d.ts +9 -0
- package/dist/gvc/first-layer.d.ts.map +1 -0
- package/dist/gvc/gvrender-set-style.d.ts +28 -0
- package/dist/gvc/gvrender-set-style.d.ts.map +1 -0
- package/dist/gvc/usershape.d.ts +18 -0
- package/dist/gvc/usershape.d.ts.map +1 -1
- package/dist/index.js +2478 -912
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/compound.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-clip.d.ts +14 -4
- package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-routing.d.ts.map +1 -1
- package/dist/layout/dot/graph-label.d.ts.map +1 -1
- package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts +11 -0
- package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts.map +1 -0
- package/dist/layout/neato/__fixtures__/hier-imds.d.ts +36 -0
- package/dist/layout/neato/__fixtures__/hier-imds.d.ts.map +1 -0
- package/dist/layout/neato/__fixtures__/hier-majorization.d.ts +32 -0
- package/dist/layout/neato/__fixtures__/hier-majorization.d.ts.map +1 -0
- package/dist/layout/neato/cdt-surface.d.ts.map +1 -1
- package/dist/layout/neato/compute-hierarchy.d.ts +24 -0
- package/dist/layout/neato/compute-hierarchy.d.ts.map +1 -0
- package/dist/layout/neato/conjgrad-mkernel.d.ts +20 -0
- package/dist/layout/neato/conjgrad-mkernel.d.ts.map +1 -0
- package/dist/layout/neato/conjgrad.d.ts +19 -0
- package/dist/layout/neato/conjgrad.d.ts.map +1 -1
- package/dist/layout/neato/constrained-majorization.d.ts +26 -0
- package/dist/layout/neato/constrained-majorization.d.ts.map +1 -0
- package/dist/layout/neato/dijkstra.d.ts +33 -16
- package/dist/layout/neato/dijkstra.d.ts.map +1 -1
- package/dist/layout/neato/gts-triangle.d.ts +14 -0
- package/dist/layout/neato/gts-triangle.d.ts.map +1 -0
- package/dist/layout/neato/init.d.ts +2 -12
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/neato/kkutils.d.ts +20 -0
- package/dist/layout/neato/kkutils.d.ts.map +1 -0
- package/dist/layout/neato/make-graph-data.d.ts +43 -0
- package/dist/layout/neato/make-graph-data.d.ts.map +1 -0
- package/dist/layout/neato/matrix-ops.d.ts +46 -0
- package/dist/layout/neato/matrix-ops.d.ts.map +1 -1
- package/dist/layout/neato/opt-arrangement.d.ts +20 -0
- package/dist/layout/neato/opt-arrangement.d.ts.map +1 -0
- package/dist/layout/neato/quad-prog-solve.d.ts +44 -0
- package/dist/layout/neato/quad-prog-solve.d.ts.map +1 -0
- package/dist/layout/neato/smart-ini-x.d.ts +9 -0
- package/dist/layout/neato/smart-ini-x.d.ts.map +1 -0
- package/dist/layout/neato/splines.d.ts +1 -1
- package/dist/layout/neato/splines.d.ts.map +1 -1
- package/dist/layout/neato/start.d.ts +4 -1
- package/dist/layout/neato/start.d.ts.map +1 -1
- package/dist/layout/neato/stress.d.ts +8 -0
- package/dist/layout/neato/stress.d.ts.map +1 -1
- package/dist/model/edge.d.ts +1 -1
- package/dist/model/edge.d.ts.map +1 -1
- package/dist/model/lazy-attrs.d.ts +10 -0
- package/dist/model/lazy-attrs.d.ts.map +1 -0
- package/dist/model/node.d.ts +1 -1
- package/dist/model/node.d.ts.map +1 -1
- package/dist/ortho/index.d.ts.map +1 -1
- package/dist/render/dot/edge-draw.d.ts +1 -1
- package/dist/render/dot/edge-draw.d.ts.map +1 -1
- package/dist/render/svg-multicolor.d.ts +2 -2
- package/dist/render/svg-multicolor.d.ts.map +1 -1
- package/dist/render.js +2358 -792
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/attr-get.ts +46 -0
- package/src/common/graph-init.ts +1 -1
- package/src/common/htmltable-emit-fill.ts +56 -11
- package/src/common/htmltable-emit.ts +4 -3
- package/src/common/htmltable-lex-expat.ts +21 -3
- package/src/common/htmltable-pos-runs.ts +11 -6
- package/src/common/htmltable.ts +28 -116
- package/src/common/libm-trig.ts +43 -0
- package/src/common/make-label.ts +14 -2
- package/src/common/multicolor.ts +88 -24
- package/src/common/poly-gencode.ts +16 -8
- package/src/common/poly-init.ts +23 -19
- package/src/common/postproc.ts +2 -2
- package/src/common/splines-clip.ts +15 -12
- package/src/common/splines-routespl.ts +2 -2
- package/src/common/textmeasure-lookup.ts +1 -1
- package/src/gvc/context.ts +8 -0
- package/src/gvc/device-cluster.ts +63 -8
- package/src/gvc/device.ts +16 -2
- package/src/gvc/first-layer.ts +26 -0
- package/src/gvc/gvrender-set-style.ts +114 -0
- package/src/gvc/usershape.ts +26 -0
- package/src/layout/dot/cluster.ts +1 -1
- package/src/layout/dot/compound.ts +3 -4
- package/src/layout/dot/conc.ts +1 -1
- package/src/layout/dot/edge-route-clip.ts +19 -7
- package/src/layout/dot/edge-route-routing.ts +11 -3
- package/src/layout/dot/fastgr.ts +2 -2
- package/src/layout/dot/graph-label.ts +1 -15
- package/src/layout/neato/__fixtures__/dijkstra-f.ts +17 -0
- package/src/layout/neato/__fixtures__/hier/c1554.gv +33 -0
- package/src/layout/neato/__fixtures__/hier/c1554.plain +26 -0
- package/src/layout/neato/__fixtures__/hier/c1554.xdot +161 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.plain +11 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.plain +13 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.plain +8 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.plain +8 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.plain +13 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.plain +16 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.xdot +62 -0
- package/src/layout/neato/__fixtures__/hier-imds.ts +151 -0
- package/src/layout/neato/__fixtures__/hier-majorization.ts +145 -0
- package/src/layout/neato/cdt-surface.ts +6 -16
- package/src/layout/neato/compute-hierarchy.ts +90 -0
- package/src/layout/neato/conjgrad-mkernel.ts +141 -0
- package/src/layout/neato/conjgrad.ts +208 -0
- package/src/layout/neato/constrained-majorization.ts +479 -0
- package/src/layout/neato/dijkstra.ts +218 -92
- package/src/layout/neato/edge-len.ts +2 -2
- package/src/layout/neato/fdp-adjust.ts +3 -3
- package/src/layout/neato/gts-triangle.ts +42 -0
- package/src/layout/neato/init.ts +57 -57
- package/src/layout/neato/kk.ts +2 -2
- package/src/layout/neato/kkutils.ts +96 -0
- package/src/layout/neato/make-graph-data.ts +166 -0
- package/src/layout/neato/matrix-ops.ts +138 -0
- package/src/layout/neato/opt-arrangement.ts +86 -0
- package/src/layout/neato/quad-prog-solve.ts +489 -0
- package/src/layout/neato/smart-ini-x.ts +503 -0
- package/src/layout/neato/splines.ts +4 -4
- package/src/layout/neato/start.ts +7 -6
- package/src/layout/neato/stress.ts +28 -0
- package/src/model/edge.ts +3 -2
- package/src/model/lazy-attrs.ts +36 -0
- package/src/model/node.ts +3 -2
- package/src/ortho/index.ts +2 -3
- package/src/parser/dot.js +1 -1
- package/src/parser/dot.pegjs +1 -1
- package/src/parser/index.ts +1 -1
- package/src/render/color-resolve.ts +2 -2
- package/src/render/dot/edge-draw.ts +6 -3
- package/src/render/dot.ts +1 -1
- package/src/render/svg-edge-split.ts +2 -2
- package/src/render/svg-multicolor.ts +4 -3
- package/src/render/svg-parallel-edge.ts +2 -2
package/dist/index.js
CHANGED
|
@@ -299,7 +299,7 @@ function peg$parse(input, options) {
|
|
|
299
299
|
return s;
|
|
300
300
|
}
|
|
301
301
|
function peg$f13(t, m, attrs) {
|
|
302
|
-
if (m) agwarningf("attribute macros not implemented"
|
|
302
|
+
if (m) agwarningf("attribute macros not implemented");
|
|
303
303
|
return { type: "attr", target: t, attrs };
|
|
304
304
|
}
|
|
305
305
|
function peg$f14(a) {
|
|
@@ -3688,6 +3688,20 @@ var Graph = class {
|
|
|
3688
3688
|
}
|
|
3689
3689
|
};
|
|
3690
3690
|
|
|
3691
|
+
// src/model/lazy-attrs.ts
|
|
3692
|
+
var SharedEmptyAttrs = class extends Map {
|
|
3693
|
+
set(key, _value) {
|
|
3694
|
+
throw new Error(`attrs.set("${key}") on a shared empty map; use ownAttrs()`);
|
|
3695
|
+
}
|
|
3696
|
+
delete(key) {
|
|
3697
|
+
throw new Error(`attrs.delete("${key}") on a shared empty map; use ownAttrs()`);
|
|
3698
|
+
}
|
|
3699
|
+
clear() {
|
|
3700
|
+
throw new Error("attrs.clear() on a shared empty map; use ownAttrs()");
|
|
3701
|
+
}
|
|
3702
|
+
};
|
|
3703
|
+
var EMPTY_ATTRS = new SharedEmptyAttrs();
|
|
3704
|
+
|
|
3691
3705
|
// src/model/algData.ts
|
|
3692
3706
|
var THETA_UNSET = 10;
|
|
3693
3707
|
|
|
@@ -3790,10 +3804,10 @@ var Node = class {
|
|
|
3790
3804
|
*/
|
|
3791
3805
|
nodeDefaultsSnapshot;
|
|
3792
3806
|
/** @see lib/cgraph/node.c:agnode */
|
|
3793
|
-
constructor(id, name, root) {
|
|
3807
|
+
constructor(id, name, root, lazyAttrs = false) {
|
|
3794
3808
|
this.id = id;
|
|
3795
3809
|
this.name = name;
|
|
3796
|
-
this.attrs = /* @__PURE__ */ new Map();
|
|
3810
|
+
this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
|
|
3797
3811
|
this.info = makeNodeInfo();
|
|
3798
3812
|
this.root = root;
|
|
3799
3813
|
}
|
|
@@ -3963,12 +3977,12 @@ var Edge = class _Edge {
|
|
|
3963
3977
|
*/
|
|
3964
3978
|
info;
|
|
3965
3979
|
/** @see lib/cgraph/edge.c:agedge */
|
|
3966
|
-
constructor(tail, head, name) {
|
|
3980
|
+
constructor(tail, head, name, lazyAttrs = false) {
|
|
3967
3981
|
this.seq = _Edge._nextSeq++;
|
|
3968
3982
|
this.tail = tail;
|
|
3969
3983
|
this.head = head;
|
|
3970
3984
|
this.name = name;
|
|
3971
|
-
this.attrs = /* @__PURE__ */ new Map();
|
|
3985
|
+
this.attrs = lazyAttrs ? EMPTY_ATTRS : /* @__PURE__ */ new Map();
|
|
3972
3986
|
this.info = makeEdgeInfo(makePort(), makePort());
|
|
3973
3987
|
}
|
|
3974
3988
|
};
|
|
@@ -4854,7 +4868,7 @@ function isPeggyError(err) {
|
|
|
4854
4868
|
function warnNumberAmbiguities(src, upTo) {
|
|
4855
4869
|
for (const a of scanNumberAmbiguities(src, Stripper.strip(src))) {
|
|
4856
4870
|
if (a.offset > upTo) break;
|
|
4857
|
-
agerrFinished(numberAmbiguityMessage(a)
|
|
4871
|
+
agerrFinished(numberAmbiguityMessage(a));
|
|
4858
4872
|
}
|
|
4859
4873
|
}
|
|
4860
4874
|
function parse(src) {
|
|
@@ -5627,6 +5641,12 @@ var GvcContext = class {
|
|
|
5627
5641
|
* rendering happens in between and must see the layout state
|
|
5628
5642
|
* (e.g. cluster arrays).
|
|
5629
5643
|
*
|
|
5644
|
+
* Contract (AD-4/AD-8): first resets the C process state (RNG streams,
|
|
5645
|
+
* sequence counters, once-only warnings), so each `layout` call behaves
|
|
5646
|
+
* as one native run — drive one graph per `layout`. Caller-installed hooks
|
|
5647
|
+
* (setTextMeasurer, setImageSizer, setImageResolver, the per-context
|
|
5648
|
+
* measurer/sizer/resolver) are configuration and are not reset.
|
|
5649
|
+
*
|
|
5630
5650
|
* @throws TypeError (ERR_INVALID_ARG_TYPE / ERR_INVALID_ARG_VALUE) for a
|
|
5631
5651
|
* bad `g`, or an engine argument that is not registered
|
|
5632
5652
|
* @throws RenderError (UNKNOWN_LAYOUT) if the `layout` attribute names no
|
|
@@ -5637,6 +5657,7 @@ var GvcContext = class {
|
|
|
5637
5657
|
* @see lib/gvc/gvlayout.c:gvLayoutJobs
|
|
5638
5658
|
*/
|
|
5639
5659
|
layout(g, engineName) {
|
|
5660
|
+
resetRenderState();
|
|
5640
5661
|
const selected = this.checkLayoutArgs(g, engineName);
|
|
5641
5662
|
const attr2 = g.attrs?.get("layout");
|
|
5642
5663
|
let engine = selected;
|
|
@@ -8793,6 +8814,16 @@ function colorxlate(str, color, targetType) {
|
|
|
8793
8814
|
}
|
|
8794
8815
|
|
|
8795
8816
|
// src/common/multicolor.ts
|
|
8817
|
+
var parseSegsState = { warned: false };
|
|
8818
|
+
registerRenderState(() => {
|
|
8819
|
+
parseSegsState.warned = false;
|
|
8820
|
+
});
|
|
8821
|
+
function claimWarned() {
|
|
8822
|
+
if (parseSegsState.warned) return false;
|
|
8823
|
+
parseSegsState.warned = true;
|
|
8824
|
+
return true;
|
|
8825
|
+
}
|
|
8826
|
+
var claimNever = () => false;
|
|
8796
8827
|
var EPS = 1e-5;
|
|
8797
8828
|
function aeq0(x) {
|
|
8798
8829
|
return x < EPS && x > -EPS;
|
|
@@ -8806,17 +8837,14 @@ function getSegLen(token) {
|
|
|
8806
8837
|
const parsed = parseFloat(rest);
|
|
8807
8838
|
return !isNaN(parsed) && parsed >= 0 ? { color, v: parsed } : { color, v: -1 };
|
|
8808
8839
|
}
|
|
8809
|
-
function appendSeg(token, left2, segs,
|
|
8840
|
+
function appendSeg(token, left2, segs, claim) {
|
|
8810
8841
|
const { color, v } = getSegLen(token);
|
|
8811
8842
|
if (v < 0) return null;
|
|
8812
8843
|
let t = v;
|
|
8813
8844
|
let rval = 0;
|
|
8814
8845
|
const del = t - left2;
|
|
8815
8846
|
if (del > 0) {
|
|
8816
|
-
if (!aeq0(del) &&
|
|
8817
|
-
warnedExceeded.v = true;
|
|
8818
|
-
rval = 3;
|
|
8819
|
-
}
|
|
8847
|
+
if (!aeq0(del) && claim()) rval = 3;
|
|
8820
8848
|
t = left2;
|
|
8821
8849
|
}
|
|
8822
8850
|
left2 -= t;
|
|
@@ -8840,19 +8868,13 @@ function trimTrailing(segs) {
|
|
|
8840
8868
|
segs.pop();
|
|
8841
8869
|
}
|
|
8842
8870
|
}
|
|
8843
|
-
function
|
|
8871
|
+
function scanSegs(colorlist, claim) {
|
|
8844
8872
|
const segs = [];
|
|
8845
8873
|
let left2 = 1;
|
|
8846
8874
|
let rval = 0;
|
|
8847
|
-
let badFloatCount = 0;
|
|
8848
|
-
const warnedExceeded = { v: false };
|
|
8849
8875
|
for (const token of colorlist.split(":")) {
|
|
8850
|
-
const result = appendSeg(token, left2, segs,
|
|
8851
|
-
if (result === null) {
|
|
8852
|
-
const errCode = badFloatCount === 0 ? 2 : 1;
|
|
8853
|
-
badFloatCount++;
|
|
8854
|
-
return { segs: [], error: errCode };
|
|
8855
|
-
}
|
|
8876
|
+
const result = appendSeg(token, left2, segs, claim);
|
|
8877
|
+
if (result === null) return { segs: [], error: claim() ? 2 : 1 };
|
|
8856
8878
|
if (result.rval === 3) rval = 3;
|
|
8857
8879
|
left2 = result.left;
|
|
8858
8880
|
if (aeq0(left2)) {
|
|
@@ -8864,6 +8886,26 @@ function parseSegs(colorlist) {
|
|
|
8864
8886
|
trimTrailing(segs);
|
|
8865
8887
|
return { segs, error: rval };
|
|
8866
8888
|
}
|
|
8889
|
+
function parseSegs(colorlist, context) {
|
|
8890
|
+
const result = scanSegs(colorlist, claimWarned);
|
|
8891
|
+
if (result.error === 3) {
|
|
8892
|
+
const tail = context === void 0 ? "" : context();
|
|
8893
|
+
agwarningf(`Total size > 1 in "${colorlist}" color spec ${tail}`);
|
|
8894
|
+
} else if (result.error === 2) {
|
|
8895
|
+
agerrorf(`Illegal value in "${colorlist}" color attribute; float expected after ';'`);
|
|
8896
|
+
if (context !== void 0) agerr("prev", context());
|
|
8897
|
+
}
|
|
8898
|
+
return result;
|
|
8899
|
+
}
|
|
8900
|
+
function parseSegsSilent(colorlist) {
|
|
8901
|
+
return scanSegs(colorlist, claimNever);
|
|
8902
|
+
}
|
|
8903
|
+
function edgeSegsContext(e) {
|
|
8904
|
+
return () => {
|
|
8905
|
+
const directed = !e.tail.root.kind.endsWith("undirected");
|
|
8906
|
+
return `in edge ${e.tail.name}${directed ? " -> " : " -- "}${e.head.name}`;
|
|
8907
|
+
};
|
|
8908
|
+
}
|
|
8867
8909
|
|
|
8868
8910
|
// src/common/style-resolve.ts
|
|
8869
8911
|
var DEFAULT_COLOR = "black";
|
|
@@ -9283,7 +9325,7 @@ function countChar(s, ch) {
|
|
|
9283
9325
|
return s.split(ch).length - 1;
|
|
9284
9326
|
}
|
|
9285
9327
|
function multicolorNames(color, arrows) {
|
|
9286
|
-
const { segs, error } =
|
|
9328
|
+
const { segs, error } = parseSegsSilent(color);
|
|
9287
9329
|
if (error === 1 || error === 2) return null;
|
|
9288
9330
|
const out = [];
|
|
9289
9331
|
const front = segs[0]?.color ?? null;
|
|
@@ -9870,6 +9912,71 @@ function htmlStyle(style2) {
|
|
|
9870
9912
|
return s;
|
|
9871
9913
|
}
|
|
9872
9914
|
|
|
9915
|
+
// src/gvc/gvrender-set-style.ts
|
|
9916
|
+
var SUPPORTED_STYLES = /* @__PURE__ */ new Set([
|
|
9917
|
+
"solid",
|
|
9918
|
+
"dashed",
|
|
9919
|
+
"dotted",
|
|
9920
|
+
"invis",
|
|
9921
|
+
"invisible",
|
|
9922
|
+
"bold",
|
|
9923
|
+
"setlinewidth",
|
|
9924
|
+
"filled",
|
|
9925
|
+
"unfilled",
|
|
9926
|
+
"tapered"
|
|
9927
|
+
]);
|
|
9928
|
+
var BOX_ORIENTATION_TOLERANCE = 0.5;
|
|
9929
|
+
var BOX_ORIENTATION_STEP = 90;
|
|
9930
|
+
var BOX_SIDES = 4;
|
|
9931
|
+
var ELLIPSE_MAX_SIDES = 2;
|
|
9932
|
+
function styleName(token) {
|
|
9933
|
+
const paren = token.indexOf("(");
|
|
9934
|
+
return paren < 0 ? token : token.slice(0, paren);
|
|
9935
|
+
}
|
|
9936
|
+
function gvrenderSetStyle(styles) {
|
|
9937
|
+
if (styles === null) return;
|
|
9938
|
+
for (const token of styles) {
|
|
9939
|
+
const name = styleName(token);
|
|
9940
|
+
if (!SUPPORTED_STYLES.has(name)) {
|
|
9941
|
+
agwarningf(`gvrender_set_style: unsupported style ${name} - ignoring`);
|
|
9942
|
+
}
|
|
9943
|
+
}
|
|
9944
|
+
}
|
|
9945
|
+
function isBox(p) {
|
|
9946
|
+
if (p === null) return false;
|
|
9947
|
+
return p.sides === BOX_SIDES && Math.abs(p.orientation % BOX_ORIENTATION_STEP) < BOX_ORIENTATION_TOLERANCE && p.distortion === 0 && p.skew === 0;
|
|
9948
|
+
}
|
|
9949
|
+
function isEllipse(p) {
|
|
9950
|
+
return p !== null && p.sides <= ELLIPSE_MAX_SIDES;
|
|
9951
|
+
}
|
|
9952
|
+
function checkStyleTokens(styles, shape) {
|
|
9953
|
+
return styles.filter((p) => {
|
|
9954
|
+
if (p === "rounded" || p === "diagonals" || p === "radial") return false;
|
|
9955
|
+
if (p === "striped") return !isBox(shape);
|
|
9956
|
+
if (p === "wedged") return !isEllipse(shape);
|
|
9957
|
+
return true;
|
|
9958
|
+
});
|
|
9959
|
+
}
|
|
9960
|
+
function checkClusterStyleTokens(styles) {
|
|
9961
|
+
return styles.filter((p) => p !== "radial" && p !== "striped" && p !== "rounded");
|
|
9962
|
+
}
|
|
9963
|
+
function countChar2(s, ch) {
|
|
9964
|
+
return [...s].filter((c) => c === ch).length;
|
|
9965
|
+
}
|
|
9966
|
+
function multicolorTaken(color) {
|
|
9967
|
+
if (countChar2(color, ";") === 0 || countChar2(color, ":") === 0) return false;
|
|
9968
|
+
const { error } = parseSegsSilent(color);
|
|
9969
|
+
return error !== 1 && error !== 2;
|
|
9970
|
+
}
|
|
9971
|
+
function edgeStyleResets(e, styles) {
|
|
9972
|
+
const spl = e.info.spl;
|
|
9973
|
+
if (spl === void 0 || spl.size <= 1 || styles.length === 0) return 0;
|
|
9974
|
+
const color = e.attrs.get("color") ?? "";
|
|
9975
|
+
const otherBranch = styles.includes("tapered") || countChar2(color, ":") > 0;
|
|
9976
|
+
if (otherBranch && !multicolorTaken(color)) return 0;
|
|
9977
|
+
return spl.list.filter((bz) => bz.sflag !== 0 || bz.eflag !== 0).length;
|
|
9978
|
+
}
|
|
9979
|
+
|
|
9873
9980
|
// src/common/htmltable-types.ts
|
|
9874
9981
|
var HtmlParseError = class extends DotEngineError {
|
|
9875
9982
|
type = "semantic";
|
|
@@ -9889,13 +9996,21 @@ var BORDER_BOTTOM = 1 << 13;
|
|
|
9889
9996
|
var BORDER_MASK = BORDER_LEFT | BORDER_TOP | BORDER_RIGHT | BORDER_BOTTOM;
|
|
9890
9997
|
|
|
9891
9998
|
// src/common/htmltable-emit-fill.ts
|
|
9999
|
+
var MSG_MANY_COLORS = "More than 2 colors specified for a gradient - ignoring remaining";
|
|
10000
|
+
function findHtmlStopColor(color, silent = false) {
|
|
10001
|
+
const { segs, error } = silent ? parseSegsSilent(color) : parseSegs(color);
|
|
10002
|
+
const first = segs[0];
|
|
10003
|
+
const second = segs[1];
|
|
10004
|
+
if (error !== 0 || first === void 0 || second === void 0 || first.color === null) {
|
|
10005
|
+
return null;
|
|
10006
|
+
}
|
|
10007
|
+
if (segs.length > 2 && !silent) agwarningf(MSG_MANY_COLORS);
|
|
10008
|
+
const frac = first.hasFraction ? first.t : second.hasFraction ? 1 - second.t : 0;
|
|
10009
|
+
return { fill: first.color, stop: second.color, frac };
|
|
10010
|
+
}
|
|
9892
10011
|
function parseGradientSpec(color) {
|
|
9893
|
-
const
|
|
9894
|
-
|
|
9895
|
-
const c0 = color.slice(0, idx).trim();
|
|
9896
|
-
const c1 = color.slice(idx + 1).trim();
|
|
9897
|
-
if (c0.length === 0) return null;
|
|
9898
|
-
return [c0, c1.length > 0 ? c1 : "black"];
|
|
10012
|
+
const spec = findHtmlStopColor(color, true);
|
|
10013
|
+
return spec === null ? null : [spec.fill, spec.stop ?? "black"];
|
|
9899
10014
|
}
|
|
9900
10015
|
var paintObj = {
|
|
9901
10016
|
parent: null,
|
|
@@ -9952,6 +10067,12 @@ function resetHtmlFillPenWidth() {
|
|
|
9952
10067
|
htmlFillPen = 1;
|
|
9953
10068
|
}
|
|
9954
10069
|
registerRenderState(resetHtmlFillPenWidth);
|
|
10070
|
+
var DEFAULT_LINE_STYLE = ["solid", "setlinewidth(1)"];
|
|
10071
|
+
function htmlBorderStyle(pen) {
|
|
10072
|
+
if (pen === 1 /* Dashed */) return ["dashed"];
|
|
10073
|
+
if (pen === 2 /* Dotted */) return ["dotted"];
|
|
10074
|
+
return DEFAULT_LINE_STYLE;
|
|
10075
|
+
}
|
|
9955
10076
|
function penTypeOf(style2) {
|
|
9956
10077
|
const st = htmlStyle(style2);
|
|
9957
10078
|
if (st.dashed) return 1 /* Dashed */;
|
|
@@ -9959,12 +10080,13 @@ function penTypeOf(style2) {
|
|
|
9959
10080
|
return 3 /* Solid */;
|
|
9960
10081
|
}
|
|
9961
10082
|
function withHtmlPaint(paint, job, drawFn) {
|
|
9962
|
-
paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(paint.fill) : { type: "none" };
|
|
10083
|
+
paintObj.fillColor = paint.fill !== void 0 ? resolveRenderColor(firstColor(paint.fill)) : { type: "none" };
|
|
9963
10084
|
paintObj.penColor = paint.pen !== void 0 ? resolveRenderColor(paint.pen) : { type: "string", s: "transparent" };
|
|
9964
10085
|
applyHtmlFill(paint);
|
|
9965
10086
|
paintObj.pen = penTypeOf(paint.penStyle);
|
|
9966
10087
|
paintObj.penWidth = paint.penWidth !== void 0 ? paint.penWidth : 1;
|
|
9967
10088
|
paintObj.rawStyle = paintObj.pen === 3 /* Solid */ ? ["solid"] : [];
|
|
10089
|
+
gvrenderSetStyle(htmlBorderStyle(paintObj.pen));
|
|
9968
10090
|
paintObj.emitState = job.obj?.emitState ?? 8 /* NDraw */;
|
|
9969
10091
|
job.pushObj(paintObj);
|
|
9970
10092
|
try {
|
|
@@ -9978,7 +10100,7 @@ function applyHtmlFill(paint) {
|
|
|
9978
10100
|
paintObj.fill = paint.radial === true ? 3 /* Radial */ : 2 /* Linear */;
|
|
9979
10101
|
paintObj.stopColor = resolveRenderColor(paint.stop);
|
|
9980
10102
|
paintObj.gradientAngle = paint.gradientAngle ?? 0;
|
|
9981
|
-
paintObj.gradientFrac = 0;
|
|
10103
|
+
paintObj.gradientFrac = paint.gradientFrac ?? 0;
|
|
9982
10104
|
return;
|
|
9983
10105
|
}
|
|
9984
10106
|
paintObj.fill = paint.fill !== void 0 ? 1 /* Solid */ : 0 /* None */;
|
|
@@ -10247,11 +10369,12 @@ function emitHtmlLine(line, pos, renderer, job) {
|
|
|
10247
10369
|
}
|
|
10248
10370
|
function bgFillPaint(ctx) {
|
|
10249
10371
|
const penWidth = htmlFillPenWidth();
|
|
10250
|
-
const spec =
|
|
10372
|
+
const spec = findHtmlStopColor(ctx.bgcolor);
|
|
10251
10373
|
if (spec === null) return { fill: ctx.bgcolor, penWidth };
|
|
10252
10374
|
return {
|
|
10253
|
-
fill: spec
|
|
10254
|
-
stop: spec
|
|
10375
|
+
fill: spec.fill,
|
|
10376
|
+
stop: spec.stop ?? "black",
|
|
10377
|
+
gradientFrac: spec.frac,
|
|
10255
10378
|
gradientAngle: ctx.gradientangle ?? 0,
|
|
10256
10379
|
radial: htmlStyle(ctx.style).radial,
|
|
10257
10380
|
penWidth
|
|
@@ -10395,6 +10518,17 @@ function emitHtmlLabel(placed, pos, renderer, job) {
|
|
|
10395
10518
|
}
|
|
10396
10519
|
}
|
|
10397
10520
|
|
|
10521
|
+
// src/common/attr-get.ts
|
|
10522
|
+
function nodeAttr(n, g, key) {
|
|
10523
|
+
const own = n.attrs.get(key);
|
|
10524
|
+
if (own !== void 0) return own;
|
|
10525
|
+
if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
|
|
10526
|
+
return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
|
|
10527
|
+
}
|
|
10528
|
+
function graphAttrInherited(sg, key) {
|
|
10529
|
+
return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
|
|
10530
|
+
}
|
|
10531
|
+
|
|
10398
10532
|
// src/common/htmltable-attr-warn.ts
|
|
10399
10533
|
var accepted = (v) => ({ keep: v, text: [], warn: false });
|
|
10400
10534
|
var ignored = (text) => ({ keep: void 0, text: [text], warn: true });
|
|
@@ -11126,9 +11260,15 @@ function scanCdata(text, p, base, dataOf, tokens) {
|
|
|
11126
11260
|
if (end > p) tokens.push({ kind: "cdata", start: base + p, end: base + end, data: dataOf(base + p, base + end) });
|
|
11127
11261
|
return close < 0 ? -1 : close + CDATA_CLOSE.length;
|
|
11128
11262
|
}
|
|
11263
|
+
var CONTENT_NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
|
|
11129
11264
|
function scanText(text, p, base, tokens) {
|
|
11130
11265
|
const e = text.indexOf("<", p);
|
|
11131
11266
|
const slice = text.slice(p, e < 0 ? text.length : e);
|
|
11267
|
+
const bad = CONTENT_NON_XML.exec(slice)?.index;
|
|
11268
|
+
if (bad !== void 0) {
|
|
11269
|
+
if (bad > 0) tokens.push({ kind: "text", start: base + p, end: base + p + bad });
|
|
11270
|
+
return { at: p + bad, held: false, invalid: p + bad };
|
|
11271
|
+
}
|
|
11132
11272
|
const from = e < 0 ? heldRefStart(slice) : void 0;
|
|
11133
11273
|
const end = from === void 0 ? p + slice.length : p + from;
|
|
11134
11274
|
if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
@@ -11148,6 +11288,7 @@ function scanContent(text, base, inCdata, dataOf) {
|
|
|
11148
11288
|
}
|
|
11149
11289
|
if (text[p] !== "<") {
|
|
11150
11290
|
const scanned = scanText(text, p, base, tokens);
|
|
11291
|
+
if (scanned.invalid !== void 0) return { tokens, consumed: scanned.at, invalid: base + scanned.invalid, inCdata: false };
|
|
11151
11292
|
if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
|
|
11152
11293
|
p = scanned.at;
|
|
11153
11294
|
continue;
|
|
@@ -12154,6 +12295,72 @@ var parseHtmlLabelRv = (src, stderr) => {
|
|
|
12154
12295
|
};
|
|
12155
12296
|
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
|
|
12156
12297
|
|
|
12298
|
+
// src/gvc/image-resolver.ts
|
|
12299
|
+
var activeResolver = null;
|
|
12300
|
+
function setImageResolver(fn) {
|
|
12301
|
+
if (fn !== null && typeof fn !== "function") {
|
|
12302
|
+
throw invalidArgType("resolver", "function or null", fn);
|
|
12303
|
+
}
|
|
12304
|
+
activeResolver = fn;
|
|
12305
|
+
}
|
|
12306
|
+
var EXT_MIME = {
|
|
12307
|
+
png: "image/png",
|
|
12308
|
+
jpg: "image/jpeg",
|
|
12309
|
+
jpeg: "image/jpeg",
|
|
12310
|
+
gif: "image/gif",
|
|
12311
|
+
svg: "image/svg+xml",
|
|
12312
|
+
webp: "image/webp"
|
|
12313
|
+
};
|
|
12314
|
+
var FALLBACK_MIME = "application/octet-stream";
|
|
12315
|
+
function inferMimeFromSrc(src) {
|
|
12316
|
+
const dot = src.lastIndexOf(".");
|
|
12317
|
+
if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
|
|
12318
|
+
const ext = src.slice(dot + 1).toLowerCase();
|
|
12319
|
+
return EXT_MIME[ext] ?? FALLBACK_MIME;
|
|
12320
|
+
}
|
|
12321
|
+
function findImageBytes(src, resolver) {
|
|
12322
|
+
const active = resolver ?? activeResolver;
|
|
12323
|
+
if (active === null) return null;
|
|
12324
|
+
const result = active(src);
|
|
12325
|
+
if (result === null) return null;
|
|
12326
|
+
if (result instanceof Uint8Array) {
|
|
12327
|
+
return { bytes: result, mime: inferMimeFromSrc(src) };
|
|
12328
|
+
}
|
|
12329
|
+
return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
|
|
12330
|
+
}
|
|
12331
|
+
var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
12332
|
+
function base64Encode(bytes) {
|
|
12333
|
+
const len = bytes.length;
|
|
12334
|
+
const out = [];
|
|
12335
|
+
let i = 0;
|
|
12336
|
+
for (; i + 2 < len; i += 3) {
|
|
12337
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
12338
|
+
out.push(
|
|
12339
|
+
B64_CHARS[n >> 18 & 63],
|
|
12340
|
+
B64_CHARS[n >> 12 & 63],
|
|
12341
|
+
B64_CHARS[n >> 6 & 63],
|
|
12342
|
+
B64_CHARS[n & 63]
|
|
12343
|
+
);
|
|
12344
|
+
}
|
|
12345
|
+
const remaining = len - i;
|
|
12346
|
+
if (remaining === 1) {
|
|
12347
|
+
const n = bytes[i] << 16;
|
|
12348
|
+
out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
|
|
12349
|
+
} else if (remaining === 2) {
|
|
12350
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8;
|
|
12351
|
+
out.push(
|
|
12352
|
+
B64_CHARS[n >> 18 & 63],
|
|
12353
|
+
B64_CHARS[n >> 12 & 63],
|
|
12354
|
+
B64_CHARS[n >> 6 & 63],
|
|
12355
|
+
"="
|
|
12356
|
+
);
|
|
12357
|
+
}
|
|
12358
|
+
return out.join("");
|
|
12359
|
+
}
|
|
12360
|
+
function toDataUri(bytes, mime) {
|
|
12361
|
+
return "data:" + mime + ";base64," + base64Encode(bytes);
|
|
12362
|
+
}
|
|
12363
|
+
|
|
12157
12364
|
// src/gvc/usershape.ts
|
|
12158
12365
|
var activeSizer = null;
|
|
12159
12366
|
function setImageSizer(sizer) {
|
|
@@ -12165,6 +12372,14 @@ function setImageSizer(sizer) {
|
|
|
12165
12372
|
function findImageSize(src) {
|
|
12166
12373
|
return activeSizer !== null ? activeSizer(src) : null;
|
|
12167
12374
|
}
|
|
12375
|
+
var STRERROR_ENOENT = "No such file or directory";
|
|
12376
|
+
function imageIsSupplied(name, sizer, resolver) {
|
|
12377
|
+
const size = sizer !== void 0 ? sizer(name) : findImageSize(name);
|
|
12378
|
+
return size !== null || findImageBytes(name, resolver) !== null;
|
|
12379
|
+
}
|
|
12380
|
+
function imageOpenWarning(name) {
|
|
12381
|
+
return `${STRERROR_ENOENT} while opening ${name}`;
|
|
12382
|
+
}
|
|
12168
12383
|
|
|
12169
12384
|
// src/common/pointset.ts
|
|
12170
12385
|
function cmpPair(a, b) {
|
|
@@ -12217,363 +12432,6 @@ var PointSet = class {
|
|
|
12217
12432
|
}
|
|
12218
12433
|
};
|
|
12219
12434
|
|
|
12220
|
-
// src/common/htmltable-fontinfo.ts
|
|
12221
|
-
var SIZE_SAVEF = { fontsize: 0 };
|
|
12222
|
-
var EMIT_SAVEF = { fontsize: 0 };
|
|
12223
|
-
var pushFontInfo = (env, fp, savp) => {
|
|
12224
|
-
if (fp.fontFace !== void 0) {
|
|
12225
|
-
savp.fontname = env.fontname;
|
|
12226
|
-
env.fontname = fp.fontFace;
|
|
12227
|
-
} else savp.fontname = void 0;
|
|
12228
|
-
if (env.fontcolor !== void 0) {
|
|
12229
|
-
if (fp.fontColor !== void 0) {
|
|
12230
|
-
savp.fontcolor = env.fontcolor;
|
|
12231
|
-
env.fontcolor = fp.fontColor;
|
|
12232
|
-
} else savp.fontcolor = void 0;
|
|
12233
|
-
}
|
|
12234
|
-
if (env.fontsize >= 0) {
|
|
12235
|
-
if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
|
|
12236
|
-
savp.fontsize = env.fontsize;
|
|
12237
|
-
env.fontsize = fp.fontSize;
|
|
12238
|
-
} else savp.fontsize = -1;
|
|
12239
|
-
}
|
|
12240
|
-
};
|
|
12241
|
-
var popFontInfo = (env, savp) => {
|
|
12242
|
-
if (savp.fontname !== void 0) env.fontname = savp.fontname;
|
|
12243
|
-
if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
|
|
12244
|
-
if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
|
|
12245
|
-
};
|
|
12246
|
-
var withTableFont = (env, font, slot, fn) => {
|
|
12247
|
-
if (font === void 0) return fn();
|
|
12248
|
-
const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
|
|
12249
|
-
pushFontInfo(env, font, savp);
|
|
12250
|
-
const r = fn();
|
|
12251
|
-
popFontInfo(env, savp);
|
|
12252
|
-
return r;
|
|
12253
|
-
};
|
|
12254
|
-
|
|
12255
|
-
// src/common/htmltable.ts
|
|
12256
|
-
var DEFAULT_BORDER = 1;
|
|
12257
|
-
var DEFAULT_CELLPADDING = 2;
|
|
12258
|
-
var DEFAULT_CELLSPACING = 2;
|
|
12259
|
-
var DEFAULT_FONTSIZE = 14;
|
|
12260
|
-
var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
12261
|
-
let col = startCol;
|
|
12262
|
-
let notFound = true;
|
|
12263
|
-
const end = colspan - 1;
|
|
12264
|
-
while (notFound) {
|
|
12265
|
-
const lastc = col + end;
|
|
12266
|
-
let c;
|
|
12267
|
-
for (c = lastc; c >= col; c--) {
|
|
12268
|
-
if (ps.isInPS(c, row)) break;
|
|
12269
|
-
}
|
|
12270
|
-
if (c >= col) col = c + 1;
|
|
12271
|
-
else notFound = false;
|
|
12272
|
-
}
|
|
12273
|
-
for (let j = col; j < col + colspan; j++) {
|
|
12274
|
-
for (let i = row; i < row + rowspan; i++) {
|
|
12275
|
-
ps.addPS(j, i);
|
|
12276
|
-
}
|
|
12277
|
-
}
|
|
12278
|
-
return col;
|
|
12279
|
-
};
|
|
12280
|
-
var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
|
|
12281
|
-
var itemFont = (item, env) => ({
|
|
12282
|
-
fs: item.fontSize !== void 0 ? item.fontSize : env.fontsize,
|
|
12283
|
-
face: item.fontFace !== void 0 ? item.fontFace : env.fontname
|
|
12284
|
-
});
|
|
12285
|
-
var measureItem = (item, measurer, env) => {
|
|
12286
|
-
const { fs, face } = itemFont(item, env);
|
|
12287
|
-
const flags = item.bold === true || item.italic === true ? { bold: item.bold === true, italic: item.italic === true } : void 0;
|
|
12288
|
-
return measurer.measure(item.text ?? "", face, fs, flags);
|
|
12289
|
-
};
|
|
12290
|
-
var splitSizedLines = (texts, measurer, env) => {
|
|
12291
|
-
const lines = [];
|
|
12292
|
-
let cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
|
|
12293
|
-
const accumulate = (item) => {
|
|
12294
|
-
const sz = measureItem(item, measurer, env);
|
|
12295
|
-
cur.items.push(item);
|
|
12296
|
-
cur.width += sz.w;
|
|
12297
|
-
cur.mxysize = Math.max(cur.mxysize, sz.h);
|
|
12298
|
-
cur.mxfsize = Math.max(cur.mxfsize, itemFont(item, env).fs);
|
|
12299
|
-
};
|
|
12300
|
-
const flush = (br) => {
|
|
12301
|
-
if (cur.items.length === 0 && br !== void 0) {
|
|
12302
|
-
const { br: _b, brAlign: _a, ...fontProps } = br;
|
|
12303
|
-
accumulate({ text: "", ...fontProps });
|
|
12304
|
-
}
|
|
12305
|
-
lines.push(cur);
|
|
12306
|
-
cur = { items: [], width: 0, mxysize: 0, mxfsize: 0 };
|
|
12307
|
-
};
|
|
12308
|
-
for (const txt of texts) {
|
|
12309
|
-
for (const item of txt.items) {
|
|
12310
|
-
if (item.br) {
|
|
12311
|
-
flush(item);
|
|
12312
|
-
continue;
|
|
12313
|
-
}
|
|
12314
|
-
if (item.text === void 0) continue;
|
|
12315
|
-
accumulate(item);
|
|
12316
|
-
}
|
|
12317
|
-
if (cur.items.length > 0) flush();
|
|
12318
|
-
}
|
|
12319
|
-
return lines;
|
|
12320
|
-
};
|
|
12321
|
-
var itemHasFlags = (i) => i.bold === true || i.italic === true || i.underline === true || i.strikethrough === true || i.overline === true || i.subscript === true || i.superscript === true;
|
|
12322
|
-
var htmlTextIsSimple = (lines, env) => {
|
|
12323
|
-
let prevFs = -1;
|
|
12324
|
-
let prevFace = null;
|
|
12325
|
-
for (const ln of lines) {
|
|
12326
|
-
const item = ln.items[0];
|
|
12327
|
-
if (ln.items.length > 1 || itemHasFlags(item)) return false;
|
|
12328
|
-
const { fs, face } = itemFont(item, env);
|
|
12329
|
-
if (prevFs < 0) prevFs = fs;
|
|
12330
|
-
else if (fs !== prevFs) return false;
|
|
12331
|
-
if (prevFace === null) prevFace = face;
|
|
12332
|
-
else if (face !== prevFace) return false;
|
|
12333
|
-
}
|
|
12334
|
-
return true;
|
|
12335
|
-
};
|
|
12336
|
-
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
12337
|
-
const lines = splitSizedLines(texts, measurer, env);
|
|
12338
|
-
const simple = htmlTextIsSimple(lines, env);
|
|
12339
|
-
let w = 0;
|
|
12340
|
-
let h = 0;
|
|
12341
|
-
for (const ln of lines) {
|
|
12342
|
-
w = Math.max(w, ln.width);
|
|
12343
|
-
const lsize = simple ? ln.mxysize : ln.mxfsize;
|
|
12344
|
-
h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
|
|
12345
|
-
}
|
|
12346
|
-
if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].mxysize : DEFAULT_FONTSIZE;
|
|
12347
|
-
return { w, h };
|
|
12348
|
-
};
|
|
12349
|
-
var missingImages = /* @__PURE__ */ new WeakSet();
|
|
12350
|
-
var sizeHtmlImg = (img, { imageSizer, stderr }) => {
|
|
12351
|
-
if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
|
|
12352
|
-
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
12353
|
-
if (sz !== null) {
|
|
12354
|
-
img.width = sz.w;
|
|
12355
|
-
img.height = sz.h;
|
|
12356
|
-
return 0;
|
|
12357
|
-
}
|
|
12358
|
-
agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
|
|
12359
|
-
img.width = 0;
|
|
12360
|
-
img.height = 0;
|
|
12361
|
-
missingImages.add(img);
|
|
12362
|
-
return 1;
|
|
12363
|
-
};
|
|
12364
|
-
var sizeContentItem = (item, measurer, env) => {
|
|
12365
|
-
if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
|
|
12366
|
-
if (item.kind === "table") {
|
|
12367
|
-
const rv = sizeTableInner(item, measurer, env);
|
|
12368
|
-
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
12369
|
-
}
|
|
12370
|
-
if (item.kind === "image") {
|
|
12371
|
-
const rv = sizeHtmlImg(item, env);
|
|
12372
|
-
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
12373
|
-
}
|
|
12374
|
-
return { w: 0, h: 0, rv: 0 };
|
|
12375
|
-
};
|
|
12376
|
-
var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
|
|
12377
|
-
var cellBorder = (cell2, tbl) => {
|
|
12378
|
-
if (cell2.border !== void 0) return cell2.border;
|
|
12379
|
-
const cb = tbl.cellborder;
|
|
12380
|
-
if (cb !== void 0 && cb >= 0) return cb;
|
|
12381
|
-
if (tbl.border !== void 0) return tbl.border;
|
|
12382
|
-
return DEFAULT_BORDER;
|
|
12383
|
-
};
|
|
12384
|
-
function inheritTablePenColor(tbl, parentColor) {
|
|
12385
|
-
if (tbl.color === void 0) tbl.color = parentColor;
|
|
12386
|
-
const tblColor = tbl.color;
|
|
12387
|
-
for (const row of tbl.rows) {
|
|
12388
|
-
for (const cell2 of row.cells) {
|
|
12389
|
-
if (cell2.color === void 0) cell2.color = tblColor;
|
|
12390
|
-
for (const item of cell2.content) {
|
|
12391
|
-
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
12392
|
-
}
|
|
12393
|
-
}
|
|
12394
|
-
}
|
|
12395
|
-
}
|
|
12396
|
-
var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
|
|
12397
|
-
var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
|
|
12398
|
-
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
12399
|
-
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
12400
|
-
var sizeWarned = /* @__PURE__ */ new WeakSet();
|
|
12401
|
-
var fixedCellCheck = (cell2, sz, warn, out) => {
|
|
12402
|
-
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
12403
|
-
if (cell2.width && cell2.height) {
|
|
12404
|
-
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
12405
|
-
if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
|
|
12406
|
-
return { rv: small ? 1 : 0, zero: true };
|
|
12407
|
-
}
|
|
12408
|
-
if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
|
|
12409
|
-
return { rv: 1, zero: false };
|
|
12410
|
-
};
|
|
12411
|
-
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
12412
|
-
const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
|
|
12413
|
-
let cw = 0, ch = 0, rv = 0;
|
|
12414
|
-
for (const item of cell2.content) {
|
|
12415
|
-
const s = sizeContentItem(item, measurer, env);
|
|
12416
|
-
cw = Math.max(cw, s.w);
|
|
12417
|
-
ch += s.h;
|
|
12418
|
-
rv |= s.rv;
|
|
12419
|
-
}
|
|
12420
|
-
let szx = cw + margin;
|
|
12421
|
-
let szy = ch + margin;
|
|
12422
|
-
const warn = !sizeWarned.has(cell2);
|
|
12423
|
-
sizeWarned.add(cell2);
|
|
12424
|
-
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
|
|
12425
|
-
rv |= fixed.rv;
|
|
12426
|
-
if (fixed.zero) {
|
|
12427
|
-
szx = 0;
|
|
12428
|
-
szy = 0;
|
|
12429
|
-
}
|
|
12430
|
-
const bw = cell2.width !== void 0 ? cell2.width : 0;
|
|
12431
|
-
const bh = cell2.height !== void 0 ? cell2.height : 0;
|
|
12432
|
-
return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
|
|
12433
|
-
};
|
|
12434
|
-
var buildLayouts = (tbl, measurer, env) => {
|
|
12435
|
-
const entries = [];
|
|
12436
|
-
let rv = 0;
|
|
12437
|
-
const ps = new PointSet();
|
|
12438
|
-
let rowIdx = 0;
|
|
12439
|
-
for (const row of tbl.rows) {
|
|
12440
|
-
let col = 0;
|
|
12441
|
-
for (const c of row.cells) {
|
|
12442
|
-
if (c.kind !== "cell") {
|
|
12443
|
-
continue;
|
|
12444
|
-
}
|
|
12445
|
-
const colspan = c.colspan !== void 0 ? c.colspan : 1;
|
|
12446
|
-
const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
|
|
12447
|
-
const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
|
|
12448
|
-
rv |= cellRv;
|
|
12449
|
-
col = findCol(ps, rowIdx, col, colspan, rowspan);
|
|
12450
|
-
entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
|
|
12451
|
-
col += colspan;
|
|
12452
|
-
}
|
|
12453
|
-
rowIdx++;
|
|
12454
|
-
}
|
|
12455
|
-
return { entries, rv };
|
|
12456
|
-
};
|
|
12457
|
-
var setColWidths = (entries, ncols, spacing) => {
|
|
12458
|
-
const widths = new Array(ncols + 1).fill(0);
|
|
12459
|
-
for (const e of entries)
|
|
12460
|
-
if (e.colspan === 1) widths[e.col] = Math.max(widths[e.col], e.w);
|
|
12461
|
-
for (const e of entries) {
|
|
12462
|
-
if (e.colspan === 1) continue;
|
|
12463
|
-
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
12464
|
-
const need = e.w - spanW - (e.colspan - 1) * spacing;
|
|
12465
|
-
if (need > 0) {
|
|
12466
|
-
const add2 = need / e.colspan;
|
|
12467
|
-
for (let j = 0; j < e.colspan; j++) widths[e.col + j] += add2;
|
|
12468
|
-
}
|
|
12469
|
-
}
|
|
12470
|
-
for (const e of entries) {
|
|
12471
|
-
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
12472
|
-
e.w = Math.max(e.w, spanW + (e.colspan - 1) * spacing);
|
|
12473
|
-
}
|
|
12474
|
-
return widths;
|
|
12475
|
-
};
|
|
12476
|
-
var setRowHeights = (entries, nrows, spacing) => {
|
|
12477
|
-
const heights = new Array(nrows + 1).fill(0);
|
|
12478
|
-
for (const e of entries)
|
|
12479
|
-
if (e.rowspan === 1) heights[e.row] = Math.max(heights[e.row], e.h);
|
|
12480
|
-
for (const e of entries) {
|
|
12481
|
-
if (e.rowspan === 1) continue;
|
|
12482
|
-
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
12483
|
-
const need = e.h - spanH - (e.rowspan - 1) * spacing;
|
|
12484
|
-
if (need > 0) {
|
|
12485
|
-
const add2 = need / e.rowspan;
|
|
12486
|
-
for (let j = 0; j < e.rowspan; j++) heights[e.row + j] += add2;
|
|
12487
|
-
}
|
|
12488
|
-
}
|
|
12489
|
-
for (const e of entries) {
|
|
12490
|
-
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
12491
|
-
e.h = Math.max(e.h, spanH + (e.rowspan - 1) * spacing);
|
|
12492
|
-
}
|
|
12493
|
-
return heights;
|
|
12494
|
-
};
|
|
12495
|
-
var getSpacing = (tbl) => tbl.cellspacing !== void 0 ? tbl.cellspacing : DEFAULT_CELLSPACING;
|
|
12496
|
-
var getBorder = (tbl) => tbl.border !== void 0 ? tbl.border : DEFAULT_BORDER;
|
|
12497
|
-
var isTblFixed = (tbl) => tbl.fixedsize === true && tbl.width !== void 0 && tbl.height !== void 0;
|
|
12498
|
-
var sumTableDims = (a) => {
|
|
12499
|
-
let wd = (a.ncols + 1) * a.spacing + 2 * a.border;
|
|
12500
|
-
let ht = (a.nrows + 1) * a.spacing + 2 * a.border;
|
|
12501
|
-
for (let i = 0; i < a.ncols; i++) wd += a.widths[i];
|
|
12502
|
-
for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
|
|
12503
|
-
return { wd, ht };
|
|
12504
|
-
};
|
|
12505
|
-
var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
12506
|
-
const spacing = getSpacing(tbl);
|
|
12507
|
-
const border2 = getBorder(tbl);
|
|
12508
|
-
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
12509
|
-
if (entries.length === 0) {
|
|
12510
|
-
return { entries, widths: [], heights: [], spacing, border: border2, rv };
|
|
12511
|
-
}
|
|
12512
|
-
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
12513
|
-
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
12514
|
-
const widths = setColWidths(entries, ncols, spacing);
|
|
12515
|
-
const heights = setRowHeights(entries, nrows, spacing);
|
|
12516
|
-
return { entries, widths, heights, spacing, border: border2, rv };
|
|
12517
|
-
};
|
|
12518
|
-
var warnFixedTable = (tbl, dims, out) => {
|
|
12519
|
-
const warn = !sizeWarned.has(tbl);
|
|
12520
|
-
sizeWarned.add(tbl);
|
|
12521
|
-
if (tbl.fixedsize !== true) return 0;
|
|
12522
|
-
if (tbl.width && tbl.height) {
|
|
12523
|
-
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
12524
|
-
if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
|
|
12525
|
-
return 1;
|
|
12526
|
-
}
|
|
12527
|
-
if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
|
|
12528
|
-
return 1;
|
|
12529
|
-
};
|
|
12530
|
-
var sizeTableBody = (tbl, measurer, env) => {
|
|
12531
|
-
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
12532
|
-
if (entries.length === 0) {
|
|
12533
|
-
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
|
|
12534
|
-
tbl.dimen = { w: 0, h: 0 };
|
|
12535
|
-
return rv | fixed2;
|
|
12536
|
-
}
|
|
12537
|
-
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
12538
|
-
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
12539
|
-
for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
|
|
12540
|
-
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
12541
|
-
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
12542
|
-
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
12543
|
-
const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
|
|
12544
|
-
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
12545
|
-
tbl.dimen = {
|
|
12546
|
-
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
12547
|
-
h: Math.max(zeroContent ? 0 : ht, baseHt)
|
|
12548
|
-
};
|
|
12549
|
-
return rv | fixed;
|
|
12550
|
-
};
|
|
12551
|
-
var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
|
|
12552
|
-
var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
|
|
12553
|
-
if (label.kind === "table") {
|
|
12554
|
-
const rv = sizeTableInner(label.table, measurer, env);
|
|
12555
|
-
label.dimen = label.table.dimen;
|
|
12556
|
-
return rv;
|
|
12557
|
-
}
|
|
12558
|
-
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
12559
|
-
return 0;
|
|
12560
|
-
};
|
|
12561
|
-
|
|
12562
|
-
// src/common/splines-constants.ts
|
|
12563
|
-
var REGULAREDGE = 1;
|
|
12564
|
-
var FLATEDGE = 2;
|
|
12565
|
-
var ARR_NONE = 0;
|
|
12566
|
-
var BOTTOM = 1 << 0;
|
|
12567
|
-
var RIGHT = 1 << 1;
|
|
12568
|
-
var TOP = 1 << 2;
|
|
12569
|
-
var LEFT = 1 << 3;
|
|
12570
|
-
var SELF_EDGE_SIZE = 18;
|
|
12571
|
-
var MILLIPOINT = 1e-3;
|
|
12572
|
-
var FUDGE = 2;
|
|
12573
|
-
var INIT_DELTA = 10;
|
|
12574
|
-
var LOOP_TRIES = 15;
|
|
12575
|
-
var ROUTESPL_FUDGE = 1e-4;
|
|
12576
|
-
|
|
12577
12435
|
// src/common/textmeasure-lut-data-a.ts
|
|
12578
12436
|
var TR = [
|
|
12579
12437
|
-1,
|
|
@@ -17416,7 +17274,7 @@ function getFamilyMetrics(fontName) {
|
|
|
17416
17274
|
if (!warnedFontNames.has(fontName)) {
|
|
17417
17275
|
warnedFontNames.add(fontName);
|
|
17418
17276
|
agwarningf(
|
|
17419
|
-
`no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
17277
|
+
`Warning: no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
17420
17278
|
);
|
|
17421
17279
|
}
|
|
17422
17280
|
return TIMES_FALLBACK;
|
|
@@ -17757,7 +17615,7 @@ function itemFace(item, finfo) {
|
|
|
17757
17615
|
face: item.fontFace !== void 0 ? item.fontFace : finfo.fontname
|
|
17758
17616
|
};
|
|
17759
17617
|
}
|
|
17760
|
-
function
|
|
17618
|
+
function measureItem(item, finfo, measurer) {
|
|
17761
17619
|
if (item.text === void 0) return null;
|
|
17762
17620
|
const { fs, face } = itemFace(item, finfo);
|
|
17763
17621
|
const flags = itemFontFlags(item);
|
|
@@ -17792,7 +17650,7 @@ function buildLineRuns(texts, finfo, measurer) {
|
|
|
17792
17650
|
if (cur.items.length === 0 && br !== void 0) {
|
|
17793
17651
|
const { br: _b, brAlign: _a, ...fontProps } = br;
|
|
17794
17652
|
const empty = { text: "", ...fontProps };
|
|
17795
|
-
const m =
|
|
17653
|
+
const m = measureItem(empty, finfo, measurer);
|
|
17796
17654
|
if (m !== null) accumulateItem(cur, empty, m);
|
|
17797
17655
|
}
|
|
17798
17656
|
cur.just = br?.brAlign;
|
|
@@ -17805,7 +17663,7 @@ function buildLineRuns(texts, finfo, measurer) {
|
|
|
17805
17663
|
flush(item);
|
|
17806
17664
|
continue;
|
|
17807
17665
|
}
|
|
17808
|
-
const m =
|
|
17666
|
+
const m = measureItem(item, finfo, measurer);
|
|
17809
17667
|
if (m !== null) accumulateItem(cur, item, m);
|
|
17810
17668
|
}
|
|
17811
17669
|
if (cur.items.length > 0) flush();
|
|
@@ -17896,6 +17754,313 @@ function placeComplexRuns(runs, box, finfo, measurer) {
|
|
|
17896
17754
|
return lines;
|
|
17897
17755
|
}
|
|
17898
17756
|
|
|
17757
|
+
// src/common/htmltable-fontinfo.ts
|
|
17758
|
+
var SIZE_SAVEF = { fontsize: 0 };
|
|
17759
|
+
var EMIT_SAVEF = { fontsize: 0 };
|
|
17760
|
+
var pushFontInfo = (env, fp, savp) => {
|
|
17761
|
+
if (fp.fontFace !== void 0) {
|
|
17762
|
+
savp.fontname = env.fontname;
|
|
17763
|
+
env.fontname = fp.fontFace;
|
|
17764
|
+
} else savp.fontname = void 0;
|
|
17765
|
+
if (env.fontcolor !== void 0) {
|
|
17766
|
+
if (fp.fontColor !== void 0) {
|
|
17767
|
+
savp.fontcolor = env.fontcolor;
|
|
17768
|
+
env.fontcolor = fp.fontColor;
|
|
17769
|
+
} else savp.fontcolor = void 0;
|
|
17770
|
+
}
|
|
17771
|
+
if (env.fontsize >= 0) {
|
|
17772
|
+
if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
|
|
17773
|
+
savp.fontsize = env.fontsize;
|
|
17774
|
+
env.fontsize = fp.fontSize;
|
|
17775
|
+
} else savp.fontsize = -1;
|
|
17776
|
+
}
|
|
17777
|
+
};
|
|
17778
|
+
var popFontInfo = (env, savp) => {
|
|
17779
|
+
if (savp.fontname !== void 0) env.fontname = savp.fontname;
|
|
17780
|
+
if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
|
|
17781
|
+
if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
|
|
17782
|
+
};
|
|
17783
|
+
var withTableFont = (env, font, slot, fn) => {
|
|
17784
|
+
if (font === void 0) return fn();
|
|
17785
|
+
const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
|
|
17786
|
+
pushFontInfo(env, font, savp);
|
|
17787
|
+
const r = fn();
|
|
17788
|
+
popFontInfo(env, savp);
|
|
17789
|
+
return r;
|
|
17790
|
+
};
|
|
17791
|
+
|
|
17792
|
+
// src/common/htmltable.ts
|
|
17793
|
+
var DEFAULT_BORDER = 1;
|
|
17794
|
+
var DEFAULT_CELLPADDING = 2;
|
|
17795
|
+
var DEFAULT_CELLSPACING = 2;
|
|
17796
|
+
var DEFAULT_FONTSIZE = 14;
|
|
17797
|
+
var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
17798
|
+
let col = startCol;
|
|
17799
|
+
let notFound = true;
|
|
17800
|
+
const end = colspan - 1;
|
|
17801
|
+
while (notFound) {
|
|
17802
|
+
const lastc = col + end;
|
|
17803
|
+
let c;
|
|
17804
|
+
for (c = lastc; c >= col; c--) {
|
|
17805
|
+
if (ps.isInPS(c, row)) break;
|
|
17806
|
+
}
|
|
17807
|
+
if (c >= col) col = c + 1;
|
|
17808
|
+
else notFound = false;
|
|
17809
|
+
}
|
|
17810
|
+
for (let j = col; j < col + colspan; j++) {
|
|
17811
|
+
for (let i = row; i < row + rowspan; i++) {
|
|
17812
|
+
ps.addPS(j, i);
|
|
17813
|
+
}
|
|
17814
|
+
}
|
|
17815
|
+
return col;
|
|
17816
|
+
};
|
|
17817
|
+
var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
|
|
17818
|
+
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
17819
|
+
const lines = buildLineRuns(texts, env, measurer);
|
|
17820
|
+
const simple = runsAreSimple(lines, env);
|
|
17821
|
+
let w = 0;
|
|
17822
|
+
let h = 0;
|
|
17823
|
+
for (const ln of lines) {
|
|
17824
|
+
w = Math.max(w, ln.width);
|
|
17825
|
+
const lsize = simple ? ln.height : ln.fontSize;
|
|
17826
|
+
h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
|
|
17827
|
+
}
|
|
17828
|
+
if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].height : DEFAULT_FONTSIZE;
|
|
17829
|
+
return { w, h };
|
|
17830
|
+
};
|
|
17831
|
+
var missingImages = { set: /* @__PURE__ */ new WeakSet() };
|
|
17832
|
+
var sizeHtmlImg = (img, { imageSizer, stderr }) => {
|
|
17833
|
+
if (img.width !== void 0 && img.height !== void 0) return missingImages.set.has(img) ? 1 : 0;
|
|
17834
|
+
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
17835
|
+
if (sz !== null) {
|
|
17836
|
+
img.width = sz.w;
|
|
17837
|
+
img.height = sz.h;
|
|
17838
|
+
return 0;
|
|
17839
|
+
}
|
|
17840
|
+
if (!imageIsSupplied(img.src, imageSizer)) agerrLine(stderr, `Warning: ${imageOpenWarning(img.src)}`);
|
|
17841
|
+
agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
|
|
17842
|
+
img.width = 0;
|
|
17843
|
+
img.height = 0;
|
|
17844
|
+
missingImages.set.add(img);
|
|
17845
|
+
return 1;
|
|
17846
|
+
};
|
|
17847
|
+
var sizeContentItem = (item, measurer, env) => {
|
|
17848
|
+
if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
|
|
17849
|
+
if (item.kind === "table") {
|
|
17850
|
+
const rv = sizeTableInner(item, measurer, env);
|
|
17851
|
+
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
17852
|
+
}
|
|
17853
|
+
if (item.kind === "image") {
|
|
17854
|
+
const rv = sizeHtmlImg(item, env);
|
|
17855
|
+
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
17856
|
+
}
|
|
17857
|
+
return { w: 0, h: 0, rv: 0 };
|
|
17858
|
+
};
|
|
17859
|
+
var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
|
|
17860
|
+
var cellBorder = (cell2, tbl) => {
|
|
17861
|
+
if (cell2.border !== void 0) return cell2.border;
|
|
17862
|
+
const cb = tbl.cellborder;
|
|
17863
|
+
if (cb !== void 0 && cb >= 0) return cb;
|
|
17864
|
+
if (tbl.border !== void 0) return tbl.border;
|
|
17865
|
+
return DEFAULT_BORDER;
|
|
17866
|
+
};
|
|
17867
|
+
function inheritTablePenColor(tbl, parentColor) {
|
|
17868
|
+
if (tbl.color === void 0) tbl.color = parentColor;
|
|
17869
|
+
const tblColor = tbl.color;
|
|
17870
|
+
for (const row of tbl.rows) {
|
|
17871
|
+
for (const cell2 of row.cells) {
|
|
17872
|
+
if (cell2.color === void 0) cell2.color = tblColor;
|
|
17873
|
+
for (const item of cell2.content) {
|
|
17874
|
+
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
17875
|
+
}
|
|
17876
|
+
}
|
|
17877
|
+
}
|
|
17878
|
+
}
|
|
17879
|
+
var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
|
|
17880
|
+
var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
|
|
17881
|
+
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
17882
|
+
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
17883
|
+
var sizeWarned = { set: /* @__PURE__ */ new WeakSet() };
|
|
17884
|
+
registerRenderState(() => {
|
|
17885
|
+
missingImages.set = /* @__PURE__ */ new WeakSet();
|
|
17886
|
+
sizeWarned.set = /* @__PURE__ */ new WeakSet();
|
|
17887
|
+
});
|
|
17888
|
+
var fixedCellCheck = (cell2, sz, warn, out) => {
|
|
17889
|
+
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
17890
|
+
if (cell2.width && cell2.height) {
|
|
17891
|
+
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
17892
|
+
if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
|
|
17893
|
+
return { rv: small ? 1 : 0, zero: true };
|
|
17894
|
+
}
|
|
17895
|
+
if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
|
|
17896
|
+
return { rv: 1, zero: false };
|
|
17897
|
+
};
|
|
17898
|
+
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
17899
|
+
const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
|
|
17900
|
+
let cw = 0, ch = 0, rv = 0;
|
|
17901
|
+
for (const item of cell2.content) {
|
|
17902
|
+
const s = sizeContentItem(item, measurer, env);
|
|
17903
|
+
cw = Math.max(cw, s.w);
|
|
17904
|
+
ch += s.h;
|
|
17905
|
+
rv |= s.rv;
|
|
17906
|
+
}
|
|
17907
|
+
let szx = cw + margin;
|
|
17908
|
+
let szy = ch + margin;
|
|
17909
|
+
const warn = !sizeWarned.set.has(cell2);
|
|
17910
|
+
sizeWarned.set.add(cell2);
|
|
17911
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
|
|
17912
|
+
rv |= fixed.rv;
|
|
17913
|
+
if (fixed.zero) {
|
|
17914
|
+
szx = 0;
|
|
17915
|
+
szy = 0;
|
|
17916
|
+
}
|
|
17917
|
+
const bw = cell2.width !== void 0 ? cell2.width : 0;
|
|
17918
|
+
const bh = cell2.height !== void 0 ? cell2.height : 0;
|
|
17919
|
+
return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
|
|
17920
|
+
};
|
|
17921
|
+
var buildLayouts = (tbl, measurer, env) => {
|
|
17922
|
+
const entries = [];
|
|
17923
|
+
let rv = 0;
|
|
17924
|
+
const ps = new PointSet();
|
|
17925
|
+
let rowIdx = 0;
|
|
17926
|
+
for (const row of tbl.rows) {
|
|
17927
|
+
let col = 0;
|
|
17928
|
+
for (const c of row.cells) {
|
|
17929
|
+
if (c.kind !== "cell") {
|
|
17930
|
+
continue;
|
|
17931
|
+
}
|
|
17932
|
+
const colspan = c.colspan !== void 0 ? c.colspan : 1;
|
|
17933
|
+
const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
|
|
17934
|
+
const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
|
|
17935
|
+
rv |= cellRv;
|
|
17936
|
+
col = findCol(ps, rowIdx, col, colspan, rowspan);
|
|
17937
|
+
entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
|
|
17938
|
+
col += colspan;
|
|
17939
|
+
}
|
|
17940
|
+
rowIdx++;
|
|
17941
|
+
}
|
|
17942
|
+
return { entries, rv };
|
|
17943
|
+
};
|
|
17944
|
+
var setColWidths = (entries, ncols, spacing) => {
|
|
17945
|
+
const widths = new Array(ncols + 1).fill(0);
|
|
17946
|
+
for (const e of entries)
|
|
17947
|
+
if (e.colspan === 1) widths[e.col] = Math.max(widths[e.col], e.w);
|
|
17948
|
+
for (const e of entries) {
|
|
17949
|
+
if (e.colspan === 1) continue;
|
|
17950
|
+
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
17951
|
+
const need = e.w - spanW - (e.colspan - 1) * spacing;
|
|
17952
|
+
if (need > 0) {
|
|
17953
|
+
const add2 = need / e.colspan;
|
|
17954
|
+
for (let j = 0; j < e.colspan; j++) widths[e.col + j] += add2;
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17957
|
+
for (const e of entries) {
|
|
17958
|
+
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
17959
|
+
e.w = Math.max(e.w, spanW + (e.colspan - 1) * spacing);
|
|
17960
|
+
}
|
|
17961
|
+
return widths;
|
|
17962
|
+
};
|
|
17963
|
+
var setRowHeights = (entries, nrows, spacing) => {
|
|
17964
|
+
const heights = new Array(nrows + 1).fill(0);
|
|
17965
|
+
for (const e of entries)
|
|
17966
|
+
if (e.rowspan === 1) heights[e.row] = Math.max(heights[e.row], e.h);
|
|
17967
|
+
for (const e of entries) {
|
|
17968
|
+
if (e.rowspan === 1) continue;
|
|
17969
|
+
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
17970
|
+
const need = e.h - spanH - (e.rowspan - 1) * spacing;
|
|
17971
|
+
if (need > 0) {
|
|
17972
|
+
const add2 = need / e.rowspan;
|
|
17973
|
+
for (let j = 0; j < e.rowspan; j++) heights[e.row + j] += add2;
|
|
17974
|
+
}
|
|
17975
|
+
}
|
|
17976
|
+
for (const e of entries) {
|
|
17977
|
+
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
17978
|
+
e.h = Math.max(e.h, spanH + (e.rowspan - 1) * spacing);
|
|
17979
|
+
}
|
|
17980
|
+
return heights;
|
|
17981
|
+
};
|
|
17982
|
+
var getSpacing = (tbl) => tbl.cellspacing !== void 0 ? tbl.cellspacing : DEFAULT_CELLSPACING;
|
|
17983
|
+
var getBorder = (tbl) => tbl.border !== void 0 ? tbl.border : DEFAULT_BORDER;
|
|
17984
|
+
var isTblFixed = (tbl) => tbl.fixedsize === true && tbl.width !== void 0 && tbl.height !== void 0;
|
|
17985
|
+
var sumTableDims = (a) => {
|
|
17986
|
+
let wd = (a.ncols + 1) * a.spacing + 2 * a.border;
|
|
17987
|
+
let ht = (a.nrows + 1) * a.spacing + 2 * a.border;
|
|
17988
|
+
for (let i = 0; i < a.ncols; i++) wd += a.widths[i];
|
|
17989
|
+
for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
|
|
17990
|
+
return { wd, ht };
|
|
17991
|
+
};
|
|
17992
|
+
var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
17993
|
+
const spacing = getSpacing(tbl);
|
|
17994
|
+
const border2 = getBorder(tbl);
|
|
17995
|
+
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
17996
|
+
if (entries.length === 0) {
|
|
17997
|
+
return { entries, widths: [], heights: [], spacing, border: border2, rv };
|
|
17998
|
+
}
|
|
17999
|
+
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
18000
|
+
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
18001
|
+
const widths = setColWidths(entries, ncols, spacing);
|
|
18002
|
+
const heights = setRowHeights(entries, nrows, spacing);
|
|
18003
|
+
return { entries, widths, heights, spacing, border: border2, rv };
|
|
18004
|
+
};
|
|
18005
|
+
var warnFixedTable = (tbl, dims, out) => {
|
|
18006
|
+
const warn = !sizeWarned.set.has(tbl);
|
|
18007
|
+
sizeWarned.set.add(tbl);
|
|
18008
|
+
if (tbl.fixedsize !== true) return 0;
|
|
18009
|
+
if (tbl.width && tbl.height) {
|
|
18010
|
+
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
18011
|
+
if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
|
|
18012
|
+
return 1;
|
|
18013
|
+
}
|
|
18014
|
+
if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
|
|
18015
|
+
return 1;
|
|
18016
|
+
};
|
|
18017
|
+
var sizeTableBody = (tbl, measurer, env) => {
|
|
18018
|
+
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
18019
|
+
if (entries.length === 0) {
|
|
18020
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
|
|
18021
|
+
tbl.dimen = { w: 0, h: 0 };
|
|
18022
|
+
return rv | fixed2;
|
|
18023
|
+
}
|
|
18024
|
+
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
18025
|
+
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
18026
|
+
for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
|
|
18027
|
+
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
18028
|
+
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
18029
|
+
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
18030
|
+
const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
|
|
18031
|
+
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
18032
|
+
tbl.dimen = {
|
|
18033
|
+
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
18034
|
+
h: Math.max(zeroContent ? 0 : ht, baseHt)
|
|
18035
|
+
};
|
|
18036
|
+
return rv | fixed;
|
|
18037
|
+
};
|
|
18038
|
+
var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
|
|
18039
|
+
var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
|
|
18040
|
+
if (label.kind === "table") {
|
|
18041
|
+
const rv = sizeTableInner(label.table, measurer, env);
|
|
18042
|
+
label.dimen = label.table.dimen;
|
|
18043
|
+
return rv;
|
|
18044
|
+
}
|
|
18045
|
+
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
18046
|
+
return 0;
|
|
18047
|
+
};
|
|
18048
|
+
|
|
18049
|
+
// src/common/splines-constants.ts
|
|
18050
|
+
var REGULAREDGE = 1;
|
|
18051
|
+
var FLATEDGE = 2;
|
|
18052
|
+
var ARR_NONE = 0;
|
|
18053
|
+
var BOTTOM = 1 << 0;
|
|
18054
|
+
var RIGHT = 1 << 1;
|
|
18055
|
+
var TOP = 1 << 2;
|
|
18056
|
+
var LEFT = 1 << 3;
|
|
18057
|
+
var SELF_EDGE_SIZE = 18;
|
|
18058
|
+
var MILLIPOINT = 1e-3;
|
|
18059
|
+
var FUDGE = 2;
|
|
18060
|
+
var INIT_DELTA = 10;
|
|
18061
|
+
var LOOP_TRIES = 15;
|
|
18062
|
+
var ROUTESPL_FUDGE = 1e-4;
|
|
18063
|
+
|
|
17899
18064
|
// src/common/htmltable-pos.ts
|
|
17900
18065
|
function alignContentBox(box, cell2, w, h) {
|
|
17901
18066
|
const out = { ll: { ...box.ll }, ur: { ...box.ur } };
|
|
@@ -18291,12 +18456,17 @@ var DEFAULT_FONTNAME = "Times-Roman";
|
|
|
18291
18456
|
var DEFAULT_COLOR3 = "black";
|
|
18292
18457
|
function getPenColor(obj) {
|
|
18293
18458
|
if (obj === void 0) return void 0;
|
|
18294
|
-
const pc = obj
|
|
18459
|
+
const pc = aggetObj(obj, "pencolor");
|
|
18295
18460
|
if (pc !== void 0 && pc !== "") return pc;
|
|
18296
|
-
const c = obj
|
|
18461
|
+
const c = aggetObj(obj, "color");
|
|
18297
18462
|
if (c !== void 0 && c !== "") return c;
|
|
18298
18463
|
return void 0;
|
|
18299
18464
|
}
|
|
18465
|
+
function aggetObj(obj, key) {
|
|
18466
|
+
if (obj instanceof Node) return nodeAttr(obj, obj.root, key);
|
|
18467
|
+
if (obj instanceof Graph) return graphAttrInherited(obj, key);
|
|
18468
|
+
return obj.attrs.get(key);
|
|
18469
|
+
}
|
|
18300
18470
|
function rootOf(obj) {
|
|
18301
18471
|
return obj instanceof Edge ? obj.tail.root : obj.root;
|
|
18302
18472
|
}
|
|
@@ -18693,7 +18863,7 @@ function transformUnitVertex(R2, g, c, bb) {
|
|
|
18693
18863
|
const r = libmHypot(D.x, D.y);
|
|
18694
18864
|
return { x: r * Math.cos(alpha) * bb.x, y: r * Math.sin(alpha) * bb.y };
|
|
18695
18865
|
}
|
|
18696
|
-
function polygonVertices(bb, g,
|
|
18866
|
+
function polygonVertices(bb, g, isBox4) {
|
|
18697
18867
|
const sectorangle = 2 * Math.PI / g.sides;
|
|
18698
18868
|
const sidelength = Math.sin(sectorangle / 2);
|
|
18699
18869
|
const c = {
|
|
@@ -18711,7 +18881,7 @@ function polygonVertices(bb, g, isBox3) {
|
|
|
18711
18881
|
R2.y = fma(sidelength, Math.sin(angle), R2.y);
|
|
18712
18882
|
const P = transformUnitVertex(R2, g, c, bb);
|
|
18713
18883
|
verts.push(P);
|
|
18714
|
-
if (
|
|
18884
|
+
if (isBox4) {
|
|
18715
18885
|
verts.push({ x: -P.x, y: P.y }, { x: -P.x, y: -P.y }, { x: P.x, y: -P.y });
|
|
18716
18886
|
break;
|
|
18717
18887
|
}
|
|
@@ -18802,14 +18972,14 @@ function starVertexGen(bb) {
|
|
|
18802
18972
|
}
|
|
18803
18973
|
return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
|
|
18804
18974
|
}
|
|
18805
|
-
function polygonBB(bb, minSize, p, sides2,
|
|
18975
|
+
function polygonBB(bb, minSize, p, sides2, isBox4) {
|
|
18806
18976
|
const geom = {
|
|
18807
18977
|
sides: sides2,
|
|
18808
18978
|
orientation: p.orientation,
|
|
18809
18979
|
distortion: p.distortion,
|
|
18810
18980
|
skew: p.skew
|
|
18811
18981
|
};
|
|
18812
|
-
const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom,
|
|
18982
|
+
const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox4);
|
|
18813
18983
|
const xmax2 = 2 * xmax;
|
|
18814
18984
|
const ymax2 = 2 * ymax;
|
|
18815
18985
|
const nbb = { x: Math.max(minSize.x, xmax2), y: Math.max(minSize.y, ymax2) };
|
|
@@ -18821,7 +18991,7 @@ function polygonBB(bb, minSize, p, sides2, isBox3) {
|
|
|
18821
18991
|
v.x *= scalex;
|
|
18822
18992
|
v.y *= scaley;
|
|
18823
18993
|
}
|
|
18824
|
-
return { ...polygonPeripheryBB(verts,
|
|
18994
|
+
return { ...polygonPeripheryBB(verts, isBox4 ? 4 : sides2, p, nbb), base: nbb };
|
|
18825
18995
|
}
|
|
18826
18996
|
function gvNodesize(widthPts, heightPts, flip) {
|
|
18827
18997
|
if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
|
|
@@ -18846,9 +19016,9 @@ function applySizeConstraints(p, bb0, width0, height0) {
|
|
|
18846
19016
|
function polySize(p) {
|
|
18847
19017
|
const init = initialSizePts(p);
|
|
18848
19018
|
const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
|
|
18849
|
-
const { sides: sides2, isBox:
|
|
19019
|
+
const { sides: sides2, isBox: isBox4 } = effectiveShape(p);
|
|
18850
19020
|
let bb = { x: dimen.x, y: dimen.y };
|
|
18851
|
-
if (
|
|
19021
|
+
if (isBox4) {
|
|
18852
19022
|
} else if (p.optionShape === STAR) {
|
|
18853
19023
|
bb = starSize(bb);
|
|
18854
19024
|
} else if (p.optionShape === CYLINDER) {
|
|
@@ -18860,16 +19030,16 @@ function polySize(p) {
|
|
|
18860
19030
|
const c = applySizeConstraints(p, bb, init.width, init.height);
|
|
18861
19031
|
const penwidth = p.penwidth ?? 1;
|
|
18862
19032
|
const hasOutline = penwidth > 0 || p.peripheries < 1;
|
|
18863
|
-
const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2,
|
|
19033
|
+
const grown = sides2 < 3 ? { ...ellipsePeripheryBB(c.bb, p.peripheries, penwidth, hasOutline), base: c.bb } : polygonBB(c.bb, { x: c.width, y: c.height }, { ...p, penwidth, hasOutline }, sides2, isBox4);
|
|
18864
19034
|
const result = assembleResult(p, dimen, grown, c.fixedshape);
|
|
18865
|
-
return { ...result, ...labelSpace(p, dimen, c.bb, minBb,
|
|
19035
|
+
return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox4, c.fixedshape) };
|
|
18866
19036
|
}
|
|
18867
|
-
function labelSpace(p, dimen, bb, minBb,
|
|
19037
|
+
function labelSpace(p, dimen, bb, minBb, isBox4, fixedshape) {
|
|
18868
19038
|
const spacex = dimen.x - p.labelDimen.x;
|
|
18869
19039
|
let spaceX;
|
|
18870
19040
|
if (p.nojustify) {
|
|
18871
19041
|
spaceX = dimen.x - spacex;
|
|
18872
|
-
} else if (
|
|
19042
|
+
} else if (isBox4) {
|
|
18873
19043
|
spaceX = Math.max(dimen.x, bb.x) - spacex;
|
|
18874
19044
|
} else if (dimen.y < bb.y) {
|
|
18875
19045
|
spaceX = Math.max(dimen.x, bb.x * Math.sqrt(1 - dimen.y * dimen.y / (bb.y * bb.y))) - spacex;
|
|
@@ -18882,8 +19052,8 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
|
|
|
18882
19052
|
function effectiveShape(p) {
|
|
18883
19053
|
let sides2 = p.sides;
|
|
18884
19054
|
if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
|
|
18885
|
-
const
|
|
18886
|
-
return { sides: sides2, isBox:
|
|
19055
|
+
const isBox4 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
|
|
19056
|
+
return { sides: sides2, isBox: isBox4 };
|
|
18887
19057
|
}
|
|
18888
19058
|
function labelValign(p) {
|
|
18889
19059
|
const ll = p.labelloc?.[0];
|
|
@@ -18977,7 +19147,7 @@ function copyVirtualEdgeInfo(e, orig) {
|
|
|
18977
19147
|
e.seq = orig.seq;
|
|
18978
19148
|
}
|
|
18979
19149
|
function newVirtualEdge(u, v, orig) {
|
|
18980
|
-
const e = new Edge(u, v, "");
|
|
19150
|
+
const e = new Edge(u, v, "", true);
|
|
18981
19151
|
e.info.edge_type = VIRTUAL;
|
|
18982
19152
|
if (orig) {
|
|
18983
19153
|
copyVirtualEdgeInfo(e, orig);
|
|
@@ -19078,7 +19248,7 @@ function removeFromRank(g, n) {
|
|
|
19078
19248
|
}
|
|
19079
19249
|
}
|
|
19080
19250
|
function virtualNode(g) {
|
|
19081
|
-
const n = new Node(0, "", g.root);
|
|
19251
|
+
const n = new Node(0, "", g.root, true);
|
|
19082
19252
|
n.info.node_type = VIRTUAL;
|
|
19083
19253
|
n.info.lw = 1;
|
|
19084
19254
|
n.info.rw = 1;
|
|
@@ -19370,10 +19540,10 @@ var ARROW_EPSILON = 1e-4;
|
|
|
19370
19540
|
var vsub2 = (p, q) => ({ x: p.x - q.x, y: p.y - q.y });
|
|
19371
19541
|
var vadd2 = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
|
|
19372
19542
|
var vscale = (c, p) => ({ x: c * p.x, y: c * p.y });
|
|
19373
|
-
var negUnit = (u,
|
|
19543
|
+
var negUnit = (u, dist5) => {
|
|
19374
19544
|
if (u.x === 0 && u.y === 0) return { x: 0, y: 0 };
|
|
19375
19545
|
const h = Math.hypot(u.x, u.y);
|
|
19376
|
-
return { x:
|
|
19546
|
+
return { x: dist5 * (-u.x / h), y: dist5 * (-u.y / h) };
|
|
19377
19547
|
};
|
|
19378
19548
|
var backwardDelta = (u, penwidth) => negUnit(u, penwidth / 2);
|
|
19379
19549
|
function axialProjection(phiSrc, from, to, sign2) {
|
|
@@ -19922,9 +20092,9 @@ function makeEllipseInsideFn(rx, ry, penwidth = DEFAULT_NODEPENWIDTH) {
|
|
|
19922
20092
|
return (lx, ly) => lx * lx / (erx * erx) + ly * ly / (ery * ery) < 1;
|
|
19923
20093
|
}
|
|
19924
20094
|
function tailArrowEndClip(path4, tailTip, elen) {
|
|
19925
|
-
|
|
19926
|
-
const
|
|
19927
|
-
return
|
|
20095
|
+
const sp = [path4[3], path4[2], path4[1], tailTip];
|
|
20096
|
+
const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, tailTip) <= elen, false) : sp;
|
|
20097
|
+
return [clipped[3], clipped[2], clipped[1], clipped[0]];
|
|
19928
20098
|
}
|
|
19929
20099
|
|
|
19930
20100
|
// src/layout/dot/edge-route-geom.ts
|
|
@@ -19983,6 +20153,7 @@ function arrowDrawOpsForEnd(e, end, tip2, dir, penwidth) {
|
|
|
19983
20153
|
|
|
19984
20154
|
// src/common/splines-clip.ts
|
|
19985
20155
|
var ARR_NORM = 1;
|
|
20156
|
+
var dist = distFused;
|
|
19986
20157
|
var SplineClipHelper = class _SplineClipHelper {
|
|
19987
20158
|
static makeEmptySpl() {
|
|
19988
20159
|
return { list: [], size: 0, bb: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } } };
|
|
@@ -20075,15 +20246,11 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20075
20246
|
if (j) return [eflag, sflag];
|
|
20076
20247
|
return [sflag, eflag];
|
|
20077
20248
|
}
|
|
20078
|
-
/** DIST(p, q). */
|
|
20079
|
-
static dist(p, q) {
|
|
20080
|
-
return Math.hypot(p.x - q.x, p.y - q.y);
|
|
20081
|
-
}
|
|
20082
20249
|
/** Sphere inside-fn around `tip` with radius `r` for bezierClip. */
|
|
20083
20250
|
static sphereCtx(tip2, r) {
|
|
20084
20251
|
return {
|
|
20085
20252
|
ctx: { nodeCoord: { x: 0, y: 0 }, rw: 0, bp: null },
|
|
20086
|
-
fn: (_c, p) =>
|
|
20253
|
+
fn: (_c, p) => dist(p, tip2) <= r
|
|
20087
20254
|
};
|
|
20088
20255
|
}
|
|
20089
20256
|
/**
|
|
@@ -20115,7 +20282,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20115
20282
|
);
|
|
20116
20283
|
spl.eflag = eflag;
|
|
20117
20284
|
spl.ep = ps[endp + 3];
|
|
20118
|
-
if (endp > startp &&
|
|
20285
|
+
if (endp > startp && dist(ps[endp], ps[endp + 3]) < elen) {
|
|
20119
20286
|
endp -= 3;
|
|
20120
20287
|
}
|
|
20121
20288
|
const sp = [spl.ep, ps[endp + 2], ps[endp + 1], ps[endp]];
|
|
@@ -20142,7 +20309,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20142
20309
|
);
|
|
20143
20310
|
spl.sflag = sflag;
|
|
20144
20311
|
spl.sp = ps[startp];
|
|
20145
|
-
if (endp > startp &&
|
|
20312
|
+
if (endp > startp && dist(ps[startp], ps[startp + 3]) < slen) {
|
|
20146
20313
|
startp += 3;
|
|
20147
20314
|
}
|
|
20148
20315
|
const sp = [ps[startp + 3], ps[startp + 2], ps[startp + 1], spl.sp];
|
|
@@ -20243,7 +20410,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20243
20410
|
if (sflag && eflag && endp === startp) {
|
|
20244
20411
|
const p = ps[endp];
|
|
20245
20412
|
const q = ps[endp + 3];
|
|
20246
|
-
const d =
|
|
20413
|
+
const d = dist(p, q);
|
|
20247
20414
|
let hlen = hlen0;
|
|
20248
20415
|
let tlen = tlen0;
|
|
20249
20416
|
if (hlen + tlen >= d) {
|
|
@@ -20286,7 +20453,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20286
20453
|
let hlen = hlen0;
|
|
20287
20454
|
const p = ps[endp];
|
|
20288
20455
|
const q = ps[endp + 3];
|
|
20289
|
-
const maxd = 0.9 *
|
|
20456
|
+
const maxd = 0.9 * dist(p, q);
|
|
20290
20457
|
if (hlen >= maxd) hlen = maxd;
|
|
20291
20458
|
const r = { x: p.x, y: p.y };
|
|
20292
20459
|
if (p.y === q.y) {
|
|
@@ -20306,7 +20473,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20306
20473
|
let tlen = tlen0;
|
|
20307
20474
|
const p = ps[startp];
|
|
20308
20475
|
const q = ps[startp + 3];
|
|
20309
|
-
const maxd = 0.9 *
|
|
20476
|
+
const maxd = 0.9 * dist(p, q);
|
|
20310
20477
|
if (tlen >= maxd) tlen = maxd;
|
|
20311
20478
|
const r = { x: p.x, y: p.y };
|
|
20312
20479
|
if (p.y === q.y) {
|
|
@@ -21017,9 +21184,6 @@ function readLabelPos(sg) {
|
|
|
21017
21184
|
}
|
|
21018
21185
|
return pos;
|
|
21019
21186
|
}
|
|
21020
|
-
function graphAttrInherited(sg, key) {
|
|
21021
|
-
return sg.attrs.get(key) ?? sg.graphDefaultsSnapshot?.get(key);
|
|
21022
|
-
}
|
|
21023
21187
|
function readFontParams(sg) {
|
|
21024
21188
|
return {
|
|
21025
21189
|
fontsize: parseFloat(graphAttrInherited(sg, "fontsize") ?? "") || DEFAULT_FONTSIZE2,
|
|
@@ -22538,13 +22702,13 @@ function dfsNode(Xg, v, frames) {
|
|
|
22538
22702
|
frames.push({ v, edges: v.outEdges(Xg).slice(), i: 0 });
|
|
22539
22703
|
}
|
|
22540
22704
|
function dfsStep2(Xg, frames) {
|
|
22541
|
-
const
|
|
22542
|
-
if (
|
|
22543
|
-
const e =
|
|
22705
|
+
const fr7 = frames[frames.length - 1];
|
|
22706
|
+
if (fr7.i < fr7.edges.length) {
|
|
22707
|
+
const e = fr7.edges[fr7.i++];
|
|
22544
22708
|
if (e.head.info.onstack) reverseEdge2(Xg, e);
|
|
22545
22709
|
else if (!e.head.info.mark) dfsNode(Xg, e.head, frames);
|
|
22546
22710
|
} else {
|
|
22547
|
-
|
|
22711
|
+
fr7.v.info.onstack = 0;
|
|
22548
22712
|
frames.pop();
|
|
22549
22713
|
}
|
|
22550
22714
|
}
|
|
@@ -23718,7 +23882,7 @@ function pruneForeignClusterNodes(par, clust) {
|
|
|
23718
23882
|
}
|
|
23719
23883
|
function markClusterNode(clust, n, g) {
|
|
23720
23884
|
if ((n.info.ranktype ?? 0) !== 0) {
|
|
23721
|
-
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}
|
|
23885
|
+
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`);
|
|
23722
23886
|
agDeleteFromCluster(clust, n);
|
|
23723
23887
|
return;
|
|
23724
23888
|
}
|
|
@@ -24943,12 +25107,6 @@ function drawRecordBox(job, n, ll, ur, filled) {
|
|
|
24943
25107
|
var DEFAULT_LW = 27;
|
|
24944
25108
|
var DEFAULT_RW = 27;
|
|
24945
25109
|
var DEFAULT_HT = 36;
|
|
24946
|
-
function nodeAttr(n, g, key) {
|
|
24947
|
-
const own = n.attrs.get(key);
|
|
24948
|
-
if (own !== void 0) return own;
|
|
24949
|
-
if (n.nodeDefaultsSnapshot !== void 0) return n.nodeDefaultsSnapshot.get(key);
|
|
24950
|
-
return g.nodeDefaults.get(key) ?? (g !== g.root ? g.root.nodeDefaults.get(key) : void 0);
|
|
24951
|
-
}
|
|
24952
25110
|
function readFontAttrs(n, g) {
|
|
24953
25111
|
return {
|
|
24954
25112
|
fontname: nodeAttr(n, g, "fontname") ?? DEFAULT_FONTNAME,
|
|
@@ -24973,17 +25131,27 @@ function buildNodeLabel(n, g, measurer) {
|
|
|
24973
25131
|
const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
|
|
24974
25132
|
n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
|
|
24975
25133
|
}
|
|
25134
|
+
function warnMissingImage(n, g, shapefile) {
|
|
25135
|
+
if (shapefile !== void 0 && shapefile !== "" && nodeAttr(n, g, "shape") !== "epsf") return;
|
|
25136
|
+
const image = nodeAttr(n, g, "image");
|
|
25137
|
+
if (image === void 0 || image === "") return;
|
|
25138
|
+
const gvc = g.root.info.gvc;
|
|
25139
|
+
if (imageIsSupplied(image, gvc?.imageSizer, gvc?.imageResolver)) return;
|
|
25140
|
+
agwarningf(imageOpenWarning(image));
|
|
25141
|
+
agwarningf(`No or improper image="${image}" for node "${n.name}"`);
|
|
25142
|
+
}
|
|
24976
25143
|
function polyInit(n, g, measurer) {
|
|
24977
25144
|
const shapeName2 = nodeAttr(n, g, "shape") ?? "ellipse";
|
|
24978
25145
|
const shapefile = nodeAttr(n, g, "shapefile");
|
|
24979
25146
|
n.info.shape = bindShape(shapeName2, shapefile);
|
|
24980
25147
|
if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
|
|
24981
|
-
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"
|
|
25148
|
+
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`);
|
|
24982
25149
|
}
|
|
24983
25150
|
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
24984
25151
|
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
24985
25152
|
return;
|
|
24986
25153
|
}
|
|
25154
|
+
warnMissingImage(n, g, shapefile);
|
|
24987
25155
|
buildNodeLabel(n, g, measurer);
|
|
24988
25156
|
if (n.info.shape_info !== void 0) return;
|
|
24989
25157
|
const polyDesc = n.info.shape.polygon;
|
|
@@ -25109,8 +25277,8 @@ function drawWedge(seg2, e, ctx) {
|
|
|
25109
25277
|
ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
|
|
25110
25278
|
return angle1;
|
|
25111
25279
|
}
|
|
25112
|
-
function wedgedEllipse(job, pf, clrs, renderer) {
|
|
25113
|
-
const { segs, error } = parseSegs(clrs);
|
|
25280
|
+
function wedgedEllipse(job, pf, clrs, renderer, context) {
|
|
25281
|
+
const { segs, error } = parseSegs(clrs, context);
|
|
25114
25282
|
if (error === 1 || error === 2) return error;
|
|
25115
25283
|
const ctrX = (pf[0].x + pf[1].x) / 2;
|
|
25116
25284
|
const ctrY = (pf[0].y + pf[1].y) / 2;
|
|
@@ -25142,8 +25310,8 @@ function drawBand(p, seg2, ctx) {
|
|
|
25142
25310
|
ctx.renderer.polygon([...p], true, ctx.job);
|
|
25143
25311
|
p[0].x = p[3].x = p[1].x;
|
|
25144
25312
|
}
|
|
25145
|
-
function stripedBox(job, pts, clrs, rotate, renderer) {
|
|
25146
|
-
const { segs, error } = parseSegs(clrs);
|
|
25313
|
+
function stripedBox(job, pts, clrs, rotate, renderer, context) {
|
|
25314
|
+
const { segs, error } = parseSegs(clrs, context);
|
|
25147
25315
|
if (error === 1 || error === 2) return error;
|
|
25148
25316
|
const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
|
|
25149
25317
|
const lastx = p[1].x;
|
|
@@ -25301,6 +25469,27 @@ function escapeXmlText(s) {
|
|
|
25301
25469
|
return gvXmlEscape(s, FLAGS_TEXT);
|
|
25302
25470
|
}
|
|
25303
25471
|
|
|
25472
|
+
// src/gvc/device-transform.ts
|
|
25473
|
+
function transformPoint(p, job) {
|
|
25474
|
+
if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
|
|
25475
|
+
return p;
|
|
25476
|
+
}
|
|
25477
|
+
const sx = job.zoom * job.devscale.x;
|
|
25478
|
+
const sy = job.zoom * job.devscale.y;
|
|
25479
|
+
const tx = job.translation.x;
|
|
25480
|
+
const ty = job.translation.y;
|
|
25481
|
+
return applyScale(p, tx, ty, sx, sy);
|
|
25482
|
+
}
|
|
25483
|
+
function applyScale(p, tx, ty, sx, sy) {
|
|
25484
|
+
const x = (p.x + tx) * sx;
|
|
25485
|
+
const y = (p.y + ty) * sy;
|
|
25486
|
+
return buildPoint(x, y);
|
|
25487
|
+
}
|
|
25488
|
+
function buildPoint(x, y) {
|
|
25489
|
+
const pt = { x, y };
|
|
25490
|
+
return pt;
|
|
25491
|
+
}
|
|
25492
|
+
|
|
25304
25493
|
// src/gvc/device-cluster.ts
|
|
25305
25494
|
function applyClusterGradient(obj, fill) {
|
|
25306
25495
|
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
@@ -25348,6 +25537,7 @@ function applyClusterObjState(sg, job) {
|
|
|
25348
25537
|
const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
|
|
25349
25538
|
if (job.obj === null) return false;
|
|
25350
25539
|
const obj = job.obj;
|
|
25540
|
+
gvrenderSetStyle(checkClusterStyleTokens(styleTokens(clusterStyle(sg))));
|
|
25351
25541
|
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
25352
25542
|
const filled = applyClusterFill(obj, fillRes);
|
|
25353
25543
|
applyClusterPenState(obj, sg);
|
|
@@ -25355,17 +25545,47 @@ function applyClusterObjState(sg, job) {
|
|
|
25355
25545
|
return filled;
|
|
25356
25546
|
});
|
|
25357
25547
|
}
|
|
25358
|
-
function
|
|
25548
|
+
function isStripedCluster(sg) {
|
|
25549
|
+
const flags = parseStyleFlags(clusterStyle(sg));
|
|
25550
|
+
return flags.striped && !flags.rounded;
|
|
25551
|
+
}
|
|
25552
|
+
function stripedFillSpec(sg) {
|
|
25359
25553
|
const flags = parseStyleFlags(clusterStyle(sg));
|
|
25360
|
-
if (!flags.striped || flags.rounded) return [];
|
|
25361
25554
|
const color = clusterAttr(sg, "color") ?? "";
|
|
25362
25555
|
let fill = clusterAttr(sg, "fillcolor") || color;
|
|
25363
25556
|
const bg = clusterAttr(sg, "bgcolor") ?? "";
|
|
25364
25557
|
if ((!flags.filled || fill === "") && bg !== "") fill = bg;
|
|
25365
|
-
|
|
25558
|
+
return fill === "" ? "lightgrey" : fill;
|
|
25559
|
+
}
|
|
25560
|
+
function stripedClusterColors(sg) {
|
|
25561
|
+
if (!isStripedCluster(sg)) return [];
|
|
25562
|
+
const { segs, error } = parseSegs(stripedFillSpec(sg), () => `in cluster ${sg.name}`);
|
|
25366
25563
|
if (error === 1 || error === 2) return [];
|
|
25367
25564
|
return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
|
|
25368
25565
|
}
|
|
25566
|
+
function renderStripedClusterBox(sg, renderer, job) {
|
|
25567
|
+
withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
25568
|
+
const { ll, ur } = sg.info.bb;
|
|
25569
|
+
const af = [
|
|
25570
|
+
{ x: ll.x, y: ll.y },
|
|
25571
|
+
{ x: ur.x, y: ll.y },
|
|
25572
|
+
{ x: ur.x, y: ur.y },
|
|
25573
|
+
{ x: ll.x, y: ur.y }
|
|
25574
|
+
].map((p) => transformPoint(p, job));
|
|
25575
|
+
const obj = job.obj;
|
|
25576
|
+
const savedFill = obj?.fill;
|
|
25577
|
+
if (obj !== null && savedFill !== void 0) obj.fill = 1 /* Solid */;
|
|
25578
|
+
stripedBox(job, af, stripedFillSpec(sg), false, renderer, () => `in cluster ${sg.name}`);
|
|
25579
|
+
if (obj !== null && savedFill !== void 0) obj.fill = savedFill;
|
|
25580
|
+
const rawPts = [
|
|
25581
|
+
{ x: ll.x, y: ll.y },
|
|
25582
|
+
{ x: ll.x, y: ur.y },
|
|
25583
|
+
{ x: ur.x, y: ur.y },
|
|
25584
|
+
{ x: ur.x, y: ll.y }
|
|
25585
|
+
];
|
|
25586
|
+
renderer.polygon(rawPts.map((p) => transformPoint(p, job)), false, job);
|
|
25587
|
+
});
|
|
25588
|
+
}
|
|
25369
25589
|
function applyClusterFill(obj, fillRes) {
|
|
25370
25590
|
if (fillRes.kind === "none") {
|
|
25371
25591
|
obj.fill = 0 /* None */;
|
|
@@ -25431,7 +25651,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
|
25431
25651
|
const pf = ring.map(
|
|
25432
25652
|
(v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
|
|
25433
25653
|
);
|
|
25434
|
-
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
|
|
25654
|
+
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer, () => `in node ${ctx.nodeName}`);
|
|
25435
25655
|
renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
|
|
25436
25656
|
} else {
|
|
25437
25657
|
renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
|
|
@@ -25440,7 +25660,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
|
25440
25660
|
}
|
|
25441
25661
|
function renderStripedRing(ring, coord, ctx) {
|
|
25442
25662
|
const af = ring.map((v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job));
|
|
25443
|
-
stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer);
|
|
25663
|
+
stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer, () => `in node ${ctx.nodeName}`);
|
|
25444
25664
|
renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
|
|
25445
25665
|
}
|
|
25446
25666
|
function renderPolyRing(ring, coord, filled, j, ctx) {
|
|
@@ -25566,6 +25786,10 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
25566
25786
|
function applyNodeStyle(obj, n, job) {
|
|
25567
25787
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
25568
25788
|
const colorAttr = nodeAttr(n, n.root, "color");
|
|
25789
|
+
if (!isPointNode(n)) {
|
|
25790
|
+
const shape = n.info.shape;
|
|
25791
|
+
gvrenderSetStyle(checkStyleTokens(styleTokens(styleAttr), shape?.polygon ?? null));
|
|
25792
|
+
}
|
|
25569
25793
|
const penwidth = nodeAttr(n, n.root, "penwidth");
|
|
25570
25794
|
if (n.info.shape?.kind === 2 /* SH_RECORD */) {
|
|
25571
25795
|
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
@@ -25577,7 +25801,7 @@ function applyNodeStyle(obj, n, job) {
|
|
|
25577
25801
|
}
|
|
25578
25802
|
function prepareDrawPoly(poly, filled, obj) {
|
|
25579
25803
|
if (poly.peripheries !== 0 || !filled) return poly;
|
|
25580
|
-
obj.penColor =
|
|
25804
|
+
obj.penColor = resolveRenderColor("transparent");
|
|
25581
25805
|
return { ...poly, peripheries: 1 };
|
|
25582
25806
|
}
|
|
25583
25807
|
function vertexScale(n, poly) {
|
|
@@ -25607,6 +25831,7 @@ function resolveNodeDrawCtx(job, n) {
|
|
|
25607
25831
|
job,
|
|
25608
25832
|
style: styleFlags,
|
|
25609
25833
|
fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
|
|
25834
|
+
nodeName: n.name,
|
|
25610
25835
|
...specialCornerFlags(drawPoly.option, styleFlags)
|
|
25611
25836
|
};
|
|
25612
25837
|
return { poly: drawPoly, coord, filled, ringCtx };
|
|
@@ -25915,7 +26140,7 @@ function findCharset(g) {
|
|
|
25915
26140
|
}
|
|
25916
26141
|
if (p === "big-5" || p === "big5") return CHAR_BIG5;
|
|
25917
26142
|
if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
|
|
25918
|
-
agwarningf(`Unsupported charset "${raw}" - assuming utf-8
|
|
26143
|
+
agwarningf(`Unsupported charset "${raw}" - assuming utf-8`);
|
|
25919
26144
|
return CHAR_UTF8;
|
|
25920
26145
|
}
|
|
25921
26146
|
function maptoken(p, names, vals) {
|
|
@@ -26133,7 +26358,7 @@ function portToTbl(tbl, id) {
|
|
|
26133
26358
|
}
|
|
26134
26359
|
|
|
26135
26360
|
// src/common/compass-port.ts
|
|
26136
|
-
function
|
|
26361
|
+
function isBox2(n) {
|
|
26137
26362
|
return n.info.shape?.polygon === P_BOX;
|
|
26138
26363
|
}
|
|
26139
26364
|
function gdRankdir(n) {
|
|
@@ -26324,7 +26549,7 @@ function compassPort(n, args, pp) {
|
|
|
26324
26549
|
const { bp, compass, sides: sides2 } = args;
|
|
26325
26550
|
const { b, p, defined: defBp } = compassBbox(n, bp);
|
|
26326
26551
|
const dir = compassDirection(compass, b, p, sides2);
|
|
26327
|
-
if (bp === null && !
|
|
26552
|
+
if (bp === null && !isBox2(n)) applyIctxt(n, dir, b, p);
|
|
26328
26553
|
const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
|
|
26329
26554
|
applyDir(pp, bp, dir, gdRankdir(n), defFinal);
|
|
26330
26555
|
return dir.rv;
|
|
@@ -27606,7 +27831,7 @@ function emitParallelEdgePaths(e, job, colorList) {
|
|
|
27606
27831
|
const spl = e.info.spl;
|
|
27607
27832
|
const numc = (colorList.match(/:/g) ?? []).length;
|
|
27608
27833
|
const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
|
|
27609
|
-
const colors =
|
|
27834
|
+
const colors = parseSegsSilent(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR4);
|
|
27610
27835
|
emitColorPasses(segData, colors, job);
|
|
27611
27836
|
return {
|
|
27612
27837
|
headColor: colors[0] ?? DEFAULT_COLOR4,
|
|
@@ -28438,25 +28663,14 @@ function walkNodesAndEdges(g, renderer, job, info) {
|
|
|
28438
28663
|
}
|
|
28439
28664
|
}
|
|
28440
28665
|
|
|
28441
|
-
// src/gvc/
|
|
28442
|
-
|
|
28443
|
-
|
|
28444
|
-
|
|
28445
|
-
|
|
28446
|
-
|
|
28447
|
-
|
|
28448
|
-
|
|
28449
|
-
const ty = job.translation.y;
|
|
28450
|
-
return applyScale(p, tx, ty, sx, sy);
|
|
28451
|
-
}
|
|
28452
|
-
function applyScale(p, tx, ty, sx, sy) {
|
|
28453
|
-
const x = (p.x + tx) * sx;
|
|
28454
|
-
const y = (p.y + ty) * sy;
|
|
28455
|
-
return buildPoint(x, y);
|
|
28456
|
-
}
|
|
28457
|
-
function buildPoint(x, y) {
|
|
28458
|
-
const pt = { x, y };
|
|
28459
|
-
return pt;
|
|
28666
|
+
// src/gvc/first-layer.ts
|
|
28667
|
+
var NATIVE_LANGNAME = /* @__PURE__ */ new Map([
|
|
28668
|
+
["cmapx-np", "cmapx_np"],
|
|
28669
|
+
["imap-np", "imap_np"]
|
|
28670
|
+
]);
|
|
28671
|
+
function warnLayersUnsupported(format, numLayers, doesLayers) {
|
|
28672
|
+
if (numLayers <= 1 || doesLayers) return;
|
|
28673
|
+
agwarningf(`layers not supported in ${NATIVE_LANGNAME.get(format) ?? format} output`);
|
|
28460
28674
|
}
|
|
28461
28675
|
|
|
28462
28676
|
// src/gvc/device-labels.ts
|
|
@@ -28601,6 +28815,7 @@ function setEdgePen(e, job) {
|
|
|
28601
28815
|
obj.pen = resolvePenType(flags);
|
|
28602
28816
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
28603
28817
|
obj.rawStyle = styleTokens(e.attrs.get("style"));
|
|
28818
|
+
if (e.info.spl !== void 0) gvrenderSetStyle(obj.rawStyle);
|
|
28604
28819
|
}
|
|
28605
28820
|
function renderEdge(e, renderer, job) {
|
|
28606
28821
|
emitEdgeComments(e, renderer, job);
|
|
@@ -28616,6 +28831,8 @@ function renderEdge(e, renderer, job) {
|
|
|
28616
28831
|
withColorScheme(e.attrs.get("colorscheme"), () => {
|
|
28617
28832
|
renderer.beginEdge(e, job);
|
|
28618
28833
|
reportEdgeColors(e);
|
|
28834
|
+
const styles = styleTokens(e.attrs.get("style"));
|
|
28835
|
+
for (let i = edgeStyleResets(e, styles); i > 0; i--) gvrenderSetStyle(styles);
|
|
28619
28836
|
reportEdgeLabelColors(e);
|
|
28620
28837
|
renderer.endEdge(e, job);
|
|
28621
28838
|
});
|
|
@@ -28629,6 +28846,10 @@ function renderGraphLabel(g, renderer, job) {
|
|
|
28629
28846
|
}
|
|
28630
28847
|
function renderClusterBox(sg, filled, renderer, job) {
|
|
28631
28848
|
const { ll, ur } = sg.info.bb;
|
|
28849
|
+
if (isStripedCluster(sg)) {
|
|
28850
|
+
renderStripedClusterBox(sg, renderer, job);
|
|
28851
|
+
return;
|
|
28852
|
+
}
|
|
28632
28853
|
if (parseStyleFlags(clusterStyle(sg)).rounded) {
|
|
28633
28854
|
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 }];
|
|
28634
28855
|
emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer, job });
|
|
@@ -28652,7 +28873,7 @@ function renderOneCluster(sg, renderer, job) {
|
|
|
28652
28873
|
resolveObjAnchor(sg, labelTextOf2(sg.info.label), svgClusterId(sg, job), job.obj);
|
|
28653
28874
|
}
|
|
28654
28875
|
const anchored = beginAnchorIf(renderer, job);
|
|
28655
|
-
if ((clusterPeripheries(sg) !== 0 || filled) && job.obj?.pen !== 0 /* None */) {
|
|
28876
|
+
if ((clusterPeripheries(sg) !== 0 || filled || isStripedCluster(sg)) && job.obj?.pen !== 0 /* None */) {
|
|
28656
28877
|
renderClusterBox(sg, filled, renderer, job);
|
|
28657
28878
|
}
|
|
28658
28879
|
renderClusterLabel(sg, renderer, job);
|
|
@@ -28682,6 +28903,7 @@ function renderGraph(g, job, renderer) {
|
|
|
28682
28903
|
job.numLayers = layered ? info.numLayers : 1;
|
|
28683
28904
|
job.layerIDs = info.layerIDs;
|
|
28684
28905
|
renderer.beginGraph(g, job);
|
|
28906
|
+
warnLayersUnsupported(job.format, info.numLayers, renderer.beginLayer !== void 0);
|
|
28685
28907
|
for (let ln = 1; ln <= job.numLayers; ln++) {
|
|
28686
28908
|
job.layerNum = ln;
|
|
28687
28909
|
if (layered) renderer.beginLayer(info.layerIDs[ln], job);
|
|
@@ -30021,7 +30243,7 @@ function fillRankVlist(g, r, root) {
|
|
|
30021
30243
|
rankArr[r].v = rootRank.v;
|
|
30022
30244
|
rankArr[r].vStart = lead.info.order ?? 0;
|
|
30023
30245
|
const maxi = computeMaxi(g, r);
|
|
30024
|
-
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}
|
|
30246
|
+
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`);
|
|
30025
30247
|
rankArr[r].n = maxi + 1;
|
|
30026
30248
|
return 0;
|
|
30027
30249
|
}
|
|
@@ -32840,7 +33062,7 @@ function routeSplinesInternal(pp, polyline) {
|
|
|
32840
33062
|
];
|
|
32841
33063
|
const pl = shortestPath(poly, eps);
|
|
32842
33064
|
if (pl === null) {
|
|
32843
|
-
|
|
33065
|
+
agerrorf("in routesplines, Pshortestpath failed");
|
|
32844
33066
|
return null;
|
|
32845
33067
|
}
|
|
32846
33068
|
emitDump("S3_POLY", dumpNames, () => ({
|
|
@@ -34846,9 +35068,9 @@ function writePortlabelPos(l, pe, pf, angleStr, distanceStr) {
|
|
|
34846
35068
|
const angleDeg = lateDouble(angleStr, PORT_LABEL_ANGLE, -180);
|
|
34847
35069
|
const angle = Math.atan2(pf.y - pe.y, pf.x - pe.x) + RADIANS(angleDeg);
|
|
34848
35070
|
const distMult = lateDouble(distanceStr || void 0, 1, 0);
|
|
34849
|
-
const
|
|
34850
|
-
l.pos.x = pe.x +
|
|
34851
|
-
l.pos.y = pe.y +
|
|
35071
|
+
const dist5 = PORT_LABEL_DISTANCE * distMult;
|
|
35072
|
+
l.pos.x = pe.x + dist5 * Math.cos(angle);
|
|
35073
|
+
l.pos.y = pe.y + dist5 * Math.sin(angle);
|
|
34852
35074
|
l.set = true;
|
|
34853
35075
|
}
|
|
34854
35076
|
function updateBB(g, l) {
|
|
@@ -35250,7 +35472,7 @@ function translateDrawing(g) {
|
|
|
35250
35472
|
if (e.tail !== v) continue;
|
|
35251
35473
|
if (e.info.spl === void 0) {
|
|
35252
35474
|
if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
|
|
35253
|
-
|
|
35475
|
+
agerrorf(`lost ${e.tail.name} ${e.head.name} edge`);
|
|
35254
35476
|
}
|
|
35255
35477
|
continue;
|
|
35256
35478
|
}
|
|
@@ -36013,9 +36235,14 @@ function nodeInsideFn2(box) {
|
|
|
36013
36235
|
function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
|
|
36014
36236
|
const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
|
|
36015
36237
|
const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
|
|
36016
|
-
const
|
|
36238
|
+
const startp = 0;
|
|
36239
|
+
let endp = 0;
|
|
36240
|
+
const arrowTip = step2[endp + 3];
|
|
36017
36241
|
const elen = normalArrowLen(penwidth);
|
|
36018
|
-
|
|
36242
|
+
if (endp > startp && distFused(step2[endp], step2[endp + 3]) < elen) {
|
|
36243
|
+
endp -= 3;
|
|
36244
|
+
}
|
|
36245
|
+
const clipped = arrowEndClip(step2.slice(endp, endp + 4), arrowTip, elen);
|
|
36019
36246
|
const arrowDir = normalizeVec({
|
|
36020
36247
|
x: clipped[3].x - arrowTip.x,
|
|
36021
36248
|
y: clipped[3].y - arrowTip.y
|
|
@@ -38554,8 +38781,7 @@ function ensureDummyNodes(sg, gstart) {
|
|
|
38554
38781
|
}
|
|
38555
38782
|
function orthoEdges(g, useLbls, clipAndInstall2) {
|
|
38556
38783
|
if (useLbls) {
|
|
38557
|
-
|
|
38558
|
-
"warn",
|
|
38784
|
+
agwarningf(
|
|
38559
38785
|
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
|
|
38560
38786
|
);
|
|
38561
38787
|
useLbls = false;
|
|
@@ -38690,7 +38916,7 @@ function dispatchOrthoEdges(g, useLbls) {
|
|
|
38690
38916
|
}
|
|
38691
38917
|
|
|
38692
38918
|
// src/common/arrows-geometry.ts
|
|
38693
|
-
function
|
|
38919
|
+
function dist3(a, b) {
|
|
38694
38920
|
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
38695
38921
|
}
|
|
38696
38922
|
|
|
@@ -38794,7 +39020,7 @@ function getCycleCentroid(g, edge) {
|
|
|
38794
39020
|
}
|
|
38795
39021
|
function bend(spl, centroid) {
|
|
38796
39022
|
const midpt = midPointf(spl[0], spl[3]);
|
|
38797
|
-
const distVal =
|
|
39023
|
+
const distVal = dist3(spl[3], spl[0]);
|
|
38798
39024
|
const r = distVal / 5;
|
|
38799
39025
|
const vX = centroid.x - midpt.x;
|
|
38800
39026
|
const vY = centroid.y - midpt.y;
|
|
@@ -39407,7 +39633,7 @@ function arrowEndClipIdx(state3, endp) {
|
|
|
39407
39633
|
const elen = arrowClipLength(edgeArrowName(e, "head"), edgeArrowsize(e), edgePenwidthAttr(e));
|
|
39408
39634
|
bez.eflag = bez.eflag || 1;
|
|
39409
39635
|
bez.ep = { ...bez.list[endp + 3] };
|
|
39410
|
-
if (endp > state3.starti &&
|
|
39636
|
+
if (endp > state3.starti && distFused(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
|
|
39411
39637
|
const seg2 = [bez.list[endp], bez.list[endp + 1], bez.list[endp + 2], bez.list[endp + 3]];
|
|
39412
39638
|
const clipped = arrowEndClip(seg2, bez.ep, elen);
|
|
39413
39639
|
for (let k = 0; k < 4; k++) bez.list[endp + k] = clipped[k];
|
|
@@ -39418,7 +39644,7 @@ function arrowStartClipIdx(state3, startp, endp) {
|
|
|
39418
39644
|
const slen = arrowClipLength(edgeArrowName(e, "tail"), edgeArrowsize(e), edgePenwidthAttr(e));
|
|
39419
39645
|
bez.sflag = bez.sflag || 1;
|
|
39420
39646
|
bez.sp = { ...bez.list[startp] };
|
|
39421
|
-
if (endp > startp &&
|
|
39647
|
+
if (endp > startp && distFused(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
|
|
39422
39648
|
const seg2 = [bez.list[startp], bez.list[startp + 1], bez.list[startp + 2], bez.list[startp + 3]];
|
|
39423
39649
|
const clipped = tailArrowEndClip(seg2, bez.sp, slen);
|
|
39424
39650
|
for (let k = 0; k < 4; k++) bez.list[startp + k] = clipped[k];
|
|
@@ -40687,120 +40913,522 @@ var DOT_LAYOUT_ENGINE = {
|
|
|
40687
40913
|
};
|
|
40688
40914
|
|
|
40689
40915
|
// src/layout/neato/dijkstra.ts
|
|
40690
|
-
|
|
40691
|
-
|
|
40692
|
-
|
|
40693
|
-
|
|
40694
|
-
|
|
40695
|
-
|
|
40696
|
-
const tmp = heap[parent2];
|
|
40697
|
-
heap[parent2] = heap[pos];
|
|
40698
|
-
heap[pos] = tmp;
|
|
40699
|
-
pos = parent2;
|
|
40700
|
-
}
|
|
40701
|
-
}
|
|
40702
|
-
function heapSiftDown2(heap, dist4) {
|
|
40703
|
-
let pos = 0;
|
|
40916
|
+
var FLT_MAX = 34028234663852886e22;
|
|
40917
|
+
function greaterPriorityF(h, i, j, dist5) {
|
|
40918
|
+
return dist5[h.data[i]] < dist5[h.data[j]];
|
|
40919
|
+
}
|
|
40920
|
+
function heapifyF(h, start, dist5) {
|
|
40921
|
+
let i = start;
|
|
40704
40922
|
for (; ; ) {
|
|
40705
|
-
const l =
|
|
40706
|
-
const r =
|
|
40707
|
-
let
|
|
40708
|
-
if (
|
|
40709
|
-
if (
|
|
40710
|
-
|
|
40711
|
-
|
|
40712
|
-
|
|
40713
|
-
|
|
40714
|
-
|
|
40715
|
-
|
|
40716
|
-
|
|
40717
|
-
|
|
40718
|
-
|
|
40719
|
-
|
|
40720
|
-
|
|
40721
|
-
heap[0] = last;
|
|
40722
|
-
heapSiftDown2(heap, dist4);
|
|
40723
|
-
return top;
|
|
40724
|
-
}
|
|
40725
|
-
function heapBuildExcluding(src, n, dist4) {
|
|
40726
|
-
const heap = [];
|
|
40923
|
+
const l = ngLeft(i);
|
|
40924
|
+
const r = ngRight(i);
|
|
40925
|
+
let largest = ngInsideHeap(h, l) && greaterPriorityF(h, l, i, dist5) ? l : i;
|
|
40926
|
+
if (ngInsideHeap(h, r) && greaterPriorityF(h, r, largest, dist5)) largest = r;
|
|
40927
|
+
if (largest === i) break;
|
|
40928
|
+
ngExchange(h, largest, i);
|
|
40929
|
+
i = largest;
|
|
40930
|
+
}
|
|
40931
|
+
}
|
|
40932
|
+
function initHeapF(startVertex, dist5, n) {
|
|
40933
|
+
const h = {
|
|
40934
|
+
data: new Array(Math.max(n - 1, 0)).fill(0),
|
|
40935
|
+
heapSize: n - 1,
|
|
40936
|
+
index: new Int32Array(n)
|
|
40937
|
+
};
|
|
40938
|
+
let count = 0;
|
|
40727
40939
|
for (let i = 0; i < n; i++) {
|
|
40728
|
-
if (i !==
|
|
40940
|
+
if (i !== startVertex) {
|
|
40941
|
+
h.data[count] = i;
|
|
40942
|
+
h.index[i] = count;
|
|
40943
|
+
count++;
|
|
40944
|
+
}
|
|
40729
40945
|
}
|
|
40730
|
-
|
|
40946
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapifyF(h, j, dist5);
|
|
40947
|
+
return h;
|
|
40948
|
+
}
|
|
40949
|
+
function extractMaxF(h, dist5) {
|
|
40950
|
+
if (h.heapSize === 0) return -1;
|
|
40951
|
+
const max = h.data[0];
|
|
40952
|
+
h.data[0] = h.data[h.heapSize - 1];
|
|
40953
|
+
h.index[h.data[0]] = 0;
|
|
40954
|
+
h.heapSize--;
|
|
40955
|
+
heapifyF(h, 0, dist5);
|
|
40956
|
+
return max;
|
|
40957
|
+
}
|
|
40958
|
+
function increaseKeyF(h, increasedVertex, newDist, dist5) {
|
|
40959
|
+
if (dist5[increasedVertex] <= newDist) return;
|
|
40960
|
+
let i = h.index[increasedVertex];
|
|
40961
|
+
dist5[increasedVertex] = newDist;
|
|
40962
|
+
while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
|
|
40963
|
+
ngAssign(h, i, ngParent(i));
|
|
40964
|
+
i = ngParent(i);
|
|
40965
|
+
}
|
|
40966
|
+
h.data[i] = increasedVertex;
|
|
40967
|
+
h.index[increasedVertex] = i;
|
|
40968
|
+
}
|
|
40969
|
+
function dijkstra(vertex, graph, n, dist5) {
|
|
40970
|
+
for (let i = 0; i < n; i++) dist5[i] = FLT_MAX;
|
|
40971
|
+
dist5[vertex] = 0;
|
|
40972
|
+
const vd = graph[vertex];
|
|
40973
|
+
for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = vd.ewgts[i];
|
|
40974
|
+
const h = initHeapF(vertex, dist5, n);
|
|
40975
|
+
for (let closest = extractMaxF(h, dist5); closest >= 0; closest = extractMaxF(h, dist5)) {
|
|
40976
|
+
const closestDist = dist5[closest];
|
|
40977
|
+
if (closestDist === FLT_MAX) break;
|
|
40978
|
+
const cd = graph[closest];
|
|
40979
|
+
for (let i = 1; i < cd.nedges; i++) {
|
|
40980
|
+
increaseKeyF(h, cd.edges[i], Math.fround(closestDist + Math.fround(cd.ewgts[i])), dist5);
|
|
40981
|
+
}
|
|
40982
|
+
}
|
|
40983
|
+
}
|
|
40984
|
+
var MAX_DIST = 2147483647;
|
|
40985
|
+
function ngLeft(i) {
|
|
40986
|
+
return 2 * i;
|
|
40987
|
+
}
|
|
40988
|
+
function ngRight(i) {
|
|
40989
|
+
return 2 * i + 1;
|
|
40990
|
+
}
|
|
40991
|
+
function ngParent(i) {
|
|
40992
|
+
return Math.trunc(i / 2);
|
|
40993
|
+
}
|
|
40994
|
+
function ngInsideHeap(h, i) {
|
|
40995
|
+
return i < h.heapSize;
|
|
40996
|
+
}
|
|
40997
|
+
function ngGreaterPriority(h, i, j, dist5) {
|
|
40998
|
+
return dist5[h.data[i]] < dist5[h.data[j]];
|
|
40999
|
+
}
|
|
41000
|
+
function ngAssign(h, i, j) {
|
|
41001
|
+
h.data[i] = h.data[j];
|
|
41002
|
+
h.index[h.data[i]] = i;
|
|
40731
41003
|
}
|
|
40732
|
-
function
|
|
40733
|
-
|
|
40734
|
-
|
|
40735
|
-
|
|
40736
|
-
|
|
41004
|
+
function ngExchange(h, i, j) {
|
|
41005
|
+
const t = h.data[i];
|
|
41006
|
+
h.data[i] = h.data[j];
|
|
41007
|
+
h.data[j] = t;
|
|
41008
|
+
h.index[h.data[i]] = i;
|
|
41009
|
+
h.index[h.data[j]] = j;
|
|
40737
41010
|
}
|
|
40738
|
-
function
|
|
40739
|
-
|
|
40740
|
-
for (
|
|
40741
|
-
const
|
|
40742
|
-
const
|
|
40743
|
-
|
|
40744
|
-
|
|
40745
|
-
|
|
41011
|
+
function ngHeapify(h, start, dist5) {
|
|
41012
|
+
let i = start;
|
|
41013
|
+
for (; ; ) {
|
|
41014
|
+
const l = ngLeft(i);
|
|
41015
|
+
const r = ngRight(i);
|
|
41016
|
+
let largest = ngInsideHeap(h, l) && ngGreaterPriority(h, l, i, dist5) ? l : i;
|
|
41017
|
+
if (ngInsideHeap(h, r) && ngGreaterPriority(h, r, largest, dist5)) largest = r;
|
|
41018
|
+
if (largest === i) break;
|
|
41019
|
+
ngExchange(h, largest, i);
|
|
41020
|
+
i = largest;
|
|
41021
|
+
}
|
|
41022
|
+
}
|
|
41023
|
+
function ngInitHeap(startVertex, dist5, n) {
|
|
41024
|
+
const h = {
|
|
41025
|
+
data: new Array(Math.max(n - 1, 0)).fill(0),
|
|
41026
|
+
heapSize: n - 1,
|
|
41027
|
+
index: new Int32Array(n)
|
|
41028
|
+
};
|
|
41029
|
+
let count = 0;
|
|
41030
|
+
for (let i = 0; i < n; i++) {
|
|
41031
|
+
if (i !== startVertex) {
|
|
41032
|
+
h.data[count] = i;
|
|
41033
|
+
h.index[i] = count;
|
|
41034
|
+
count++;
|
|
40746
41035
|
}
|
|
40747
41036
|
}
|
|
41037
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) ngHeapify(h, j, dist5);
|
|
41038
|
+
return h;
|
|
41039
|
+
}
|
|
41040
|
+
function ngExtractMax(h, dist5) {
|
|
41041
|
+
if (h.heapSize === 0) return -1;
|
|
41042
|
+
const max = h.data[0];
|
|
41043
|
+
h.data[0] = h.data[h.heapSize - 1];
|
|
41044
|
+
h.index[h.data[0]] = 0;
|
|
41045
|
+
h.heapSize--;
|
|
41046
|
+
ngHeapify(h, 0, dist5);
|
|
41047
|
+
return max;
|
|
40748
41048
|
}
|
|
40749
|
-
function
|
|
40750
|
-
|
|
40751
|
-
|
|
40752
|
-
|
|
40753
|
-
|
|
40754
|
-
|
|
40755
|
-
|
|
40756
|
-
|
|
41049
|
+
function ngIncreaseKey(h, increasedVertex, newDist, dist5) {
|
|
41050
|
+
if (dist5[increasedVertex] <= newDist) return;
|
|
41051
|
+
let i = h.index[increasedVertex];
|
|
41052
|
+
dist5[increasedVertex] = newDist;
|
|
41053
|
+
while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
|
|
41054
|
+
ngAssign(h, i, ngParent(i));
|
|
41055
|
+
i = ngParent(i);
|
|
41056
|
+
}
|
|
41057
|
+
h.data[i] = increasedVertex;
|
|
41058
|
+
h.index[increasedVertex] = i;
|
|
41059
|
+
}
|
|
41060
|
+
function toDistType(w) {
|
|
41061
|
+
return Math.trunc(Math.fround(w));
|
|
41062
|
+
}
|
|
41063
|
+
function ngdijkstra(vertex, graph, n, dist5) {
|
|
41064
|
+
let prevClosestDist = MAX_DIST;
|
|
41065
|
+
for (let i = 0; i < n; i++) dist5[i] = MAX_DIST;
|
|
41066
|
+
dist5[vertex] = 0;
|
|
41067
|
+
const vd = graph[vertex];
|
|
41068
|
+
for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = toDistType(vd.ewgts[i]);
|
|
41069
|
+
const h = ngInitHeap(vertex, dist5, n);
|
|
41070
|
+
for (let closest = ngExtractMax(h, dist5); closest >= 0; closest = ngExtractMax(h, dist5)) {
|
|
41071
|
+
const closestDist = dist5[closest];
|
|
41072
|
+
if (closestDist === MAX_DIST) break;
|
|
41073
|
+
const cd = graph[closest];
|
|
41074
|
+
for (let i = 1; i < cd.nedges; i++) {
|
|
41075
|
+
ngIncreaseKey(h, cd.edges[i], closestDist + toDistType(cd.ewgts[i]) | 0, dist5);
|
|
41076
|
+
}
|
|
41077
|
+
prevClosestDist = closestDist;
|
|
41078
|
+
}
|
|
41079
|
+
for (let i = 0; i < n; i++) {
|
|
41080
|
+
if (dist5[i] === MAX_DIST) {
|
|
41081
|
+
dist5[i] = MAX_DIST - prevClosestDist < 10 ? MAX_DIST : prevClosestDist + 10;
|
|
41082
|
+
}
|
|
40757
41083
|
}
|
|
40758
41084
|
}
|
|
40759
41085
|
|
|
40760
41086
|
// src/layout/neato/bfs.ts
|
|
40761
|
-
function bfsInit(src, n,
|
|
40762
|
-
for (let i = 0; i < n; i++)
|
|
40763
|
-
|
|
41087
|
+
function bfsInit(src, n, dist5) {
|
|
41088
|
+
for (let i = 0; i < n; i++) dist5[i] = -1;
|
|
41089
|
+
dist5[src] = 0;
|
|
40764
41090
|
return [src];
|
|
40765
41091
|
}
|
|
40766
|
-
function bfsFixDisconnected(n,
|
|
41092
|
+
function bfsFixDisconnected(n, dist5, closestDist) {
|
|
40767
41093
|
for (let i = 0; i < n; i++) {
|
|
40768
|
-
if (
|
|
41094
|
+
if (dist5[i] < 0) dist5[i] = closestDist + 10;
|
|
40769
41095
|
}
|
|
40770
41096
|
}
|
|
40771
|
-
function bfsVisitNeighbors(vertex, graph,
|
|
41097
|
+
function bfsVisitNeighbors(vertex, graph, dist5, queue) {
|
|
40772
41098
|
const vd = graph[vertex];
|
|
40773
|
-
const d =
|
|
41099
|
+
const d = dist5[vertex];
|
|
40774
41100
|
const unit = graph[0].ewgts.length === 0;
|
|
40775
41101
|
for (let i = 1; i < vd.nedges; i++) {
|
|
40776
41102
|
const nb = vd.edges[i];
|
|
40777
|
-
if (
|
|
40778
|
-
|
|
41103
|
+
if (dist5[nb] < 0) {
|
|
41104
|
+
dist5[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
|
|
40779
41105
|
queue.push(nb);
|
|
40780
41106
|
}
|
|
40781
41107
|
}
|
|
40782
41108
|
return d;
|
|
40783
41109
|
}
|
|
40784
|
-
function bfs(src, graph, n,
|
|
40785
|
-
const queue = bfsInit(src, n,
|
|
41110
|
+
function bfs(src, graph, n, dist5) {
|
|
41111
|
+
const queue = bfsInit(src, n, dist5);
|
|
40786
41112
|
let closestDist = 0;
|
|
40787
41113
|
let head = 0;
|
|
40788
41114
|
while (head < queue.length) {
|
|
40789
41115
|
const vertex = queue[head++];
|
|
40790
|
-
closestDist = bfsVisitNeighbors(vertex, graph,
|
|
41116
|
+
closestDist = bfsVisitNeighbors(vertex, graph, dist5, queue);
|
|
41117
|
+
}
|
|
41118
|
+
bfsFixDisconnected(n, dist5, closestDist);
|
|
41119
|
+
}
|
|
41120
|
+
function packedIndex(i, j, n) {
|
|
41121
|
+
return i * (2 * n - i - 1) / 2 + j;
|
|
41122
|
+
}
|
|
41123
|
+
function computeWeightedApspPacked(graph, n) {
|
|
41124
|
+
const result = new Float32Array(n * (n + 1) / 2);
|
|
41125
|
+
const di = new Float32Array(n);
|
|
41126
|
+
for (let i = 0; i < n; i++) {
|
|
41127
|
+
dijkstra(i, graph, n, di);
|
|
41128
|
+
for (let j = i; j < n; j++) result[packedIndex(i, j, n)] = di[j];
|
|
40791
41129
|
}
|
|
40792
|
-
|
|
41130
|
+
return result;
|
|
41131
|
+
}
|
|
41132
|
+
|
|
41133
|
+
// src/common/crand.ts
|
|
41134
|
+
var C_RAND_MAX = 2147483647;
|
|
41135
|
+
var UNSEEDED_STATE2 = 1;
|
|
41136
|
+
var state2 = UNSEEDED_STATE2;
|
|
41137
|
+
registerRenderState(() => {
|
|
41138
|
+
state2 = UNSEEDED_STATE2;
|
|
41139
|
+
});
|
|
41140
|
+
function csrand(seed) {
|
|
41141
|
+
state2 = seed;
|
|
41142
|
+
}
|
|
41143
|
+
function crand() {
|
|
41144
|
+
state2 = state2 * 16807 % 2147483647;
|
|
41145
|
+
return state2;
|
|
41146
|
+
}
|
|
41147
|
+
function cdrand() {
|
|
41148
|
+
return crand() / C_RAND_MAX;
|
|
41149
|
+
}
|
|
41150
|
+
function gvRandom(bound) {
|
|
41151
|
+
const discardThreshold = C_RAND_MAX - 2147483648 % bound;
|
|
41152
|
+
let r;
|
|
41153
|
+
do {
|
|
41154
|
+
r = crand();
|
|
41155
|
+
} while (r > discardThreshold);
|
|
41156
|
+
return r % bound;
|
|
41157
|
+
}
|
|
41158
|
+
function gvPermutation(bound) {
|
|
41159
|
+
if (bound <= 0) return [];
|
|
41160
|
+
const p = [];
|
|
41161
|
+
for (let i = 0; i < bound; i++) p.push(i);
|
|
41162
|
+
for (let i = bound - 1; i > 0; --i) {
|
|
41163
|
+
const j = gvRandom(i + 1);
|
|
41164
|
+
const t = p[i];
|
|
41165
|
+
p[i] = p[j];
|
|
41166
|
+
p[j] = t;
|
|
41167
|
+
}
|
|
41168
|
+
return p;
|
|
41169
|
+
}
|
|
41170
|
+
|
|
41171
|
+
// src/layout/neato/matrix-ops.ts
|
|
41172
|
+
var fr = Math.fround;
|
|
41173
|
+
function fma2(a, b, c) {
|
|
41174
|
+
const p = a * b;
|
|
41175
|
+
return Number.isFinite(p) && Number.isFinite(c) ? fma(a, b, c) : p + c;
|
|
41176
|
+
}
|
|
41177
|
+
function orthog1(n, vec) {
|
|
41178
|
+
let sum = 0;
|
|
41179
|
+
for (let i = 0; i < n; i++) sum += vec[i];
|
|
41180
|
+
sum /= n;
|
|
41181
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
|
|
41182
|
+
}
|
|
41183
|
+
function orthog1f(n, vec) {
|
|
41184
|
+
let sum = fr(0);
|
|
41185
|
+
for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
|
|
41186
|
+
sum = fr(sum / n);
|
|
41187
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
|
|
41188
|
+
}
|
|
41189
|
+
function rightMultWithVectorFF(m, n, vector, result) {
|
|
41190
|
+
for (let i = 0; i < n; i++) result[i] = 0;
|
|
41191
|
+
let index = 0;
|
|
41192
|
+
for (let i = 0; i < n; i++) {
|
|
41193
|
+
const vi = vector[i];
|
|
41194
|
+
let res = fr(m[index++] * vi);
|
|
41195
|
+
for (let j = i + 1; j < n; j++, index++) {
|
|
41196
|
+
res = fr(res + fr(m[index] * vector[j]));
|
|
41197
|
+
result[j] = result[j] + fr(m[index] * vi);
|
|
41198
|
+
}
|
|
41199
|
+
result[i] = result[i] + res;
|
|
41200
|
+
}
|
|
41201
|
+
}
|
|
41202
|
+
function vectorsSubtractionF(n, v1, v2, result) {
|
|
41203
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
|
|
41204
|
+
}
|
|
41205
|
+
function vectorsMultAdditionF(n, v1, alpha, v2) {
|
|
41206
|
+
const a = fr(alpha);
|
|
41207
|
+
for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
|
|
41208
|
+
}
|
|
41209
|
+
function vectorsInnerProductF(n, v1, v2) {
|
|
41210
|
+
let result = 0;
|
|
41211
|
+
for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
|
|
41212
|
+
return result;
|
|
41213
|
+
}
|
|
41214
|
+
function copyVectorF(n, src, dst) {
|
|
41215
|
+
for (let i = 0; i < n; i++) dst[i] = src[i];
|
|
41216
|
+
}
|
|
41217
|
+
function maxAbsF(n, vec) {
|
|
41218
|
+
let max = fr(-1e30);
|
|
41219
|
+
for (let i = 0; i < n; i++) {
|
|
41220
|
+
const a = fr(Math.abs(vec[i]));
|
|
41221
|
+
if (a > max) max = a;
|
|
41222
|
+
}
|
|
41223
|
+
return max;
|
|
41224
|
+
}
|
|
41225
|
+
function squareVec(n, vec) {
|
|
41226
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
|
|
41227
|
+
}
|
|
41228
|
+
function invertVec(n, vec) {
|
|
41229
|
+
for (let i = 0; i < n; i++) {
|
|
41230
|
+
if (vec[i] !== 0) vec[i] = 1 / vec[i];
|
|
41231
|
+
}
|
|
41232
|
+
}
|
|
41233
|
+
function sqrtVecF(n, source, target) {
|
|
41234
|
+
for (let i = 0; i < n; i++) {
|
|
41235
|
+
if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
|
|
41236
|
+
}
|
|
41237
|
+
}
|
|
41238
|
+
function invertSqrtVec(n, vec) {
|
|
41239
|
+
for (let i = 0; i < n; i++) {
|
|
41240
|
+
if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
|
|
41241
|
+
}
|
|
41242
|
+
}
|
|
41243
|
+
var BLOCK_NONE = 1;
|
|
41244
|
+
function innerProduct(n, v1, v2, block) {
|
|
41245
|
+
let result = 0;
|
|
41246
|
+
const blocked = block === BLOCK_NONE ? 0 : n - n % block;
|
|
41247
|
+
let i = 0;
|
|
41248
|
+
for (; i < blocked; i++) result += v1[i] * v2[i];
|
|
41249
|
+
for (; i < n; i++) result = fma2(v1[i], v2[i], result);
|
|
41250
|
+
return result;
|
|
41251
|
+
}
|
|
41252
|
+
function scadd(vec1, end, fac, vec2) {
|
|
41253
|
+
for (let i = 0; i <= end; i++) vec1[i] = fma2(fac, vec2[i], vec1[i]);
|
|
41254
|
+
}
|
|
41255
|
+
function norm(vec, end, block) {
|
|
41256
|
+
return Math.sqrt(innerProduct(end + 1, vec, vec, block));
|
|
41257
|
+
}
|
|
41258
|
+
function vectorsScalarMult(n, vector, alpha, result) {
|
|
41259
|
+
for (let i = 0; i < n; i++) result[i] = vector[i] * alpha;
|
|
41260
|
+
}
|
|
41261
|
+
function copyVector(n, source, dest) {
|
|
41262
|
+
for (let i = 0; i < n; i++) dest[i] = source[i];
|
|
41263
|
+
}
|
|
41264
|
+
function vectorsAddition(n, v1, v2, result) {
|
|
41265
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] + v2[i];
|
|
41266
|
+
}
|
|
41267
|
+
function vectorsSubtraction(n, v1, v2, result) {
|
|
41268
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
|
|
41269
|
+
}
|
|
41270
|
+
function maxAbs(n, vector) {
|
|
41271
|
+
let maxVal = -1e50;
|
|
41272
|
+
for (let i = 0; i < n; i++) {
|
|
41273
|
+
const a = Math.abs(vector[i]);
|
|
41274
|
+
if (a > maxVal) maxVal = a;
|
|
41275
|
+
}
|
|
41276
|
+
return maxVal;
|
|
41277
|
+
}
|
|
41278
|
+
function rightMultWithVectorF(matrix, n, vector, result, block) {
|
|
41279
|
+
const blocked = block === BLOCK_NONE ? 0 : n - n % block;
|
|
41280
|
+
for (let i = 0; i < n; i++) {
|
|
41281
|
+
const row = matrix[i];
|
|
41282
|
+
let res = 0;
|
|
41283
|
+
let j = 0;
|
|
41284
|
+
for (; j < blocked; j++) res += row[j] * vector[j];
|
|
41285
|
+
for (; j < n; j++) res = fma2(row[j], vector[j], res);
|
|
41286
|
+
result[i] = res;
|
|
41287
|
+
}
|
|
41288
|
+
}
|
|
41289
|
+
function rightMultWithVector(matrix, n, vector, result) {
|
|
41290
|
+
for (let i = 0; i < n; i++) {
|
|
41291
|
+
let res = 0;
|
|
41292
|
+
const row = matrix[i];
|
|
41293
|
+
for (let j = 0; j < row.nedges; j++) res = fma2(row.ewgts[j], vector[row.edges[j]], res);
|
|
41294
|
+
result[i] = res;
|
|
41295
|
+
}
|
|
41296
|
+
}
|
|
41297
|
+
var RANGE = 500;
|
|
41298
|
+
function initVecOrth1(n, vec) {
|
|
41299
|
+
for (let i = 0; i < n; i++) vec[i] = crand() % RANGE;
|
|
41300
|
+
orthog1(n, vec);
|
|
41301
|
+
}
|
|
41302
|
+
|
|
41303
|
+
// src/layout/neato/conjgrad.ts
|
|
41304
|
+
var BLOCK_INITIAL_RR = 4;
|
|
41305
|
+
var BLOCK_P_AP = 8;
|
|
41306
|
+
function cgNextDirection(n, w, alpha, rR) {
|
|
41307
|
+
vectorsScalarMult(n, w.Ap, alpha, w.Ap);
|
|
41308
|
+
vectorsSubtraction(n, w.r, w.Ap, w.r);
|
|
41309
|
+
const rRNew = innerProduct(n, w.r, w.r, BLOCK_NONE);
|
|
41310
|
+
if (rR === 0) {
|
|
41311
|
+
agerrorf("conjugate_gradient: unexpected length 0 vector\n");
|
|
41312
|
+
return null;
|
|
41313
|
+
}
|
|
41314
|
+
const beta = rRNew / rR;
|
|
41315
|
+
vectorsScalarMult(n, w.p, beta, w.p);
|
|
41316
|
+
vectorsAddition(n, w.r, w.p, w.p);
|
|
41317
|
+
return rRNew;
|
|
41318
|
+
}
|
|
41319
|
+
function cgStart(A3, x, b, n) {
|
|
41320
|
+
const w = {
|
|
41321
|
+
r: new Float64Array(n),
|
|
41322
|
+
p: new Float64Array(n),
|
|
41323
|
+
Ap: new Float64Array(n),
|
|
41324
|
+
alphap: new Float64Array(n)
|
|
41325
|
+
};
|
|
41326
|
+
const Ax = new Float64Array(n);
|
|
41327
|
+
const orthB = Float64Array.from(b.subarray(0, n));
|
|
41328
|
+
orthog1(n, orthB);
|
|
41329
|
+
orthog1(n, x);
|
|
41330
|
+
rightMultWithVector(A3, n, x, Ax);
|
|
41331
|
+
vectorsSubtraction(n, orthB, Ax, w.r);
|
|
41332
|
+
w.p.set(w.r.subarray(0, n));
|
|
41333
|
+
return w;
|
|
41334
|
+
}
|
|
41335
|
+
function conjugateGradient(A3, x, b, n, tol, maxIterations) {
|
|
41336
|
+
const w = cgStart(A3, x, b, n);
|
|
41337
|
+
let rR = innerProduct(n, w.r, w.r, BLOCK_INITIAL_RR);
|
|
41338
|
+
for (let i = 0; i < maxIterations && maxAbs(n, w.r) > tol; i++) {
|
|
41339
|
+
rightMultWithVector(A3, n, w.p, w.Ap);
|
|
41340
|
+
const pAp = innerProduct(n, w.p, w.Ap, BLOCK_P_AP);
|
|
41341
|
+
if (pAp === 0) break;
|
|
41342
|
+
const alpha = rR / pAp;
|
|
41343
|
+
vectorsScalarMult(n, w.p, alpha, w.alphap);
|
|
41344
|
+
vectorsAddition(n, x, w.alphap, x);
|
|
41345
|
+
if (i < maxIterations - 1) {
|
|
41346
|
+
const next = cgNextDirection(n, w, alpha, rR);
|
|
41347
|
+
if (next === null) return 1;
|
|
41348
|
+
rR = next;
|
|
41349
|
+
}
|
|
41350
|
+
}
|
|
41351
|
+
return 0;
|
|
41352
|
+
}
|
|
41353
|
+
var CGF_BLOCK_AX = 4;
|
|
41354
|
+
var CGF_BLOCK_AP = 4;
|
|
41355
|
+
var CGF_BLOCK_INITIAL_RR = 4;
|
|
41356
|
+
var CGF_BLOCK_P_AP = 8;
|
|
41357
|
+
function cgfInit(A3, x, b, n, ortho1) {
|
|
41358
|
+
const orthB = new Float64Array(n);
|
|
41359
|
+
copyVector(n, b, orthB);
|
|
41360
|
+
if (ortho1) {
|
|
41361
|
+
orthog1(n, orthB);
|
|
41362
|
+
orthog1(n, x);
|
|
41363
|
+
}
|
|
41364
|
+
const Ax = new Float64Array(n);
|
|
41365
|
+
rightMultWithVectorF(A3, n, x, Ax, CGF_BLOCK_AX);
|
|
41366
|
+
const r = new Float64Array(n);
|
|
41367
|
+
vectorsSubtraction(n, orthB, Ax, r);
|
|
41368
|
+
const p = new Float64Array(n);
|
|
41369
|
+
copyVector(n, r, p);
|
|
41370
|
+
return {
|
|
41371
|
+
r,
|
|
41372
|
+
p,
|
|
41373
|
+
Ap: new Float64Array(n),
|
|
41374
|
+
alphap: new Float64Array(n),
|
|
41375
|
+
rr: innerProduct(n, r, r, CGF_BLOCK_INITIAL_RR)
|
|
41376
|
+
};
|
|
41377
|
+
}
|
|
41378
|
+
function cgfUpdate(n, alpha, st) {
|
|
41379
|
+
vectorsScalarMult(n, st.Ap, alpha, st.Ap);
|
|
41380
|
+
vectorsSubtraction(n, st.r, st.Ap, st.r);
|
|
41381
|
+
const rrNew = innerProduct(n, st.r, st.r, BLOCK_NONE);
|
|
41382
|
+
if (st.rr === 0) {
|
|
41383
|
+
agerrorf("conjugate_gradient: unexpected length 0 vector\n");
|
|
41384
|
+
return 1;
|
|
41385
|
+
}
|
|
41386
|
+
const beta = rrNew / st.rr;
|
|
41387
|
+
st.rr = rrNew;
|
|
41388
|
+
vectorsScalarMult(n, st.p, beta, st.p);
|
|
41389
|
+
vectorsAddition(n, st.r, st.p, st.p);
|
|
41390
|
+
return 0;
|
|
41391
|
+
}
|
|
41392
|
+
function conjugateGradientF(A3, x, b, n, opts) {
|
|
41393
|
+
const { tol, maxIterations, ortho1 } = opts;
|
|
41394
|
+
const st = cgfInit(A3, x, b, n, ortho1);
|
|
41395
|
+
for (let i = 0; i < maxIterations && maxAbs(n, st.r) > tol; i++) {
|
|
41396
|
+
rightMultWithVectorF(A3, n, st.p, st.Ap, CGF_BLOCK_AP);
|
|
41397
|
+
const pAp = innerProduct(n, st.p, st.Ap, CGF_BLOCK_P_AP);
|
|
41398
|
+
if (pAp === 0) break;
|
|
41399
|
+
const alpha = st.rr / pAp;
|
|
41400
|
+
vectorsScalarMult(n, st.p, alpha, st.alphap);
|
|
41401
|
+
vectorsAddition(n, x, st.alphap, x);
|
|
41402
|
+
if (i < maxIterations - 1 && cgfUpdate(n, alpha, st) === 1) return 1;
|
|
41403
|
+
}
|
|
41404
|
+
return 0;
|
|
40793
41405
|
}
|
|
40794
41406
|
|
|
40795
41407
|
// src/layout/neato/stress.ts
|
|
41408
|
+
var TOLERANCE_CG = 1e-3;
|
|
40796
41409
|
var DFLT_ITERATIONS = 200;
|
|
41410
|
+
var OPT_SMART_INIT = 4;
|
|
41411
|
+
function mdsModel(graph, nG) {
|
|
41412
|
+
if (graph[0].ewgts.length === 0) return null;
|
|
41413
|
+
const Dij = computeWeightedApspPacked(graph, nG);
|
|
41414
|
+
let shift = 0;
|
|
41415
|
+
for (let i = 0; i < nG; i++) {
|
|
41416
|
+
shift += i;
|
|
41417
|
+
for (let e = 1; e < graph[i].nedges; e++) {
|
|
41418
|
+
const j = graph[i].edges[e];
|
|
41419
|
+
if (j < i) continue;
|
|
41420
|
+
Dij[i * nG + j - shift] = graph[i].ewgts[e];
|
|
41421
|
+
}
|
|
41422
|
+
}
|
|
41423
|
+
return Dij;
|
|
41424
|
+
}
|
|
40797
41425
|
|
|
40798
41426
|
// src/layout/neato/sgd-dijkstra.ts
|
|
40799
|
-
var
|
|
41427
|
+
var FLT_MAX2 = 34028234663852886e22;
|
|
40800
41428
|
var left = (i) => 2 * i;
|
|
40801
41429
|
var right = (i) => 2 * i + 1;
|
|
40802
41430
|
var parent = (i) => Math.trunc(i / 2);
|
|
40803
|
-
var greaterPriority = (h, i, j,
|
|
41431
|
+
var greaterPriority = (h, i, j, dist5) => dist5[h.data[i]] < dist5[h.data[j]];
|
|
40804
41432
|
function exchange2(h, i, j) {
|
|
40805
41433
|
const t = h.data[i];
|
|
40806
41434
|
h.data[i] = h.data[j];
|
|
@@ -40808,19 +41436,19 @@ function exchange2(h, i, j) {
|
|
|
40808
41436
|
h.index[h.data[i]] = i;
|
|
40809
41437
|
h.index[h.data[j]] = j;
|
|
40810
41438
|
}
|
|
40811
|
-
function heapify(h, start,
|
|
41439
|
+
function heapify(h, start, dist5) {
|
|
40812
41440
|
let i = start;
|
|
40813
41441
|
for (; ; ) {
|
|
40814
41442
|
const l = left(i);
|
|
40815
41443
|
const r = right(i);
|
|
40816
|
-
let largest = l < h.heapSize && greaterPriority(h, l, i,
|
|
40817
|
-
if (r < h.heapSize && greaterPriority(h, r, largest,
|
|
41444
|
+
let largest = l < h.heapSize && greaterPriority(h, l, i, dist5) ? l : i;
|
|
41445
|
+
if (r < h.heapSize && greaterPriority(h, r, largest, dist5)) largest = r;
|
|
40818
41446
|
if (largest === i) break;
|
|
40819
41447
|
exchange2(h, largest, i);
|
|
40820
41448
|
i = largest;
|
|
40821
41449
|
}
|
|
40822
41450
|
}
|
|
40823
|
-
function initHeap(startVertex,
|
|
41451
|
+
function initHeap(startVertex, dist5, n) {
|
|
40824
41452
|
const h = {
|
|
40825
41453
|
data: new Int32Array(Math.max(n - 1, 0)),
|
|
40826
41454
|
heapSize: n - 1,
|
|
@@ -40832,23 +41460,23 @@ function initHeap(startVertex, dist4, n) {
|
|
|
40832
41460
|
h.data[count] = i;
|
|
40833
41461
|
h.index[i] = count++;
|
|
40834
41462
|
}
|
|
40835
|
-
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j,
|
|
41463
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist5);
|
|
40836
41464
|
return h;
|
|
40837
41465
|
}
|
|
40838
|
-
function extractMax(h,
|
|
41466
|
+
function extractMax(h, dist5) {
|
|
40839
41467
|
if (h.heapSize === 0) return -1;
|
|
40840
41468
|
const max = h.data[0];
|
|
40841
41469
|
h.data[0] = h.data[h.heapSize - 1];
|
|
40842
41470
|
h.index[h.data[0]] = 0;
|
|
40843
41471
|
h.heapSize--;
|
|
40844
|
-
heapify(h, 0,
|
|
41472
|
+
heapify(h, 0, dist5);
|
|
40845
41473
|
return max;
|
|
40846
41474
|
}
|
|
40847
|
-
function increaseKey(h, v, newDist,
|
|
40848
|
-
if (
|
|
40849
|
-
|
|
41475
|
+
function increaseKey(h, v, newDist, dist5) {
|
|
41476
|
+
if (dist5[v] <= newDist) return;
|
|
41477
|
+
dist5[v] = newDist;
|
|
40850
41478
|
let i = h.index[v];
|
|
40851
|
-
while (i > 0 &&
|
|
41479
|
+
while (i > 0 && dist5[h.data[parent(i)]] > newDist) {
|
|
40852
41480
|
h.data[i] = h.data[parent(i)];
|
|
40853
41481
|
h.index[h.data[i]] = i;
|
|
40854
41482
|
i = parent(i);
|
|
@@ -40857,7 +41485,7 @@ function increaseKey(h, v, newDist, dist4) {
|
|
|
40857
41485
|
h.index[v] = i;
|
|
40858
41486
|
}
|
|
40859
41487
|
function dijkstraSgd(graph, source, terms) {
|
|
40860
|
-
const dists = new Float32Array(graph.n).fill(
|
|
41488
|
+
const dists = new Float32Array(graph.n).fill(FLT_MAX2);
|
|
40861
41489
|
dists[source] = 0;
|
|
40862
41490
|
for (let i = graph.sources[source]; i < graph.sources[source + 1]; i++) {
|
|
40863
41491
|
dists[graph.targets[i]] = graph.weights[i];
|
|
@@ -40866,7 +41494,7 @@ function dijkstraSgd(graph, source, terms) {
|
|
|
40866
41494
|
let offset = 0;
|
|
40867
41495
|
for (let closest = extractMax(h, dists); closest >= 0; closest = extractMax(h, dists)) {
|
|
40868
41496
|
const d = dists[closest];
|
|
40869
|
-
if (d ===
|
|
41497
|
+
if (d === FLT_MAX2) break;
|
|
40870
41498
|
if (graph.pinneds[closest] || closest < source) {
|
|
40871
41499
|
terms[offset++] = { i: source, j: closest, d, w: Math.fround(1 / Math.fround(d * d)) };
|
|
40872
41500
|
}
|
|
@@ -40885,7 +41513,7 @@ function lenattr(ep, g) {
|
|
|
40885
41513
|
const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
|
|
40886
41514
|
const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
|
|
40887
41515
|
if (Number.isNaN(len) || len < 0 || len === 0) {
|
|
40888
|
-
|
|
41516
|
+
agwarningf(`bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
|
|
40889
41517
|
return DEFAULT_EDGE_LEN;
|
|
40890
41518
|
}
|
|
40891
41519
|
return len;
|
|
@@ -41049,12 +41677,11 @@ function neatoMode(g) {
|
|
|
41049
41677
|
if (str === void 0 || str === "") return MODE_MAJOR;
|
|
41050
41678
|
const mode = modeByName().get(str);
|
|
41051
41679
|
if (mode !== void 0) return mode;
|
|
41052
|
-
|
|
41680
|
+
agwarningf(`Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
|
|
41053
41681
|
return MODE_MAJOR;
|
|
41054
41682
|
}
|
|
41055
41683
|
function checkMode(g, mode) {
|
|
41056
|
-
const value = g.root.attrs.get("mode") ||
|
|
41057
|
-
if (mode === MODE_HIER) unsupported("mode", value, "hierarchical stress majorization");
|
|
41684
|
+
const value = g.root.attrs.get("mode") || "ipsep";
|
|
41058
41685
|
if (mode === MODE_IPSEP && ipsepHasConstraints(g)) {
|
|
41059
41686
|
unsupported("mode", value, "constrained (ipsep) majorization");
|
|
41060
41687
|
}
|
|
@@ -41407,10 +42034,10 @@ function solve(a, b, c, n) {
|
|
|
41407
42034
|
}
|
|
41408
42035
|
|
|
41409
42036
|
// src/layout/neato/kk-paths.ts
|
|
41410
|
-
function newPathState(n,
|
|
42037
|
+
function newPathState(n, dist5, adj, initialDist2) {
|
|
41411
42038
|
return {
|
|
41412
42039
|
n,
|
|
41413
|
-
dist:
|
|
42040
|
+
dist: dist5,
|
|
41414
42041
|
adj,
|
|
41415
42042
|
initialDist: initialDist2,
|
|
41416
42043
|
heap: new Int32Array(n + 1),
|
|
@@ -41488,10 +42115,10 @@ function s1(s, src) {
|
|
|
41488
42115
|
function shortestPath2(s) {
|
|
41489
42116
|
for (let v = 0; v < s.n; v++) s1(s, v);
|
|
41490
42117
|
}
|
|
41491
|
-
function
|
|
42118
|
+
function mdsModel2(dist5, n, edges) {
|
|
41492
42119
|
for (const { tailSeq: i, headSeq: j, len } of edges) {
|
|
41493
42120
|
if (i === j) continue;
|
|
41494
|
-
for (const k of [i * n + j, j * n + i]) if (k <
|
|
42121
|
+
for (const k of [i * n + j, j * n + i]) if (k < dist5.length) dist5[k] = len;
|
|
41495
42122
|
}
|
|
41496
42123
|
}
|
|
41497
42124
|
|
|
@@ -41584,12 +42211,12 @@ function initialPositions2(g, st) {
|
|
|
41584
42211
|
}
|
|
41585
42212
|
}
|
|
41586
42213
|
function distvec(p0, p1, del) {
|
|
41587
|
-
let
|
|
42214
|
+
let dist5 = 0;
|
|
41588
42215
|
for (let k = 0; k < NDIM; k++) {
|
|
41589
42216
|
del[k] = p0[k] - p1[k];
|
|
41590
|
-
|
|
42217
|
+
dist5 += del[k] * del[k];
|
|
41591
42218
|
}
|
|
41592
|
-
return Math.sqrt(
|
|
42219
|
+
return Math.sqrt(dist5);
|
|
41593
42220
|
}
|
|
41594
42221
|
function springFactors(g) {
|
|
41595
42222
|
const byEnds = /* @__PURE__ */ new Map();
|
|
@@ -41606,9 +42233,9 @@ function fillRow(st, i, del) {
|
|
|
41606
42233
|
const vi = st.nodes[i];
|
|
41607
42234
|
for (let j = 0; j < st.n; j++) {
|
|
41608
42235
|
if (i === j) continue;
|
|
41609
|
-
const
|
|
42236
|
+
const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
|
|
41610
42237
|
for (let k = 0; k < NDIM; k++) {
|
|
41611
|
-
const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] /
|
|
42238
|
+
const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist5);
|
|
41612
42239
|
st.t[(i * st.n + j) * NDIM + k] = v;
|
|
41613
42240
|
st.sumT[i * NDIM + k] += v;
|
|
41614
42241
|
}
|
|
@@ -41637,9 +42264,9 @@ function updateArrays(st, i) {
|
|
|
41637
42264
|
for (let k = 0; k < NDIM; k++) st.sumT[i * NDIM + k] = 0;
|
|
41638
42265
|
for (let j = 0; j < n; j++) {
|
|
41639
42266
|
if (i === j) continue;
|
|
41640
|
-
const
|
|
42267
|
+
const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
|
|
41641
42268
|
for (let k = 0; k < NDIM; k++) {
|
|
41642
|
-
const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] /
|
|
42269
|
+
const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist5);
|
|
41643
42270
|
st.t[(i * n + j) * NDIM + k] = tij;
|
|
41644
42271
|
st.sumT[i * NDIM + k] += tij;
|
|
41645
42272
|
const old = st.t[(j * n + i) * NDIM + k];
|
|
@@ -41706,7 +42333,7 @@ function moveNode(st, m) {
|
|
|
41706
42333
|
function solveModel(g, st) {
|
|
41707
42334
|
for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
|
|
41708
42335
|
if (st.move === st.maxIter) {
|
|
41709
|
-
|
|
42336
|
+
agwarningf(`Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
|
|
41710
42337
|
}
|
|
41711
42338
|
}
|
|
41712
42339
|
function mdsEdges(g, nodes, lens) {
|
|
@@ -41719,84 +42346,852 @@ function kkNeato(g, nG, model) {
|
|
|
41719
42346
|
if (nG < 2 || maxIter < 0) return;
|
|
41720
42347
|
const { st, adj, ini, lens } = scanGraphMode(g, maxIter);
|
|
41721
42348
|
shortestPath2(newPathState(st.n, st.dist, adj, ini));
|
|
41722
|
-
if (model === MODEL_MDS2)
|
|
42349
|
+
if (model === MODEL_MDS2) mdsModel2(st.dist, st.n, mdsEdges(g, st.nodes, lens));
|
|
41723
42350
|
initialPositions2(g, st);
|
|
41724
42351
|
diffeqModel(g, st);
|
|
41725
42352
|
solveModel(g, st);
|
|
41726
42353
|
}
|
|
41727
42354
|
|
|
41728
|
-
// src/layout/neato/
|
|
41729
|
-
var
|
|
41730
|
-
|
|
41731
|
-
|
|
41732
|
-
|
|
41733
|
-
|
|
41734
|
-
for (
|
|
42355
|
+
// src/layout/neato/make-graph-data.ts
|
|
42356
|
+
var MODE_IPSEP2 = 3;
|
|
42357
|
+
var EDIST_IN = 1;
|
|
42358
|
+
var EDIST_OUT = -1;
|
|
42359
|
+
var EDIST_NONE = 0;
|
|
42360
|
+
function graphHasLen(g) {
|
|
42361
|
+
for (const e of g.edges) {
|
|
42362
|
+
if (e.attrs.has("len")) return true;
|
|
42363
|
+
}
|
|
42364
|
+
return false;
|
|
41735
42365
|
}
|
|
41736
|
-
|
|
41737
|
-
|
|
41738
|
-
|
|
41739
|
-
|
|
41740
|
-
|
|
42366
|
+
var edistsOf = (v) => v.edists;
|
|
42367
|
+
function reverseBackEdge(graph, i, e, mode) {
|
|
42368
|
+
const node = graph[i];
|
|
42369
|
+
const j = node.edges[e];
|
|
42370
|
+
edistsOf(node)[e] = mode === MODE_IPSEP2 ? EDIST_OUT : EDIST_IN;
|
|
42371
|
+
const target = graph[j];
|
|
42372
|
+
let f = 1;
|
|
42373
|
+
while (f < target.nedges && target.edges[f] !== i) f++;
|
|
42374
|
+
if (f >= target.nedges) throw new Error(`neato: edge ${i}-${j} has no reverse entry`);
|
|
42375
|
+
edistsOf(target)[f] = EDIST_OUT;
|
|
42376
|
+
}
|
|
42377
|
+
function dfsCycle(graph, start, st) {
|
|
42378
|
+
const { mode, mark, onstack } = st;
|
|
42379
|
+
const stack = [{ i: start, e: 1 }];
|
|
42380
|
+
mark[start] = 1;
|
|
42381
|
+
onstack[start] = 1;
|
|
42382
|
+
for (let frame = stack.at(-1); frame !== void 0; frame = stack.at(-1)) {
|
|
42383
|
+
const { i } = frame;
|
|
42384
|
+
const node = graph[i];
|
|
42385
|
+
if (frame.e >= node.nedges) {
|
|
42386
|
+
onstack[i] = 0;
|
|
42387
|
+
stack.pop();
|
|
42388
|
+
continue;
|
|
42389
|
+
}
|
|
42390
|
+
const e = frame.e++;
|
|
42391
|
+
if (edistsOf(node)[e] === EDIST_IN) continue;
|
|
42392
|
+
const j = node.edges[e];
|
|
42393
|
+
if (onstack[j]) {
|
|
42394
|
+
reverseBackEdge(graph, i, e, mode);
|
|
42395
|
+
} else if (!mark[j]) {
|
|
42396
|
+
mark[j] = 1;
|
|
42397
|
+
onstack[j] = 1;
|
|
42398
|
+
stack.push({ i: j, e: 1 });
|
|
42399
|
+
}
|
|
42400
|
+
}
|
|
41741
42401
|
}
|
|
41742
|
-
function
|
|
42402
|
+
function acyclic2(graph, nv, mode) {
|
|
42403
|
+
const st = { mode, mark: new Uint8Array(nv), onstack: new Uint8Array(nv) };
|
|
42404
|
+
for (let i = 0; i < nv; i++) {
|
|
42405
|
+
if (st.mark[i]) continue;
|
|
42406
|
+
dfsCycle(graph, i, st);
|
|
42407
|
+
}
|
|
42408
|
+
}
|
|
42409
|
+
function edgeDist2(dir, np, head) {
|
|
42410
|
+
if (dir !== void 0 && dir.startsWith("none")) return EDIST_NONE;
|
|
42411
|
+
return np === head ? EDIST_IN : EDIST_OUT;
|
|
42412
|
+
}
|
|
42413
|
+
function addNeighbours(g, np, entry, o) {
|
|
42414
|
+
const seen2 = /* @__PURE__ */ new Map();
|
|
42415
|
+
for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
|
|
42416
|
+
if (ep.head === ep.tail) continue;
|
|
42417
|
+
const vp = ep.tail === np ? ep.head : ep.tail;
|
|
42418
|
+
const vid = vp.info.id;
|
|
42419
|
+
const dist5 = o.haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
|
|
42420
|
+
const idx = seen2.get(vid);
|
|
42421
|
+
if (idx !== void 0) {
|
|
42422
|
+
if (o.haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist5);
|
|
42423
|
+
continue;
|
|
42424
|
+
}
|
|
42425
|
+
seen2.set(vid, entry.nedges);
|
|
42426
|
+
entry.edges.push(vid);
|
|
42427
|
+
if (o.haveLen || o.haveDir) entry.ewgts.push(dist5);
|
|
42428
|
+
if (o.haveDir) edistsOf(entry).push(edgeDist2(ep.attrs.get("dir"), np, ep.head));
|
|
42429
|
+
entry.nedges++;
|
|
42430
|
+
}
|
|
42431
|
+
}
|
|
42432
|
+
function makeGraphDataC(g, nodeList, haveLen, haveDir, mode = -1) {
|
|
42433
|
+
const vtx = nodeList.map((_, i) => ({
|
|
42434
|
+
nedges: 1,
|
|
42435
|
+
edges: [i],
|
|
42436
|
+
ewgts: haveLen || haveDir ? [0] : [],
|
|
42437
|
+
...haveDir ? { edists: [0] } : {}
|
|
42438
|
+
}));
|
|
42439
|
+
for (const np of nodeList) addNeighbours(g, np, vtx[np.info.id], { haveLen, haveDir });
|
|
42440
|
+
if (haveDir) acyclic2(vtx, nodeList.length, mode);
|
|
42441
|
+
return vtx;
|
|
42442
|
+
}
|
|
42443
|
+
|
|
42444
|
+
// src/layout/neato/kkutils.ts
|
|
42445
|
+
function compareKeys(a, b) {
|
|
42446
|
+
if (a < b) return -1;
|
|
42447
|
+
if (a > b) return 1;
|
|
42448
|
+
return 0;
|
|
42449
|
+
}
|
|
42450
|
+
function gvSortByPlace(place, ordering, first, count) {
|
|
42451
|
+
const slice = Array.from(ordering.subarray(first, first + count));
|
|
42452
|
+
gvQsort(slice, (x, y) => compareKeys(place[x], place[y]));
|
|
42453
|
+
for (let i = 0; i < count; i++) ordering[first + i] = slice[i];
|
|
42454
|
+
}
|
|
42455
|
+
function quicksortPlace(place, ordering, size) {
|
|
42456
|
+
gvSortByPlace(place, ordering, 0, size);
|
|
42457
|
+
}
|
|
42458
|
+
function quicksortPlacef(place, ordering, first, last) {
|
|
42459
|
+
if (first < last) {
|
|
42460
|
+
gvSortByPlace(place, ordering, first, last - first + 1);
|
|
42461
|
+
}
|
|
42462
|
+
}
|
|
42463
|
+
function computeApspDijkstra(graph, n) {
|
|
42464
|
+
const dij = [];
|
|
42465
|
+
for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
|
|
42466
|
+
for (let i = 0; i < n; i++) ngdijkstra(i, graph, n, dij[i]);
|
|
42467
|
+
return dij;
|
|
42468
|
+
}
|
|
42469
|
+
function computeApspSimple(graph, n) {
|
|
42470
|
+
const dij = [];
|
|
42471
|
+
for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
|
|
42472
|
+
for (let i = 0; i < n; i++) bfs(i, graph, n, dij[i]);
|
|
42473
|
+
return dij;
|
|
42474
|
+
}
|
|
42475
|
+
function computeApsp(graph, n) {
|
|
42476
|
+
return graph[0].ewgts.length > 0 ? computeApspDijkstra(graph, n) : computeApspSimple(graph, n);
|
|
42477
|
+
}
|
|
42478
|
+
|
|
42479
|
+
// src/layout/neato/quad-prog-solve.ts
|
|
42480
|
+
var fr2 = Math.fround;
|
|
42481
|
+
var TOLERANCE = fr2(0.01);
|
|
42482
|
+
var BOUND = 1e9;
|
|
42483
|
+
var BLOCK_EPSILON = 1e-9;
|
|
42484
|
+
var NO_SPLIT = -1;
|
|
42485
|
+
var BITS = new DataView(new ArrayBuffer(8));
|
|
42486
|
+
function oddNeighbour(s, awayFromZero) {
|
|
42487
|
+
BITS.setFloat64(0, s);
|
|
42488
|
+
const hi = BITS.getUint32(0);
|
|
42489
|
+
const lo = BITS.getUint32(4);
|
|
42490
|
+
if (awayFromZero) {
|
|
42491
|
+
BITS.setUint32(4, lo + 1);
|
|
42492
|
+
} else if (lo === 0) {
|
|
42493
|
+
BITS.setUint32(0, hi - 1);
|
|
42494
|
+
BITS.setUint32(4, 4294967295);
|
|
42495
|
+
} else {
|
|
42496
|
+
BITS.setUint32(4, lo - 1);
|
|
42497
|
+
}
|
|
42498
|
+
return BITS.getFloat64(0);
|
|
42499
|
+
}
|
|
42500
|
+
function fmaf(a, b, c) {
|
|
42501
|
+
const p = a * b;
|
|
42502
|
+
const s = p + c;
|
|
42503
|
+
const bv = s - p;
|
|
42504
|
+
const err = p - (s - bv) + (c - bv);
|
|
42505
|
+
if (err === 0 || !Number.isFinite(s)) return fr2(s);
|
|
42506
|
+
BITS.setFloat64(0, s);
|
|
42507
|
+
if ((BITS.getUint32(4) & 1) !== 0) return fr2(s);
|
|
42508
|
+
return fr2(oddNeighbour(s, err > 0 === s > 0));
|
|
42509
|
+
}
|
|
42510
|
+
function blockPlaceNumerator(blockDeg, desPlaceBlock, negLapTimesDesired, toBlockConnectivity, curPlace) {
|
|
42511
|
+
const t = fmaf(blockDeg, desPlaceBlock, negLapTimesDesired);
|
|
42512
|
+
return fmaf(toBlockConnectivity, curPlace, t);
|
|
42513
|
+
}
|
|
42514
|
+
function equals(a, b) {
|
|
42515
|
+
return Math.abs(fr2(a - b)) < TOLERANCE;
|
|
42516
|
+
}
|
|
42517
|
+
function fminf(a, b) {
|
|
42518
|
+
if (Number.isNaN(a)) return b;
|
|
42519
|
+
if (Number.isNaN(b)) return a;
|
|
42520
|
+
return a < b ? a : b;
|
|
42521
|
+
}
|
|
42522
|
+
function fmaxf(a, b) {
|
|
42523
|
+
if (Number.isNaN(a)) return b;
|
|
42524
|
+
if (Number.isNaN(b)) return a;
|
|
42525
|
+
return a > b ? a : b;
|
|
42526
|
+
}
|
|
42527
|
+
function unpackMatrix(packedMat, n) {
|
|
42528
|
+
const flat = new Float32Array(n * n);
|
|
42529
|
+
const mat = new Array(n);
|
|
42530
|
+
for (let i = 0; i < n; i++) mat[i] = flat.subarray(i * n, (i + 1) * n);
|
|
42531
|
+
for (let i = 0, k = 0; i < n; i++) {
|
|
42532
|
+
for (let j = i; j < n; j++, k++) {
|
|
42533
|
+
mat[j][i] = mat[i][j] = packedMat[k];
|
|
42534
|
+
}
|
|
42535
|
+
}
|
|
42536
|
+
return mat;
|
|
42537
|
+
}
|
|
42538
|
+
function ensureMonotonicOrderingWithGaps(place, n, ordering, levels, numLevels, levelsGap) {
|
|
42539
|
+
let lowerBound = fr2(-1e9);
|
|
42540
|
+
let level = -1;
|
|
42541
|
+
let maxInLevel = 0;
|
|
42542
|
+
for (let i = 0; i < n; i++) {
|
|
42543
|
+
if (i >= maxInLevel) {
|
|
42544
|
+
level++;
|
|
42545
|
+
maxInLevel = level === numLevels ? n : levels[level];
|
|
42546
|
+
lowerBound = i > 0 ? fr2(place[ordering[i - 1]] + levelsGap) : fr2(-1e9);
|
|
42547
|
+
quicksortPlacef(place, ordering, i, maxInLevel - 1);
|
|
42548
|
+
}
|
|
42549
|
+
const node = ordering[i];
|
|
42550
|
+
if (place[node] < lowerBound) place[node] = lowerBound;
|
|
42551
|
+
}
|
|
42552
|
+
}
|
|
42553
|
+
function computeNodeLevels(e) {
|
|
42554
|
+
const lev = new Int32Array(e.n);
|
|
42555
|
+
let level = -1;
|
|
42556
|
+
let maxInLevel = 0;
|
|
42557
|
+
for (let i = 0; i < e.n; i++) {
|
|
42558
|
+
if (i >= maxInLevel) {
|
|
42559
|
+
level++;
|
|
42560
|
+
maxInLevel = level === e.numLevels ? e.n : e.levels[level];
|
|
42561
|
+
}
|
|
42562
|
+
lev[e.ordering[i]] = level;
|
|
42563
|
+
}
|
|
42564
|
+
return lev;
|
|
42565
|
+
}
|
|
42566
|
+
function growBlock(c, left2, curPlace) {
|
|
42567
|
+
const { place, lev, levelsGap, e } = c;
|
|
42568
|
+
const gap = e.fArray4;
|
|
42569
|
+
let targetPlace = curPlace;
|
|
42570
|
+
gap[e.ordering[left2]] = 0;
|
|
42571
|
+
let right2;
|
|
42572
|
+
for (right2 = left2 + 1; right2 < e.n; right2++) {
|
|
42573
|
+
if (lev[right2] > lev[right2 - 1]) {
|
|
42574
|
+
targetPlace = fr2(targetPlace + levelsGap);
|
|
42575
|
+
}
|
|
42576
|
+
const node = e.ordering[right2];
|
|
42577
|
+
if (Math.abs(fr2(place[node] - targetPlace)) > BLOCK_EPSILON) break;
|
|
42578
|
+
gap[node] = fr2(place[node] - curPlace);
|
|
42579
|
+
}
|
|
42580
|
+
return right2;
|
|
42581
|
+
}
|
|
42582
|
+
function computeDesiredPlaces(c, left2, right2) {
|
|
42583
|
+
const { e, place, b } = c;
|
|
42584
|
+
for (let i = left2; i < right2; i++) {
|
|
42585
|
+
const node = e.ordering[i];
|
|
42586
|
+
let newPlaceI = -b[node];
|
|
42587
|
+
const lapNode = e.A[node];
|
|
42588
|
+
for (let j = 0; j < e.n; j++) {
|
|
42589
|
+
if (j === node) continue;
|
|
42590
|
+
newPlaceI = fmaf(lapNode[j], place[j], newPlaceI);
|
|
42591
|
+
}
|
|
42592
|
+
e.fArray1[node] = fr2(fr2(newPlaceI / -lapNode[node]) - e.fArray4[node]);
|
|
42593
|
+
}
|
|
42594
|
+
}
|
|
42595
|
+
function collectWhere(c, from, to, test) {
|
|
42596
|
+
for (let j = from; j < to; j++) {
|
|
42597
|
+
const node = c.e.ordering[j];
|
|
42598
|
+
if (test(c.e.fArray1[node])) c.block.push(node);
|
|
42599
|
+
}
|
|
42600
|
+
}
|
|
42601
|
+
function orderBlockByLevels(c, left2, right2, curPlace) {
|
|
42602
|
+
const { e } = c;
|
|
42603
|
+
c.block.length = 0;
|
|
42604
|
+
let firstNextLevel = 0;
|
|
42605
|
+
for (let i = left2; i < right2; i = firstNextLevel) {
|
|
42606
|
+
const level = c.lev[e.ordering[i]];
|
|
42607
|
+
firstNextLevel = level === e.numLevels ? right2 : Math.min(right2, e.levels[level]);
|
|
42608
|
+
collectWhere(c, i, firstNextLevel, (d) => d < curPlace);
|
|
42609
|
+
collectWhere(c, i, firstNextLevel, (d) => d === curPlace);
|
|
42610
|
+
collectWhere(c, i, firstNextLevel, (d) => d > curPlace);
|
|
42611
|
+
}
|
|
42612
|
+
}
|
|
42613
|
+
function computePrefixDesiredPlaces(c, curPlace) {
|
|
42614
|
+
const { e, block } = c;
|
|
42615
|
+
let desPlaceBlock = 0;
|
|
42616
|
+
let blockDeg = 0;
|
|
42617
|
+
for (let i = 0; i < block.length; i++) {
|
|
42618
|
+
const node = block[i];
|
|
42619
|
+
let toBlockConnectivity = 0;
|
|
42620
|
+
const lapNode = e.A[node];
|
|
42621
|
+
for (let j = 0; j < i; j++) {
|
|
42622
|
+
toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
|
|
42623
|
+
}
|
|
42624
|
+
toBlockConnectivity = fr2(toBlockConnectivity * 2);
|
|
42625
|
+
const num2 = blockPlaceNumerator(
|
|
42626
|
+
blockDeg,
|
|
42627
|
+
desPlaceBlock,
|
|
42628
|
+
fr2(-lapNode[node] * e.fArray1[node]),
|
|
42629
|
+
toBlockConnectivity,
|
|
42630
|
+
curPlace
|
|
42631
|
+
);
|
|
42632
|
+
desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
|
|
42633
|
+
e.fArray2[i] = desPlaceBlock;
|
|
42634
|
+
blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
|
|
42635
|
+
}
|
|
42636
|
+
if (e.n >= 0 && block.length === e.n) {
|
|
42637
|
+
e.fArray2[e.n - 1] = curPlace;
|
|
42638
|
+
}
|
|
42639
|
+
}
|
|
42640
|
+
function computeSuffixDesiredPlaces(c, curPlace) {
|
|
42641
|
+
const { e, block } = c;
|
|
42642
|
+
let desPlaceBlock = 0;
|
|
42643
|
+
let blockDeg = 0;
|
|
42644
|
+
for (let i = block.length - 1; i >= 0; i--) {
|
|
42645
|
+
const node = block[i];
|
|
42646
|
+
let toBlockConnectivity = 0;
|
|
42647
|
+
const lapNode = e.A[node];
|
|
42648
|
+
for (let j = i + 1; j < block.length; j++) {
|
|
42649
|
+
toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
|
|
42650
|
+
}
|
|
42651
|
+
toBlockConnectivity = fr2(toBlockConnectivity * 2);
|
|
42652
|
+
const num2 = blockPlaceNumerator(
|
|
42653
|
+
blockDeg,
|
|
42654
|
+
desPlaceBlock,
|
|
42655
|
+
fr2(-lapNode[node] * e.fArray1[node]),
|
|
42656
|
+
toBlockConnectivity,
|
|
42657
|
+
curPlace
|
|
42658
|
+
);
|
|
42659
|
+
desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
|
|
42660
|
+
e.fArray3[i] = desPlaceBlock;
|
|
42661
|
+
blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
|
|
42662
|
+
}
|
|
42663
|
+
if (e.n >= 0 && block.length === e.n) {
|
|
42664
|
+
e.fArray3[0] = curPlace;
|
|
42665
|
+
}
|
|
42666
|
+
}
|
|
42667
|
+
var LIMITED = new Float64Array(2);
|
|
42668
|
+
function limitMoves(prefix, suffix, curPlace) {
|
|
42669
|
+
if (suffix < prefix) {
|
|
42670
|
+
if (suffix < curPlace) {
|
|
42671
|
+
if (prefix > curPlace) prefix = curPlace;
|
|
42672
|
+
suffix = prefix;
|
|
42673
|
+
} else if (prefix > curPlace) {
|
|
42674
|
+
prefix = suffix;
|
|
42675
|
+
}
|
|
42676
|
+
}
|
|
42677
|
+
LIMITED[0] = prefix;
|
|
42678
|
+
LIMITED[1] = suffix;
|
|
42679
|
+
}
|
|
42680
|
+
function findBestSplit(c, curPlace) {
|
|
42681
|
+
const { e, block } = c;
|
|
42682
|
+
let bestI = NO_SPLIT;
|
|
42683
|
+
let maxMovement = 0;
|
|
42684
|
+
for (let i = 0; i < block.length; i++) {
|
|
42685
|
+
const suffixDesPlace = e.fArray3[i];
|
|
42686
|
+
const prefixDesPlace = i > 0 ? e.fArray2[i - 1] : suffixDesPlace;
|
|
42687
|
+
limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
|
|
42688
|
+
const movement = (block.length - i) * Math.abs(fr2(LIMITED[1] - curPlace)) + i * Math.abs(fr2(LIMITED[0] - curPlace));
|
|
42689
|
+
if (movement > maxMovement) {
|
|
42690
|
+
maxMovement = movement;
|
|
42691
|
+
bestI = i;
|
|
42692
|
+
}
|
|
42693
|
+
}
|
|
42694
|
+
return bestI;
|
|
42695
|
+
}
|
|
42696
|
+
function computeUpperBound(c, right2) {
|
|
42697
|
+
const { e, place, lev, levelsGap, block } = c;
|
|
42698
|
+
if (right2 >= e.n) return BOUND;
|
|
42699
|
+
const lastGap = e.fArray4[block[block.length - 1]];
|
|
42700
|
+
const nextPlace = place[e.ordering[right2]];
|
|
42701
|
+
if (lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
|
|
42702
|
+
return fr2(fr2(nextPlace - levelsGap) - lastGap);
|
|
42703
|
+
}
|
|
42704
|
+
return fr2(nextPlace - lastGap);
|
|
42705
|
+
}
|
|
42706
|
+
function nextLowerBound(c, right2) {
|
|
42707
|
+
const { e, place, lev, levelsGap, block } = c;
|
|
42708
|
+
const last = place[block[block.length - 1]];
|
|
42709
|
+
if (right2 < e.n && lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
|
|
42710
|
+
return fr2(last + levelsGap);
|
|
42711
|
+
}
|
|
42712
|
+
return last;
|
|
42713
|
+
}
|
|
42714
|
+
function moveSplitBlock(c, bestI, left2, right2, curPlace) {
|
|
42715
|
+
const { e, place, block } = c;
|
|
42716
|
+
let suffixDesPlace = e.fArray3[bestI];
|
|
42717
|
+
let prefixDesPlace = bestI > 0 ? e.fArray2[bestI - 1] : suffixDesPlace;
|
|
42718
|
+
suffixDesPlace = fminf(suffixDesPlace, computeUpperBound(c, right2));
|
|
42719
|
+
prefixDesPlace = fmaxf(prefixDesPlace, c.lowerBound);
|
|
42720
|
+
limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
|
|
42721
|
+
prefixDesPlace = LIMITED[0];
|
|
42722
|
+
suffixDesPlace = LIMITED[1];
|
|
42723
|
+
for (let i = 0; i < bestI; i++) {
|
|
42724
|
+
place[block[i]] = fr2(prefixDesPlace + e.fArray4[block[i]]);
|
|
42725
|
+
}
|
|
42726
|
+
for (let i = bestI; i < block.length; i++) {
|
|
42727
|
+
place[block[i]] = fr2(suffixDesPlace + e.fArray4[block[i]]);
|
|
42728
|
+
}
|
|
42729
|
+
c.lowerBound = nextLowerBound(c, right2);
|
|
42730
|
+
for (let i = left2; i < right2; i++) e.ordering[i] = block[i - left2];
|
|
42731
|
+
c.converged = c.converged && equals(prefixDesPlace, curPlace) && equals(suffixDesPlace, curPlace);
|
|
42732
|
+
}
|
|
42733
|
+
function processBlock(c, left2) {
|
|
42734
|
+
const curPlace = c.place[c.e.ordering[left2]];
|
|
42735
|
+
const right2 = growBlock(c, left2, curPlace);
|
|
42736
|
+
computeDesiredPlaces(c, left2, right2);
|
|
42737
|
+
orderBlockByLevels(c, left2, right2, curPlace);
|
|
42738
|
+
computePrefixDesiredPlaces(c, curPlace);
|
|
42739
|
+
computeSuffixDesiredPlaces(c, curPlace);
|
|
42740
|
+
const bestI = findBestSplit(c, curPlace);
|
|
42741
|
+
if (bestI !== NO_SPLIT) {
|
|
42742
|
+
moveSplitBlock(c, bestI, left2, right2, curPlace);
|
|
42743
|
+
} else {
|
|
42744
|
+
c.lowerBound = nextLowerBound(c, right2);
|
|
42745
|
+
}
|
|
42746
|
+
return right2;
|
|
42747
|
+
}
|
|
42748
|
+
function constrainedMajorizationNewWithGaps(e, b, coords, curAxis, maxIterations, levelsGap) {
|
|
42749
|
+
const place = coords[curAxis];
|
|
42750
|
+
if (maxIterations <= 0) return;
|
|
42751
|
+
const gap = fr2(levelsGap);
|
|
42752
|
+
ensureMonotonicOrderingWithGaps(place, e.n, e.ordering, e.levels, e.numLevels, gap);
|
|
42753
|
+
const c = {
|
|
42754
|
+
e,
|
|
42755
|
+
place,
|
|
42756
|
+
b,
|
|
42757
|
+
lev: computeNodeLevels(e),
|
|
42758
|
+
levelsGap: gap,
|
|
42759
|
+
block: [],
|
|
42760
|
+
lowerBound: fr2(-BOUND),
|
|
42761
|
+
converged: false
|
|
42762
|
+
};
|
|
42763
|
+
for (let counter = 0; counter < maxIterations && !c.converged; counter++) {
|
|
42764
|
+
c.converged = true;
|
|
42765
|
+
c.lowerBound = fr2(-BOUND);
|
|
42766
|
+
for (let left2 = 0, right2; left2 < e.n; left2 = right2) {
|
|
42767
|
+
right2 = processBlock(c, left2);
|
|
42768
|
+
}
|
|
42769
|
+
orthog1f(e.n, place);
|
|
42770
|
+
}
|
|
42771
|
+
}
|
|
42772
|
+
function initConstrainedMajorization(packedMat, n, ordering, levels, numLevels) {
|
|
42773
|
+
return {
|
|
42774
|
+
A: unpackMatrix(packedMat, n),
|
|
42775
|
+
n,
|
|
42776
|
+
fArray1: new Float32Array(n),
|
|
42777
|
+
fArray2: new Float32Array(n),
|
|
42778
|
+
fArray3: new Float32Array(n),
|
|
42779
|
+
fArray4: new Float32Array(n),
|
|
42780
|
+
ordering,
|
|
42781
|
+
levels,
|
|
42782
|
+
numLevels
|
|
42783
|
+
};
|
|
42784
|
+
}
|
|
42785
|
+
|
|
42786
|
+
// src/layout/neato/conjgrad-mkernel.ts
|
|
42787
|
+
var fr3 = Math.fround;
|
|
42788
|
+
var RIGHT_MULT_BLOCK = 16;
|
|
42789
|
+
var ZERO_LENGTH_MESSAGE = "conjugate_gradient: unexpected length 0 vector\n";
|
|
42790
|
+
function rightMultWithVectorFFFused(m, n, vector, result) {
|
|
41743
42791
|
for (let i = 0; i < n; i++) result[i] = 0;
|
|
41744
42792
|
let index = 0;
|
|
41745
42793
|
for (let i = 0; i < n; i++) {
|
|
41746
42794
|
const vi = vector[i];
|
|
41747
|
-
let res =
|
|
42795
|
+
let res = fmaf(m[index++], vi, 0);
|
|
42796
|
+
const len = n - i - 1;
|
|
42797
|
+
const blockEnd = i + 1 + (len - len % RIGHT_MULT_BLOCK);
|
|
41748
42798
|
for (let j = i + 1; j < n; j++, index++) {
|
|
41749
|
-
|
|
41750
|
-
|
|
42799
|
+
const mij = m[index];
|
|
42800
|
+
res = j < blockEnd ? fr3(res + fr3(mij * vector[j])) : fmaf(mij, vector[j], res);
|
|
42801
|
+
result[j] = fmaf(mij, vi, result[j]);
|
|
41751
42802
|
}
|
|
41752
42803
|
result[i] = result[i] + res;
|
|
41753
42804
|
}
|
|
41754
42805
|
}
|
|
41755
|
-
function
|
|
41756
|
-
for (let i = 0; i < n; i++)
|
|
42806
|
+
function vectorsMultAdditionFused(n, v1, alpha, v2) {
|
|
42807
|
+
for (let i = 0; i < n; i++) v1[i] = fmaf(alpha, v2[i], v1[i]);
|
|
41757
42808
|
}
|
|
41758
|
-
|
|
41759
|
-
|
|
41760
|
-
|
|
42809
|
+
var CgStep = { CONTINUE: 0, STOP: 1, ERROR: 2 };
|
|
42810
|
+
function initialState(A3, x, b, n) {
|
|
42811
|
+
const Ax = new Float32Array(n);
|
|
42812
|
+
const st = { n, r: new Float32Array(n), p: new Float32Array(n), Ap: new Float32Array(n), rR: 0 };
|
|
42813
|
+
orthog1f(n, x);
|
|
42814
|
+
orthog1f(n, b);
|
|
42815
|
+
rightMultWithVectorFFFused(A3, n, x, Ax);
|
|
42816
|
+
orthog1f(n, Ax);
|
|
42817
|
+
vectorsSubtractionF(n, b, Ax, st.r);
|
|
42818
|
+
copyVectorF(n, st.r, st.p);
|
|
42819
|
+
st.rR = vectorsInnerProductF(n, st.r, st.r);
|
|
42820
|
+
return st;
|
|
41761
42821
|
}
|
|
41762
|
-
function
|
|
41763
|
-
|
|
41764
|
-
|
|
41765
|
-
|
|
42822
|
+
function cgIteration(A3, x, st, last) {
|
|
42823
|
+
const { n, r, p, Ap } = st;
|
|
42824
|
+
orthog1f(n, p);
|
|
42825
|
+
orthog1f(n, x);
|
|
42826
|
+
orthog1f(n, r);
|
|
42827
|
+
rightMultWithVectorFFFused(A3, n, p, Ap);
|
|
42828
|
+
orthog1f(n, Ap);
|
|
42829
|
+
const pAp = vectorsInnerProductF(n, p, Ap);
|
|
42830
|
+
if (pAp === 0) return CgStep.STOP;
|
|
42831
|
+
const alpha = st.rR / pAp;
|
|
42832
|
+
vectorsMultAdditionFused(n, x, fr3(alpha), p);
|
|
42833
|
+
if (last) return CgStep.CONTINUE;
|
|
42834
|
+
vectorsMultAdditionFused(n, r, fr3(-alpha), Ap);
|
|
42835
|
+
const rRNew = vectorsInnerProductF(n, r, r);
|
|
42836
|
+
if (st.rR === 0) {
|
|
42837
|
+
agerrorf(ZERO_LENGTH_MESSAGE);
|
|
42838
|
+
return CgStep.ERROR;
|
|
42839
|
+
}
|
|
42840
|
+
const beta = fr3(rRNew / st.rR);
|
|
42841
|
+
st.rR = rRNew;
|
|
42842
|
+
for (let j = 0; j < n; j++) p[j] = fmaf(beta, p[j], r[j]);
|
|
42843
|
+
return CgStep.CONTINUE;
|
|
42844
|
+
}
|
|
42845
|
+
function conjugateGradientMkernelFused(A3, x, b, n, o) {
|
|
42846
|
+
const st = initialState(A3, x, b, n);
|
|
42847
|
+
for (let i = 0; i < o.maxIterations && maxAbsF(n, st.r) > o.tol; i++) {
|
|
42848
|
+
const step = cgIteration(A3, x, st, i >= o.maxIterations - 1);
|
|
42849
|
+
if (step === CgStep.STOP) break;
|
|
42850
|
+
if (step === CgStep.ERROR) return 1;
|
|
42851
|
+
}
|
|
42852
|
+
return 0;
|
|
41766
42853
|
}
|
|
41767
|
-
|
|
41768
|
-
|
|
42854
|
+
|
|
42855
|
+
// src/layout/neato/opt-arrangement.ts
|
|
42856
|
+
var HIERARCHY_CG_TOL = 1e-3;
|
|
42857
|
+
function constructB(graph, n, b) {
|
|
42858
|
+
for (let i = 0; i < n; i++) {
|
|
42859
|
+
if (graph[0].edists == null) continue;
|
|
42860
|
+
let bI = 0;
|
|
42861
|
+
const node = graph[i];
|
|
42862
|
+
for (let j = 1; j < node.nedges; j++) {
|
|
42863
|
+
bI += Math.fround(Math.fround(node.ewgts[j]) * node.edists[j]);
|
|
42864
|
+
}
|
|
42865
|
+
b[i] = bI;
|
|
42866
|
+
}
|
|
41769
42867
|
}
|
|
41770
|
-
function
|
|
41771
|
-
|
|
42868
|
+
function setUniformWeights(graph, n) {
|
|
42869
|
+
const old = [];
|
|
41772
42870
|
for (let i = 0; i < n; i++) {
|
|
41773
|
-
const
|
|
41774
|
-
|
|
42871
|
+
const node = graph[i];
|
|
42872
|
+
old.push(node.ewgts);
|
|
42873
|
+
const weights = new Array(node.nedges).fill(1);
|
|
42874
|
+
weights[0] = -(node.nedges - 1);
|
|
42875
|
+
node.ewgts = weights;
|
|
41775
42876
|
}
|
|
41776
|
-
return
|
|
42877
|
+
return old;
|
|
41777
42878
|
}
|
|
41778
|
-
function
|
|
41779
|
-
|
|
42879
|
+
function computeYCoords(graph, n, yCoords, maxIterations) {
|
|
42880
|
+
let rv = 0;
|
|
42881
|
+
const b = new Float64Array(n);
|
|
42882
|
+
constructB(graph, n, b);
|
|
42883
|
+
initVecOrth1(n, yCoords);
|
|
42884
|
+
const oldEwgts = setUniformWeights(graph, n);
|
|
42885
|
+
if (conjugateGradient(graph, yCoords, b, n, HIERARCHY_CG_TOL, maxIterations) < 0) {
|
|
42886
|
+
rv = 1;
|
|
42887
|
+
}
|
|
42888
|
+
for (let i = 0; i < n; i++) graph[i].ewgts = oldEwgts[i];
|
|
42889
|
+
return rv;
|
|
41780
42890
|
}
|
|
41781
|
-
|
|
42891
|
+
|
|
42892
|
+
// src/layout/neato/compute-hierarchy.ts
|
|
42893
|
+
function countLevels(y, ordering, n, tol) {
|
|
42894
|
+
let numLevels = 0;
|
|
42895
|
+
for (let i = 1; i < n; i++) {
|
|
42896
|
+
if (y[ordering[i]] - y[ordering[i - 1]] > tol) numLevels++;
|
|
42897
|
+
}
|
|
42898
|
+
return numLevels;
|
|
42899
|
+
}
|
|
42900
|
+
function fillLevels(y, ordering, n, tol, numLevels) {
|
|
42901
|
+
if (numLevels === 0) {
|
|
42902
|
+
const levels2 = new Int32Array(1);
|
|
42903
|
+
levels2[0] = n;
|
|
42904
|
+
return levels2;
|
|
42905
|
+
}
|
|
42906
|
+
const levels = new Int32Array(numLevels);
|
|
42907
|
+
let count = 0;
|
|
42908
|
+
for (let i = 1; i < n; i++) {
|
|
42909
|
+
if (y[ordering[i]] - y[ordering[i - 1]] > tol) levels[count++] = i;
|
|
42910
|
+
}
|
|
42911
|
+
return levels;
|
|
42912
|
+
}
|
|
42913
|
+
function computeHierarchy(graph, n, absTol, relTol, given) {
|
|
42914
|
+
let y;
|
|
42915
|
+
if (given) {
|
|
42916
|
+
y = given;
|
|
42917
|
+
} else {
|
|
42918
|
+
y = new Float64Array(n);
|
|
42919
|
+
if (computeYCoords(graph, n, y, n)) return null;
|
|
42920
|
+
}
|
|
42921
|
+
const ordering = new Int32Array(n);
|
|
42922
|
+
for (let i = 0; i < n; i++) ordering[i] = i;
|
|
42923
|
+
quicksortPlace(y, ordering, n);
|
|
42924
|
+
const hierarchySpan = y[ordering[n - 1]] - y[ordering[0]];
|
|
42925
|
+
const relative = relTol * hierarchySpan / (n - 1);
|
|
42926
|
+
const tol = absTol > relative ? absTol : relative;
|
|
42927
|
+
const numLevels = countLevels(y, ordering, n, tol);
|
|
42928
|
+
return { ordering, levels: fillLevels(y, ordering, n, tol, numLevels), numLevels };
|
|
42929
|
+
}
|
|
42930
|
+
|
|
42931
|
+
// src/layout/neato/smart-ini-x.ts
|
|
42932
|
+
var fr4 = Math.fround;
|
|
42933
|
+
var SCALE_FACTOR = 256;
|
|
42934
|
+
var DBL_EPSILON = 2220446049250313e-31;
|
|
42935
|
+
var POWER_LENGTH_FLOOR = 1e-10;
|
|
42936
|
+
var BLOCK_STANDARDIZE_NORM = 4;
|
|
42937
|
+
var BLOCK_MAT_MULT_ROW = 4;
|
|
42938
|
+
var BLOCK_MAT_MULT_ORTHOG = 8;
|
|
42939
|
+
var BLOCK_GUESS_ORTHOG = 8;
|
|
42940
|
+
var BLOCK_GUESS_LEN = BLOCK_NONE;
|
|
42941
|
+
var BLOCK_LOOP_LEN = BLOCK_NONE;
|
|
42942
|
+
var BLOCK_ANGLE = 8;
|
|
42943
|
+
var BLOCK_UNIFORM_SUMS = 4;
|
|
42944
|
+
var BLOCK_AVGS = 4;
|
|
42945
|
+
function standardize(orthog, nvtxs) {
|
|
42946
|
+
let avg = 0;
|
|
42947
|
+
for (let i = 0; i < nvtxs; i++) avg += orthog[i];
|
|
42948
|
+
avg /= nvtxs;
|
|
42949
|
+
for (let i = 0; i < nvtxs; i++) orthog[i] = orthog[i] - avg;
|
|
42950
|
+
const len = norm(orthog, nvtxs - 1, BLOCK_STANDARDIZE_NORM);
|
|
42951
|
+
if (Math.abs(len) < DBL_EPSILON) return;
|
|
42952
|
+
vectorsScalarMult(nvtxs, orthog, 1 / len, orthog);
|
|
42953
|
+
}
|
|
42954
|
+
function matMultVecOrthog(mat, dim, vec, result, orthog) {
|
|
42955
|
+
const blocked = dim - dim % BLOCK_MAT_MULT_ROW;
|
|
42956
|
+
for (let i = 0; i < dim; i++) {
|
|
42957
|
+
const row = mat[i];
|
|
42958
|
+
let sum = 0;
|
|
42959
|
+
let j = 0;
|
|
42960
|
+
for (; j < blocked; j++) sum += row[j] * vec[j];
|
|
42961
|
+
for (; j < dim; j++) sum = fma2(row[j], vec[j], sum);
|
|
42962
|
+
result[i] = sum;
|
|
42963
|
+
}
|
|
42964
|
+
const alpha = -innerProduct(dim, result, orthog, BLOCK_MAT_MULT_ORTHOG);
|
|
42965
|
+
scadd(result, dim - 1, alpha, orthog);
|
|
42966
|
+
}
|
|
42967
|
+
function orthogonalizeAgainstEigs(p, vec, count, block) {
|
|
42968
|
+
for (let j = 0; j < count; j++) {
|
|
42969
|
+
const alpha = -innerProduct(p.n, p.eigs[j], vec, block);
|
|
42970
|
+
scadd(vec, p.n - 1, alpha, p.eigs[j]);
|
|
42971
|
+
}
|
|
42972
|
+
}
|
|
42973
|
+
function chooseStartVector(p, i) {
|
|
42974
|
+
const curr = p.eigs[i];
|
|
42975
|
+
for (; ; ) {
|
|
42976
|
+
for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
|
|
42977
|
+
const alpha = -innerProduct(p.n, p.orthog, curr, BLOCK_GUESS_ORTHOG);
|
|
42978
|
+
scadd(curr, p.n - 1, alpha, p.orthog);
|
|
42979
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
42980
|
+
const len = norm(curr, p.n - 1, BLOCK_GUESS_LEN);
|
|
42981
|
+
if (len < POWER_LENGTH_FLOOR) continue;
|
|
42982
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
42983
|
+
return;
|
|
42984
|
+
}
|
|
42985
|
+
}
|
|
42986
|
+
function iterateEigenvector(p, i, tol, work) {
|
|
42987
|
+
const curr = p.eigs[i];
|
|
42988
|
+
for (; ; ) {
|
|
42989
|
+
copyVector(p.n, curr, work.last);
|
|
42990
|
+
matMultVecOrthog(p.mat, p.n, curr, work.tmp, p.orthog);
|
|
42991
|
+
copyVector(p.n, work.tmp, curr);
|
|
42992
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
42993
|
+
const len = norm(curr, p.n - 1, BLOCK_LOOP_LEN);
|
|
42994
|
+
if (len < POWER_LENGTH_FLOOR) {
|
|
42995
|
+
return { nullSpace: true, eval: 0 };
|
|
42996
|
+
}
|
|
42997
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
42998
|
+
const angle = innerProduct(p.n, curr, work.last, BLOCK_ANGLE);
|
|
42999
|
+
if (!(Math.abs(angle) < tol)) {
|
|
43000
|
+
return { nullSpace: false, eval: angle * len };
|
|
43001
|
+
}
|
|
43002
|
+
}
|
|
43003
|
+
}
|
|
43004
|
+
function fillNullSpaceEigenvectors(p, from, neigs) {
|
|
43005
|
+
for (let i = from; i < neigs; i++) {
|
|
43006
|
+
const curr = p.eigs[i];
|
|
43007
|
+
for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
|
|
43008
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
43009
|
+
const len = norm(curr, p.n - 1, BLOCK_NONE);
|
|
43010
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
43011
|
+
p.evals[i] = 0;
|
|
43012
|
+
}
|
|
43013
|
+
}
|
|
43014
|
+
function sortEigenvectors(p, neigs, tmp) {
|
|
43015
|
+
for (let i = 0; i < neigs - 1; i++) {
|
|
43016
|
+
let largestIndex = i;
|
|
43017
|
+
let largestEval = p.evals[largestIndex];
|
|
43018
|
+
for (let j = i + 1; j < neigs; j++) {
|
|
43019
|
+
if (largestEval < p.evals[j]) {
|
|
43020
|
+
largestIndex = j;
|
|
43021
|
+
largestEval = p.evals[largestIndex];
|
|
43022
|
+
}
|
|
43023
|
+
}
|
|
43024
|
+
if (largestIndex !== i) {
|
|
43025
|
+
copyVector(p.n, p.eigs[i], tmp);
|
|
43026
|
+
copyVector(p.n, p.eigs[largestIndex], p.eigs[i]);
|
|
43027
|
+
copyVector(p.n, tmp, p.eigs[largestIndex]);
|
|
43028
|
+
p.evals[largestIndex] = p.evals[i];
|
|
43029
|
+
p.evals[i] = largestEval;
|
|
43030
|
+
}
|
|
43031
|
+
}
|
|
43032
|
+
}
|
|
43033
|
+
function powerIterationOrthog(p, neigsIn, pIterationThreshold) {
|
|
43034
|
+
const work = { tmp: new Float64Array(p.n), last: new Float64Array(p.n) };
|
|
43035
|
+
const tol = 1 - pIterationThreshold;
|
|
43036
|
+
const neigs = neigsIn >= p.n ? p.n : neigsIn;
|
|
43037
|
+
let i = 0;
|
|
43038
|
+
for (; i < neigs; i++) {
|
|
43039
|
+
chooseStartVector(p, i);
|
|
43040
|
+
const res = iterateEigenvector(p, i, tol, work);
|
|
43041
|
+
if (res.nullSpace) break;
|
|
43042
|
+
p.evals[i] = res.eval;
|
|
43043
|
+
}
|
|
43044
|
+
fillNullSpaceEigenvectors(p, i, neigs);
|
|
43045
|
+
sortEigenvectors(p, neigs, work.tmp);
|
|
43046
|
+
}
|
|
43047
|
+
function computeAvgs(Dij, n) {
|
|
43048
|
+
const rowAvg = new Float32Array(n);
|
|
43049
|
+
let sum = 0;
|
|
43050
|
+
const blocked = n - n % BLOCK_AVGS;
|
|
41782
43051
|
for (let i = 0; i < n; i++) {
|
|
41783
|
-
|
|
43052
|
+
let sumRow = 0;
|
|
43053
|
+
const row = Dij[i];
|
|
43054
|
+
let j = 0;
|
|
43055
|
+
for (; j < blocked; j++) {
|
|
43056
|
+
sum += row[j] * row[j];
|
|
43057
|
+
sumRow += row[j] * row[j];
|
|
43058
|
+
}
|
|
43059
|
+
for (; j < n; j++) {
|
|
43060
|
+
sum = fma2(row[j], row[j], sum);
|
|
43061
|
+
sumRow = fma2(row[j], row[j], sumRow);
|
|
43062
|
+
}
|
|
43063
|
+
rowAvg[i] = fr4(fr4(sumRow) / n);
|
|
41784
43064
|
}
|
|
43065
|
+
return { rowAvg, allAvg: fr4(fr4(sum) / (n * n)) };
|
|
41785
43066
|
}
|
|
41786
|
-
function
|
|
43067
|
+
function computeBij(Dij, n) {
|
|
43068
|
+
const Bij = [];
|
|
43069
|
+
for (let i = 0; i < n; i++) Bij.push(new Float32Array(n));
|
|
43070
|
+
const { rowAvg, allAvg } = computeAvgs(Dij, n);
|
|
41787
43071
|
for (let i = 0; i < n; i++) {
|
|
41788
|
-
|
|
43072
|
+
for (let j = 0; j <= i; j++) {
|
|
43073
|
+
const fD = fr4(Dij[i][j]);
|
|
43074
|
+
const t = fr4(fma2(-fD, fD, rowAvg[i]));
|
|
43075
|
+
Bij[i][j] = fr4(fr4(t + rowAvg[j]) - allAvg);
|
|
43076
|
+
Bij[j][i] = Bij[i][j];
|
|
43077
|
+
}
|
|
43078
|
+
}
|
|
43079
|
+
return Bij;
|
|
43080
|
+
}
|
|
43081
|
+
function cmdsOrthog(n, dim, eigs, tol, input) {
|
|
43082
|
+
const { orthog, Dij } = input;
|
|
43083
|
+
const Bij = computeBij(Dij, n);
|
|
43084
|
+
const evals = new Float64Array(dim);
|
|
43085
|
+
const orthogAux = Float64Array.from(orthog.subarray(0, n));
|
|
43086
|
+
standardize(orthogAux, n);
|
|
43087
|
+
powerIterationOrthog({ mat: Bij, n, eigs, evals, orthog: orthogAux }, dim, tol);
|
|
43088
|
+
for (let i = 0; i < dim; i++) {
|
|
43089
|
+
for (let j = 0; j < n; j++) eigs[i][j] = eigs[i][j] * Math.sqrt(Math.abs(evals[i]));
|
|
41789
43090
|
}
|
|
41790
43091
|
}
|
|
41791
|
-
function
|
|
43092
|
+
function scaleGivenCoords(Dij, n, x) {
|
|
43093
|
+
let sum1 = 0;
|
|
43094
|
+
let sum2 = 0;
|
|
43095
|
+
for (let i = 1; i < n; i++) {
|
|
43096
|
+
const blocked = i - i % BLOCK_UNIFORM_SUMS;
|
|
43097
|
+
for (let j = 0; j < i; j++) {
|
|
43098
|
+
const d = Dij[i][j];
|
|
43099
|
+
const f = Math.abs(x[i] - x[j]);
|
|
43100
|
+
const t1 = 1 / d;
|
|
43101
|
+
const t2 = 1 / Math.imul(d, d) * f;
|
|
43102
|
+
if (j < blocked) {
|
|
43103
|
+
sum1 += t1 * f;
|
|
43104
|
+
sum2 += t2 * f;
|
|
43105
|
+
} else {
|
|
43106
|
+
sum1 = fma2(t1, f, sum1);
|
|
43107
|
+
sum2 = fma2(t2, f, sum2);
|
|
43108
|
+
}
|
|
43109
|
+
}
|
|
43110
|
+
}
|
|
43111
|
+
const uniLength = Math.abs(sum2) === Infinity ? 0 : sum1 / sum2;
|
|
43112
|
+
for (let i = 0; i < n; i++) x[i] = x[i] * uniLength;
|
|
43113
|
+
return uniLength;
|
|
43114
|
+
}
|
|
43115
|
+
function computeLaplacian(Dij, n) {
|
|
43116
|
+
const lap = [];
|
|
41792
43117
|
for (let i = 0; i < n; i++) {
|
|
41793
|
-
|
|
43118
|
+
const row = new Float32Array(n);
|
|
43119
|
+
let degree = fr4(0);
|
|
43120
|
+
for (let j = 0; j < n; j++) {
|
|
43121
|
+
if (j === i) continue;
|
|
43122
|
+
const w = fr4(fr4(-1) / fr4(fr4(Dij[i][j]) * fr4(Dij[i][j])));
|
|
43123
|
+
row[j] = w;
|
|
43124
|
+
degree = fr4(degree - w);
|
|
43125
|
+
}
|
|
43126
|
+
row[i] = degree;
|
|
43127
|
+
lap.push(row);
|
|
43128
|
+
}
|
|
43129
|
+
return lap;
|
|
43130
|
+
}
|
|
43131
|
+
function computeResidualDistances(Dij, n, x) {
|
|
43132
|
+
for (let i = 1; i < n; i++) {
|
|
43133
|
+
const posI = x[i];
|
|
43134
|
+
for (let j = 0; j < i; j++) {
|
|
43135
|
+
const t = posI - x[j];
|
|
43136
|
+
const d = Dij[i][j];
|
|
43137
|
+
const diff = fma2(d, d, -(t * t));
|
|
43138
|
+
const v = diff > 0 ? Math.sqrt(diff) : 0;
|
|
43139
|
+
Dij[i][j] = v;
|
|
43140
|
+
Dij[j][i] = v;
|
|
43141
|
+
}
|
|
43142
|
+
}
|
|
43143
|
+
}
|
|
43144
|
+
function balanceOf(i, n, y, ctx) {
|
|
43145
|
+
const posI = y[i];
|
|
43146
|
+
let b = 0;
|
|
43147
|
+
for (let j = 0; j < n; j++) {
|
|
43148
|
+
if (j === i) continue;
|
|
43149
|
+
const term = fr4(fr4(ctx.Dij[i][j]) * -ctx.lap[i][j]);
|
|
43150
|
+
if (posI >= y[j]) b += term;
|
|
43151
|
+
else b -= term;
|
|
41794
43152
|
}
|
|
43153
|
+
return b;
|
|
43154
|
+
}
|
|
43155
|
+
function solveBalanced(ctx, n, y, balance, convTol) {
|
|
43156
|
+
let converged = false;
|
|
43157
|
+
for (let iterations2 = 0; iterations2 < 200 && !converged; iterations2++) {
|
|
43158
|
+
if (conjugateGradientF(ctx.lap, y, balance, n, { tol: convTol, maxIterations: n, ortho1: true }) < 0) return 1;
|
|
43159
|
+
converged = true;
|
|
43160
|
+
for (let i = 0; i < n; i++) {
|
|
43161
|
+
const b = balanceOf(i, n, y, ctx);
|
|
43162
|
+
if (b !== balance[i] && Math.abs(1 - b / balance[i]) > 1e-5) {
|
|
43163
|
+
converged = false;
|
|
43164
|
+
balance[i] = b;
|
|
43165
|
+
}
|
|
43166
|
+
}
|
|
43167
|
+
}
|
|
43168
|
+
return 0;
|
|
43169
|
+
}
|
|
43170
|
+
function imdsGivenDim(graph, n, givenCoords, newCoords, conjTol) {
|
|
43171
|
+
const x = givenCoords;
|
|
43172
|
+
const y = newCoords;
|
|
43173
|
+
const Dij = computeApsp(graph, n);
|
|
43174
|
+
for (let i = 0; i < n; i++) {
|
|
43175
|
+
for (let j = 0; j < n; j++) Dij[i][j] = Dij[i][j] * SCALE_FACTOR;
|
|
43176
|
+
}
|
|
43177
|
+
const uniLength = scaleGivenCoords(Dij, n, x);
|
|
43178
|
+
cmdsOrthog(n, 1, [y], conjTol, { orthog: x, Dij });
|
|
43179
|
+
const lap = computeLaplacian(Dij, n);
|
|
43180
|
+
computeResidualDistances(Dij, n, x);
|
|
43181
|
+
const ctx = { Dij, lap };
|
|
43182
|
+
const balance = new Float64Array(n);
|
|
43183
|
+
for (let i = 0; i < n; i++) balance[i] = balanceOf(i, n, y, ctx);
|
|
43184
|
+
if (solveBalanced(ctx, n, y, balance, conjTol) === 1) return 1;
|
|
43185
|
+
for (let i = 0; !(Math.abs(uniLength) < DBL_EPSILON) && i < n; i++) {
|
|
43186
|
+
x[i] = x[i] / uniLength;
|
|
43187
|
+
y[i] = y[i] / uniLength;
|
|
43188
|
+
}
|
|
43189
|
+
return 0;
|
|
41795
43190
|
}
|
|
41796
43191
|
|
|
41797
43192
|
// src/layout/neato/stress-kernel.ts
|
|
41798
|
-
var
|
|
41799
|
-
var
|
|
43193
|
+
var fr5 = Math.fround;
|
|
43194
|
+
var TOLERANCE_CG2 = 1e-3;
|
|
41800
43195
|
var OPT_EXP_FLAG = 2;
|
|
41801
43196
|
function computeApspPacked2(graph, n) {
|
|
41802
43197
|
const Dij = new Float32Array(n * (n + 1) / 2);
|
|
@@ -41856,9 +43251,9 @@ function cgStep(st, last) {
|
|
|
41856
43251
|
vectorsMultAdditionF(n, st.r, -alpha, st.Ap);
|
|
41857
43252
|
const rRNew = vectorsInnerProductF(n, st.r, st.r);
|
|
41858
43253
|
if (st.rR === 0) return false;
|
|
41859
|
-
const betaF =
|
|
43254
|
+
const betaF = fr5(rRNew / st.rR);
|
|
41860
43255
|
st.rR = rRNew;
|
|
41861
|
-
for (let j = 0; j < n; j++) st.p[j] =
|
|
43256
|
+
for (let j = 0; j < n; j++) st.p[j] = fr5(betaF * st.p[j]) + st.r[j];
|
|
41862
43257
|
}
|
|
41863
43258
|
return true;
|
|
41864
43259
|
}
|
|
@@ -41920,8 +43315,8 @@ function buildLap1(lap1, lap2, coords, shape) {
|
|
|
41920
43315
|
for (let k = 0; k < dim; k++) {
|
|
41921
43316
|
const ck = coords[k];
|
|
41922
43317
|
for (let x = 0; x < len; x++) {
|
|
41923
|
-
const tmp =
|
|
41924
|
-
distAccumulator[x] = distAccumulator[x] +
|
|
43318
|
+
const tmp = fr5(ck[i] + fr5(-1 * ck[i + 1 + x]));
|
|
43319
|
+
distAccumulator[x] = distAccumulator[x] + fr5(tmp * tmp);
|
|
41925
43320
|
}
|
|
41926
43321
|
}
|
|
41927
43322
|
invertSqrtVec(len, distAccumulator);
|
|
@@ -41933,7 +43328,7 @@ function buildLap1(lap1, lap2, coords, shape) {
|
|
|
41933
43328
|
let degree = 0;
|
|
41934
43329
|
if (exp === 2) {
|
|
41935
43330
|
for (let j = 0; j < len; j++, count++) {
|
|
41936
|
-
const val2 = lap1[count] =
|
|
43331
|
+
const val2 = lap1[count] = fr5(lap1[count] * distAccumulator[j]);
|
|
41937
43332
|
degree += val2;
|
|
41938
43333
|
degrees[i + j + 1] = degrees[i + j + 1] - val2;
|
|
41939
43334
|
}
|
|
@@ -41967,10 +43362,10 @@ function computeStress(st) {
|
|
|
41967
43362
|
}
|
|
41968
43363
|
function solveAxis(st, k, havePinned, nodes) {
|
|
41969
43364
|
if (!havePinned) {
|
|
41970
|
-
return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n,
|
|
43365
|
+
return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG2, st.n);
|
|
41971
43366
|
}
|
|
41972
43367
|
copyVectorF(st.n, st.coords[k], st.tmpCoords);
|
|
41973
|
-
const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n,
|
|
43368
|
+
const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG2, st.n);
|
|
41974
43369
|
if (rc < 0) return rc;
|
|
41975
43370
|
for (let i = 0; i < st.n; i++) {
|
|
41976
43371
|
if (!isFixed(nodes[i])) st.coords[k][i] = st.tmpCoords[i];
|
|
@@ -41986,10 +43381,10 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
|
|
|
41986
43381
|
const coords = [];
|
|
41987
43382
|
for (let i = 0; i < dim; i++) {
|
|
41988
43383
|
const c = new Float32Array(n);
|
|
41989
|
-
for (let j = 0; j < n; j++) c[j] =
|
|
43384
|
+
for (let j = 0; j < n; j++) c[j] = fr5(dCoords[i][j]);
|
|
41990
43385
|
coords.push(c);
|
|
41991
43386
|
}
|
|
41992
|
-
const constantTerm =
|
|
43387
|
+
const constantTerm = fr5(n * (n - 1) / 2);
|
|
41993
43388
|
const lap2 = Dij;
|
|
41994
43389
|
buildLap2(lap2, n, exp);
|
|
41995
43390
|
const lapLength = n * (n + 1) / 2;
|
|
@@ -42024,6 +43419,261 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
|
|
|
42024
43419
|
return iterations;
|
|
42025
43420
|
}
|
|
42026
43421
|
|
|
43422
|
+
// src/layout/neato/constrained-majorization.ts
|
|
43423
|
+
var fr6 = Math.fround;
|
|
43424
|
+
var LOCAL_CONSTR_MAJOR_ITERATIONS = 15;
|
|
43425
|
+
var LEVELS_SEP_TOL = 0.1;
|
|
43426
|
+
var ABS_TOL = 0.01;
|
|
43427
|
+
var SUBSPACE_ITERATIONS = 15;
|
|
43428
|
+
var FLT_MAX3 = 34028234663852886e22;
|
|
43429
|
+
var DBL_MAX = Number.MAX_VALUE;
|
|
43430
|
+
var MIN_LEVELS = 1;
|
|
43431
|
+
var Y_AXIS = 1;
|
|
43432
|
+
function unsupported2(what) {
|
|
43433
|
+
throw new RenderError(`hierarchical stress majorization: ${what} is not supported yet`, "UNSUPPORTED_FEATURE");
|
|
43434
|
+
}
|
|
43435
|
+
function modelDistances(graph, n, model) {
|
|
43436
|
+
if (model === MODEL_SUBSET) unsupported2("the subset distance model");
|
|
43437
|
+
if (model === MODEL_CIRCUIT) unsupported2("the circuit distance model");
|
|
43438
|
+
return model === MODEL_MDS2 ? mdsModel(graph, n) : null;
|
|
43439
|
+
}
|
|
43440
|
+
function unconstrainedMajorization(graph, n, dCoords, nodes, o) {
|
|
43441
|
+
if (o.maxi < 0) return 0;
|
|
43442
|
+
const weighted = (graph[0]?.ewgts.length ?? 0) > 0;
|
|
43443
|
+
const Dij = modelDistances(graph, n, o.model) ?? (weighted ? computeWeightedApspPacked2(graph, n) : computeApspPacked2(graph, n));
|
|
43444
|
+
if ((o.opts & OPT_SMART_INIT) !== 0 && n > 1) unsupported2("the smart initial layout");
|
|
43445
|
+
return stressMajorizationKDMkernel(Dij, n, dCoords, nodes, {
|
|
43446
|
+
dim: o.dim,
|
|
43447
|
+
opts: o.opts,
|
|
43448
|
+
maxi: o.maxi,
|
|
43449
|
+
epsilon: o.epsilon
|
|
43450
|
+
});
|
|
43451
|
+
}
|
|
43452
|
+
function hasDirectionality(graph, n) {
|
|
43453
|
+
if (!graph[0]?.edists) return false;
|
|
43454
|
+
let directionalityExist = false;
|
|
43455
|
+
for (let i = 0; i < n; i++) {
|
|
43456
|
+
const edists = graph[i].edists;
|
|
43457
|
+
for (let j = 1; j < graph[i].nedges; j++) {
|
|
43458
|
+
directionalityExist ||= edists[j] !== 0;
|
|
43459
|
+
}
|
|
43460
|
+
}
|
|
43461
|
+
return directionalityExist;
|
|
43462
|
+
}
|
|
43463
|
+
function separateLevels(y, h, n, levelsGap) {
|
|
43464
|
+
const { ordering, levels, numLevels } = h;
|
|
43465
|
+
let displacement = 0;
|
|
43466
|
+
for (let i = 0; i < numLevels; i++) {
|
|
43467
|
+
const shortfall = levelsGap - (y[ordering[levels[i]]] + displacement - y[ordering[levels[i] - 1]]);
|
|
43468
|
+
displacement += 0 > shortfall ? 0 : shortfall;
|
|
43469
|
+
const stop = i < numLevels - 1 ? levels[i + 1] : n;
|
|
43470
|
+
for (let j = levels[i]; j < stop; j++) y[ordering[j]] += displacement;
|
|
43471
|
+
}
|
|
43472
|
+
}
|
|
43473
|
+
function smartInitLayers(graph, n, dCoords, nodes, o) {
|
|
43474
|
+
const { dim } = o;
|
|
43475
|
+
if (dim > 2) {
|
|
43476
|
+
const sub = { dim: dim - 1, opts: o.opts, model: o.model, maxi: SUBSPACE_ITERATIONS, epsilon: o.epsilon };
|
|
43477
|
+
if (unconstrainedMajorization(graph, n, dCoords.slice(1), nodes, sub) < 0) return -1;
|
|
43478
|
+
dCoords[dim - 1].set(dCoords[1].subarray(0, n));
|
|
43479
|
+
}
|
|
43480
|
+
const x = dCoords[0];
|
|
43481
|
+
const y = dCoords[1];
|
|
43482
|
+
if (computeYCoords(graph, n, y, n)) return -1;
|
|
43483
|
+
const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, y);
|
|
43484
|
+
if (h === null) return -1;
|
|
43485
|
+
if (h.numLevels < MIN_LEVELS) {
|
|
43486
|
+
return unconstrainedMajorization(graph, n, dCoords, nodes, o);
|
|
43487
|
+
}
|
|
43488
|
+
if (o.levelsGap > 0) separateLevels(y, h, n, o.levelsGap);
|
|
43489
|
+
if (dim === 2 && imdsGivenDim(graph, n, y, x, o.epsilon)) return -1;
|
|
43490
|
+
return h;
|
|
43491
|
+
}
|
|
43492
|
+
function plainInitLayers(graph, n, dCoords, nodes, dim) {
|
|
43493
|
+
initLayout(n, dim, dCoords, nodes);
|
|
43494
|
+
const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, null);
|
|
43495
|
+
return h === null ? -1 : h;
|
|
43496
|
+
}
|
|
43497
|
+
function distanceKD(coords, dim, i, j) {
|
|
43498
|
+
let sum = 0;
|
|
43499
|
+
for (let k = 0; k < dim; k++) {
|
|
43500
|
+
const d = coords[k][i] - coords[k][j];
|
|
43501
|
+
sum = fma2(d, d, sum);
|
|
43502
|
+
}
|
|
43503
|
+
return Math.sqrt(sum);
|
|
43504
|
+
}
|
|
43505
|
+
function scaleDownLayout(dCoords, n, dim) {
|
|
43506
|
+
let max = 1;
|
|
43507
|
+
for (let i = 0; i < dim; i++) {
|
|
43508
|
+
for (let j = 0; j < n; j++) {
|
|
43509
|
+
const a = Math.abs(dCoords[i][j]);
|
|
43510
|
+
if (a > max) max = a;
|
|
43511
|
+
}
|
|
43512
|
+
}
|
|
43513
|
+
for (let i = 0; i < dim; i++) {
|
|
43514
|
+
for (let j = 0; j < n; j++) dCoords[i][j] *= 10 / max;
|
|
43515
|
+
}
|
|
43516
|
+
}
|
|
43517
|
+
function scaleDistances(Dij, dCoords, n, dim) {
|
|
43518
|
+
const length = n + Math.trunc(n * (n - 1) / 2);
|
|
43519
|
+
const sum1 = Math.trunc(n * (n - 1) / 2);
|
|
43520
|
+
let sum2 = 0;
|
|
43521
|
+
for (let count = 0, i = 0; i < n - 1; i++) {
|
|
43522
|
+
count++;
|
|
43523
|
+
for (let j = i + 1; j < n; j++, count++) {
|
|
43524
|
+
sum2 += distanceKD(dCoords, dim, i, j) / Dij[count];
|
|
43525
|
+
}
|
|
43526
|
+
}
|
|
43527
|
+
const scaleRatio = fr6(sum2 / sum1);
|
|
43528
|
+
for (let i = 0; i < length; i++) Dij[i] = Dij[i] * scaleRatio;
|
|
43529
|
+
}
|
|
43530
|
+
function centerLayout(dCoords, n, dim) {
|
|
43531
|
+
for (let i = 0; i < dim; i++) orthog1(n, dCoords[i]);
|
|
43532
|
+
const y0 = dCoords[Y_AXIS][0];
|
|
43533
|
+
for (let i = 0; i < n; i++) dCoords[Y_AXIS][i] -= y0;
|
|
43534
|
+
}
|
|
43535
|
+
function negatedDegrees(lap2, n) {
|
|
43536
|
+
const degrees = new Float64Array(n);
|
|
43537
|
+
for (let i = 0, count = 0; i < n - 1; i++) {
|
|
43538
|
+
let degree = 0;
|
|
43539
|
+
count++;
|
|
43540
|
+
for (let j = 1; j < n - i; j++, count++) {
|
|
43541
|
+
const val2 = lap2[count];
|
|
43542
|
+
degree += val2;
|
|
43543
|
+
degrees[i + j] -= val2;
|
|
43544
|
+
}
|
|
43545
|
+
degrees[i] -= degree;
|
|
43546
|
+
}
|
|
43547
|
+
return degrees;
|
|
43548
|
+
}
|
|
43549
|
+
function buildLap22(lap2, n) {
|
|
43550
|
+
const lapLength = n + Math.trunc(n * (n - 1) / 2);
|
|
43551
|
+
squareVec(lapLength, lap2);
|
|
43552
|
+
invertVec(lapLength, lap2);
|
|
43553
|
+
const degrees = negatedDegrees(lap2, n);
|
|
43554
|
+
for (let step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
|
|
43555
|
+
lap2[count] = degrees[i];
|
|
43556
|
+
}
|
|
43557
|
+
}
|
|
43558
|
+
function inverseDistances(st, i, len) {
|
|
43559
|
+
const { coords, tmpCoords, distAccumulator } = st;
|
|
43560
|
+
distAccumulator.fill(0, 0, st.n);
|
|
43561
|
+
for (let k = 0; k < st.dim; k++) {
|
|
43562
|
+
const ck = coords[k];
|
|
43563
|
+
for (let j = 0; j < len; j++) tmpCoords[j] = ck[i] - ck[i + 1 + j];
|
|
43564
|
+
for (let j = 0; j < len; j++) tmpCoords[j] = tmpCoords[j] * tmpCoords[j];
|
|
43565
|
+
for (let j = 0; j < len; j++) distAccumulator[j] = tmpCoords[j] + distAccumulator[j];
|
|
43566
|
+
}
|
|
43567
|
+
invertSqrtVec(len, distAccumulator);
|
|
43568
|
+
for (let j = 0; j < len; j++) {
|
|
43569
|
+
if (distAccumulator[j] >= FLT_MAX3 || distAccumulator[j] < 0) distAccumulator[j] = 0;
|
|
43570
|
+
}
|
|
43571
|
+
}
|
|
43572
|
+
function buildLap12(st) {
|
|
43573
|
+
const { n, lap1, lap2, degrees, distAccumulator } = st;
|
|
43574
|
+
degrees.fill(0);
|
|
43575
|
+
sqrtVecF(n + Math.trunc(n * (n - 1) / 2), lap2, lap1);
|
|
43576
|
+
let count = 0;
|
|
43577
|
+
for (let i = 0; i < n - 1; i++) {
|
|
43578
|
+
const len = n - i - 1;
|
|
43579
|
+
inverseDistances(st, i, len);
|
|
43580
|
+
count++;
|
|
43581
|
+
let degree = 0;
|
|
43582
|
+
for (let j = 0; j < len; j++, count++) {
|
|
43583
|
+
const val2 = fr6(lap1[count] * distAccumulator[j]);
|
|
43584
|
+
lap1[count] = val2;
|
|
43585
|
+
degree += val2;
|
|
43586
|
+
degrees[i + j + 1] -= val2;
|
|
43587
|
+
}
|
|
43588
|
+
degrees[i] -= degree;
|
|
43589
|
+
}
|
|
43590
|
+
for (let step = n, count2 = 0, i = 0; i < n; i++, count2 += step, step--) {
|
|
43591
|
+
lap1[count2] = degrees[i];
|
|
43592
|
+
}
|
|
43593
|
+
}
|
|
43594
|
+
function computeNewStress(st, constantTerm) {
|
|
43595
|
+
const { n, dim, lap1, lap2, coords, b, tmpCoords } = st;
|
|
43596
|
+
for (let k = 0; k < dim; k++) rightMultWithVectorFFFused(lap1, n, coords[k], b[k]);
|
|
43597
|
+
let newStress = 0;
|
|
43598
|
+
for (let k = 0; k < dim; k++) newStress += vectorsInnerProductF(n, coords[k], b[k]);
|
|
43599
|
+
newStress *= 2;
|
|
43600
|
+
newStress += constantTerm;
|
|
43601
|
+
for (let k = 0; k < dim; k++) {
|
|
43602
|
+
rightMultWithVectorFFFused(lap2, n, coords[k], tmpCoords);
|
|
43603
|
+
newStress -= vectorsInnerProductF(n, coords[k], tmpCoords);
|
|
43604
|
+
}
|
|
43605
|
+
return newStress;
|
|
43606
|
+
}
|
|
43607
|
+
function solveAxes(st, ctx) {
|
|
43608
|
+
for (let k = 0; k < st.dim; k++) {
|
|
43609
|
+
if (k === Y_AXIS) {
|
|
43610
|
+
constrainedMajorizationNewWithGaps(
|
|
43611
|
+
ctx.cMajEnv,
|
|
43612
|
+
st.b[k],
|
|
43613
|
+
st.coords,
|
|
43614
|
+
k,
|
|
43615
|
+
LOCAL_CONSTR_MAJOR_ITERATIONS,
|
|
43616
|
+
ctx.levelsGap
|
|
43617
|
+
);
|
|
43618
|
+
} else if (conjugateGradientMkernelFused(st.lap2, st.coords[k], st.b[k], st.n, { tol: TOLERANCE_CG, maxIterations: st.n })) {
|
|
43619
|
+
return true;
|
|
43620
|
+
}
|
|
43621
|
+
}
|
|
43622
|
+
return false;
|
|
43623
|
+
}
|
|
43624
|
+
function majorize(st, ctx, dCoords) {
|
|
43625
|
+
const constantTerm = Math.trunc(st.n * (st.n - 1) / 2);
|
|
43626
|
+
let oldStress = DBL_MAX;
|
|
43627
|
+
let iterations = 0;
|
|
43628
|
+
for (let converged = false; iterations < ctx.maxi && !converged; iterations++) {
|
|
43629
|
+
buildLap12(st);
|
|
43630
|
+
const newStress = computeNewStress(st, constantTerm);
|
|
43631
|
+
converged = Math.abs(newStress - oldStress) / Math.abs(oldStress + 1e-10) < ctx.epsilon;
|
|
43632
|
+
converged ||= iterations > 1 && newStress > oldStress;
|
|
43633
|
+
oldStress = newStress;
|
|
43634
|
+
if (solveAxes(st, ctx)) return -1;
|
|
43635
|
+
}
|
|
43636
|
+
for (let i = 0; i < st.dim; i++) {
|
|
43637
|
+
for (let j = 0; j < st.n; j++) dCoords[i][j] = st.coords[i][j];
|
|
43638
|
+
}
|
|
43639
|
+
return iterations;
|
|
43640
|
+
}
|
|
43641
|
+
function toFloatCoords(dCoords, n, dim) {
|
|
43642
|
+
const coords = [];
|
|
43643
|
+
for (let i = 0; i < dim; i++) coords.push(Float32Array.from(dCoords[i].subarray(0, n)));
|
|
43644
|
+
return coords;
|
|
43645
|
+
}
|
|
43646
|
+
function newLoopState(lap2, coords, n) {
|
|
43647
|
+
const dim = coords.length;
|
|
43648
|
+
return {
|
|
43649
|
+
n,
|
|
43650
|
+
dim,
|
|
43651
|
+
lap2,
|
|
43652
|
+
coords,
|
|
43653
|
+
lap1: new Float32Array(n + Math.trunc(n * (n - 1) / 2)),
|
|
43654
|
+
b: Array.from({ length: dim }, () => new Float32Array(n)),
|
|
43655
|
+
tmpCoords: new Float32Array(n),
|
|
43656
|
+
distAccumulator: new Float32Array(n),
|
|
43657
|
+
degrees: new Float64Array(n)
|
|
43658
|
+
};
|
|
43659
|
+
}
|
|
43660
|
+
function stressMajorizationWithHierarchy(graph, n, dCoords, nodes, o) {
|
|
43661
|
+
if (!hasDirectionality(graph, n)) return unconstrainedMajorization(graph, n, dCoords, nodes, o);
|
|
43662
|
+
const smartIni = (o.opts & OPT_SMART_INIT) !== 0;
|
|
43663
|
+
const layers = smartIni ? smartInitLayers(graph, n, dCoords, nodes, o) : plainInitLayers(graph, n, dCoords, nodes, o.dim);
|
|
43664
|
+
if (typeof layers === "number") return layers;
|
|
43665
|
+
if (n === 1) return 0;
|
|
43666
|
+
if (o.maxi === 0) return 0;
|
|
43667
|
+
const Dij = modelDistances(graph, n, o.model) ?? computeApspPacked2(graph, n);
|
|
43668
|
+
if (!smartIni) scaleDownLayout(dCoords, n, o.dim);
|
|
43669
|
+
if (o.levelsGap > 0) scaleDistances(Dij, dCoords, n, o.dim);
|
|
43670
|
+
centerLayout(dCoords, n, o.dim);
|
|
43671
|
+
const st = newLoopState(Dij, toFloatCoords(dCoords, n, o.dim), n);
|
|
43672
|
+
buildLap22(Dij, n);
|
|
43673
|
+
const cMajEnv = initConstrainedMajorization(Dij, n, layers.ordering, layers.levels, layers.numLevels);
|
|
43674
|
+
return majorize(st, { cMajEnv, levelsGap: o.levelsGap, maxi: o.maxi, epsilon: o.epsilon }, dCoords);
|
|
43675
|
+
}
|
|
43676
|
+
|
|
42027
43677
|
// src/common/utils-inputscale.ts
|
|
42028
43678
|
var POINTS_PER_INCH3 = 72;
|
|
42029
43679
|
function getInputscale(g) {
|
|
@@ -42210,61 +43860,47 @@ function neatoMaxIter(maxiter, mode, n) {
|
|
|
42210
43860
|
if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
|
|
42211
43861
|
return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
|
|
42212
43862
|
}
|
|
42213
|
-
|
|
42214
|
-
|
|
42215
|
-
const
|
|
43863
|
+
var levelsGapOf = (g) => lateDouble(g.root.attrs.get("levelsgap"), 0, -Number.MAX_VALUE);
|
|
43864
|
+
function solveStress(c, vtx, dCoords, nodeList) {
|
|
43865
|
+
const { g, mode, model, haveLen, opts } = c;
|
|
42216
43866
|
const n = nodeList.length;
|
|
42217
|
-
const haveLen = graphHasLen(g);
|
|
42218
|
-
const vtx = makeGraphDataC(g, nodeList, haveLen, mode === MODE_HIER || mode === MODE_IPSEP);
|
|
42219
|
-
checkStart(g);
|
|
42220
43867
|
const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
|
|
42221
43868
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
43869
|
+
if (mode === MODE_HIER) {
|
|
43870
|
+
return stressMajorizationWithHierarchy(vtx, n, dCoords, nodeList, {
|
|
43871
|
+
dim: DFLT_DIM,
|
|
43872
|
+
opts,
|
|
43873
|
+
model,
|
|
43874
|
+
maxi,
|
|
43875
|
+
epsilon,
|
|
43876
|
+
levelsGap: levelsGapOf(g)
|
|
43877
|
+
});
|
|
43878
|
+
}
|
|
42222
43879
|
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
42223
43880
|
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
42224
|
-
|
|
42225
|
-
stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
43881
|
+
return stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
42226
43882
|
dim: DFLT_DIM,
|
|
42227
|
-
opts
|
|
43883
|
+
opts,
|
|
42228
43884
|
maxi,
|
|
42229
43885
|
epsilon
|
|
42230
43886
|
});
|
|
42231
|
-
for (let i = 0; i < n; i++) {
|
|
42232
|
-
nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
|
|
42233
|
-
}
|
|
42234
43887
|
}
|
|
42235
|
-
function
|
|
42236
|
-
|
|
42237
|
-
|
|
43888
|
+
function runMajorization(g, mode, model) {
|
|
43889
|
+
const nodeList = assignNodeIds2(g);
|
|
43890
|
+
const n = nodeList.length;
|
|
43891
|
+
const haveLen = graphHasLen(g);
|
|
43892
|
+
const init = checkStart(g, n, mode === MODE_HIER ? INIT_SELF : INIT_RANDOM);
|
|
43893
|
+
const opts = init === INIT_SELF ? OPT_EXP_FLAG | OPT_SMART_INIT : OPT_EXP_FLAG;
|
|
43894
|
+
const haveDir = mode === MODE_HIER || mode === MODE_IPSEP;
|
|
43895
|
+
const vtx = makeGraphDataC(g, nodeList, haveLen, haveDir, mode);
|
|
43896
|
+
const dCoords = [new Float64Array(n), new Float64Array(n)];
|
|
43897
|
+
if (solveStress({ g, mode, model, haveLen, opts }, vtx, dCoords, nodeList) < 0) {
|
|
43898
|
+
agerr("prev", "layout aborted");
|
|
43899
|
+
return;
|
|
42238
43900
|
}
|
|
42239
|
-
|
|
42240
|
-
|
|
42241
|
-
function makeGraphDataC(g, nodeList, haveLen, haveDir) {
|
|
42242
|
-
const vtx = nodeList.map((_, i) => ({
|
|
42243
|
-
nedges: 1,
|
|
42244
|
-
edges: [i],
|
|
42245
|
-
ewgts: haveLen || haveDir ? [0] : []
|
|
42246
|
-
}));
|
|
42247
|
-
for (const np of nodeList) {
|
|
42248
|
-
const i = np.info.id;
|
|
42249
|
-
const entry = vtx[i];
|
|
42250
|
-
const seen2 = /* @__PURE__ */ new Map();
|
|
42251
|
-
for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
|
|
42252
|
-
if (ep.head === ep.tail) continue;
|
|
42253
|
-
const vp = ep.tail === np ? ep.head : ep.tail;
|
|
42254
|
-
const vid = vp.info.id;
|
|
42255
|
-
const dist4 = haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
|
|
42256
|
-
const idx = seen2.get(vid);
|
|
42257
|
-
if (idx !== void 0) {
|
|
42258
|
-
if (haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist4);
|
|
42259
|
-
continue;
|
|
42260
|
-
}
|
|
42261
|
-
seen2.set(vid, entry.nedges);
|
|
42262
|
-
entry.edges.push(vid);
|
|
42263
|
-
if (haveLen || haveDir) entry.ewgts.push(dist4);
|
|
42264
|
-
entry.nedges++;
|
|
42265
|
-
}
|
|
43901
|
+
for (let i = 0; i < n; i++) {
|
|
43902
|
+
nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
|
|
42266
43903
|
}
|
|
42267
|
-
return vtx;
|
|
42268
43904
|
}
|
|
42269
43905
|
function solveModel2(g, mode, model) {
|
|
42270
43906
|
if (g.nodes.size < 2) return;
|
|
@@ -42456,6 +44092,25 @@ function esepFactor(g) {
|
|
|
42456
44092
|
return { x: SEPFACT * DFLT_MARGIN, y: SEPFACT * DFLT_MARGIN, doAdd: true };
|
|
42457
44093
|
}
|
|
42458
44094
|
|
|
44095
|
+
// src/common/libm-trig.ts
|
|
44096
|
+
var OCTAGON_TRIG = /* @__PURE__ */ new Map([
|
|
44097
|
+
[-0.39269908169872414, [0.9238795325112867, -0.3826834323650898]],
|
|
44098
|
+
[0.39269908169872414, [0.9238795325112867, 0.3826834323650898]],
|
|
44099
|
+
[1.1780972450961724, [0.38268343236508984, 0.9238795325112867]],
|
|
44100
|
+
[1.9634954084936207, [-0.3826834323650897, 0.9238795325112867]],
|
|
44101
|
+
[2.748893571891069, [-0.9238795325112867, 0.3826834323650899]],
|
|
44102
|
+
[3.5342917352885173, [-0.9238795325112868, -0.38268343236508967]],
|
|
44103
|
+
[4.319689898685965, [-0.38268343236509034, -0.9238795325112865]],
|
|
44104
|
+
[5.105088062083414, [0.38268343236509, -0.9238795325112866]],
|
|
44105
|
+
[5.890486225480862, [0.9238795325112865, -0.3826834323650904]]
|
|
44106
|
+
]);
|
|
44107
|
+
function libmCos(x) {
|
|
44108
|
+
return OCTAGON_TRIG.get(x)?.[0] ?? Math.cos(x);
|
|
44109
|
+
}
|
|
44110
|
+
function libmSin(x) {
|
|
44111
|
+
return OCTAGON_TRIG.get(x)?.[1] ?? Math.sin(x);
|
|
44112
|
+
}
|
|
44113
|
+
|
|
42459
44114
|
// src/layout/neato/delaunay.ts
|
|
42460
44115
|
var ICCERRBOUND_A = (10 + 96 * 2 ** -53) * 2 ** -53;
|
|
42461
44116
|
function ulpExp(v) {
|
|
@@ -42624,6 +44279,32 @@ function delaunayTri(xv, yv, n) {
|
|
|
42624
44279
|
return edges;
|
|
42625
44280
|
}
|
|
42626
44281
|
|
|
44282
|
+
// src/layout/neato/gts-triangle.ts
|
|
44283
|
+
var SQRT3 = 1.73205080757;
|
|
44284
|
+
function gtsTriangleEnclosing(px, py, n, scale) {
|
|
44285
|
+
let xmin = px[0];
|
|
44286
|
+
let xmax = px[0];
|
|
44287
|
+
let ymin = py[0];
|
|
44288
|
+
let ymax = py[0];
|
|
44289
|
+
for (let i = 1; i < n; i++) {
|
|
44290
|
+
if (px[i] > xmax) xmax = px[i];
|
|
44291
|
+
else if (px[i] < xmin) xmin = px[i];
|
|
44292
|
+
if (py[i] > ymax) ymax = py[i];
|
|
44293
|
+
else if (py[i] < ymin) ymin = py[i];
|
|
44294
|
+
}
|
|
44295
|
+
const xo = (xmax + xmin) / 2;
|
|
44296
|
+
const yo = (ymax + ymin) / 2;
|
|
44297
|
+
const dx = xmax - xo;
|
|
44298
|
+
const dy = ymax - yo;
|
|
44299
|
+
let r = scale * Math.sqrt(fma(dx, dx, dy * dy));
|
|
44300
|
+
if (r === 0) r = scale;
|
|
44301
|
+
return [
|
|
44302
|
+
[fma(r, SQRT3, xo), yo - r],
|
|
44303
|
+
[xo, fma(r, 2, yo)],
|
|
44304
|
+
[fma(-r, SQRT3, xo), yo - r]
|
|
44305
|
+
];
|
|
44306
|
+
}
|
|
44307
|
+
|
|
42627
44308
|
// src/layout/neato/cdt-surface.ts
|
|
42628
44309
|
var pairKey = (u, v) => u < v ? u * 1048576 + v : v * 1048576 + u;
|
|
42629
44310
|
var Cdt = class {
|
|
@@ -43134,27 +44815,15 @@ var Cdt = class {
|
|
|
43134
44815
|
return { nfaces: kept.length, faces, neigh };
|
|
43135
44816
|
}
|
|
43136
44817
|
};
|
|
43137
|
-
var SQRT3 = 1.7320508075688772;
|
|
43138
44818
|
function mkSurface(x, y, n, segs, nsegs) {
|
|
43139
44819
|
const px = x.slice(0, n);
|
|
43140
44820
|
const py = y.slice(0, n);
|
|
43141
|
-
let xmin = px[0];
|
|
43142
|
-
let xmax = px[0];
|
|
43143
|
-
let ymin = py[0];
|
|
43144
|
-
let ymax = py[0];
|
|
43145
|
-
for (let i = 1; i < n; i++) {
|
|
43146
|
-
if (px[i] > xmax) xmax = px[i];
|
|
43147
|
-
else if (px[i] < xmin) xmin = px[i];
|
|
43148
|
-
if (py[i] > ymax) ymax = py[i];
|
|
43149
|
-
else if (py[i] < ymin) ymin = py[i];
|
|
43150
|
-
}
|
|
43151
|
-
const xo = (xmax + xmin) / 2;
|
|
43152
|
-
const yo = (ymax + ymin) / 2;
|
|
43153
|
-
let r = 100 * Math.hypot(xmax - xo, ymax - yo);
|
|
43154
|
-
if (r === 0) r = 100;
|
|
43155
44821
|
const s0 = n;
|
|
43156
|
-
|
|
43157
|
-
|
|
44822
|
+
const enc = gtsTriangleEnclosing(px, py, n, 100);
|
|
44823
|
+
for (const [ex, ey] of enc) {
|
|
44824
|
+
px.push(ex);
|
|
44825
|
+
py.push(ey);
|
|
44826
|
+
}
|
|
43158
44827
|
const cdt = new Cdt(px, py);
|
|
43159
44828
|
const cons = [];
|
|
43160
44829
|
for (let k = 0; k < nsegs; k++) {
|
|
@@ -43201,9 +44870,9 @@ function sharedEdge(faces, p3, q3) {
|
|
|
43201
44870
|
return { i: p1, j: p2 };
|
|
43202
44871
|
}
|
|
43203
44872
|
function addTriEdge(g, t, h, seg2) {
|
|
43204
|
-
const
|
|
44873
|
+
const dist5 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
|
|
43205
44874
|
const idx = g.edges.length;
|
|
43206
|
-
g.edges.push({ t, h, seg: seg2, dist:
|
|
44875
|
+
g.edges.push({ t, h, seg: seg2, dist: dist5 });
|
|
43207
44876
|
g.nodes[t].edges.push(idx);
|
|
43208
44877
|
g.nodes[h].edges.push(idx);
|
|
43209
44878
|
}
|
|
@@ -44007,8 +45676,8 @@ function ellipseTangentSlope(a, b, p) {
|
|
|
44007
45676
|
function circumscribedCorner(a, b, i, nsides) {
|
|
44008
45677
|
const angle0 = 2 * Math.PI * (i - 0.5) / nsides;
|
|
44009
45678
|
const angle1 = 2 * Math.PI * (i + 0.5) / nsides;
|
|
44010
|
-
const p0 = { x: a *
|
|
44011
|
-
const p1 = { x: a *
|
|
45679
|
+
const p0 = { x: a * libmCos(angle0), y: b * libmSin(angle0) };
|
|
45680
|
+
const p1 = { x: a * libmCos(angle1), y: b * libmSin(angle1) };
|
|
44012
45681
|
const m0 = ellipseTangentSlope(a, b, p0);
|
|
44013
45682
|
const m1 = ellipseTangentSlope(a, b, p1);
|
|
44014
45683
|
const x = (fms(p1.x, m1, fma(m0, p0.x, -p0.y)) + p1.y) / (m0 - m1);
|
|
@@ -46344,52 +48013,14 @@ function armPow(x, y) {
|
|
|
46344
48013
|
return expInline(ehi, elo, signBias);
|
|
46345
48014
|
}
|
|
46346
48015
|
|
|
46347
|
-
// src/common/crand.ts
|
|
46348
|
-
var C_RAND_MAX = 2147483647;
|
|
46349
|
-
var UNSEEDED_STATE2 = 1;
|
|
46350
|
-
var state2 = UNSEEDED_STATE2;
|
|
46351
|
-
registerRenderState(() => {
|
|
46352
|
-
state2 = UNSEEDED_STATE2;
|
|
46353
|
-
});
|
|
46354
|
-
function csrand(seed) {
|
|
46355
|
-
state2 = seed;
|
|
46356
|
-
}
|
|
46357
|
-
function crand() {
|
|
46358
|
-
state2 = state2 * 16807 % 2147483647;
|
|
46359
|
-
return state2;
|
|
46360
|
-
}
|
|
46361
|
-
function cdrand() {
|
|
46362
|
-
return crand() / C_RAND_MAX;
|
|
46363
|
-
}
|
|
46364
|
-
function gvRandom(bound) {
|
|
46365
|
-
const discardThreshold = C_RAND_MAX - 2147483648 % bound;
|
|
46366
|
-
let r;
|
|
46367
|
-
do {
|
|
46368
|
-
r = crand();
|
|
46369
|
-
} while (r > discardThreshold);
|
|
46370
|
-
return r % bound;
|
|
46371
|
-
}
|
|
46372
|
-
function gvPermutation(bound) {
|
|
46373
|
-
if (bound <= 0) return [];
|
|
46374
|
-
const p = [];
|
|
46375
|
-
for (let i = 0; i < bound; i++) p.push(i);
|
|
46376
|
-
for (let i = bound - 1; i > 0; --i) {
|
|
46377
|
-
const j = gvRandom(i + 1);
|
|
46378
|
-
const t = p[i];
|
|
46379
|
-
p[i] = p[j];
|
|
46380
|
-
p[j] = t;
|
|
46381
|
-
}
|
|
46382
|
-
return p;
|
|
46383
|
-
}
|
|
46384
|
-
|
|
46385
48016
|
// src/layout/sfdp/quadtree.ts
|
|
46386
48017
|
function pointDistance(p1, o1, p2, o2, dim) {
|
|
46387
|
-
let
|
|
48018
|
+
let dist5 = 0;
|
|
46388
48019
|
for (let i = 0; i < dim; i++) {
|
|
46389
48020
|
const d = p1[o1 + i] - p2[o2 + i];
|
|
46390
|
-
|
|
48021
|
+
dist5 = fma(d, d, dist5);
|
|
46391
48022
|
}
|
|
46392
|
-
return Math.sqrt(
|
|
48023
|
+
return Math.sqrt(dist5);
|
|
46393
48024
|
}
|
|
46394
48025
|
function quadTreeNew(dim, center, width2, maxLevel) {
|
|
46395
48026
|
return {
|
|
@@ -46524,8 +48155,8 @@ function getSupernodesInternal(qt, bh, pt, ptOff, nodeid, out) {
|
|
|
46524
48155
|
l = l.next;
|
|
46525
48156
|
}
|
|
46526
48157
|
if (qt.qts !== null) {
|
|
46527
|
-
const
|
|
46528
|
-
if (qt.width < bh *
|
|
48158
|
+
const dist5 = pointDistance(qt.center, 0, pt, ptOff, dim);
|
|
48159
|
+
if (qt.width < bh * dist5) {
|
|
46529
48160
|
for (let i = 0; i < dim; i++) {
|
|
46530
48161
|
out.center[dim * out.nsuper + i] = qt.average[i];
|
|
46531
48162
|
}
|
|
@@ -46623,12 +48254,12 @@ function onedOptimizerTrain(opt, work) {
|
|
|
46623
48254
|
else optHill(opt, i);
|
|
46624
48255
|
}
|
|
46625
48256
|
function distance(x, dim, i, j) {
|
|
46626
|
-
let
|
|
48257
|
+
let dist5 = 0;
|
|
46627
48258
|
for (let k = 0; k < dim; k++) {
|
|
46628
48259
|
const d = x[i * dim + k] - x[j * dim + k];
|
|
46629
|
-
|
|
48260
|
+
dist5 = fma(d, d, dist5);
|
|
46630
48261
|
}
|
|
46631
|
-
return Math.sqrt(
|
|
48262
|
+
return Math.sqrt(dist5);
|
|
46632
48263
|
}
|
|
46633
48264
|
function distanceCropped(x, dim, i, j) {
|
|
46634
48265
|
return Math.max(distance(x, dim, i, j), MINDIST);
|
|
@@ -46636,16 +48267,16 @@ function distanceCropped(x, dim, i, j) {
|
|
|
46636
48267
|
function gatherLeaves(A3, p, checked, x, dim) {
|
|
46637
48268
|
const { ia, ja } = A3;
|
|
46638
48269
|
const leaves = [];
|
|
46639
|
-
let
|
|
48270
|
+
let dist5 = 0;
|
|
46640
48271
|
for (let j = ia[p]; j < ia[p + 1]; j++) {
|
|
46641
48272
|
const c = ja[j];
|
|
46642
48273
|
if (ia[c + 1] - ia[c] === 1) {
|
|
46643
48274
|
checked[c] = true;
|
|
46644
|
-
|
|
48275
|
+
dist5 += distance(x, dim, p, c);
|
|
46645
48276
|
leaves.push(c);
|
|
46646
48277
|
}
|
|
46647
48278
|
}
|
|
46648
|
-
return { leaves, avgDist:
|
|
48279
|
+
return { leaves, avgDist: dist5 / leaves.length };
|
|
46649
48280
|
}
|
|
46650
48281
|
function beautifyLeaves(dim, A3, x) {
|
|
46651
48282
|
const { ia, ja, m } = A3;
|
|
@@ -46668,7 +48299,7 @@ function beautifyLeaves(dim, A3, x) {
|
|
|
46668
48299
|
}
|
|
46669
48300
|
}
|
|
46670
48301
|
function averageEdgeLength(A3, dim, coord) {
|
|
46671
|
-
let
|
|
48302
|
+
let dist5 = 0;
|
|
46672
48303
|
const { ia, ja } = A3;
|
|
46673
48304
|
if (ia[A3.m] === 0) return 1;
|
|
46674
48305
|
for (let i = 0; i < A3.m; i++) {
|
|
@@ -46678,10 +48309,10 @@ function averageEdgeLength(A3, dim, coord) {
|
|
|
46678
48309
|
const dd = coord[dim * i + k] - coord[dim * ja[j]];
|
|
46679
48310
|
d = fma(dd, dd, d);
|
|
46680
48311
|
}
|
|
46681
|
-
|
|
48312
|
+
dist5 += Math.sqrt(d);
|
|
46682
48313
|
}
|
|
46683
48314
|
}
|
|
46684
|
-
return
|
|
48315
|
+
return dist5 / ia[A3.m];
|
|
46685
48316
|
}
|
|
46686
48317
|
function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
|
|
46687
48318
|
if (!adaptiveCooling) return COOL * step;
|
|
@@ -46692,18 +48323,18 @@ function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
|
|
|
46692
48323
|
}
|
|
46693
48324
|
return 0.99 * step / COOL;
|
|
46694
48325
|
}
|
|
46695
|
-
function repulsivePow(
|
|
46696
|
-
return armPow(
|
|
48326
|
+
function repulsivePow(dist5, p) {
|
|
48327
|
+
return armPow(dist5, 1 - p);
|
|
46697
48328
|
}
|
|
46698
48329
|
function attractiveForce(ctx, i) {
|
|
46699
48330
|
const { A: A3, x, dim, fp, f } = ctx;
|
|
46700
48331
|
const { ia, ja } = A3;
|
|
46701
48332
|
for (let j = ia[i]; j < ia[i + 1]; j++) {
|
|
46702
48333
|
if (ja[j] === i) continue;
|
|
46703
|
-
const
|
|
48334
|
+
const dist5 = distance(x, dim, i, ja[j]);
|
|
46704
48335
|
for (let k = 0; k < dim; k++) {
|
|
46705
48336
|
const t = fp.CRK * (x[i * dim + k] - x[ja[j] * dim + k]);
|
|
46706
|
-
f[k] = fma(-t,
|
|
48337
|
+
f[k] = fma(-t, dist5, f[k]);
|
|
46707
48338
|
}
|
|
46708
48339
|
}
|
|
46709
48340
|
}
|
|
@@ -46711,9 +48342,9 @@ function repulsiveForceDirect(ctx, i) {
|
|
|
46711
48342
|
const { x, dim, n, fp, f } = ctx;
|
|
46712
48343
|
for (let j = 0; j < n; j++) {
|
|
46713
48344
|
if (j === i) continue;
|
|
46714
|
-
const
|
|
48345
|
+
const dist5 = distanceCropped(x, dim, i, j);
|
|
46715
48346
|
for (let k = 0; k < dim; k++) {
|
|
46716
|
-
f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(
|
|
48347
|
+
f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist5, fp.p);
|
|
46717
48348
|
}
|
|
46718
48349
|
}
|
|
46719
48350
|
}
|
|
@@ -46723,9 +48354,9 @@ function repulsiveForceQT(ctx, qt, i, acc) {
|
|
|
46723
48354
|
acc.countsAvg += counts;
|
|
46724
48355
|
acc.nsuperAvg += nsuper;
|
|
46725
48356
|
for (let j = 0; j < nsuper; j++) {
|
|
46726
|
-
const
|
|
48357
|
+
const dist5 = Math.max(distances[j], MINDIST);
|
|
46727
48358
|
for (let k = 0; k < dim; k++) {
|
|
46728
|
-
f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(
|
|
48359
|
+
f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist5, fp.p);
|
|
46729
48360
|
}
|
|
46730
48361
|
}
|
|
46731
48362
|
}
|
|
@@ -46981,7 +48612,7 @@ function diagPreconNew(A3) {
|
|
|
46981
48612
|
}
|
|
46982
48613
|
return diag;
|
|
46983
48614
|
}
|
|
46984
|
-
function
|
|
48615
|
+
function conjugateGradient2(A3, precon, n, x, rhs, tol, maxit) {
|
|
46985
48616
|
let rho = 0;
|
|
46986
48617
|
let rhoOld = 1;
|
|
46987
48618
|
let iter = 0;
|
|
@@ -47022,7 +48653,7 @@ function smSolve(A3, dim, x0, rhs, tol, maxit) {
|
|
|
47022
48653
|
x[i] = x0[i * dim + k];
|
|
47023
48654
|
b[i] = rhs[i * dim + k];
|
|
47024
48655
|
}
|
|
47025
|
-
res +=
|
|
48656
|
+
res += conjugateGradient2(A3, precond, n, x, b, tol, maxit);
|
|
47026
48657
|
for (let i = 0; i < n; i++) {
|
|
47027
48658
|
rhs[i * dim + k] = x[i];
|
|
47028
48659
|
}
|
|
@@ -47376,7 +49007,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
|
47376
49007
|
for (let j = ia[i]; j < ia[i + 1]; j++) {
|
|
47377
49008
|
const jj = ja[j];
|
|
47378
49009
|
if (jj === i) continue;
|
|
47379
|
-
const
|
|
49010
|
+
const dist5 = distance(x, dim, i, jj);
|
|
47380
49011
|
const dx = Math.abs(x[i * dim] - x[jj * dim]);
|
|
47381
49012
|
const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
|
|
47382
49013
|
const wx = width2[i * dim] + width2[jj * dim];
|
|
@@ -47399,9 +49030,9 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
|
47399
49030
|
t = Math.min(expandmax, t);
|
|
47400
49031
|
t = Math.max(expandmin, t);
|
|
47401
49032
|
if (t > 1) {
|
|
47402
|
-
idealDistance[j] = t *
|
|
49033
|
+
idealDistance[j] = t * dist5;
|
|
47403
49034
|
} else {
|
|
47404
|
-
idealDistance[j] = -t *
|
|
49035
|
+
idealDistance[j] = -t * dist5;
|
|
47405
49036
|
}
|
|
47406
49037
|
}
|
|
47407
49038
|
}
|
|
@@ -47496,9 +49127,9 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
|
47496
49127
|
w[j] = -1 / d[j] / d[j];
|
|
47497
49128
|
d[j] = -d[j];
|
|
47498
49129
|
}
|
|
47499
|
-
const
|
|
49130
|
+
const dist5 = d[j];
|
|
47500
49131
|
diagW += w[j];
|
|
47501
|
-
d[j] = w[j] *
|
|
49132
|
+
d[j] = w[j] * dist5;
|
|
47502
49133
|
diagD += d[j];
|
|
47503
49134
|
}
|
|
47504
49135
|
w[jdiag] = -diagW;
|
|
@@ -47509,11 +49140,11 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
|
47509
49140
|
function totalDistance(m, dim, x, y) {
|
|
47510
49141
|
let total = 0;
|
|
47511
49142
|
for (let i = 0; i < m; i++) {
|
|
47512
|
-
let
|
|
49143
|
+
let dist5 = 0;
|
|
47513
49144
|
for (let j = 0; j < dim; j++) {
|
|
47514
|
-
|
|
49145
|
+
dist5 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
|
|
47515
49146
|
}
|
|
47516
|
-
total += Math.sqrt(
|
|
49147
|
+
total += Math.sqrt(dist5);
|
|
47517
49148
|
}
|
|
47518
49149
|
return total;
|
|
47519
49150
|
}
|
|
@@ -47546,18 +49177,18 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
|
|
|
47546
49177
|
idiag = j;
|
|
47547
49178
|
continue;
|
|
47548
49179
|
}
|
|
47549
|
-
let
|
|
49180
|
+
let dist5 = distance(x, dim, i, jd[j]);
|
|
47550
49181
|
if (d[j] === 0) {
|
|
47551
49182
|
dd[j] = 0;
|
|
47552
49183
|
} else {
|
|
47553
|
-
if (
|
|
49184
|
+
if (dist5 === 0) {
|
|
47554
49185
|
const dij = d[j] / Lw.a[j];
|
|
47555
49186
|
for (let k = 0; k < dim; k++) {
|
|
47556
49187
|
x[jd[j] * dim + k] += 1e-4 * (cdrand() + 1e-4) * dij;
|
|
47557
49188
|
}
|
|
47558
|
-
|
|
49189
|
+
dist5 = distance(x, dim, i, jd[j]);
|
|
47559
49190
|
}
|
|
47560
|
-
dd[j] = d[j] /
|
|
49191
|
+
dd[j] = d[j] / dist5;
|
|
47561
49192
|
}
|
|
47562
49193
|
diag += dd[j];
|
|
47563
49194
|
}
|
|
@@ -47576,9 +49207,9 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
|
|
|
47576
49207
|
return diff;
|
|
47577
49208
|
}
|
|
47578
49209
|
function scaleToEdgeLength(dim, A3, x, avgLabelSize) {
|
|
47579
|
-
let
|
|
47580
|
-
|
|
47581
|
-
for (let i = 0; i < dim * A3.m; i++) x[i] *=
|
|
49210
|
+
let dist5 = averageEdgeLength(A3, dim, x);
|
|
49211
|
+
dist5 = avgLabelSize / Math.max(dist5, MACHINEACC);
|
|
49212
|
+
for (let i = 0; i < dim * A3.m; i++) x[i] *= dist5;
|
|
47582
49213
|
}
|
|
47583
49214
|
function removeOverlapPrism(dim, A3, x, labelSizes, ntry, initialScaling, doShrinking) {
|
|
47584
49215
|
if (!labelSizes) return;
|
|
@@ -47945,7 +49576,7 @@ function makeHasEdge(g) {
|
|
|
47945
49576
|
}
|
|
47946
49577
|
return (a, b) => pairs.get(a)?.has(b) === true || undirected && pairs.get(b)?.has(a) === true;
|
|
47947
49578
|
}
|
|
47948
|
-
function mkNConstraintG(g, list, intersect,
|
|
49579
|
+
function mkNConstraintG(g, list, intersect, dist5) {
|
|
47949
49580
|
const cg = newCg();
|
|
47950
49581
|
const flat = flatten(list);
|
|
47951
49582
|
let lastn;
|
|
@@ -47962,7 +49593,7 @@ function mkNConstraintG(g, list, intersect, dist4) {
|
|
|
47962
49593
|
const nxp = flat[j];
|
|
47963
49594
|
if (!intersect(p, nxp)) continue;
|
|
47964
49595
|
const e = cgEdge(cg, cnodeOf(p), cnodeOf(nxp));
|
|
47965
|
-
e.info.minlen =
|
|
49596
|
+
e.info.minlen = dist5(p.bb, nxp.bb);
|
|
47966
49597
|
e.info.weight = hasEdge(p.np, nxp.np) ? 100 : 1;
|
|
47967
49598
|
created.push(e);
|
|
47968
49599
|
}
|
|
@@ -48009,12 +49640,12 @@ function buildVisibility(flat, intersect) {
|
|
|
48009
49640
|
}
|
|
48010
49641
|
return vg;
|
|
48011
49642
|
}
|
|
48012
|
-
function mapGraphs(vg, flat, cg,
|
|
49643
|
+
function mapGraphs(vg, flat, cg, dist5) {
|
|
48013
49644
|
for (let i = 0; i < flat.length; i++) {
|
|
48014
49645
|
const tp = flat[i];
|
|
48015
49646
|
for (const j of vg[i]) {
|
|
48016
49647
|
const hp = flat[j];
|
|
48017
|
-
const delta2 =
|
|
49648
|
+
const delta2 = dist5(tp.bb, hp.bb);
|
|
48018
49649
|
const ce = cgEdge(cg, cnodeOf(tp), cnodeOf(hp));
|
|
48019
49650
|
ce.info.weight = 1;
|
|
48020
49651
|
if ((ce.info.minlen ?? 0) < delta2) {
|
|
@@ -48024,15 +49655,15 @@ function mapGraphs(vg, flat, cg, dist4) {
|
|
|
48024
49655
|
}
|
|
48025
49656
|
}
|
|
48026
49657
|
}
|
|
48027
|
-
function mkConstraintG(list, intersect,
|
|
49658
|
+
function mkConstraintG(list, intersect, dist5) {
|
|
48028
49659
|
const cg = newCg();
|
|
48029
49660
|
const flat = flatten(list);
|
|
48030
49661
|
buildChain(cg, flat);
|
|
48031
|
-
mapGraphs(buildVisibility(flat, intersect), flat, cg,
|
|
49662
|
+
mapGraphs(buildVisibility(flat, intersect), flat, cg, dist5);
|
|
48032
49663
|
return cg;
|
|
48033
49664
|
}
|
|
48034
|
-
function buildConstraintGraph(g, list, ifn,
|
|
48035
|
-
return ortho ? mkConstraintG(list, ifn,
|
|
49665
|
+
function buildConstraintGraph(g, list, ifn, dist5, ortho) {
|
|
49666
|
+
return ortho ? mkConstraintG(list, ifn, dist5) : mkNConstraintG(g, list, ifn, dist5);
|
|
48036
49667
|
}
|
|
48037
49668
|
function newItems() {
|
|
48038
49669
|
return new DtBag((p) => p.val, cmpitem);
|
|
@@ -48173,7 +49804,7 @@ function inflatePts(verts, xmargin, ymargin) {
|
|
|
48173
49804
|
v.y *= ymargin;
|
|
48174
49805
|
}
|
|
48175
49806
|
}
|
|
48176
|
-
function
|
|
49807
|
+
function isBox3(verts) {
|
|
48177
49808
|
if (verts.length !== 4) return false;
|
|
48178
49809
|
const [v0, v1, v2, v3] = verts;
|
|
48179
49810
|
if (v0.y === v1.y) {
|
|
@@ -48233,7 +49864,7 @@ function clusterVerts(n, xmargin, ymargin) {
|
|
|
48233
49864
|
function polyKind(n, poly, verts) {
|
|
48234
49865
|
const name = shapeName(n);
|
|
48235
49866
|
if (name === "box") return POLY_BOX;
|
|
48236
|
-
if (name === "polygon" &&
|
|
49867
|
+
if (name === "polygon" && isBox3(verts)) return POLY_BOX;
|
|
48237
49868
|
if (poly.sides < 3 && poly.regular) return POLY_CIRCLE;
|
|
48238
49869
|
return 0;
|
|
48239
49870
|
}
|
|
@@ -48741,7 +50372,7 @@ function heapSiftUp(h, i) {
|
|
|
48741
50372
|
i = parent2;
|
|
48742
50373
|
}
|
|
48743
50374
|
}
|
|
48744
|
-
function
|
|
50375
|
+
function heapSiftDown2(h, i) {
|
|
48745
50376
|
const n = h.length;
|
|
48746
50377
|
for (; ; ) {
|
|
48747
50378
|
let smallest = i;
|
|
@@ -48758,7 +50389,7 @@ function heapSiftDown3(h, i) {
|
|
|
48758
50389
|
}
|
|
48759
50390
|
function makeHeap(h) {
|
|
48760
50391
|
for (let i = (h.length >> 1) - 1; i >= 0; i--) {
|
|
48761
|
-
|
|
50392
|
+
heapSiftDown2(h, i);
|
|
48762
50393
|
}
|
|
48763
50394
|
}
|
|
48764
50395
|
function heapFindMin(h) {
|
|
@@ -48767,7 +50398,7 @@ function heapFindMin(h) {
|
|
|
48767
50398
|
function heapDeleteMin(h) {
|
|
48768
50399
|
h[0] = h[h.length - 1];
|
|
48769
50400
|
h.pop();
|
|
48770
|
-
if (h.length > 0)
|
|
50401
|
+
if (h.length > 0) heapSiftDown2(h, 0);
|
|
48771
50402
|
}
|
|
48772
50403
|
function heapInsert(h, c) {
|
|
48773
50404
|
h.push(c);
|
|
@@ -48851,27 +50482,27 @@ var Block = class _Block {
|
|
|
48851
50482
|
* @see lib/vpsc/block.cpp: Block::merge(Block* b, Constraint* c)
|
|
48852
50483
|
*/
|
|
48853
50484
|
mergeTwoArg(b, c) {
|
|
48854
|
-
const
|
|
50485
|
+
const dist5 = c.right.offset - c.left.offset - c.gap;
|
|
48855
50486
|
let l = c.left.block;
|
|
48856
50487
|
let r = c.right.block;
|
|
48857
50488
|
if (this.vars.length < b.vars.length) {
|
|
48858
|
-
r.mergeInto(l, c,
|
|
50489
|
+
r.mergeInto(l, c, dist5);
|
|
48859
50490
|
} else {
|
|
48860
|
-
l.mergeInto(r, c, -
|
|
50491
|
+
l.mergeInto(r, c, -dist5);
|
|
48861
50492
|
}
|
|
48862
50493
|
}
|
|
48863
50494
|
/**
|
|
48864
50495
|
* Merge block b into this across constraint c by dist.
|
|
48865
50496
|
* @see lib/vpsc/block.cpp: Block::merge(Block *b, Constraint *c, double dist)
|
|
48866
50497
|
*/
|
|
48867
|
-
mergeInto(b, c,
|
|
50498
|
+
mergeInto(b, c, dist5) {
|
|
48868
50499
|
c.active = true;
|
|
48869
|
-
this.wposn += b.wposn -
|
|
50500
|
+
this.wposn += b.wposn - dist5 * b.weight;
|
|
48870
50501
|
this.weight += b.weight;
|
|
48871
50502
|
this.posn = this.wposn / this.weight;
|
|
48872
50503
|
for (const v of b.vars) {
|
|
48873
50504
|
v.block = this;
|
|
48874
|
-
v.offset +=
|
|
50505
|
+
v.offset += dist5;
|
|
48875
50506
|
this.vars.push(v);
|
|
48876
50507
|
}
|
|
48877
50508
|
b.deleted = true;
|
|
@@ -49160,13 +50791,13 @@ var Blocks = class {
|
|
|
49160
50791
|
r.deleteMinInConstraint();
|
|
49161
50792
|
let l = c.left.block;
|
|
49162
50793
|
if (l.in.length === 0) l.setUpInConstraints();
|
|
49163
|
-
let
|
|
50794
|
+
let dist5 = c.right.offset - c.left.offset - c.gap;
|
|
49164
50795
|
if (r.vars.length < l.vars.length) {
|
|
49165
|
-
|
|
50796
|
+
dist5 = -dist5;
|
|
49166
50797
|
[l, r] = [r, l];
|
|
49167
50798
|
}
|
|
49168
50799
|
this.timeCtr.value++;
|
|
49169
|
-
r.mergeInto(l, c,
|
|
50800
|
+
r.mergeInto(l, c, dist5);
|
|
49170
50801
|
r.mergeIn(l);
|
|
49171
50802
|
r.timeStamp = this.timeCtr.value;
|
|
49172
50803
|
this.removeBlock(l);
|
|
@@ -49184,12 +50815,12 @@ var Blocks = class {
|
|
|
49184
50815
|
l.deleteMinOutConstraint();
|
|
49185
50816
|
let r = c.right.block;
|
|
49186
50817
|
r.setUpOutConstraints();
|
|
49187
|
-
let
|
|
50818
|
+
let dist5 = c.left.offset + c.gap - c.right.offset;
|
|
49188
50819
|
if (l.vars.length > r.vars.length) {
|
|
49189
|
-
|
|
50820
|
+
dist5 = -dist5;
|
|
49190
50821
|
[l, r] = [r, l];
|
|
49191
50822
|
}
|
|
49192
|
-
l.mergeInto(r, c,
|
|
50823
|
+
l.mergeInto(r, c, dist5);
|
|
49193
50824
|
l.mergeOut(r);
|
|
49194
50825
|
this.removeBlock(r);
|
|
49195
50826
|
c = l.findMinOutConstraint();
|
|
@@ -49705,7 +51336,7 @@ function warnUnrecognizedOverlap(flag) {
|
|
|
49705
51336
|
const s = flag.toLowerCase();
|
|
49706
51337
|
if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
|
|
49707
51338
|
if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
|
|
49708
|
-
|
|
51339
|
+
agwarningf(`Unrecognized overlap value "${flag}" - using false`);
|
|
49709
51340
|
}
|
|
49710
51341
|
function getAdjustMode(flag) {
|
|
49711
51342
|
warnUnrecognizedOverlap(flag);
|
|
@@ -49738,7 +51369,7 @@ function adjustLate(g, am) {
|
|
|
49738
51369
|
case AM_VPSC:
|
|
49739
51370
|
return vpscAdjust(g);
|
|
49740
51371
|
default:
|
|
49741
|
-
|
|
51372
|
+
agwarningf(`Unhandled adjust option ${am.print}`);
|
|
49742
51373
|
return 0;
|
|
49743
51374
|
}
|
|
49744
51375
|
}
|
|
@@ -50712,20 +52343,20 @@ function coincidentDelta() {
|
|
|
50712
52343
|
} while (xdelta === 0 && ydelta === 0);
|
|
50713
52344
|
return { xdelta, ydelta };
|
|
50714
52345
|
}
|
|
50715
|
-
function doRep(p, q, xdelta, ydelta,
|
|
52346
|
+
function doRep(p, q, xdelta, ydelta, dist5) {
|
|
50716
52347
|
let force;
|
|
50717
|
-
if (!(
|
|
52348
|
+
if (!(dist5 > 0)) {
|
|
50718
52349
|
const d = coincidentDelta();
|
|
50719
52350
|
xdelta = d.xdelta;
|
|
50720
52351
|
ydelta = d.ydelta;
|
|
50721
|
-
|
|
52352
|
+
dist5 = libmHypot(xdelta, ydelta);
|
|
50722
52353
|
}
|
|
50723
|
-
if (
|
|
52354
|
+
if (dist5 > fdpParms.Mlimit) {
|
|
50724
52355
|
force = 0;
|
|
50725
52356
|
} else if (parms.useNew) {
|
|
50726
|
-
force = parms.K * parms.K / (
|
|
52357
|
+
force = parms.K * parms.K / (dist5 * dist5 * dist5);
|
|
50727
52358
|
} else {
|
|
50728
|
-
force = parms.K * parms.K / (
|
|
52359
|
+
force = parms.K * parms.K / (dist5 * dist5);
|
|
50729
52360
|
}
|
|
50730
52361
|
if (isPort(p) && isPort(q)) force *= 10;
|
|
50731
52362
|
const dq = disp(q);
|
|
@@ -50747,8 +52378,8 @@ function doNeighbor(grid2, i, j, nodes) {
|
|
|
50747
52378
|
for (const q of cellp.nodes) {
|
|
50748
52379
|
const xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50749
52380
|
const ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50750
|
-
const
|
|
50751
|
-
if (
|
|
52381
|
+
const dist5 = libmHypot(xdelta, ydelta);
|
|
52382
|
+
if (dist5 < parms.Cell) doRep(p, q, xdelta, ydelta, dist5);
|
|
50752
52383
|
}
|
|
50753
52384
|
}
|
|
50754
52385
|
}
|
|
@@ -50780,12 +52411,12 @@ function applyAttr(p, q, e) {
|
|
|
50780
52411
|
ydelta = d.ydelta;
|
|
50781
52412
|
dist22 = fma(xdelta, xdelta, ydelta * ydelta);
|
|
50782
52413
|
}
|
|
50783
|
-
const
|
|
52414
|
+
const dist5 = Math.sqrt(dist22);
|
|
50784
52415
|
let force;
|
|
50785
52416
|
if (parms.useNew) {
|
|
50786
|
-
force = (e.info.factor ?? 1) * (
|
|
52417
|
+
force = (e.info.factor ?? 1) * (dist5 - (e.info.dist ?? 1)) / dist5;
|
|
50787
52418
|
} else {
|
|
50788
|
-
force = (e.info.factor ?? 1) *
|
|
52419
|
+
force = (e.info.factor ?? 1) * dist5 / (e.info.dist ?? 1);
|
|
50789
52420
|
}
|
|
50790
52421
|
const dq = disp(q);
|
|
50791
52422
|
const dp = disp(p);
|
|
@@ -50960,16 +52591,16 @@ function cntOverlaps(g) {
|
|
|
50960
52591
|
function applyRep2(p, q, rs) {
|
|
50961
52592
|
let xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50962
52593
|
let ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50963
|
-
let
|
|
50964
|
-
if (!(
|
|
52594
|
+
let dist5 = libmHypot(xdelta, ydelta);
|
|
52595
|
+
if (!(dist5 > 0)) {
|
|
50965
52596
|
const d = coincidentDelta();
|
|
50966
52597
|
xdelta = d.xdelta;
|
|
50967
52598
|
ydelta = d.ydelta;
|
|
50968
|
-
|
|
52599
|
+
dist5 = libmHypot(xdelta, ydelta);
|
|
50969
52600
|
}
|
|
50970
52601
|
const ov = overlap4(p, q) ? 1 : 0;
|
|
50971
|
-
let force = ov ? rs.ov / (
|
|
50972
|
-
if (
|
|
52602
|
+
let force = ov ? rs.ov / (dist5 * dist5) : rs.nonov / (dist5 * dist5);
|
|
52603
|
+
if (dist5 > fdpParms.Mlimit) force = 0;
|
|
50973
52604
|
const dq = disp(q);
|
|
50974
52605
|
const dp = disp(p);
|
|
50975
52606
|
dq[0] = fma(xdelta, force, dq[0]);
|
|
@@ -50982,10 +52613,10 @@ function applyAttr2(p, q) {
|
|
|
50982
52613
|
if (overlap4(p, q)) return;
|
|
50983
52614
|
const xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50984
52615
|
const ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50985
|
-
const
|
|
52616
|
+
const dist5 = libmHypot(xdelta, ydelta);
|
|
50986
52617
|
const din = rad(p) + rad(q);
|
|
50987
|
-
const dout =
|
|
50988
|
-
const force = dout * dout / ((xParams.K + din) *
|
|
52618
|
+
const dout = dist5 - din;
|
|
52619
|
+
const force = dout * dout / ((xParams.K + din) * dist5);
|
|
50989
52620
|
const dq = disp(q);
|
|
50990
52621
|
const dp = disp(p);
|
|
50991
52622
|
dq[0] = fms(xdelta, force, dq[0]);
|
|
@@ -52140,9 +53771,9 @@ function pcpRotate(n, dim, x) {
|
|
|
52140
53771
|
axis[0] = -(-y[0] + y[3] - Math.sqrt(radicand)) / (2 * y[1]);
|
|
52141
53772
|
axis[1] = 1;
|
|
52142
53773
|
}
|
|
52143
|
-
const
|
|
52144
|
-
axis[0] = axis[0] /
|
|
52145
|
-
axis[1] = axis[1] /
|
|
53774
|
+
const dist5 = Math.sqrt(fma(axis[0], axis[0], 1));
|
|
53775
|
+
axis[0] = axis[0] / dist5;
|
|
53776
|
+
axis[1] = axis[1] / dist5;
|
|
52146
53777
|
for (let i = 0; i < n; i++) {
|
|
52147
53778
|
const x0 = fma(x[dim * i], axis[0], x[dim * i + 1] * axis[1]);
|
|
52148
53779
|
const x1 = fma(-x[dim * i], axis[1], x[dim * i + 1] * axis[0]);
|
|
@@ -52555,10 +54186,10 @@ function buildSpanTree(nodes, edges) {
|
|
|
52555
54186
|
}
|
|
52556
54187
|
return map;
|
|
52557
54188
|
}
|
|
52558
|
-
function measureDist(leaf, anc,
|
|
54189
|
+
function measureDist(leaf, anc, dist5, change) {
|
|
52559
54190
|
const p = anc.tparent;
|
|
52560
54191
|
if (!p) return;
|
|
52561
|
-
const d =
|
|
54192
|
+
const d = dist5 + 1;
|
|
52562
54193
|
if (p.distone === 0) {
|
|
52563
54194
|
p.leafone = leaf;
|
|
52564
54195
|
p.distone = d;
|
|
@@ -54058,11 +55689,11 @@ var DEFAULT_COLOR5 = "black";
|
|
|
54058
55689
|
var PENWIDTH_NORMAL4 = 1;
|
|
54059
55690
|
var PENWIDTH_THRESHOLD4 = 5e-3;
|
|
54060
55691
|
var EPS3 = 1e-5;
|
|
54061
|
-
function
|
|
55692
|
+
function dist4(a, b) {
|
|
54062
55693
|
return Math.sqrt(dist2(a, b));
|
|
54063
55694
|
}
|
|
54064
55695
|
function approxLen(list, off) {
|
|
54065
|
-
return
|
|
55696
|
+
return dist4(list[off], list[off + 1]) + dist4(list[off + 1], list[off + 2]) + dist4(list[off + 2], list[off + 3]);
|
|
54066
55697
|
}
|
|
54067
55698
|
function splitCubic(v, t) {
|
|
54068
55699
|
const left2 = [];
|
|
@@ -54141,7 +55772,7 @@ function drawSplitSpline(list, segs, job) {
|
|
|
54141
55772
|
return endColor;
|
|
54142
55773
|
}
|
|
54143
55774
|
function emitSplitEdgePaths(e, job, colorList) {
|
|
54144
|
-
const segs = parseSegs(colorList).segs;
|
|
55775
|
+
const segs = parseSegs(colorList, edgeSegsContext(e)).segs;
|
|
54145
55776
|
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
|
|
54146
55777
|
const spl = e.info.spl;
|
|
54147
55778
|
let endColor = firstColor2;
|
|
@@ -54162,8 +55793,8 @@ var forfunc = (cur, total, init) => (1 - cur / total) * init / 2;
|
|
|
54162
55793
|
var revfunc = (cur, total, init) => cur / total * init / 2;
|
|
54163
55794
|
var nonefunc = (_cur, _total, init) => init / 2;
|
|
54164
55795
|
var bothfunc = (cur, total, init) => {
|
|
54165
|
-
const
|
|
54166
|
-
return
|
|
55796
|
+
const fr7 = cur / total;
|
|
55797
|
+
return fr7 <= 0.5 ? fr7 * init : (1 - fr7) * init;
|
|
54167
55798
|
};
|
|
54168
55799
|
function taperfun(dir, directed) {
|
|
54169
55800
|
if (dir === "forward") return forfunc;
|
|
@@ -55597,7 +57228,7 @@ var DotWriterBase = class {
|
|
|
55597
57228
|
|
|
55598
57229
|
// src/render/dot/edge-draw.ts
|
|
55599
57230
|
var DEFAULT_COLOR6 = "black";
|
|
55600
|
-
var
|
|
57231
|
+
var DEFAULT_LINE_STYLE2 = ["solid", "setlinewidth(1)"];
|
|
55601
57232
|
function emitArrowOp(buf, op, pen) {
|
|
55602
57233
|
switch (op.kind) {
|
|
55603
57234
|
case "polygon":
|
|
@@ -55632,8 +57263,9 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55632
57263
|
*/
|
|
55633
57264
|
attachmentPolyline(pts, pencolor, job) {
|
|
55634
57265
|
const obj = job.obj;
|
|
57266
|
+
gvrenderSetStyle(DEFAULT_LINE_STYLE2);
|
|
55635
57267
|
if (obj !== null) {
|
|
55636
|
-
obj.rawStyle = [...
|
|
57268
|
+
obj.rawStyle = [...DEFAULT_LINE_STYLE2];
|
|
55637
57269
|
obj.pen = 3 /* Solid */;
|
|
55638
57270
|
obj.penWidth = 1;
|
|
55639
57271
|
obj.penColor = resolveRenderColor(pencolor.split(":")[0]);
|
|
@@ -55687,8 +57319,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55687
57319
|
* under that segment's pen. Reuses the same split geometry
|
|
55688
57320
|
* (splitSplineByColor) as the SVG path. @see lib/common/emit.c:1975 multicolor
|
|
55689
57321
|
*/
|
|
55690
|
-
emitSplitSpline(bzList, colorAttr, edraw, job) {
|
|
55691
|
-
const segs = parseSegs(colorAttr).segs;
|
|
57322
|
+
emitSplitSpline(bzList, e, colorAttr, edraw, job) {
|
|
57323
|
+
const segs = parseSegs(colorAttr, edgeSegsContext(e)).segs;
|
|
55692
57324
|
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
|
|
55693
57325
|
let endColor = firstColor2;
|
|
55694
57326
|
for (const bz of bzList) {
|
|
@@ -55711,7 +57343,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55711
57343
|
const segData = bzList.map(
|
|
55712
57344
|
(bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
|
|
55713
57345
|
);
|
|
55714
|
-
const colors =
|
|
57346
|
+
const colors = parseSegsSilent(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
|
|
55715
57347
|
for (const color of colors) {
|
|
55716
57348
|
const pen = xdotPenColor(resolveRenderColor(color));
|
|
55717
57349
|
for (const sd of segData) {
|
|
@@ -55867,7 +57499,7 @@ var XdotRenderer = class extends EdgeDrawBase {
|
|
|
55867
57499
|
let tailArrowColor;
|
|
55868
57500
|
let headArrowColor;
|
|
55869
57501
|
if (numsemi > 0 && numc > 0) {
|
|
55870
|
-
const c = this.emitSplitSpline(spl.list, colorAttr, edraw, job);
|
|
57502
|
+
const c = this.emitSplitSpline(spl.list, e, colorAttr, edraw, job);
|
|
55871
57503
|
tailArrowColor = c.firstColor;
|
|
55872
57504
|
headArrowColor = c.endColor;
|
|
55873
57505
|
} else if (edgeIsTapered(e)) {
|
|
@@ -56103,72 +57735,6 @@ function svgTaperedEdge(e, job) {
|
|
|
56103
57735
|
svgArrowPolygons(e, job);
|
|
56104
57736
|
}
|
|
56105
57737
|
|
|
56106
|
-
// src/gvc/image-resolver.ts
|
|
56107
|
-
var activeResolver = null;
|
|
56108
|
-
function setImageResolver(fn) {
|
|
56109
|
-
if (fn !== null && typeof fn !== "function") {
|
|
56110
|
-
throw invalidArgType("resolver", "function or null", fn);
|
|
56111
|
-
}
|
|
56112
|
-
activeResolver = fn;
|
|
56113
|
-
}
|
|
56114
|
-
var EXT_MIME = {
|
|
56115
|
-
png: "image/png",
|
|
56116
|
-
jpg: "image/jpeg",
|
|
56117
|
-
jpeg: "image/jpeg",
|
|
56118
|
-
gif: "image/gif",
|
|
56119
|
-
svg: "image/svg+xml",
|
|
56120
|
-
webp: "image/webp"
|
|
56121
|
-
};
|
|
56122
|
-
var FALLBACK_MIME = "application/octet-stream";
|
|
56123
|
-
function inferMimeFromSrc(src) {
|
|
56124
|
-
const dot = src.lastIndexOf(".");
|
|
56125
|
-
if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
|
|
56126
|
-
const ext = src.slice(dot + 1).toLowerCase();
|
|
56127
|
-
return EXT_MIME[ext] ?? FALLBACK_MIME;
|
|
56128
|
-
}
|
|
56129
|
-
function findImageBytes(src, resolver) {
|
|
56130
|
-
const active = resolver ?? activeResolver;
|
|
56131
|
-
if (active === null) return null;
|
|
56132
|
-
const result = active(src);
|
|
56133
|
-
if (result === null) return null;
|
|
56134
|
-
if (result instanceof Uint8Array) {
|
|
56135
|
-
return { bytes: result, mime: inferMimeFromSrc(src) };
|
|
56136
|
-
}
|
|
56137
|
-
return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
|
|
56138
|
-
}
|
|
56139
|
-
var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
56140
|
-
function base64Encode(bytes) {
|
|
56141
|
-
const len = bytes.length;
|
|
56142
|
-
const out = [];
|
|
56143
|
-
let i = 0;
|
|
56144
|
-
for (; i + 2 < len; i += 3) {
|
|
56145
|
-
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
56146
|
-
out.push(
|
|
56147
|
-
B64_CHARS[n >> 18 & 63],
|
|
56148
|
-
B64_CHARS[n >> 12 & 63],
|
|
56149
|
-
B64_CHARS[n >> 6 & 63],
|
|
56150
|
-
B64_CHARS[n & 63]
|
|
56151
|
-
);
|
|
56152
|
-
}
|
|
56153
|
-
const remaining = len - i;
|
|
56154
|
-
if (remaining === 1) {
|
|
56155
|
-
const n = bytes[i] << 16;
|
|
56156
|
-
out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
|
|
56157
|
-
} else if (remaining === 2) {
|
|
56158
|
-
const n = bytes[i] << 16 | bytes[i + 1] << 8;
|
|
56159
|
-
out.push(
|
|
56160
|
-
B64_CHARS[n >> 18 & 63],
|
|
56161
|
-
B64_CHARS[n >> 12 & 63],
|
|
56162
|
-
B64_CHARS[n >> 6 & 63],
|
|
56163
|
-
"="
|
|
56164
|
-
);
|
|
56165
|
-
}
|
|
56166
|
-
return out.join("");
|
|
56167
|
-
}
|
|
56168
|
-
function toDataUri(bytes, mime) {
|
|
56169
|
-
return "data:" + mime + ";base64," + base64Encode(bytes);
|
|
56170
|
-
}
|
|
56171
|
-
|
|
56172
57738
|
// src/render/svg.ts
|
|
56173
57739
|
function emitMulticolorArrows(e, job, headColor, tailColor) {
|
|
56174
57740
|
const obj = job.obj;
|