@knowvah/dot-engine 2.6.12 → 2.7.0
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/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/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.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 +2460 -901
- 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/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 +2340 -781
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- 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/multicolor.ts +88 -24
- package/src/common/poly-gencode.ts +16 -8
- package/src/common/poly-init.ts +19 -1
- 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/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
|
|
@@ -11126,9 +11249,15 @@ function scanCdata(text, p, base, dataOf, tokens) {
|
|
|
11126
11249
|
if (end > p) tokens.push({ kind: "cdata", start: base + p, end: base + end, data: dataOf(base + p, base + end) });
|
|
11127
11250
|
return close < 0 ? -1 : close + CDATA_CLOSE.length;
|
|
11128
11251
|
}
|
|
11252
|
+
var CONTENT_NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
|
|
11129
11253
|
function scanText(text, p, base, tokens) {
|
|
11130
11254
|
const e = text.indexOf("<", p);
|
|
11131
11255
|
const slice = text.slice(p, e < 0 ? text.length : e);
|
|
11256
|
+
const bad = CONTENT_NON_XML.exec(slice)?.index;
|
|
11257
|
+
if (bad !== void 0) {
|
|
11258
|
+
if (bad > 0) tokens.push({ kind: "text", start: base + p, end: base + p + bad });
|
|
11259
|
+
return { at: p + bad, held: false, invalid: p + bad };
|
|
11260
|
+
}
|
|
11132
11261
|
const from = e < 0 ? heldRefStart(slice) : void 0;
|
|
11133
11262
|
const end = from === void 0 ? p + slice.length : p + from;
|
|
11134
11263
|
if (end > p) tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
@@ -11148,6 +11277,7 @@ function scanContent(text, base, inCdata, dataOf) {
|
|
|
11148
11277
|
}
|
|
11149
11278
|
if (text[p] !== "<") {
|
|
11150
11279
|
const scanned = scanText(text, p, base, tokens);
|
|
11280
|
+
if (scanned.invalid !== void 0) return { tokens, consumed: scanned.at, invalid: base + scanned.invalid, inCdata: false };
|
|
11151
11281
|
if (scanned.held) return { tokens, consumed: scanned.at, inCdata: false };
|
|
11152
11282
|
p = scanned.at;
|
|
11153
11283
|
continue;
|
|
@@ -12154,6 +12284,72 @@ var parseHtmlLabelRv = (src, stderr) => {
|
|
|
12154
12284
|
};
|
|
12155
12285
|
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
|
|
12156
12286
|
|
|
12287
|
+
// src/gvc/image-resolver.ts
|
|
12288
|
+
var activeResolver = null;
|
|
12289
|
+
function setImageResolver(fn) {
|
|
12290
|
+
if (fn !== null && typeof fn !== "function") {
|
|
12291
|
+
throw invalidArgType("resolver", "function or null", fn);
|
|
12292
|
+
}
|
|
12293
|
+
activeResolver = fn;
|
|
12294
|
+
}
|
|
12295
|
+
var EXT_MIME = {
|
|
12296
|
+
png: "image/png",
|
|
12297
|
+
jpg: "image/jpeg",
|
|
12298
|
+
jpeg: "image/jpeg",
|
|
12299
|
+
gif: "image/gif",
|
|
12300
|
+
svg: "image/svg+xml",
|
|
12301
|
+
webp: "image/webp"
|
|
12302
|
+
};
|
|
12303
|
+
var FALLBACK_MIME = "application/octet-stream";
|
|
12304
|
+
function inferMimeFromSrc(src) {
|
|
12305
|
+
const dot = src.lastIndexOf(".");
|
|
12306
|
+
if (dot < 0 || dot === src.length - 1) return FALLBACK_MIME;
|
|
12307
|
+
const ext = src.slice(dot + 1).toLowerCase();
|
|
12308
|
+
return EXT_MIME[ext] ?? FALLBACK_MIME;
|
|
12309
|
+
}
|
|
12310
|
+
function findImageBytes(src, resolver) {
|
|
12311
|
+
const active = resolver ?? activeResolver;
|
|
12312
|
+
if (active === null) return null;
|
|
12313
|
+
const result = active(src);
|
|
12314
|
+
if (result === null) return null;
|
|
12315
|
+
if (result instanceof Uint8Array) {
|
|
12316
|
+
return { bytes: result, mime: inferMimeFromSrc(src) };
|
|
12317
|
+
}
|
|
12318
|
+
return { bytes: result.bytes, mime: result.mime ?? inferMimeFromSrc(src) };
|
|
12319
|
+
}
|
|
12320
|
+
var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
12321
|
+
function base64Encode(bytes) {
|
|
12322
|
+
const len = bytes.length;
|
|
12323
|
+
const out = [];
|
|
12324
|
+
let i = 0;
|
|
12325
|
+
for (; i + 2 < len; i += 3) {
|
|
12326
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
12327
|
+
out.push(
|
|
12328
|
+
B64_CHARS[n >> 18 & 63],
|
|
12329
|
+
B64_CHARS[n >> 12 & 63],
|
|
12330
|
+
B64_CHARS[n >> 6 & 63],
|
|
12331
|
+
B64_CHARS[n & 63]
|
|
12332
|
+
);
|
|
12333
|
+
}
|
|
12334
|
+
const remaining = len - i;
|
|
12335
|
+
if (remaining === 1) {
|
|
12336
|
+
const n = bytes[i] << 16;
|
|
12337
|
+
out.push(B64_CHARS[n >> 18 & 63], B64_CHARS[n >> 12 & 63], "==");
|
|
12338
|
+
} else if (remaining === 2) {
|
|
12339
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8;
|
|
12340
|
+
out.push(
|
|
12341
|
+
B64_CHARS[n >> 18 & 63],
|
|
12342
|
+
B64_CHARS[n >> 12 & 63],
|
|
12343
|
+
B64_CHARS[n >> 6 & 63],
|
|
12344
|
+
"="
|
|
12345
|
+
);
|
|
12346
|
+
}
|
|
12347
|
+
return out.join("");
|
|
12348
|
+
}
|
|
12349
|
+
function toDataUri(bytes, mime) {
|
|
12350
|
+
return "data:" + mime + ";base64," + base64Encode(bytes);
|
|
12351
|
+
}
|
|
12352
|
+
|
|
12157
12353
|
// src/gvc/usershape.ts
|
|
12158
12354
|
var activeSizer = null;
|
|
12159
12355
|
function setImageSizer(sizer) {
|
|
@@ -12165,6 +12361,14 @@ function setImageSizer(sizer) {
|
|
|
12165
12361
|
function findImageSize(src) {
|
|
12166
12362
|
return activeSizer !== null ? activeSizer(src) : null;
|
|
12167
12363
|
}
|
|
12364
|
+
var STRERROR_ENOENT = "No such file or directory";
|
|
12365
|
+
function imageIsSupplied(name, sizer, resolver) {
|
|
12366
|
+
const size = sizer !== void 0 ? sizer(name) : findImageSize(name);
|
|
12367
|
+
return size !== null || findImageBytes(name, resolver) !== null;
|
|
12368
|
+
}
|
|
12369
|
+
function imageOpenWarning(name) {
|
|
12370
|
+
return `${STRERROR_ENOENT} while opening ${name}`;
|
|
12371
|
+
}
|
|
12168
12372
|
|
|
12169
12373
|
// src/common/pointset.ts
|
|
12170
12374
|
function cmpPair(a, b) {
|
|
@@ -12217,363 +12421,6 @@ var PointSet = class {
|
|
|
12217
12421
|
}
|
|
12218
12422
|
};
|
|
12219
12423
|
|
|
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
12424
|
// src/common/textmeasure-lut-data-a.ts
|
|
12578
12425
|
var TR = [
|
|
12579
12426
|
-1,
|
|
@@ -17416,7 +17263,7 @@ function getFamilyMetrics(fontName) {
|
|
|
17416
17263
|
if (!warnedFontNames.has(fontName)) {
|
|
17417
17264
|
warnedFontNames.add(fontName);
|
|
17418
17265
|
agwarningf(
|
|
17419
|
-
`no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
17266
|
+
`Warning: no hard-coded metrics for '${fontName}'. Falling back to 'Times' metrics`
|
|
17420
17267
|
);
|
|
17421
17268
|
}
|
|
17422
17269
|
return TIMES_FALLBACK;
|
|
@@ -17757,7 +17604,7 @@ function itemFace(item, finfo) {
|
|
|
17757
17604
|
face: item.fontFace !== void 0 ? item.fontFace : finfo.fontname
|
|
17758
17605
|
};
|
|
17759
17606
|
}
|
|
17760
|
-
function
|
|
17607
|
+
function measureItem(item, finfo, measurer) {
|
|
17761
17608
|
if (item.text === void 0) return null;
|
|
17762
17609
|
const { fs, face } = itemFace(item, finfo);
|
|
17763
17610
|
const flags = itemFontFlags(item);
|
|
@@ -17792,7 +17639,7 @@ function buildLineRuns(texts, finfo, measurer) {
|
|
|
17792
17639
|
if (cur.items.length === 0 && br !== void 0) {
|
|
17793
17640
|
const { br: _b, brAlign: _a, ...fontProps } = br;
|
|
17794
17641
|
const empty = { text: "", ...fontProps };
|
|
17795
|
-
const m =
|
|
17642
|
+
const m = measureItem(empty, finfo, measurer);
|
|
17796
17643
|
if (m !== null) accumulateItem(cur, empty, m);
|
|
17797
17644
|
}
|
|
17798
17645
|
cur.just = br?.brAlign;
|
|
@@ -17805,7 +17652,7 @@ function buildLineRuns(texts, finfo, measurer) {
|
|
|
17805
17652
|
flush(item);
|
|
17806
17653
|
continue;
|
|
17807
17654
|
}
|
|
17808
|
-
const m =
|
|
17655
|
+
const m = measureItem(item, finfo, measurer);
|
|
17809
17656
|
if (m !== null) accumulateItem(cur, item, m);
|
|
17810
17657
|
}
|
|
17811
17658
|
if (cur.items.length > 0) flush();
|
|
@@ -17896,6 +17743,313 @@ function placeComplexRuns(runs, box, finfo, measurer) {
|
|
|
17896
17743
|
return lines;
|
|
17897
17744
|
}
|
|
17898
17745
|
|
|
17746
|
+
// src/common/htmltable-fontinfo.ts
|
|
17747
|
+
var SIZE_SAVEF = { fontsize: 0 };
|
|
17748
|
+
var EMIT_SAVEF = { fontsize: 0 };
|
|
17749
|
+
var pushFontInfo = (env, fp, savp) => {
|
|
17750
|
+
if (fp.fontFace !== void 0) {
|
|
17751
|
+
savp.fontname = env.fontname;
|
|
17752
|
+
env.fontname = fp.fontFace;
|
|
17753
|
+
} else savp.fontname = void 0;
|
|
17754
|
+
if (env.fontcolor !== void 0) {
|
|
17755
|
+
if (fp.fontColor !== void 0) {
|
|
17756
|
+
savp.fontcolor = env.fontcolor;
|
|
17757
|
+
env.fontcolor = fp.fontColor;
|
|
17758
|
+
} else savp.fontcolor = void 0;
|
|
17759
|
+
}
|
|
17760
|
+
if (env.fontsize >= 0) {
|
|
17761
|
+
if (fp.fontSize !== void 0 && fp.fontSize >= 0) {
|
|
17762
|
+
savp.fontsize = env.fontsize;
|
|
17763
|
+
env.fontsize = fp.fontSize;
|
|
17764
|
+
} else savp.fontsize = -1;
|
|
17765
|
+
}
|
|
17766
|
+
};
|
|
17767
|
+
var popFontInfo = (env, savp) => {
|
|
17768
|
+
if (savp.fontname !== void 0) env.fontname = savp.fontname;
|
|
17769
|
+
if (savp.fontcolor !== void 0) env.fontcolor = savp.fontcolor;
|
|
17770
|
+
if (savp.fontsize >= 0) env.fontsize = savp.fontsize;
|
|
17771
|
+
};
|
|
17772
|
+
var withTableFont = (env, font, slot, fn) => {
|
|
17773
|
+
if (font === void 0) return fn();
|
|
17774
|
+
const savp = slot === "size" ? SIZE_SAVEF : EMIT_SAVEF;
|
|
17775
|
+
pushFontInfo(env, font, savp);
|
|
17776
|
+
const r = fn();
|
|
17777
|
+
popFontInfo(env, savp);
|
|
17778
|
+
return r;
|
|
17779
|
+
};
|
|
17780
|
+
|
|
17781
|
+
// src/common/htmltable.ts
|
|
17782
|
+
var DEFAULT_BORDER = 1;
|
|
17783
|
+
var DEFAULT_CELLPADDING = 2;
|
|
17784
|
+
var DEFAULT_CELLSPACING = 2;
|
|
17785
|
+
var DEFAULT_FONTSIZE = 14;
|
|
17786
|
+
var findCol = (ps, row, startCol, colspan, rowspan) => {
|
|
17787
|
+
let col = startCol;
|
|
17788
|
+
let notFound = true;
|
|
17789
|
+
const end = colspan - 1;
|
|
17790
|
+
while (notFound) {
|
|
17791
|
+
const lastc = col + end;
|
|
17792
|
+
let c;
|
|
17793
|
+
for (c = lastc; c >= col; c--) {
|
|
17794
|
+
if (ps.isInPS(c, row)) break;
|
|
17795
|
+
}
|
|
17796
|
+
if (c >= col) col = c + 1;
|
|
17797
|
+
else notFound = false;
|
|
17798
|
+
}
|
|
17799
|
+
for (let j = col; j < col + colspan; j++) {
|
|
17800
|
+
for (let i = row; i < row + rowspan; i++) {
|
|
17801
|
+
ps.addPS(j, i);
|
|
17802
|
+
}
|
|
17803
|
+
}
|
|
17804
|
+
return col;
|
|
17805
|
+
};
|
|
17806
|
+
var defaultSizeEnv = () => ({ fontsize: DEFAULT_FONTSIZE, fontname: "" });
|
|
17807
|
+
var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
17808
|
+
const lines = buildLineRuns(texts, env, measurer);
|
|
17809
|
+
const simple = runsAreSimple(lines, env);
|
|
17810
|
+
let w = 0;
|
|
17811
|
+
let h = 0;
|
|
17812
|
+
for (const ln of lines) {
|
|
17813
|
+
w = Math.max(w, ln.width);
|
|
17814
|
+
const lsize = simple ? ln.height : ln.fontSize;
|
|
17815
|
+
h += ln.items.length > 0 ? lsize : DEFAULT_FONTSIZE;
|
|
17816
|
+
}
|
|
17817
|
+
if (lines.length === 1) h = lines[0].items.length > 0 ? lines[0].height : DEFAULT_FONTSIZE;
|
|
17818
|
+
return { w, h };
|
|
17819
|
+
};
|
|
17820
|
+
var missingImages = { set: /* @__PURE__ */ new WeakSet() };
|
|
17821
|
+
var sizeHtmlImg = (img, { imageSizer, stderr }) => {
|
|
17822
|
+
if (img.width !== void 0 && img.height !== void 0) return missingImages.set.has(img) ? 1 : 0;
|
|
17823
|
+
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
17824
|
+
if (sz !== null) {
|
|
17825
|
+
img.width = sz.w;
|
|
17826
|
+
img.height = sz.h;
|
|
17827
|
+
return 0;
|
|
17828
|
+
}
|
|
17829
|
+
if (!imageIsSupplied(img.src, imageSizer)) agerrLine(stderr, `Warning: ${imageOpenWarning(img.src)}`);
|
|
17830
|
+
agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
|
|
17831
|
+
img.width = 0;
|
|
17832
|
+
img.height = 0;
|
|
17833
|
+
missingImages.set.add(img);
|
|
17834
|
+
return 1;
|
|
17835
|
+
};
|
|
17836
|
+
var sizeContentItem = (item, measurer, env) => {
|
|
17837
|
+
if (item.kind === "text") return { ...sizeTextContent([item], measurer, env), rv: 0 };
|
|
17838
|
+
if (item.kind === "table") {
|
|
17839
|
+
const rv = sizeTableInner(item, measurer, env);
|
|
17840
|
+
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
17841
|
+
}
|
|
17842
|
+
if (item.kind === "image") {
|
|
17843
|
+
const rv = sizeHtmlImg(item, env);
|
|
17844
|
+
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
17845
|
+
}
|
|
17846
|
+
return { w: 0, h: 0, rv: 0 };
|
|
17847
|
+
};
|
|
17848
|
+
var cellPad = (cell2, tbl) => cell2.cellpadding !== void 0 ? cell2.cellpadding : tbl.cellpadding !== void 0 ? tbl.cellpadding : DEFAULT_CELLPADDING;
|
|
17849
|
+
var cellBorder = (cell2, tbl) => {
|
|
17850
|
+
if (cell2.border !== void 0) return cell2.border;
|
|
17851
|
+
const cb = tbl.cellborder;
|
|
17852
|
+
if (cb !== void 0 && cb >= 0) return cb;
|
|
17853
|
+
if (tbl.border !== void 0) return tbl.border;
|
|
17854
|
+
return DEFAULT_BORDER;
|
|
17855
|
+
};
|
|
17856
|
+
function inheritTablePenColor(tbl, parentColor) {
|
|
17857
|
+
if (tbl.color === void 0) tbl.color = parentColor;
|
|
17858
|
+
const tblColor = tbl.color;
|
|
17859
|
+
for (const row of tbl.rows) {
|
|
17860
|
+
for (const cell2 of row.cells) {
|
|
17861
|
+
if (cell2.color === void 0) cell2.color = tblColor;
|
|
17862
|
+
for (const item of cell2.content) {
|
|
17863
|
+
if (item.kind === "table") inheritTablePenColor(item, cell2.color);
|
|
17864
|
+
}
|
|
17865
|
+
}
|
|
17866
|
+
}
|
|
17867
|
+
}
|
|
17868
|
+
var WARN_CELL_TOO_SMALL = "Warning: cell size too small for content";
|
|
17869
|
+
var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or height";
|
|
17870
|
+
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
17871
|
+
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
17872
|
+
var sizeWarned = { set: /* @__PURE__ */ new WeakSet() };
|
|
17873
|
+
registerRenderState(() => {
|
|
17874
|
+
missingImages.set = /* @__PURE__ */ new WeakSet();
|
|
17875
|
+
sizeWarned.set = /* @__PURE__ */ new WeakSet();
|
|
17876
|
+
});
|
|
17877
|
+
var fixedCellCheck = (cell2, sz, warn, out) => {
|
|
17878
|
+
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
17879
|
+
if (cell2.width && cell2.height) {
|
|
17880
|
+
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
17881
|
+
if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
|
|
17882
|
+
return { rv: small ? 1 : 0, zero: true };
|
|
17883
|
+
}
|
|
17884
|
+
if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
|
|
17885
|
+
return { rv: 1, zero: false };
|
|
17886
|
+
};
|
|
17887
|
+
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
17888
|
+
const margin = 2 * (cellPad(cell2, tbl) + cellBorder(cell2, tbl));
|
|
17889
|
+
let cw = 0, ch = 0, rv = 0;
|
|
17890
|
+
for (const item of cell2.content) {
|
|
17891
|
+
const s = sizeContentItem(item, measurer, env);
|
|
17892
|
+
cw = Math.max(cw, s.w);
|
|
17893
|
+
ch += s.h;
|
|
17894
|
+
rv |= s.rv;
|
|
17895
|
+
}
|
|
17896
|
+
let szx = cw + margin;
|
|
17897
|
+
let szy = ch + margin;
|
|
17898
|
+
const warn = !sizeWarned.set.has(cell2);
|
|
17899
|
+
sizeWarned.set.add(cell2);
|
|
17900
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
|
|
17901
|
+
rv |= fixed.rv;
|
|
17902
|
+
if (fixed.zero) {
|
|
17903
|
+
szx = 0;
|
|
17904
|
+
szy = 0;
|
|
17905
|
+
}
|
|
17906
|
+
const bw = cell2.width !== void 0 ? cell2.width : 0;
|
|
17907
|
+
const bh = cell2.height !== void 0 ? cell2.height : 0;
|
|
17908
|
+
return { w: Math.max(szx, bw), h: Math.max(szy, bh), rv };
|
|
17909
|
+
};
|
|
17910
|
+
var buildLayouts = (tbl, measurer, env) => {
|
|
17911
|
+
const entries = [];
|
|
17912
|
+
let rv = 0;
|
|
17913
|
+
const ps = new PointSet();
|
|
17914
|
+
let rowIdx = 0;
|
|
17915
|
+
for (const row of tbl.rows) {
|
|
17916
|
+
let col = 0;
|
|
17917
|
+
for (const c of row.cells) {
|
|
17918
|
+
if (c.kind !== "cell") {
|
|
17919
|
+
continue;
|
|
17920
|
+
}
|
|
17921
|
+
const colspan = c.colspan !== void 0 ? c.colspan : 1;
|
|
17922
|
+
const rowspan = c.rowspan !== void 0 ? c.rowspan : 1;
|
|
17923
|
+
const { w, h, rv: cellRv } = getCellSize(c, tbl, measurer, env);
|
|
17924
|
+
rv |= cellRv;
|
|
17925
|
+
col = findCol(ps, rowIdx, col, colspan, rowspan);
|
|
17926
|
+
entries.push({ cell: c, row: rowIdx, col, colspan, rowspan, w, h });
|
|
17927
|
+
col += colspan;
|
|
17928
|
+
}
|
|
17929
|
+
rowIdx++;
|
|
17930
|
+
}
|
|
17931
|
+
return { entries, rv };
|
|
17932
|
+
};
|
|
17933
|
+
var setColWidths = (entries, ncols, spacing) => {
|
|
17934
|
+
const widths = new Array(ncols + 1).fill(0);
|
|
17935
|
+
for (const e of entries)
|
|
17936
|
+
if (e.colspan === 1) widths[e.col] = Math.max(widths[e.col], e.w);
|
|
17937
|
+
for (const e of entries) {
|
|
17938
|
+
if (e.colspan === 1) continue;
|
|
17939
|
+
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
17940
|
+
const need = e.w - spanW - (e.colspan - 1) * spacing;
|
|
17941
|
+
if (need > 0) {
|
|
17942
|
+
const add2 = need / e.colspan;
|
|
17943
|
+
for (let j = 0; j < e.colspan; j++) widths[e.col + j] += add2;
|
|
17944
|
+
}
|
|
17945
|
+
}
|
|
17946
|
+
for (const e of entries) {
|
|
17947
|
+
const spanW = widths.slice(e.col, e.col + e.colspan).reduce((a, v) => a + v, 0);
|
|
17948
|
+
e.w = Math.max(e.w, spanW + (e.colspan - 1) * spacing);
|
|
17949
|
+
}
|
|
17950
|
+
return widths;
|
|
17951
|
+
};
|
|
17952
|
+
var setRowHeights = (entries, nrows, spacing) => {
|
|
17953
|
+
const heights = new Array(nrows + 1).fill(0);
|
|
17954
|
+
for (const e of entries)
|
|
17955
|
+
if (e.rowspan === 1) heights[e.row] = Math.max(heights[e.row], e.h);
|
|
17956
|
+
for (const e of entries) {
|
|
17957
|
+
if (e.rowspan === 1) continue;
|
|
17958
|
+
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
17959
|
+
const need = e.h - spanH - (e.rowspan - 1) * spacing;
|
|
17960
|
+
if (need > 0) {
|
|
17961
|
+
const add2 = need / e.rowspan;
|
|
17962
|
+
for (let j = 0; j < e.rowspan; j++) heights[e.row + j] += add2;
|
|
17963
|
+
}
|
|
17964
|
+
}
|
|
17965
|
+
for (const e of entries) {
|
|
17966
|
+
const spanH = heights.slice(e.row, e.row + e.rowspan).reduce((a, v) => a + v, 0);
|
|
17967
|
+
e.h = Math.max(e.h, spanH + (e.rowspan - 1) * spacing);
|
|
17968
|
+
}
|
|
17969
|
+
return heights;
|
|
17970
|
+
};
|
|
17971
|
+
var getSpacing = (tbl) => tbl.cellspacing !== void 0 ? tbl.cellspacing : DEFAULT_CELLSPACING;
|
|
17972
|
+
var getBorder = (tbl) => tbl.border !== void 0 ? tbl.border : DEFAULT_BORDER;
|
|
17973
|
+
var isTblFixed = (tbl) => tbl.fixedsize === true && tbl.width !== void 0 && tbl.height !== void 0;
|
|
17974
|
+
var sumTableDims = (a) => {
|
|
17975
|
+
let wd = (a.ncols + 1) * a.spacing + 2 * a.border;
|
|
17976
|
+
let ht = (a.nrows + 1) * a.spacing + 2 * a.border;
|
|
17977
|
+
for (let i = 0; i < a.ncols; i++) wd += a.widths[i];
|
|
17978
|
+
for (let i = 0; i < a.nrows; i++) ht += a.heights[i];
|
|
17979
|
+
return { wd, ht };
|
|
17980
|
+
};
|
|
17981
|
+
var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
17982
|
+
const spacing = getSpacing(tbl);
|
|
17983
|
+
const border2 = getBorder(tbl);
|
|
17984
|
+
const { entries, rv } = buildLayouts(tbl, measurer, env);
|
|
17985
|
+
if (entries.length === 0) {
|
|
17986
|
+
return { entries, widths: [], heights: [], spacing, border: border2, rv };
|
|
17987
|
+
}
|
|
17988
|
+
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
17989
|
+
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
17990
|
+
const widths = setColWidths(entries, ncols, spacing);
|
|
17991
|
+
const heights = setRowHeights(entries, nrows, spacing);
|
|
17992
|
+
return { entries, widths, heights, spacing, border: border2, rv };
|
|
17993
|
+
};
|
|
17994
|
+
var warnFixedTable = (tbl, dims, out) => {
|
|
17995
|
+
const warn = !sizeWarned.set.has(tbl);
|
|
17996
|
+
sizeWarned.set.add(tbl);
|
|
17997
|
+
if (tbl.fixedsize !== true) return 0;
|
|
17998
|
+
if (tbl.width && tbl.height) {
|
|
17999
|
+
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
18000
|
+
if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
|
|
18001
|
+
return 1;
|
|
18002
|
+
}
|
|
18003
|
+
if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
|
|
18004
|
+
return 1;
|
|
18005
|
+
};
|
|
18006
|
+
var sizeTableBody = (tbl, measurer, env) => {
|
|
18007
|
+
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
18008
|
+
if (entries.length === 0) {
|
|
18009
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
|
|
18010
|
+
tbl.dimen = { w: 0, h: 0 };
|
|
18011
|
+
return rv | fixed2;
|
|
18012
|
+
}
|
|
18013
|
+
const ncols = Math.max(...entries.map((e) => e.col + e.colspan));
|
|
18014
|
+
const nrows = Math.max(...entries.map((e) => e.row + e.rowspan));
|
|
18015
|
+
for (const e of entries) e.cell.dimen = { w: e.w, h: e.h };
|
|
18016
|
+
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
18017
|
+
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
18018
|
+
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
18019
|
+
const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
|
|
18020
|
+
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
18021
|
+
tbl.dimen = {
|
|
18022
|
+
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
18023
|
+
h: Math.max(zeroContent ? 0 : ht, baseHt)
|
|
18024
|
+
};
|
|
18025
|
+
return rv | fixed;
|
|
18026
|
+
};
|
|
18027
|
+
var sizeTableInner = (tbl, measurer, env) => withTableFont(env, tbl.font, "size", () => sizeTableBody(tbl, measurer, env));
|
|
18028
|
+
var sizeHtmlLabel = (label, measurer, env = defaultSizeEnv()) => {
|
|
18029
|
+
if (label.kind === "table") {
|
|
18030
|
+
const rv = sizeTableInner(label.table, measurer, env);
|
|
18031
|
+
label.dimen = label.table.dimen;
|
|
18032
|
+
return rv;
|
|
18033
|
+
}
|
|
18034
|
+
label.dimen = sizeTextContent(label.texts, measurer, env);
|
|
18035
|
+
return 0;
|
|
18036
|
+
};
|
|
18037
|
+
|
|
18038
|
+
// src/common/splines-constants.ts
|
|
18039
|
+
var REGULAREDGE = 1;
|
|
18040
|
+
var FLATEDGE = 2;
|
|
18041
|
+
var ARR_NONE = 0;
|
|
18042
|
+
var BOTTOM = 1 << 0;
|
|
18043
|
+
var RIGHT = 1 << 1;
|
|
18044
|
+
var TOP = 1 << 2;
|
|
18045
|
+
var LEFT = 1 << 3;
|
|
18046
|
+
var SELF_EDGE_SIZE = 18;
|
|
18047
|
+
var MILLIPOINT = 1e-3;
|
|
18048
|
+
var FUDGE = 2;
|
|
18049
|
+
var INIT_DELTA = 10;
|
|
18050
|
+
var LOOP_TRIES = 15;
|
|
18051
|
+
var ROUTESPL_FUDGE = 1e-4;
|
|
18052
|
+
|
|
17899
18053
|
// src/common/htmltable-pos.ts
|
|
17900
18054
|
function alignContentBox(box, cell2, w, h) {
|
|
17901
18055
|
const out = { ll: { ...box.ll }, ur: { ...box.ur } };
|
|
@@ -18693,7 +18847,7 @@ function transformUnitVertex(R2, g, c, bb) {
|
|
|
18693
18847
|
const r = libmHypot(D.x, D.y);
|
|
18694
18848
|
return { x: r * Math.cos(alpha) * bb.x, y: r * Math.sin(alpha) * bb.y };
|
|
18695
18849
|
}
|
|
18696
|
-
function polygonVertices(bb, g,
|
|
18850
|
+
function polygonVertices(bb, g, isBox4) {
|
|
18697
18851
|
const sectorangle = 2 * Math.PI / g.sides;
|
|
18698
18852
|
const sidelength = Math.sin(sectorangle / 2);
|
|
18699
18853
|
const c = {
|
|
@@ -18711,7 +18865,7 @@ function polygonVertices(bb, g, isBox3) {
|
|
|
18711
18865
|
R2.y = fma(sidelength, Math.sin(angle), R2.y);
|
|
18712
18866
|
const P = transformUnitVertex(R2, g, c, bb);
|
|
18713
18867
|
verts.push(P);
|
|
18714
|
-
if (
|
|
18868
|
+
if (isBox4) {
|
|
18715
18869
|
verts.push({ x: -P.x, y: P.y }, { x: -P.x, y: -P.y }, { x: P.x, y: -P.y });
|
|
18716
18870
|
break;
|
|
18717
18871
|
}
|
|
@@ -18802,14 +18956,14 @@ function starVertexGen(bb) {
|
|
|
18802
18956
|
}
|
|
18803
18957
|
return { verts: starVertices(bb.x, bb.y), xmax: sz.x / 2, ymax: sz.y / 2 };
|
|
18804
18958
|
}
|
|
18805
|
-
function polygonBB(bb, minSize, p, sides2,
|
|
18959
|
+
function polygonBB(bb, minSize, p, sides2, isBox4) {
|
|
18806
18960
|
const geom = {
|
|
18807
18961
|
sides: sides2,
|
|
18808
18962
|
orientation: p.orientation,
|
|
18809
18963
|
distortion: p.distortion,
|
|
18810
18964
|
skew: p.skew
|
|
18811
18965
|
};
|
|
18812
|
-
const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom,
|
|
18966
|
+
const { verts, xmax, ymax } = p.optionShape === STAR ? starVertexGen(bb) : polygonVertices(bb, geom, isBox4);
|
|
18813
18967
|
const xmax2 = 2 * xmax;
|
|
18814
18968
|
const ymax2 = 2 * ymax;
|
|
18815
18969
|
const nbb = { x: Math.max(minSize.x, xmax2), y: Math.max(minSize.y, ymax2) };
|
|
@@ -18821,7 +18975,7 @@ function polygonBB(bb, minSize, p, sides2, isBox3) {
|
|
|
18821
18975
|
v.x *= scalex;
|
|
18822
18976
|
v.y *= scaley;
|
|
18823
18977
|
}
|
|
18824
|
-
return { ...polygonPeripheryBB(verts,
|
|
18978
|
+
return { ...polygonPeripheryBB(verts, isBox4 ? 4 : sides2, p, nbb), base: nbb };
|
|
18825
18979
|
}
|
|
18826
18980
|
function gvNodesize(widthPts, heightPts, flip) {
|
|
18827
18981
|
if (flip) return { lw: heightPts / 2, rw: heightPts / 2, ht: widthPts };
|
|
@@ -18846,9 +19000,9 @@ function applySizeConstraints(p, bb0, width0, height0) {
|
|
|
18846
19000
|
function polySize(p) {
|
|
18847
19001
|
const init = initialSizePts(p);
|
|
18848
19002
|
const dimen = quantize(padLabelDimen(p.labelDimen, p.margin, p.isPlain), p.quantumIn);
|
|
18849
|
-
const { sides: sides2, isBox:
|
|
19003
|
+
const { sides: sides2, isBox: isBox4 } = effectiveShape(p);
|
|
18850
19004
|
let bb = { x: dimen.x, y: dimen.y };
|
|
18851
|
-
if (
|
|
19005
|
+
if (isBox4) {
|
|
18852
19006
|
} else if (p.optionShape === STAR) {
|
|
18853
19007
|
bb = starSize(bb);
|
|
18854
19008
|
} else if (p.optionShape === CYLINDER) {
|
|
@@ -18860,16 +19014,16 @@ function polySize(p) {
|
|
|
18860
19014
|
const c = applySizeConstraints(p, bb, init.width, init.height);
|
|
18861
19015
|
const penwidth = p.penwidth ?? 1;
|
|
18862
19016
|
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,
|
|
19017
|
+
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
19018
|
const result = assembleResult(p, dimen, grown, c.fixedshape);
|
|
18865
|
-
return { ...result, ...labelSpace(p, dimen, c.bb, minBb,
|
|
19019
|
+
return { ...result, ...labelSpace(p, dimen, c.bb, minBb, isBox4, c.fixedshape) };
|
|
18866
19020
|
}
|
|
18867
|
-
function labelSpace(p, dimen, bb, minBb,
|
|
19021
|
+
function labelSpace(p, dimen, bb, minBb, isBox4, fixedshape) {
|
|
18868
19022
|
const spacex = dimen.x - p.labelDimen.x;
|
|
18869
19023
|
let spaceX;
|
|
18870
19024
|
if (p.nojustify) {
|
|
18871
19025
|
spaceX = dimen.x - spacex;
|
|
18872
|
-
} else if (
|
|
19026
|
+
} else if (isBox4) {
|
|
18873
19027
|
spaceX = Math.max(dimen.x, bb.x) - spacex;
|
|
18874
19028
|
} else if (dimen.y < bb.y) {
|
|
18875
19029
|
spaceX = Math.max(dimen.x, bb.x * Math.sqrt(1 - dimen.y * dimen.y / (bb.y * bb.y))) - spacex;
|
|
@@ -18882,8 +19036,8 @@ function labelSpace(p, dimen, bb, minBb, isBox3, fixedshape) {
|
|
|
18882
19036
|
function effectiveShape(p) {
|
|
18883
19037
|
let sides2 = p.sides;
|
|
18884
19038
|
if (sides2 <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides2 = 120;
|
|
18885
|
-
const
|
|
18886
|
-
return { sides: sides2, isBox:
|
|
19039
|
+
const isBox4 = sides2 === 4 && Math.abs(p.orientation % 90) < 0.5 && p.distortion === 0 && p.skew === 0;
|
|
19040
|
+
return { sides: sides2, isBox: isBox4 };
|
|
18887
19041
|
}
|
|
18888
19042
|
function labelValign(p) {
|
|
18889
19043
|
const ll = p.labelloc?.[0];
|
|
@@ -18977,7 +19131,7 @@ function copyVirtualEdgeInfo(e, orig) {
|
|
|
18977
19131
|
e.seq = orig.seq;
|
|
18978
19132
|
}
|
|
18979
19133
|
function newVirtualEdge(u, v, orig) {
|
|
18980
|
-
const e = new Edge(u, v, "");
|
|
19134
|
+
const e = new Edge(u, v, "", true);
|
|
18981
19135
|
e.info.edge_type = VIRTUAL;
|
|
18982
19136
|
if (orig) {
|
|
18983
19137
|
copyVirtualEdgeInfo(e, orig);
|
|
@@ -19078,7 +19232,7 @@ function removeFromRank(g, n) {
|
|
|
19078
19232
|
}
|
|
19079
19233
|
}
|
|
19080
19234
|
function virtualNode(g) {
|
|
19081
|
-
const n = new Node(0, "", g.root);
|
|
19235
|
+
const n = new Node(0, "", g.root, true);
|
|
19082
19236
|
n.info.node_type = VIRTUAL;
|
|
19083
19237
|
n.info.lw = 1;
|
|
19084
19238
|
n.info.rw = 1;
|
|
@@ -19370,10 +19524,10 @@ var ARROW_EPSILON = 1e-4;
|
|
|
19370
19524
|
var vsub2 = (p, q) => ({ x: p.x - q.x, y: p.y - q.y });
|
|
19371
19525
|
var vadd2 = (p, q) => ({ x: p.x + q.x, y: p.y + q.y });
|
|
19372
19526
|
var vscale = (c, p) => ({ x: c * p.x, y: c * p.y });
|
|
19373
|
-
var negUnit = (u,
|
|
19527
|
+
var negUnit = (u, dist5) => {
|
|
19374
19528
|
if (u.x === 0 && u.y === 0) return { x: 0, y: 0 };
|
|
19375
19529
|
const h = Math.hypot(u.x, u.y);
|
|
19376
|
-
return { x:
|
|
19530
|
+
return { x: dist5 * (-u.x / h), y: dist5 * (-u.y / h) };
|
|
19377
19531
|
};
|
|
19378
19532
|
var backwardDelta = (u, penwidth) => negUnit(u, penwidth / 2);
|
|
19379
19533
|
function axialProjection(phiSrc, from, to, sign2) {
|
|
@@ -19922,9 +20076,9 @@ function makeEllipseInsideFn(rx, ry, penwidth = DEFAULT_NODEPENWIDTH) {
|
|
|
19922
20076
|
return (lx, ly) => lx * lx / (erx * erx) + ly * ly / (ery * ery) < 1;
|
|
19923
20077
|
}
|
|
19924
20078
|
function tailArrowEndClip(path4, tailTip, elen) {
|
|
19925
|
-
|
|
19926
|
-
const
|
|
19927
|
-
return
|
|
20079
|
+
const sp = [path4[3], path4[2], path4[1], tailTip];
|
|
20080
|
+
const clipped = elen > 0 ? bezierClipNode(sp, 0, 0, (x, y) => distFused({ x, y }, tailTip) <= elen, false) : sp;
|
|
20081
|
+
return [clipped[3], clipped[2], clipped[1], clipped[0]];
|
|
19928
20082
|
}
|
|
19929
20083
|
|
|
19930
20084
|
// src/layout/dot/edge-route-geom.ts
|
|
@@ -19983,6 +20137,7 @@ function arrowDrawOpsForEnd(e, end, tip2, dir, penwidth) {
|
|
|
19983
20137
|
|
|
19984
20138
|
// src/common/splines-clip.ts
|
|
19985
20139
|
var ARR_NORM = 1;
|
|
20140
|
+
var dist = distFused;
|
|
19986
20141
|
var SplineClipHelper = class _SplineClipHelper {
|
|
19987
20142
|
static makeEmptySpl() {
|
|
19988
20143
|
return { list: [], size: 0, bb: { ll: { x: 0, y: 0 }, ur: { x: 0, y: 0 } } };
|
|
@@ -20075,15 +20230,11 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20075
20230
|
if (j) return [eflag, sflag];
|
|
20076
20231
|
return [sflag, eflag];
|
|
20077
20232
|
}
|
|
20078
|
-
/** DIST(p, q). */
|
|
20079
|
-
static dist(p, q) {
|
|
20080
|
-
return Math.hypot(p.x - q.x, p.y - q.y);
|
|
20081
|
-
}
|
|
20082
20233
|
/** Sphere inside-fn around `tip` with radius `r` for bezierClip. */
|
|
20083
20234
|
static sphereCtx(tip2, r) {
|
|
20084
20235
|
return {
|
|
20085
20236
|
ctx: { nodeCoord: { x: 0, y: 0 }, rw: 0, bp: null },
|
|
20086
|
-
fn: (_c, p) =>
|
|
20237
|
+
fn: (_c, p) => dist(p, tip2) <= r
|
|
20087
20238
|
};
|
|
20088
20239
|
}
|
|
20089
20240
|
/**
|
|
@@ -20115,7 +20266,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20115
20266
|
);
|
|
20116
20267
|
spl.eflag = eflag;
|
|
20117
20268
|
spl.ep = ps[endp + 3];
|
|
20118
|
-
if (endp > startp &&
|
|
20269
|
+
if (endp > startp && dist(ps[endp], ps[endp + 3]) < elen) {
|
|
20119
20270
|
endp -= 3;
|
|
20120
20271
|
}
|
|
20121
20272
|
const sp = [spl.ep, ps[endp + 2], ps[endp + 1], ps[endp]];
|
|
@@ -20142,7 +20293,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20142
20293
|
);
|
|
20143
20294
|
spl.sflag = sflag;
|
|
20144
20295
|
spl.sp = ps[startp];
|
|
20145
|
-
if (endp > startp &&
|
|
20296
|
+
if (endp > startp && dist(ps[startp], ps[startp + 3]) < slen) {
|
|
20146
20297
|
startp += 3;
|
|
20147
20298
|
}
|
|
20148
20299
|
const sp = [ps[startp + 3], ps[startp + 2], ps[startp + 1], spl.sp];
|
|
@@ -20243,7 +20394,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20243
20394
|
if (sflag && eflag && endp === startp) {
|
|
20244
20395
|
const p = ps[endp];
|
|
20245
20396
|
const q = ps[endp + 3];
|
|
20246
|
-
const d =
|
|
20397
|
+
const d = dist(p, q);
|
|
20247
20398
|
let hlen = hlen0;
|
|
20248
20399
|
let tlen = tlen0;
|
|
20249
20400
|
if (hlen + tlen >= d) {
|
|
@@ -20286,7 +20437,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20286
20437
|
let hlen = hlen0;
|
|
20287
20438
|
const p = ps[endp];
|
|
20288
20439
|
const q = ps[endp + 3];
|
|
20289
|
-
const maxd = 0.9 *
|
|
20440
|
+
const maxd = 0.9 * dist(p, q);
|
|
20290
20441
|
if (hlen >= maxd) hlen = maxd;
|
|
20291
20442
|
const r = { x: p.x, y: p.y };
|
|
20292
20443
|
if (p.y === q.y) {
|
|
@@ -20306,7 +20457,7 @@ var SplineClipHelper = class _SplineClipHelper {
|
|
|
20306
20457
|
let tlen = tlen0;
|
|
20307
20458
|
const p = ps[startp];
|
|
20308
20459
|
const q = ps[startp + 3];
|
|
20309
|
-
const maxd = 0.9 *
|
|
20460
|
+
const maxd = 0.9 * dist(p, q);
|
|
20310
20461
|
if (tlen >= maxd) tlen = maxd;
|
|
20311
20462
|
const r = { x: p.x, y: p.y };
|
|
20312
20463
|
if (p.y === q.y) {
|
|
@@ -22538,13 +22689,13 @@ function dfsNode(Xg, v, frames) {
|
|
|
22538
22689
|
frames.push({ v, edges: v.outEdges(Xg).slice(), i: 0 });
|
|
22539
22690
|
}
|
|
22540
22691
|
function dfsStep2(Xg, frames) {
|
|
22541
|
-
const
|
|
22542
|
-
if (
|
|
22543
|
-
const e =
|
|
22692
|
+
const fr7 = frames[frames.length - 1];
|
|
22693
|
+
if (fr7.i < fr7.edges.length) {
|
|
22694
|
+
const e = fr7.edges[fr7.i++];
|
|
22544
22695
|
if (e.head.info.onstack) reverseEdge2(Xg, e);
|
|
22545
22696
|
else if (!e.head.info.mark) dfsNode(Xg, e.head, frames);
|
|
22546
22697
|
} else {
|
|
22547
|
-
|
|
22698
|
+
fr7.v.info.onstack = 0;
|
|
22548
22699
|
frames.pop();
|
|
22549
22700
|
}
|
|
22550
22701
|
}
|
|
@@ -23718,7 +23869,7 @@ function pruneForeignClusterNodes(par, clust) {
|
|
|
23718
23869
|
}
|
|
23719
23870
|
function markClusterNode(clust, n, g) {
|
|
23720
23871
|
if ((n.info.ranktype ?? 0) !== 0) {
|
|
23721
|
-
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}
|
|
23872
|
+
agwarningf(`${n.name} was already in a rankset, deleted from cluster ${g.name}`);
|
|
23722
23873
|
agDeleteFromCluster(clust, n);
|
|
23723
23874
|
return;
|
|
23724
23875
|
}
|
|
@@ -24973,17 +25124,27 @@ function buildNodeLabel(n, g, measurer) {
|
|
|
24973
25124
|
const content = isHtml ? htmlValueContent(labelAttr) : labelAttr ?? n.name;
|
|
24974
25125
|
n.info.label = makeAnyLabel(content, isHtml, font, measurer, n);
|
|
24975
25126
|
}
|
|
25127
|
+
function warnMissingImage(n, g, shapefile) {
|
|
25128
|
+
if (shapefile !== void 0 && shapefile !== "" && nodeAttr(n, g, "shape") !== "epsf") return;
|
|
25129
|
+
const image = nodeAttr(n, g, "image");
|
|
25130
|
+
if (image === void 0 || image === "") return;
|
|
25131
|
+
const gvc = g.root.info.gvc;
|
|
25132
|
+
if (imageIsSupplied(image, gvc?.imageSizer, gvc?.imageResolver)) return;
|
|
25133
|
+
agwarningf(imageOpenWarning(image));
|
|
25134
|
+
agwarningf(`No or improper image="${image}" for node "${n.name}"`);
|
|
25135
|
+
}
|
|
24976
25136
|
function polyInit(n, g, measurer) {
|
|
24977
25137
|
const shapeName2 = nodeAttr(n, g, "shape") ?? "ellipse";
|
|
24978
25138
|
const shapefile = nodeAttr(n, g, "shapefile");
|
|
24979
25139
|
n.info.shape = bindShape(shapeName2, shapefile);
|
|
24980
25140
|
if (shapefile !== void 0 && shapefile !== "" && shapeName2 !== "epsf") {
|
|
24981
|
-
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"
|
|
25141
|
+
agwarningf(`No or improper shapefile="${shapefile}" for node "${n.name}"`);
|
|
24982
25142
|
}
|
|
24983
25143
|
if (n.info.shape.kind === 2 /* SH_RECORD */) {
|
|
24984
25144
|
if (n.info.shape_info === void 0) recordNodeInit(n, g, measurer);
|
|
24985
25145
|
return;
|
|
24986
25146
|
}
|
|
25147
|
+
warnMissingImage(n, g, shapefile);
|
|
24987
25148
|
buildNodeLabel(n, g, measurer);
|
|
24988
25149
|
if (n.info.shape_info !== void 0) return;
|
|
24989
25150
|
const polyDesc = n.info.shape.polygon;
|
|
@@ -25109,8 +25270,8 @@ function drawWedge(seg2, e, ctx) {
|
|
|
25109
25270
|
ctx.renderer.bezier(ptsUp.map((p) => ({ x: p.x, y: -p.y })), true, ctx.job);
|
|
25110
25271
|
return angle1;
|
|
25111
25272
|
}
|
|
25112
|
-
function wedgedEllipse(job, pf, clrs, renderer) {
|
|
25113
|
-
const { segs, error } = parseSegs(clrs);
|
|
25273
|
+
function wedgedEllipse(job, pf, clrs, renderer, context) {
|
|
25274
|
+
const { segs, error } = parseSegs(clrs, context);
|
|
25114
25275
|
if (error === 1 || error === 2) return error;
|
|
25115
25276
|
const ctrX = (pf[0].x + pf[1].x) / 2;
|
|
25116
25277
|
const ctrY = (pf[0].y + pf[1].y) / 2;
|
|
@@ -25142,8 +25303,8 @@ function drawBand(p, seg2, ctx) {
|
|
|
25142
25303
|
ctx.renderer.polygon([...p], true, ctx.job);
|
|
25143
25304
|
p[0].x = p[3].x = p[1].x;
|
|
25144
25305
|
}
|
|
25145
|
-
function stripedBox(job, pts, clrs, rotate, renderer) {
|
|
25146
|
-
const { segs, error } = parseSegs(clrs);
|
|
25306
|
+
function stripedBox(job, pts, clrs, rotate, renderer, context) {
|
|
25307
|
+
const { segs, error } = parseSegs(clrs, context);
|
|
25147
25308
|
if (error === 1 || error === 2) return error;
|
|
25148
25309
|
const p = rotate ? [{ ...pts[2] }, { ...pts[3] }, { ...pts[0] }, { ...pts[1] }] : [{ ...pts[0] }, { ...pts[1] }, { ...pts[2] }, { ...pts[3] }];
|
|
25149
25310
|
const lastx = p[1].x;
|
|
@@ -25301,6 +25462,27 @@ function escapeXmlText(s) {
|
|
|
25301
25462
|
return gvXmlEscape(s, FLAGS_TEXT);
|
|
25302
25463
|
}
|
|
25303
25464
|
|
|
25465
|
+
// src/gvc/device-transform.ts
|
|
25466
|
+
function transformPoint(p, job) {
|
|
25467
|
+
if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
|
|
25468
|
+
return p;
|
|
25469
|
+
}
|
|
25470
|
+
const sx = job.zoom * job.devscale.x;
|
|
25471
|
+
const sy = job.zoom * job.devscale.y;
|
|
25472
|
+
const tx = job.translation.x;
|
|
25473
|
+
const ty = job.translation.y;
|
|
25474
|
+
return applyScale(p, tx, ty, sx, sy);
|
|
25475
|
+
}
|
|
25476
|
+
function applyScale(p, tx, ty, sx, sy) {
|
|
25477
|
+
const x = (p.x + tx) * sx;
|
|
25478
|
+
const y = (p.y + ty) * sy;
|
|
25479
|
+
return buildPoint(x, y);
|
|
25480
|
+
}
|
|
25481
|
+
function buildPoint(x, y) {
|
|
25482
|
+
const pt = { x, y };
|
|
25483
|
+
return pt;
|
|
25484
|
+
}
|
|
25485
|
+
|
|
25304
25486
|
// src/gvc/device-cluster.ts
|
|
25305
25487
|
function applyClusterGradient(obj, fill) {
|
|
25306
25488
|
obj.fill = fill.kind === "radial" ? 3 /* Radial */ : 2 /* Linear */;
|
|
@@ -25348,6 +25530,7 @@ function applyClusterObjState(sg, job) {
|
|
|
25348
25530
|
const fillRes = resolveClusterFillEx(clusterAttrsOf(sg));
|
|
25349
25531
|
if (job.obj === null) return false;
|
|
25350
25532
|
const obj = job.obj;
|
|
25533
|
+
gvrenderSetStyle(checkClusterStyleTokens(styleTokens(clusterStyle(sg))));
|
|
25351
25534
|
return withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
25352
25535
|
const filled = applyClusterFill(obj, fillRes);
|
|
25353
25536
|
applyClusterPenState(obj, sg);
|
|
@@ -25355,17 +25538,47 @@ function applyClusterObjState(sg, job) {
|
|
|
25355
25538
|
return filled;
|
|
25356
25539
|
});
|
|
25357
25540
|
}
|
|
25358
|
-
function
|
|
25541
|
+
function isStripedCluster(sg) {
|
|
25542
|
+
const flags = parseStyleFlags(clusterStyle(sg));
|
|
25543
|
+
return flags.striped && !flags.rounded;
|
|
25544
|
+
}
|
|
25545
|
+
function stripedFillSpec(sg) {
|
|
25359
25546
|
const flags = parseStyleFlags(clusterStyle(sg));
|
|
25360
|
-
if (!flags.striped || flags.rounded) return [];
|
|
25361
25547
|
const color = clusterAttr(sg, "color") ?? "";
|
|
25362
25548
|
let fill = clusterAttr(sg, "fillcolor") || color;
|
|
25363
25549
|
const bg = clusterAttr(sg, "bgcolor") ?? "";
|
|
25364
25550
|
if ((!flags.filled || fill === "") && bg !== "") fill = bg;
|
|
25365
|
-
|
|
25551
|
+
return fill === "" ? "lightgrey" : fill;
|
|
25552
|
+
}
|
|
25553
|
+
function stripedClusterColors(sg) {
|
|
25554
|
+
if (!isStripedCluster(sg)) return [];
|
|
25555
|
+
const { segs, error } = parseSegs(stripedFillSpec(sg), () => `in cluster ${sg.name}`);
|
|
25366
25556
|
if (error === 1 || error === 2) return [];
|
|
25367
25557
|
return segs.flatMap((seg2) => seg2.color !== null && seg2.t > 0 ? [seg2.color] : []);
|
|
25368
25558
|
}
|
|
25559
|
+
function renderStripedClusterBox(sg, renderer, job) {
|
|
25560
|
+
withColorScheme(clusterAttr(sg, "colorscheme"), () => {
|
|
25561
|
+
const { ll, ur } = sg.info.bb;
|
|
25562
|
+
const af = [
|
|
25563
|
+
{ x: ll.x, y: ll.y },
|
|
25564
|
+
{ x: ur.x, y: ll.y },
|
|
25565
|
+
{ x: ur.x, y: ur.y },
|
|
25566
|
+
{ x: ll.x, y: ur.y }
|
|
25567
|
+
].map((p) => transformPoint(p, job));
|
|
25568
|
+
const obj = job.obj;
|
|
25569
|
+
const savedFill = obj?.fill;
|
|
25570
|
+
if (obj !== null && savedFill !== void 0) obj.fill = 1 /* Solid */;
|
|
25571
|
+
stripedBox(job, af, stripedFillSpec(sg), false, renderer, () => `in cluster ${sg.name}`);
|
|
25572
|
+
if (obj !== null && savedFill !== void 0) obj.fill = savedFill;
|
|
25573
|
+
const rawPts = [
|
|
25574
|
+
{ x: ll.x, y: ll.y },
|
|
25575
|
+
{ x: ll.x, y: ur.y },
|
|
25576
|
+
{ x: ur.x, y: ur.y },
|
|
25577
|
+
{ x: ur.x, y: ll.y }
|
|
25578
|
+
];
|
|
25579
|
+
renderer.polygon(rawPts.map((p) => transformPoint(p, job)), false, job);
|
|
25580
|
+
});
|
|
25581
|
+
}
|
|
25369
25582
|
function applyClusterFill(obj, fillRes) {
|
|
25370
25583
|
if (fillRes.kind === "none") {
|
|
25371
25584
|
obj.fill = 0 /* None */;
|
|
@@ -25431,7 +25644,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
|
25431
25644
|
const pf = ring.map(
|
|
25432
25645
|
(v) => transformPoint({ x: v.x + coord.x, y: v.y + coord.y }, ctx.job)
|
|
25433
25646
|
);
|
|
25434
|
-
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer);
|
|
25647
|
+
wedgedEllipse(ctx.job, pf, ctx.fillcolor, ctx.renderer, () => `in node ${ctx.nodeName}`);
|
|
25435
25648
|
renderEllipse(ring, coord, ctx.renderer, ctx.job, false);
|
|
25436
25649
|
} else {
|
|
25437
25650
|
renderEllipse(ring, coord, ctx.renderer, ctx.job, filled);
|
|
@@ -25440,7 +25653,7 @@ function renderEllipseRing(ring, coord, filled, j, ctx) {
|
|
|
25440
25653
|
}
|
|
25441
25654
|
function renderStripedRing(ring, coord, ctx) {
|
|
25442
25655
|
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);
|
|
25656
|
+
stripedBox(ctx.job, af, ctx.fillcolor, true, ctx.renderer, () => `in node ${ctx.nodeName}`);
|
|
25444
25657
|
renderPolygon(ring, coord, ctx.renderer, ctx.job, false);
|
|
25445
25658
|
}
|
|
25446
25659
|
function renderPolyRing(ring, coord, filled, j, ctx) {
|
|
@@ -25566,6 +25779,10 @@ function applyPenState(obj, styleAttr, colorAttr, penwidthAttr) {
|
|
|
25566
25779
|
function applyNodeStyle(obj, n, job) {
|
|
25567
25780
|
const styleAttr = nodeAttr(n, n.root, "style");
|
|
25568
25781
|
const colorAttr = nodeAttr(n, n.root, "color");
|
|
25782
|
+
if (!isPointNode(n)) {
|
|
25783
|
+
const shape = n.info.shape;
|
|
25784
|
+
gvrenderSetStyle(checkStyleTokens(styleTokens(styleAttr), shape?.polygon ?? null));
|
|
25785
|
+
}
|
|
25569
25786
|
const penwidth = nodeAttr(n, n.root, "penwidth");
|
|
25570
25787
|
if (n.info.shape?.kind === 2 /* SH_RECORD */) {
|
|
25571
25788
|
applyPenState(obj, styleAttr, colorAttr, penwidth);
|
|
@@ -25577,7 +25794,7 @@ function applyNodeStyle(obj, n, job) {
|
|
|
25577
25794
|
}
|
|
25578
25795
|
function prepareDrawPoly(poly, filled, obj) {
|
|
25579
25796
|
if (poly.peripheries !== 0 || !filled) return poly;
|
|
25580
|
-
obj.penColor =
|
|
25797
|
+
obj.penColor = resolveRenderColor("transparent");
|
|
25581
25798
|
return { ...poly, peripheries: 1 };
|
|
25582
25799
|
}
|
|
25583
25800
|
function vertexScale(n, poly) {
|
|
@@ -25607,6 +25824,7 @@ function resolveNodeDrawCtx(job, n) {
|
|
|
25607
25824
|
job,
|
|
25608
25825
|
style: styleFlags,
|
|
25609
25826
|
fillcolor: nodeAttr(n, n.root, "fillcolor") ?? "",
|
|
25827
|
+
nodeName: n.name,
|
|
25610
25828
|
...specialCornerFlags(drawPoly.option, styleFlags)
|
|
25611
25829
|
};
|
|
25612
25830
|
return { poly: drawPoly, coord, filled, ringCtx };
|
|
@@ -25915,7 +26133,7 @@ function findCharset(g) {
|
|
|
25915
26133
|
}
|
|
25916
26134
|
if (p === "big-5" || p === "big5") return CHAR_BIG5;
|
|
25917
26135
|
if (p === "utf-8" || p === "utf8") return CHAR_UTF8;
|
|
25918
|
-
agwarningf(`Unsupported charset "${raw}" - assuming utf-8
|
|
26136
|
+
agwarningf(`Unsupported charset "${raw}" - assuming utf-8`);
|
|
25919
26137
|
return CHAR_UTF8;
|
|
25920
26138
|
}
|
|
25921
26139
|
function maptoken(p, names, vals) {
|
|
@@ -26133,7 +26351,7 @@ function portToTbl(tbl, id) {
|
|
|
26133
26351
|
}
|
|
26134
26352
|
|
|
26135
26353
|
// src/common/compass-port.ts
|
|
26136
|
-
function
|
|
26354
|
+
function isBox2(n) {
|
|
26137
26355
|
return n.info.shape?.polygon === P_BOX;
|
|
26138
26356
|
}
|
|
26139
26357
|
function gdRankdir(n) {
|
|
@@ -26324,7 +26542,7 @@ function compassPort(n, args, pp) {
|
|
|
26324
26542
|
const { bp, compass, sides: sides2 } = args;
|
|
26325
26543
|
const { b, p, defined: defBp } = compassBbox(n, bp);
|
|
26326
26544
|
const dir = compassDirection(compass, b, p, sides2);
|
|
26327
|
-
if (bp === null && !
|
|
26545
|
+
if (bp === null && !isBox2(n)) applyIctxt(n, dir, b, p);
|
|
26328
26546
|
const defFinal = dir.rv === 1 ? defBp : dir.defined || defBp;
|
|
26329
26547
|
applyDir(pp, bp, dir, gdRankdir(n), defFinal);
|
|
26330
26548
|
return dir.rv;
|
|
@@ -27606,7 +27824,7 @@ function emitParallelEdgePaths(e, job, colorList) {
|
|
|
27606
27824
|
const spl = e.info.spl;
|
|
27607
27825
|
const numc = (colorList.match(/:/g) ?? []).length;
|
|
27608
27826
|
const segData = buildSegData(spl?.list ?? [], (2 + numc) / 2);
|
|
27609
|
-
const colors =
|
|
27827
|
+
const colors = parseSegsSilent(colorList).segs.map((s) => s.color ?? DEFAULT_COLOR4);
|
|
27610
27828
|
emitColorPasses(segData, colors, job);
|
|
27611
27829
|
return {
|
|
27612
27830
|
headColor: colors[0] ?? DEFAULT_COLOR4,
|
|
@@ -28438,25 +28656,14 @@ function walkNodesAndEdges(g, renderer, job, info) {
|
|
|
28438
28656
|
}
|
|
28439
28657
|
}
|
|
28440
28658
|
|
|
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;
|
|
28659
|
+
// src/gvc/first-layer.ts
|
|
28660
|
+
var NATIVE_LANGNAME = /* @__PURE__ */ new Map([
|
|
28661
|
+
["cmapx-np", "cmapx_np"],
|
|
28662
|
+
["imap-np", "imap_np"]
|
|
28663
|
+
]);
|
|
28664
|
+
function warnLayersUnsupported(format, numLayers, doesLayers) {
|
|
28665
|
+
if (numLayers <= 1 || doesLayers) return;
|
|
28666
|
+
agwarningf(`layers not supported in ${NATIVE_LANGNAME.get(format) ?? format} output`);
|
|
28460
28667
|
}
|
|
28461
28668
|
|
|
28462
28669
|
// src/gvc/device-labels.ts
|
|
@@ -28601,6 +28808,7 @@ function setEdgePen(e, job) {
|
|
|
28601
28808
|
obj.pen = resolvePenType(flags);
|
|
28602
28809
|
obj.penWidth = resolvePenWidth(flags, e.attrs.get("penwidth"));
|
|
28603
28810
|
obj.rawStyle = styleTokens(e.attrs.get("style"));
|
|
28811
|
+
if (e.info.spl !== void 0) gvrenderSetStyle(obj.rawStyle);
|
|
28604
28812
|
}
|
|
28605
28813
|
function renderEdge(e, renderer, job) {
|
|
28606
28814
|
emitEdgeComments(e, renderer, job);
|
|
@@ -28616,6 +28824,8 @@ function renderEdge(e, renderer, job) {
|
|
|
28616
28824
|
withColorScheme(e.attrs.get("colorscheme"), () => {
|
|
28617
28825
|
renderer.beginEdge(e, job);
|
|
28618
28826
|
reportEdgeColors(e);
|
|
28827
|
+
const styles = styleTokens(e.attrs.get("style"));
|
|
28828
|
+
for (let i = edgeStyleResets(e, styles); i > 0; i--) gvrenderSetStyle(styles);
|
|
28619
28829
|
reportEdgeLabelColors(e);
|
|
28620
28830
|
renderer.endEdge(e, job);
|
|
28621
28831
|
});
|
|
@@ -28629,6 +28839,10 @@ function renderGraphLabel(g, renderer, job) {
|
|
|
28629
28839
|
}
|
|
28630
28840
|
function renderClusterBox(sg, filled, renderer, job) {
|
|
28631
28841
|
const { ll, ur } = sg.info.bb;
|
|
28842
|
+
if (isStripedCluster(sg)) {
|
|
28843
|
+
renderStripedClusterBox(sg, renderer, job);
|
|
28844
|
+
return;
|
|
28845
|
+
}
|
|
28632
28846
|
if (parseStyleFlags(clusterStyle(sg)).rounded) {
|
|
28633
28847
|
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
28848
|
emitRoundedBezier(af, { x: 0, y: 0 }, filled, { renderer, job });
|
|
@@ -28652,7 +28866,7 @@ function renderOneCluster(sg, renderer, job) {
|
|
|
28652
28866
|
resolveObjAnchor(sg, labelTextOf2(sg.info.label), svgClusterId(sg, job), job.obj);
|
|
28653
28867
|
}
|
|
28654
28868
|
const anchored = beginAnchorIf(renderer, job);
|
|
28655
|
-
if ((clusterPeripheries(sg) !== 0 || filled) && job.obj?.pen !== 0 /* None */) {
|
|
28869
|
+
if ((clusterPeripheries(sg) !== 0 || filled || isStripedCluster(sg)) && job.obj?.pen !== 0 /* None */) {
|
|
28656
28870
|
renderClusterBox(sg, filled, renderer, job);
|
|
28657
28871
|
}
|
|
28658
28872
|
renderClusterLabel(sg, renderer, job);
|
|
@@ -28682,6 +28896,7 @@ function renderGraph(g, job, renderer) {
|
|
|
28682
28896
|
job.numLayers = layered ? info.numLayers : 1;
|
|
28683
28897
|
job.layerIDs = info.layerIDs;
|
|
28684
28898
|
renderer.beginGraph(g, job);
|
|
28899
|
+
warnLayersUnsupported(job.format, info.numLayers, renderer.beginLayer !== void 0);
|
|
28685
28900
|
for (let ln = 1; ln <= job.numLayers; ln++) {
|
|
28686
28901
|
job.layerNum = ln;
|
|
28687
28902
|
if (layered) renderer.beginLayer(info.layerIDs[ln], job);
|
|
@@ -30021,7 +30236,7 @@ function fillRankVlist(g, r, root) {
|
|
|
30021
30236
|
rankArr[r].v = rootRank.v;
|
|
30022
30237
|
rankArr[r].vStart = lead.info.order ?? 0;
|
|
30023
30238
|
const maxi = computeMaxi(g, r);
|
|
30024
|
-
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}
|
|
30239
|
+
if (maxi === -1) agwarningf(`degenerate concentrated rank ${g.name},${r}`);
|
|
30025
30240
|
rankArr[r].n = maxi + 1;
|
|
30026
30241
|
return 0;
|
|
30027
30242
|
}
|
|
@@ -32840,7 +33055,7 @@ function routeSplinesInternal(pp, polyline) {
|
|
|
32840
33055
|
];
|
|
32841
33056
|
const pl = shortestPath(poly, eps);
|
|
32842
33057
|
if (pl === null) {
|
|
32843
|
-
|
|
33058
|
+
agerrorf("in routesplines, Pshortestpath failed");
|
|
32844
33059
|
return null;
|
|
32845
33060
|
}
|
|
32846
33061
|
emitDump("S3_POLY", dumpNames, () => ({
|
|
@@ -34846,9 +35061,9 @@ function writePortlabelPos(l, pe, pf, angleStr, distanceStr) {
|
|
|
34846
35061
|
const angleDeg = lateDouble(angleStr, PORT_LABEL_ANGLE, -180);
|
|
34847
35062
|
const angle = Math.atan2(pf.y - pe.y, pf.x - pe.x) + RADIANS(angleDeg);
|
|
34848
35063
|
const distMult = lateDouble(distanceStr || void 0, 1, 0);
|
|
34849
|
-
const
|
|
34850
|
-
l.pos.x = pe.x +
|
|
34851
|
-
l.pos.y = pe.y +
|
|
35064
|
+
const dist5 = PORT_LABEL_DISTANCE * distMult;
|
|
35065
|
+
l.pos.x = pe.x + dist5 * Math.cos(angle);
|
|
35066
|
+
l.pos.y = pe.y + dist5 * Math.sin(angle);
|
|
34852
35067
|
l.set = true;
|
|
34853
35068
|
}
|
|
34854
35069
|
function updateBB(g, l) {
|
|
@@ -35250,7 +35465,7 @@ function translateDrawing(g) {
|
|
|
35250
35465
|
if (e.tail !== v) continue;
|
|
35251
35466
|
if (e.info.spl === void 0) {
|
|
35252
35467
|
if (!(g.info.concentrate ?? false) && (e.info.edge_type ?? 0) !== IGNORED_EDGE) {
|
|
35253
|
-
|
|
35468
|
+
agerrorf(`lost ${e.tail.name} ${e.head.name} edge`);
|
|
35254
35469
|
}
|
|
35255
35470
|
continue;
|
|
35256
35471
|
}
|
|
@@ -36013,9 +36228,14 @@ function nodeInsideFn2(box) {
|
|
|
36013
36228
|
function clipToNodes(bezier2, tailBox, headBox, penwidth = DEFAULT_NODEPENWIDTH, clip = CLIP_BOTH) {
|
|
36014
36229
|
const step1 = clip.tail ? bezierClipNode(bezier2, tailBox.center.x, tailBox.center.y, nodeInsideFn2(tailBox), true) : bezier2;
|
|
36015
36230
|
const step2 = clip.head ? bezierClipNode(step1, headBox.center.x, headBox.center.y, nodeInsideFn2(headBox), false) : step1;
|
|
36016
|
-
const
|
|
36231
|
+
const startp = 0;
|
|
36232
|
+
let endp = 0;
|
|
36233
|
+
const arrowTip = step2[endp + 3];
|
|
36017
36234
|
const elen = normalArrowLen(penwidth);
|
|
36018
|
-
|
|
36235
|
+
if (endp > startp && distFused(step2[endp], step2[endp + 3]) < elen) {
|
|
36236
|
+
endp -= 3;
|
|
36237
|
+
}
|
|
36238
|
+
const clipped = arrowEndClip(step2.slice(endp, endp + 4), arrowTip, elen);
|
|
36019
36239
|
const arrowDir = normalizeVec({
|
|
36020
36240
|
x: clipped[3].x - arrowTip.x,
|
|
36021
36241
|
y: clipped[3].y - arrowTip.y
|
|
@@ -38554,8 +38774,7 @@ function ensureDummyNodes(sg, gstart) {
|
|
|
38554
38774
|
}
|
|
38555
38775
|
function orthoEdges(g, useLbls, clipAndInstall2) {
|
|
38556
38776
|
if (useLbls) {
|
|
38557
|
-
|
|
38558
|
-
"warn",
|
|
38777
|
+
agwarningf(
|
|
38559
38778
|
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"
|
|
38560
38779
|
);
|
|
38561
38780
|
useLbls = false;
|
|
@@ -38690,7 +38909,7 @@ function dispatchOrthoEdges(g, useLbls) {
|
|
|
38690
38909
|
}
|
|
38691
38910
|
|
|
38692
38911
|
// src/common/arrows-geometry.ts
|
|
38693
|
-
function
|
|
38912
|
+
function dist3(a, b) {
|
|
38694
38913
|
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
38695
38914
|
}
|
|
38696
38915
|
|
|
@@ -38794,7 +39013,7 @@ function getCycleCentroid(g, edge) {
|
|
|
38794
39013
|
}
|
|
38795
39014
|
function bend(spl, centroid) {
|
|
38796
39015
|
const midpt = midPointf(spl[0], spl[3]);
|
|
38797
|
-
const distVal =
|
|
39016
|
+
const distVal = dist3(spl[3], spl[0]);
|
|
38798
39017
|
const r = distVal / 5;
|
|
38799
39018
|
const vX = centroid.x - midpt.x;
|
|
38800
39019
|
const vY = centroid.y - midpt.y;
|
|
@@ -39407,7 +39626,7 @@ function arrowEndClipIdx(state3, endp) {
|
|
|
39407
39626
|
const elen = arrowClipLength(edgeArrowName(e, "head"), edgeArrowsize(e), edgePenwidthAttr(e));
|
|
39408
39627
|
bez.eflag = bez.eflag || 1;
|
|
39409
39628
|
bez.ep = { ...bez.list[endp + 3] };
|
|
39410
|
-
if (endp > state3.starti &&
|
|
39629
|
+
if (endp > state3.starti && distFused(bez.list[endp], bez.list[endp + 3]) < elen) endp -= 3;
|
|
39411
39630
|
const seg2 = [bez.list[endp], bez.list[endp + 1], bez.list[endp + 2], bez.list[endp + 3]];
|
|
39412
39631
|
const clipped = arrowEndClip(seg2, bez.ep, elen);
|
|
39413
39632
|
for (let k = 0; k < 4; k++) bez.list[endp + k] = clipped[k];
|
|
@@ -39418,7 +39637,7 @@ function arrowStartClipIdx(state3, startp, endp) {
|
|
|
39418
39637
|
const slen = arrowClipLength(edgeArrowName(e, "tail"), edgeArrowsize(e), edgePenwidthAttr(e));
|
|
39419
39638
|
bez.sflag = bez.sflag || 1;
|
|
39420
39639
|
bez.sp = { ...bez.list[startp] };
|
|
39421
|
-
if (endp > startp &&
|
|
39640
|
+
if (endp > startp && distFused(bez.list[startp], bez.list[startp + 3]) < slen) startp += 3;
|
|
39422
39641
|
const seg2 = [bez.list[startp], bez.list[startp + 1], bez.list[startp + 2], bez.list[startp + 3]];
|
|
39423
39642
|
const clipped = tailArrowEndClip(seg2, bez.sp, slen);
|
|
39424
39643
|
for (let k = 0; k < 4; k++) bez.list[startp + k] = clipped[k];
|
|
@@ -40687,120 +40906,522 @@ var DOT_LAYOUT_ENGINE = {
|
|
|
40687
40906
|
};
|
|
40688
40907
|
|
|
40689
40908
|
// 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;
|
|
40909
|
+
var FLT_MAX = 34028234663852886e22;
|
|
40910
|
+
function greaterPriorityF(h, i, j, dist5) {
|
|
40911
|
+
return dist5[h.data[i]] < dist5[h.data[j]];
|
|
40912
|
+
}
|
|
40913
|
+
function heapifyF(h, start, dist5) {
|
|
40914
|
+
let i = start;
|
|
40704
40915
|
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 = [];
|
|
40916
|
+
const l = ngLeft(i);
|
|
40917
|
+
const r = ngRight(i);
|
|
40918
|
+
let largest = ngInsideHeap(h, l) && greaterPriorityF(h, l, i, dist5) ? l : i;
|
|
40919
|
+
if (ngInsideHeap(h, r) && greaterPriorityF(h, r, largest, dist5)) largest = r;
|
|
40920
|
+
if (largest === i) break;
|
|
40921
|
+
ngExchange(h, largest, i);
|
|
40922
|
+
i = largest;
|
|
40923
|
+
}
|
|
40924
|
+
}
|
|
40925
|
+
function initHeapF(startVertex, dist5, n) {
|
|
40926
|
+
const h = {
|
|
40927
|
+
data: new Array(Math.max(n - 1, 0)).fill(0),
|
|
40928
|
+
heapSize: n - 1,
|
|
40929
|
+
index: new Int32Array(n)
|
|
40930
|
+
};
|
|
40931
|
+
let count = 0;
|
|
40727
40932
|
for (let i = 0; i < n; i++) {
|
|
40728
|
-
if (i !==
|
|
40933
|
+
if (i !== startVertex) {
|
|
40934
|
+
h.data[count] = i;
|
|
40935
|
+
h.index[i] = count;
|
|
40936
|
+
count++;
|
|
40937
|
+
}
|
|
40729
40938
|
}
|
|
40730
|
-
|
|
40939
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapifyF(h, j, dist5);
|
|
40940
|
+
return h;
|
|
40731
40941
|
}
|
|
40732
|
-
function
|
|
40733
|
-
|
|
40734
|
-
|
|
40735
|
-
|
|
40736
|
-
|
|
40942
|
+
function extractMaxF(h, dist5) {
|
|
40943
|
+
if (h.heapSize === 0) return -1;
|
|
40944
|
+
const max = h.data[0];
|
|
40945
|
+
h.data[0] = h.data[h.heapSize - 1];
|
|
40946
|
+
h.index[h.data[0]] = 0;
|
|
40947
|
+
h.heapSize--;
|
|
40948
|
+
heapifyF(h, 0, dist5);
|
|
40949
|
+
return max;
|
|
40737
40950
|
}
|
|
40738
|
-
function
|
|
40739
|
-
|
|
40740
|
-
|
|
40741
|
-
|
|
40742
|
-
|
|
40743
|
-
|
|
40744
|
-
|
|
40745
|
-
|
|
40951
|
+
function increaseKeyF(h, increasedVertex, newDist, dist5) {
|
|
40952
|
+
if (dist5[increasedVertex] <= newDist) return;
|
|
40953
|
+
let i = h.index[increasedVertex];
|
|
40954
|
+
dist5[increasedVertex] = newDist;
|
|
40955
|
+
while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
|
|
40956
|
+
ngAssign(h, i, ngParent(i));
|
|
40957
|
+
i = ngParent(i);
|
|
40958
|
+
}
|
|
40959
|
+
h.data[i] = increasedVertex;
|
|
40960
|
+
h.index[increasedVertex] = i;
|
|
40961
|
+
}
|
|
40962
|
+
function dijkstra(vertex, graph, n, dist5) {
|
|
40963
|
+
for (let i = 0; i < n; i++) dist5[i] = FLT_MAX;
|
|
40964
|
+
dist5[vertex] = 0;
|
|
40965
|
+
const vd = graph[vertex];
|
|
40966
|
+
for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = vd.ewgts[i];
|
|
40967
|
+
const h = initHeapF(vertex, dist5, n);
|
|
40968
|
+
for (let closest = extractMaxF(h, dist5); closest >= 0; closest = extractMaxF(h, dist5)) {
|
|
40969
|
+
const closestDist = dist5[closest];
|
|
40970
|
+
if (closestDist === FLT_MAX) break;
|
|
40971
|
+
const cd = graph[closest];
|
|
40972
|
+
for (let i = 1; i < cd.nedges; i++) {
|
|
40973
|
+
increaseKeyF(h, cd.edges[i], Math.fround(closestDist + Math.fround(cd.ewgts[i])), dist5);
|
|
40746
40974
|
}
|
|
40747
40975
|
}
|
|
40748
40976
|
}
|
|
40749
|
-
|
|
40750
|
-
|
|
40751
|
-
|
|
40752
|
-
|
|
40753
|
-
|
|
40754
|
-
|
|
40755
|
-
|
|
40756
|
-
|
|
40977
|
+
var MAX_DIST = 2147483647;
|
|
40978
|
+
function ngLeft(i) {
|
|
40979
|
+
return 2 * i;
|
|
40980
|
+
}
|
|
40981
|
+
function ngRight(i) {
|
|
40982
|
+
return 2 * i + 1;
|
|
40983
|
+
}
|
|
40984
|
+
function ngParent(i) {
|
|
40985
|
+
return Math.trunc(i / 2);
|
|
40986
|
+
}
|
|
40987
|
+
function ngInsideHeap(h, i) {
|
|
40988
|
+
return i < h.heapSize;
|
|
40989
|
+
}
|
|
40990
|
+
function ngGreaterPriority(h, i, j, dist5) {
|
|
40991
|
+
return dist5[h.data[i]] < dist5[h.data[j]];
|
|
40992
|
+
}
|
|
40993
|
+
function ngAssign(h, i, j) {
|
|
40994
|
+
h.data[i] = h.data[j];
|
|
40995
|
+
h.index[h.data[i]] = i;
|
|
40996
|
+
}
|
|
40997
|
+
function ngExchange(h, i, j) {
|
|
40998
|
+
const t = h.data[i];
|
|
40999
|
+
h.data[i] = h.data[j];
|
|
41000
|
+
h.data[j] = t;
|
|
41001
|
+
h.index[h.data[i]] = i;
|
|
41002
|
+
h.index[h.data[j]] = j;
|
|
41003
|
+
}
|
|
41004
|
+
function ngHeapify(h, start, dist5) {
|
|
41005
|
+
let i = start;
|
|
41006
|
+
for (; ; ) {
|
|
41007
|
+
const l = ngLeft(i);
|
|
41008
|
+
const r = ngRight(i);
|
|
41009
|
+
let largest = ngInsideHeap(h, l) && ngGreaterPriority(h, l, i, dist5) ? l : i;
|
|
41010
|
+
if (ngInsideHeap(h, r) && ngGreaterPriority(h, r, largest, dist5)) largest = r;
|
|
41011
|
+
if (largest === i) break;
|
|
41012
|
+
ngExchange(h, largest, i);
|
|
41013
|
+
i = largest;
|
|
41014
|
+
}
|
|
41015
|
+
}
|
|
41016
|
+
function ngInitHeap(startVertex, dist5, n) {
|
|
41017
|
+
const h = {
|
|
41018
|
+
data: new Array(Math.max(n - 1, 0)).fill(0),
|
|
41019
|
+
heapSize: n - 1,
|
|
41020
|
+
index: new Int32Array(n)
|
|
41021
|
+
};
|
|
41022
|
+
let count = 0;
|
|
41023
|
+
for (let i = 0; i < n; i++) {
|
|
41024
|
+
if (i !== startVertex) {
|
|
41025
|
+
h.data[count] = i;
|
|
41026
|
+
h.index[i] = count;
|
|
41027
|
+
count++;
|
|
41028
|
+
}
|
|
41029
|
+
}
|
|
41030
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) ngHeapify(h, j, dist5);
|
|
41031
|
+
return h;
|
|
41032
|
+
}
|
|
41033
|
+
function ngExtractMax(h, dist5) {
|
|
41034
|
+
if (h.heapSize === 0) return -1;
|
|
41035
|
+
const max = h.data[0];
|
|
41036
|
+
h.data[0] = h.data[h.heapSize - 1];
|
|
41037
|
+
h.index[h.data[0]] = 0;
|
|
41038
|
+
h.heapSize--;
|
|
41039
|
+
ngHeapify(h, 0, dist5);
|
|
41040
|
+
return max;
|
|
41041
|
+
}
|
|
41042
|
+
function ngIncreaseKey(h, increasedVertex, newDist, dist5) {
|
|
41043
|
+
if (dist5[increasedVertex] <= newDist) return;
|
|
41044
|
+
let i = h.index[increasedVertex];
|
|
41045
|
+
dist5[increasedVertex] = newDist;
|
|
41046
|
+
while (i > 0 && dist5[h.data[ngParent(i)]] > newDist) {
|
|
41047
|
+
ngAssign(h, i, ngParent(i));
|
|
41048
|
+
i = ngParent(i);
|
|
41049
|
+
}
|
|
41050
|
+
h.data[i] = increasedVertex;
|
|
41051
|
+
h.index[increasedVertex] = i;
|
|
41052
|
+
}
|
|
41053
|
+
function toDistType(w) {
|
|
41054
|
+
return Math.trunc(Math.fround(w));
|
|
41055
|
+
}
|
|
41056
|
+
function ngdijkstra(vertex, graph, n, dist5) {
|
|
41057
|
+
let prevClosestDist = MAX_DIST;
|
|
41058
|
+
for (let i = 0; i < n; i++) dist5[i] = MAX_DIST;
|
|
41059
|
+
dist5[vertex] = 0;
|
|
41060
|
+
const vd = graph[vertex];
|
|
41061
|
+
for (let i = 1; i < vd.nedges; i++) dist5[vd.edges[i]] = toDistType(vd.ewgts[i]);
|
|
41062
|
+
const h = ngInitHeap(vertex, dist5, n);
|
|
41063
|
+
for (let closest = ngExtractMax(h, dist5); closest >= 0; closest = ngExtractMax(h, dist5)) {
|
|
41064
|
+
const closestDist = dist5[closest];
|
|
41065
|
+
if (closestDist === MAX_DIST) break;
|
|
41066
|
+
const cd = graph[closest];
|
|
41067
|
+
for (let i = 1; i < cd.nedges; i++) {
|
|
41068
|
+
ngIncreaseKey(h, cd.edges[i], closestDist + toDistType(cd.ewgts[i]) | 0, dist5);
|
|
41069
|
+
}
|
|
41070
|
+
prevClosestDist = closestDist;
|
|
41071
|
+
}
|
|
41072
|
+
for (let i = 0; i < n; i++) {
|
|
41073
|
+
if (dist5[i] === MAX_DIST) {
|
|
41074
|
+
dist5[i] = MAX_DIST - prevClosestDist < 10 ? MAX_DIST : prevClosestDist + 10;
|
|
41075
|
+
}
|
|
40757
41076
|
}
|
|
40758
41077
|
}
|
|
40759
41078
|
|
|
40760
41079
|
// src/layout/neato/bfs.ts
|
|
40761
|
-
function bfsInit(src, n,
|
|
40762
|
-
for (let i = 0; i < n; i++)
|
|
40763
|
-
|
|
41080
|
+
function bfsInit(src, n, dist5) {
|
|
41081
|
+
for (let i = 0; i < n; i++) dist5[i] = -1;
|
|
41082
|
+
dist5[src] = 0;
|
|
40764
41083
|
return [src];
|
|
40765
41084
|
}
|
|
40766
|
-
function bfsFixDisconnected(n,
|
|
41085
|
+
function bfsFixDisconnected(n, dist5, closestDist) {
|
|
40767
41086
|
for (let i = 0; i < n; i++) {
|
|
40768
|
-
if (
|
|
41087
|
+
if (dist5[i] < 0) dist5[i] = closestDist + 10;
|
|
40769
41088
|
}
|
|
40770
41089
|
}
|
|
40771
|
-
function bfsVisitNeighbors(vertex, graph,
|
|
41090
|
+
function bfsVisitNeighbors(vertex, graph, dist5, queue) {
|
|
40772
41091
|
const vd = graph[vertex];
|
|
40773
|
-
const d =
|
|
41092
|
+
const d = dist5[vertex];
|
|
40774
41093
|
const unit = graph[0].ewgts.length === 0;
|
|
40775
41094
|
for (let i = 1; i < vd.nedges; i++) {
|
|
40776
41095
|
const nb = vd.edges[i];
|
|
40777
|
-
if (
|
|
40778
|
-
|
|
41096
|
+
if (dist5[nb] < 0) {
|
|
41097
|
+
dist5[nb] = d + (unit ? 1 : Math.trunc(Math.fround(vd.ewgts[i])));
|
|
40779
41098
|
queue.push(nb);
|
|
40780
41099
|
}
|
|
40781
41100
|
}
|
|
40782
41101
|
return d;
|
|
40783
41102
|
}
|
|
40784
|
-
function bfs(src, graph, n,
|
|
40785
|
-
const queue = bfsInit(src, n,
|
|
41103
|
+
function bfs(src, graph, n, dist5) {
|
|
41104
|
+
const queue = bfsInit(src, n, dist5);
|
|
40786
41105
|
let closestDist = 0;
|
|
40787
41106
|
let head = 0;
|
|
40788
41107
|
while (head < queue.length) {
|
|
40789
41108
|
const vertex = queue[head++];
|
|
40790
|
-
closestDist = bfsVisitNeighbors(vertex, graph,
|
|
41109
|
+
closestDist = bfsVisitNeighbors(vertex, graph, dist5, queue);
|
|
41110
|
+
}
|
|
41111
|
+
bfsFixDisconnected(n, dist5, closestDist);
|
|
41112
|
+
}
|
|
41113
|
+
function packedIndex(i, j, n) {
|
|
41114
|
+
return i * (2 * n - i - 1) / 2 + j;
|
|
41115
|
+
}
|
|
41116
|
+
function computeWeightedApspPacked(graph, n) {
|
|
41117
|
+
const result = new Float32Array(n * (n + 1) / 2);
|
|
41118
|
+
const di = new Float32Array(n);
|
|
41119
|
+
for (let i = 0; i < n; i++) {
|
|
41120
|
+
dijkstra(i, graph, n, di);
|
|
41121
|
+
for (let j = i; j < n; j++) result[packedIndex(i, j, n)] = di[j];
|
|
41122
|
+
}
|
|
41123
|
+
return result;
|
|
41124
|
+
}
|
|
41125
|
+
|
|
41126
|
+
// src/common/crand.ts
|
|
41127
|
+
var C_RAND_MAX = 2147483647;
|
|
41128
|
+
var UNSEEDED_STATE2 = 1;
|
|
41129
|
+
var state2 = UNSEEDED_STATE2;
|
|
41130
|
+
registerRenderState(() => {
|
|
41131
|
+
state2 = UNSEEDED_STATE2;
|
|
41132
|
+
});
|
|
41133
|
+
function csrand(seed) {
|
|
41134
|
+
state2 = seed;
|
|
41135
|
+
}
|
|
41136
|
+
function crand() {
|
|
41137
|
+
state2 = state2 * 16807 % 2147483647;
|
|
41138
|
+
return state2;
|
|
41139
|
+
}
|
|
41140
|
+
function cdrand() {
|
|
41141
|
+
return crand() / C_RAND_MAX;
|
|
41142
|
+
}
|
|
41143
|
+
function gvRandom(bound) {
|
|
41144
|
+
const discardThreshold = C_RAND_MAX - 2147483648 % bound;
|
|
41145
|
+
let r;
|
|
41146
|
+
do {
|
|
41147
|
+
r = crand();
|
|
41148
|
+
} while (r > discardThreshold);
|
|
41149
|
+
return r % bound;
|
|
41150
|
+
}
|
|
41151
|
+
function gvPermutation(bound) {
|
|
41152
|
+
if (bound <= 0) return [];
|
|
41153
|
+
const p = [];
|
|
41154
|
+
for (let i = 0; i < bound; i++) p.push(i);
|
|
41155
|
+
for (let i = bound - 1; i > 0; --i) {
|
|
41156
|
+
const j = gvRandom(i + 1);
|
|
41157
|
+
const t = p[i];
|
|
41158
|
+
p[i] = p[j];
|
|
41159
|
+
p[j] = t;
|
|
40791
41160
|
}
|
|
40792
|
-
|
|
41161
|
+
return p;
|
|
41162
|
+
}
|
|
41163
|
+
|
|
41164
|
+
// src/layout/neato/matrix-ops.ts
|
|
41165
|
+
var fr = Math.fround;
|
|
41166
|
+
function fma2(a, b, c) {
|
|
41167
|
+
const p = a * b;
|
|
41168
|
+
return Number.isFinite(p) && Number.isFinite(c) ? fma(a, b, c) : p + c;
|
|
41169
|
+
}
|
|
41170
|
+
function orthog1(n, vec) {
|
|
41171
|
+
let sum = 0;
|
|
41172
|
+
for (let i = 0; i < n; i++) sum += vec[i];
|
|
41173
|
+
sum /= n;
|
|
41174
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
|
|
41175
|
+
}
|
|
41176
|
+
function orthog1f(n, vec) {
|
|
41177
|
+
let sum = fr(0);
|
|
41178
|
+
for (let i = 0; i < n; i++) sum = fr(sum + vec[i]);
|
|
41179
|
+
sum = fr(sum / n);
|
|
41180
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] - sum;
|
|
41181
|
+
}
|
|
41182
|
+
function rightMultWithVectorFF(m, n, vector, result) {
|
|
41183
|
+
for (let i = 0; i < n; i++) result[i] = 0;
|
|
41184
|
+
let index = 0;
|
|
41185
|
+
for (let i = 0; i < n; i++) {
|
|
41186
|
+
const vi = vector[i];
|
|
41187
|
+
let res = fr(m[index++] * vi);
|
|
41188
|
+
for (let j = i + 1; j < n; j++, index++) {
|
|
41189
|
+
res = fr(res + fr(m[index] * vector[j]));
|
|
41190
|
+
result[j] = result[j] + fr(m[index] * vi);
|
|
41191
|
+
}
|
|
41192
|
+
result[i] = result[i] + res;
|
|
41193
|
+
}
|
|
41194
|
+
}
|
|
41195
|
+
function vectorsSubtractionF(n, v1, v2, result) {
|
|
41196
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
|
|
41197
|
+
}
|
|
41198
|
+
function vectorsMultAdditionF(n, v1, alpha, v2) {
|
|
41199
|
+
const a = fr(alpha);
|
|
41200
|
+
for (let i = 0; i < n; i++) v1[i] = v1[i] + fr(a * v2[i]);
|
|
41201
|
+
}
|
|
41202
|
+
function vectorsInnerProductF(n, v1, v2) {
|
|
41203
|
+
let result = 0;
|
|
41204
|
+
for (let i = 0; i < n; i++) result += fr(v1[i] * v2[i]);
|
|
41205
|
+
return result;
|
|
41206
|
+
}
|
|
41207
|
+
function copyVectorF(n, src, dst) {
|
|
41208
|
+
for (let i = 0; i < n; i++) dst[i] = src[i];
|
|
41209
|
+
}
|
|
41210
|
+
function maxAbsF(n, vec) {
|
|
41211
|
+
let max = fr(-1e30);
|
|
41212
|
+
for (let i = 0; i < n; i++) {
|
|
41213
|
+
const a = fr(Math.abs(vec[i]));
|
|
41214
|
+
if (a > max) max = a;
|
|
41215
|
+
}
|
|
41216
|
+
return max;
|
|
41217
|
+
}
|
|
41218
|
+
function squareVec(n, vec) {
|
|
41219
|
+
for (let i = 0; i < n; i++) vec[i] = vec[i] * vec[i];
|
|
41220
|
+
}
|
|
41221
|
+
function invertVec(n, vec) {
|
|
41222
|
+
for (let i = 0; i < n; i++) {
|
|
41223
|
+
if (vec[i] !== 0) vec[i] = 1 / vec[i];
|
|
41224
|
+
}
|
|
41225
|
+
}
|
|
41226
|
+
function sqrtVecF(n, source, target) {
|
|
41227
|
+
for (let i = 0; i < n; i++) {
|
|
41228
|
+
if (source[i] >= 0) target[i] = fr(Math.sqrt(source[i]));
|
|
41229
|
+
}
|
|
41230
|
+
}
|
|
41231
|
+
function invertSqrtVec(n, vec) {
|
|
41232
|
+
for (let i = 0; i < n; i++) {
|
|
41233
|
+
if (vec[i] > 0) vec[i] = 1 / fr(Math.sqrt(vec[i]));
|
|
41234
|
+
}
|
|
41235
|
+
}
|
|
41236
|
+
var BLOCK_NONE = 1;
|
|
41237
|
+
function innerProduct(n, v1, v2, block) {
|
|
41238
|
+
let result = 0;
|
|
41239
|
+
const blocked = block === BLOCK_NONE ? 0 : n - n % block;
|
|
41240
|
+
let i = 0;
|
|
41241
|
+
for (; i < blocked; i++) result += v1[i] * v2[i];
|
|
41242
|
+
for (; i < n; i++) result = fma2(v1[i], v2[i], result);
|
|
41243
|
+
return result;
|
|
41244
|
+
}
|
|
41245
|
+
function scadd(vec1, end, fac, vec2) {
|
|
41246
|
+
for (let i = 0; i <= end; i++) vec1[i] = fma2(fac, vec2[i], vec1[i]);
|
|
41247
|
+
}
|
|
41248
|
+
function norm(vec, end, block) {
|
|
41249
|
+
return Math.sqrt(innerProduct(end + 1, vec, vec, block));
|
|
41250
|
+
}
|
|
41251
|
+
function vectorsScalarMult(n, vector, alpha, result) {
|
|
41252
|
+
for (let i = 0; i < n; i++) result[i] = vector[i] * alpha;
|
|
41253
|
+
}
|
|
41254
|
+
function copyVector(n, source, dest) {
|
|
41255
|
+
for (let i = 0; i < n; i++) dest[i] = source[i];
|
|
41256
|
+
}
|
|
41257
|
+
function vectorsAddition(n, v1, v2, result) {
|
|
41258
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] + v2[i];
|
|
41259
|
+
}
|
|
41260
|
+
function vectorsSubtraction(n, v1, v2, result) {
|
|
41261
|
+
for (let i = 0; i < n; i++) result[i] = v1[i] - v2[i];
|
|
41262
|
+
}
|
|
41263
|
+
function maxAbs(n, vector) {
|
|
41264
|
+
let maxVal = -1e50;
|
|
41265
|
+
for (let i = 0; i < n; i++) {
|
|
41266
|
+
const a = Math.abs(vector[i]);
|
|
41267
|
+
if (a > maxVal) maxVal = a;
|
|
41268
|
+
}
|
|
41269
|
+
return maxVal;
|
|
41270
|
+
}
|
|
41271
|
+
function rightMultWithVectorF(matrix, n, vector, result, block) {
|
|
41272
|
+
const blocked = block === BLOCK_NONE ? 0 : n - n % block;
|
|
41273
|
+
for (let i = 0; i < n; i++) {
|
|
41274
|
+
const row = matrix[i];
|
|
41275
|
+
let res = 0;
|
|
41276
|
+
let j = 0;
|
|
41277
|
+
for (; j < blocked; j++) res += row[j] * vector[j];
|
|
41278
|
+
for (; j < n; j++) res = fma2(row[j], vector[j], res);
|
|
41279
|
+
result[i] = res;
|
|
41280
|
+
}
|
|
41281
|
+
}
|
|
41282
|
+
function rightMultWithVector(matrix, n, vector, result) {
|
|
41283
|
+
for (let i = 0; i < n; i++) {
|
|
41284
|
+
let res = 0;
|
|
41285
|
+
const row = matrix[i];
|
|
41286
|
+
for (let j = 0; j < row.nedges; j++) res = fma2(row.ewgts[j], vector[row.edges[j]], res);
|
|
41287
|
+
result[i] = res;
|
|
41288
|
+
}
|
|
41289
|
+
}
|
|
41290
|
+
var RANGE = 500;
|
|
41291
|
+
function initVecOrth1(n, vec) {
|
|
41292
|
+
for (let i = 0; i < n; i++) vec[i] = crand() % RANGE;
|
|
41293
|
+
orthog1(n, vec);
|
|
41294
|
+
}
|
|
41295
|
+
|
|
41296
|
+
// src/layout/neato/conjgrad.ts
|
|
41297
|
+
var BLOCK_INITIAL_RR = 4;
|
|
41298
|
+
var BLOCK_P_AP = 8;
|
|
41299
|
+
function cgNextDirection(n, w, alpha, rR) {
|
|
41300
|
+
vectorsScalarMult(n, w.Ap, alpha, w.Ap);
|
|
41301
|
+
vectorsSubtraction(n, w.r, w.Ap, w.r);
|
|
41302
|
+
const rRNew = innerProduct(n, w.r, w.r, BLOCK_NONE);
|
|
41303
|
+
if (rR === 0) {
|
|
41304
|
+
agerrorf("conjugate_gradient: unexpected length 0 vector\n");
|
|
41305
|
+
return null;
|
|
41306
|
+
}
|
|
41307
|
+
const beta = rRNew / rR;
|
|
41308
|
+
vectorsScalarMult(n, w.p, beta, w.p);
|
|
41309
|
+
vectorsAddition(n, w.r, w.p, w.p);
|
|
41310
|
+
return rRNew;
|
|
41311
|
+
}
|
|
41312
|
+
function cgStart(A3, x, b, n) {
|
|
41313
|
+
const w = {
|
|
41314
|
+
r: new Float64Array(n),
|
|
41315
|
+
p: new Float64Array(n),
|
|
41316
|
+
Ap: new Float64Array(n),
|
|
41317
|
+
alphap: new Float64Array(n)
|
|
41318
|
+
};
|
|
41319
|
+
const Ax = new Float64Array(n);
|
|
41320
|
+
const orthB = Float64Array.from(b.subarray(0, n));
|
|
41321
|
+
orthog1(n, orthB);
|
|
41322
|
+
orthog1(n, x);
|
|
41323
|
+
rightMultWithVector(A3, n, x, Ax);
|
|
41324
|
+
vectorsSubtraction(n, orthB, Ax, w.r);
|
|
41325
|
+
w.p.set(w.r.subarray(0, n));
|
|
41326
|
+
return w;
|
|
41327
|
+
}
|
|
41328
|
+
function conjugateGradient(A3, x, b, n, tol, maxIterations) {
|
|
41329
|
+
const w = cgStart(A3, x, b, n);
|
|
41330
|
+
let rR = innerProduct(n, w.r, w.r, BLOCK_INITIAL_RR);
|
|
41331
|
+
for (let i = 0; i < maxIterations && maxAbs(n, w.r) > tol; i++) {
|
|
41332
|
+
rightMultWithVector(A3, n, w.p, w.Ap);
|
|
41333
|
+
const pAp = innerProduct(n, w.p, w.Ap, BLOCK_P_AP);
|
|
41334
|
+
if (pAp === 0) break;
|
|
41335
|
+
const alpha = rR / pAp;
|
|
41336
|
+
vectorsScalarMult(n, w.p, alpha, w.alphap);
|
|
41337
|
+
vectorsAddition(n, x, w.alphap, x);
|
|
41338
|
+
if (i < maxIterations - 1) {
|
|
41339
|
+
const next = cgNextDirection(n, w, alpha, rR);
|
|
41340
|
+
if (next === null) return 1;
|
|
41341
|
+
rR = next;
|
|
41342
|
+
}
|
|
41343
|
+
}
|
|
41344
|
+
return 0;
|
|
41345
|
+
}
|
|
41346
|
+
var CGF_BLOCK_AX = 4;
|
|
41347
|
+
var CGF_BLOCK_AP = 4;
|
|
41348
|
+
var CGF_BLOCK_INITIAL_RR = 4;
|
|
41349
|
+
var CGF_BLOCK_P_AP = 8;
|
|
41350
|
+
function cgfInit(A3, x, b, n, ortho1) {
|
|
41351
|
+
const orthB = new Float64Array(n);
|
|
41352
|
+
copyVector(n, b, orthB);
|
|
41353
|
+
if (ortho1) {
|
|
41354
|
+
orthog1(n, orthB);
|
|
41355
|
+
orthog1(n, x);
|
|
41356
|
+
}
|
|
41357
|
+
const Ax = new Float64Array(n);
|
|
41358
|
+
rightMultWithVectorF(A3, n, x, Ax, CGF_BLOCK_AX);
|
|
41359
|
+
const r = new Float64Array(n);
|
|
41360
|
+
vectorsSubtraction(n, orthB, Ax, r);
|
|
41361
|
+
const p = new Float64Array(n);
|
|
41362
|
+
copyVector(n, r, p);
|
|
41363
|
+
return {
|
|
41364
|
+
r,
|
|
41365
|
+
p,
|
|
41366
|
+
Ap: new Float64Array(n),
|
|
41367
|
+
alphap: new Float64Array(n),
|
|
41368
|
+
rr: innerProduct(n, r, r, CGF_BLOCK_INITIAL_RR)
|
|
41369
|
+
};
|
|
41370
|
+
}
|
|
41371
|
+
function cgfUpdate(n, alpha, st) {
|
|
41372
|
+
vectorsScalarMult(n, st.Ap, alpha, st.Ap);
|
|
41373
|
+
vectorsSubtraction(n, st.r, st.Ap, st.r);
|
|
41374
|
+
const rrNew = innerProduct(n, st.r, st.r, BLOCK_NONE);
|
|
41375
|
+
if (st.rr === 0) {
|
|
41376
|
+
agerrorf("conjugate_gradient: unexpected length 0 vector\n");
|
|
41377
|
+
return 1;
|
|
41378
|
+
}
|
|
41379
|
+
const beta = rrNew / st.rr;
|
|
41380
|
+
st.rr = rrNew;
|
|
41381
|
+
vectorsScalarMult(n, st.p, beta, st.p);
|
|
41382
|
+
vectorsAddition(n, st.r, st.p, st.p);
|
|
41383
|
+
return 0;
|
|
41384
|
+
}
|
|
41385
|
+
function conjugateGradientF(A3, x, b, n, opts) {
|
|
41386
|
+
const { tol, maxIterations, ortho1 } = opts;
|
|
41387
|
+
const st = cgfInit(A3, x, b, n, ortho1);
|
|
41388
|
+
for (let i = 0; i < maxIterations && maxAbs(n, st.r) > tol; i++) {
|
|
41389
|
+
rightMultWithVectorF(A3, n, st.p, st.Ap, CGF_BLOCK_AP);
|
|
41390
|
+
const pAp = innerProduct(n, st.p, st.Ap, CGF_BLOCK_P_AP);
|
|
41391
|
+
if (pAp === 0) break;
|
|
41392
|
+
const alpha = st.rr / pAp;
|
|
41393
|
+
vectorsScalarMult(n, st.p, alpha, st.alphap);
|
|
41394
|
+
vectorsAddition(n, x, st.alphap, x);
|
|
41395
|
+
if (i < maxIterations - 1 && cgfUpdate(n, alpha, st) === 1) return 1;
|
|
41396
|
+
}
|
|
41397
|
+
return 0;
|
|
40793
41398
|
}
|
|
40794
41399
|
|
|
40795
41400
|
// src/layout/neato/stress.ts
|
|
41401
|
+
var TOLERANCE_CG = 1e-3;
|
|
40796
41402
|
var DFLT_ITERATIONS = 200;
|
|
41403
|
+
var OPT_SMART_INIT = 4;
|
|
41404
|
+
function mdsModel(graph, nG) {
|
|
41405
|
+
if (graph[0].ewgts.length === 0) return null;
|
|
41406
|
+
const Dij = computeWeightedApspPacked(graph, nG);
|
|
41407
|
+
let shift = 0;
|
|
41408
|
+
for (let i = 0; i < nG; i++) {
|
|
41409
|
+
shift += i;
|
|
41410
|
+
for (let e = 1; e < graph[i].nedges; e++) {
|
|
41411
|
+
const j = graph[i].edges[e];
|
|
41412
|
+
if (j < i) continue;
|
|
41413
|
+
Dij[i * nG + j - shift] = graph[i].ewgts[e];
|
|
41414
|
+
}
|
|
41415
|
+
}
|
|
41416
|
+
return Dij;
|
|
41417
|
+
}
|
|
40797
41418
|
|
|
40798
41419
|
// src/layout/neato/sgd-dijkstra.ts
|
|
40799
|
-
var
|
|
41420
|
+
var FLT_MAX2 = 34028234663852886e22;
|
|
40800
41421
|
var left = (i) => 2 * i;
|
|
40801
41422
|
var right = (i) => 2 * i + 1;
|
|
40802
41423
|
var parent = (i) => Math.trunc(i / 2);
|
|
40803
|
-
var greaterPriority = (h, i, j,
|
|
41424
|
+
var greaterPriority = (h, i, j, dist5) => dist5[h.data[i]] < dist5[h.data[j]];
|
|
40804
41425
|
function exchange2(h, i, j) {
|
|
40805
41426
|
const t = h.data[i];
|
|
40806
41427
|
h.data[i] = h.data[j];
|
|
@@ -40808,19 +41429,19 @@ function exchange2(h, i, j) {
|
|
|
40808
41429
|
h.index[h.data[i]] = i;
|
|
40809
41430
|
h.index[h.data[j]] = j;
|
|
40810
41431
|
}
|
|
40811
|
-
function heapify(h, start,
|
|
41432
|
+
function heapify(h, start, dist5) {
|
|
40812
41433
|
let i = start;
|
|
40813
41434
|
for (; ; ) {
|
|
40814
41435
|
const l = left(i);
|
|
40815
41436
|
const r = right(i);
|
|
40816
|
-
let largest = l < h.heapSize && greaterPriority(h, l, i,
|
|
40817
|
-
if (r < h.heapSize && greaterPriority(h, r, largest,
|
|
41437
|
+
let largest = l < h.heapSize && greaterPriority(h, l, i, dist5) ? l : i;
|
|
41438
|
+
if (r < h.heapSize && greaterPriority(h, r, largest, dist5)) largest = r;
|
|
40818
41439
|
if (largest === i) break;
|
|
40819
41440
|
exchange2(h, largest, i);
|
|
40820
41441
|
i = largest;
|
|
40821
41442
|
}
|
|
40822
41443
|
}
|
|
40823
|
-
function initHeap(startVertex,
|
|
41444
|
+
function initHeap(startVertex, dist5, n) {
|
|
40824
41445
|
const h = {
|
|
40825
41446
|
data: new Int32Array(Math.max(n - 1, 0)),
|
|
40826
41447
|
heapSize: n - 1,
|
|
@@ -40832,23 +41453,23 @@ function initHeap(startVertex, dist4, n) {
|
|
|
40832
41453
|
h.data[count] = i;
|
|
40833
41454
|
h.index[i] = count++;
|
|
40834
41455
|
}
|
|
40835
|
-
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j,
|
|
41456
|
+
for (let j = Math.trunc((n - 1) / 2); j >= 0; j--) heapify(h, j, dist5);
|
|
40836
41457
|
return h;
|
|
40837
41458
|
}
|
|
40838
|
-
function extractMax(h,
|
|
41459
|
+
function extractMax(h, dist5) {
|
|
40839
41460
|
if (h.heapSize === 0) return -1;
|
|
40840
41461
|
const max = h.data[0];
|
|
40841
41462
|
h.data[0] = h.data[h.heapSize - 1];
|
|
40842
41463
|
h.index[h.data[0]] = 0;
|
|
40843
41464
|
h.heapSize--;
|
|
40844
|
-
heapify(h, 0,
|
|
41465
|
+
heapify(h, 0, dist5);
|
|
40845
41466
|
return max;
|
|
40846
41467
|
}
|
|
40847
|
-
function increaseKey(h, v, newDist,
|
|
40848
|
-
if (
|
|
40849
|
-
|
|
41468
|
+
function increaseKey(h, v, newDist, dist5) {
|
|
41469
|
+
if (dist5[v] <= newDist) return;
|
|
41470
|
+
dist5[v] = newDist;
|
|
40850
41471
|
let i = h.index[v];
|
|
40851
|
-
while (i > 0 &&
|
|
41472
|
+
while (i > 0 && dist5[h.data[parent(i)]] > newDist) {
|
|
40852
41473
|
h.data[i] = h.data[parent(i)];
|
|
40853
41474
|
h.index[h.data[i]] = i;
|
|
40854
41475
|
i = parent(i);
|
|
@@ -40857,7 +41478,7 @@ function increaseKey(h, v, newDist, dist4) {
|
|
|
40857
41478
|
h.index[v] = i;
|
|
40858
41479
|
}
|
|
40859
41480
|
function dijkstraSgd(graph, source, terms) {
|
|
40860
|
-
const dists = new Float32Array(graph.n).fill(
|
|
41481
|
+
const dists = new Float32Array(graph.n).fill(FLT_MAX2);
|
|
40861
41482
|
dists[source] = 0;
|
|
40862
41483
|
for (let i = graph.sources[source]; i < graph.sources[source + 1]; i++) {
|
|
40863
41484
|
dists[graph.targets[i]] = graph.weights[i];
|
|
@@ -40866,7 +41487,7 @@ function dijkstraSgd(graph, source, terms) {
|
|
|
40866
41487
|
let offset = 0;
|
|
40867
41488
|
for (let closest = extractMax(h, dists); closest >= 0; closest = extractMax(h, dists)) {
|
|
40868
41489
|
const d = dists[closest];
|
|
40869
|
-
if (d ===
|
|
41490
|
+
if (d === FLT_MAX2) break;
|
|
40870
41491
|
if (graph.pinneds[closest] || closest < source) {
|
|
40871
41492
|
terms[offset++] = { i: source, j: closest, d, w: Math.fround(1 / Math.fround(d * d)) };
|
|
40872
41493
|
}
|
|
@@ -40885,7 +41506,7 @@ function lenattr(ep, g) {
|
|
|
40885
41506
|
const val2 = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?/.exec(s);
|
|
40886
41507
|
const len = val2 === null ? Number.NaN : parseFloat(val2[0]);
|
|
40887
41508
|
if (Number.isNaN(len) || len < 0 || len === 0) {
|
|
40888
|
-
|
|
41509
|
+
agwarningf(`bad edge len "${s}" in ${g.name} - setting to ${DEFAULT_EDGE_LEN.toFixed(2)}`);
|
|
40889
41510
|
return DEFAULT_EDGE_LEN;
|
|
40890
41511
|
}
|
|
40891
41512
|
return len;
|
|
@@ -41049,12 +41670,11 @@ function neatoMode(g) {
|
|
|
41049
41670
|
if (str === void 0 || str === "") return MODE_MAJOR;
|
|
41050
41671
|
const mode = modeByName().get(str);
|
|
41051
41672
|
if (mode !== void 0) return mode;
|
|
41052
|
-
|
|
41673
|
+
agwarningf(`Illegal value ${str} for attribute "mode" in graph ${g.root.name} - ignored`);
|
|
41053
41674
|
return MODE_MAJOR;
|
|
41054
41675
|
}
|
|
41055
41676
|
function checkMode(g, mode) {
|
|
41056
|
-
const value = g.root.attrs.get("mode") ||
|
|
41057
|
-
if (mode === MODE_HIER) unsupported("mode", value, "hierarchical stress majorization");
|
|
41677
|
+
const value = g.root.attrs.get("mode") || "ipsep";
|
|
41058
41678
|
if (mode === MODE_IPSEP && ipsepHasConstraints(g)) {
|
|
41059
41679
|
unsupported("mode", value, "constrained (ipsep) majorization");
|
|
41060
41680
|
}
|
|
@@ -41407,10 +42027,10 @@ function solve(a, b, c, n) {
|
|
|
41407
42027
|
}
|
|
41408
42028
|
|
|
41409
42029
|
// src/layout/neato/kk-paths.ts
|
|
41410
|
-
function newPathState(n,
|
|
42030
|
+
function newPathState(n, dist5, adj, initialDist2) {
|
|
41411
42031
|
return {
|
|
41412
42032
|
n,
|
|
41413
|
-
dist:
|
|
42033
|
+
dist: dist5,
|
|
41414
42034
|
adj,
|
|
41415
42035
|
initialDist: initialDist2,
|
|
41416
42036
|
heap: new Int32Array(n + 1),
|
|
@@ -41488,10 +42108,10 @@ function s1(s, src) {
|
|
|
41488
42108
|
function shortestPath2(s) {
|
|
41489
42109
|
for (let v = 0; v < s.n; v++) s1(s, v);
|
|
41490
42110
|
}
|
|
41491
|
-
function
|
|
42111
|
+
function mdsModel2(dist5, n, edges) {
|
|
41492
42112
|
for (const { tailSeq: i, headSeq: j, len } of edges) {
|
|
41493
42113
|
if (i === j) continue;
|
|
41494
|
-
for (const k of [i * n + j, j * n + i]) if (k <
|
|
42114
|
+
for (const k of [i * n + j, j * n + i]) if (k < dist5.length) dist5[k] = len;
|
|
41495
42115
|
}
|
|
41496
42116
|
}
|
|
41497
42117
|
|
|
@@ -41584,12 +42204,12 @@ function initialPositions2(g, st) {
|
|
|
41584
42204
|
}
|
|
41585
42205
|
}
|
|
41586
42206
|
function distvec(p0, p1, del) {
|
|
41587
|
-
let
|
|
42207
|
+
let dist5 = 0;
|
|
41588
42208
|
for (let k = 0; k < NDIM; k++) {
|
|
41589
42209
|
del[k] = p0[k] - p1[k];
|
|
41590
|
-
|
|
42210
|
+
dist5 += del[k] * del[k];
|
|
41591
42211
|
}
|
|
41592
|
-
return Math.sqrt(
|
|
42212
|
+
return Math.sqrt(dist5);
|
|
41593
42213
|
}
|
|
41594
42214
|
function springFactors(g) {
|
|
41595
42215
|
const byEnds = /* @__PURE__ */ new Map();
|
|
@@ -41606,9 +42226,9 @@ function fillRow(st, i, del) {
|
|
|
41606
42226
|
const vi = st.nodes[i];
|
|
41607
42227
|
for (let j = 0; j < st.n; j++) {
|
|
41608
42228
|
if (i === j) continue;
|
|
41609
|
-
const
|
|
42229
|
+
const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
|
|
41610
42230
|
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] /
|
|
42231
|
+
const v = st.spring[i * st.n + j] * (del[k] - st.dist[i * st.n + j] * del[k] / dist5);
|
|
41612
42232
|
st.t[(i * st.n + j) * NDIM + k] = v;
|
|
41613
42233
|
st.sumT[i * NDIM + k] += v;
|
|
41614
42234
|
}
|
|
@@ -41637,9 +42257,9 @@ function updateArrays(st, i) {
|
|
|
41637
42257
|
for (let k = 0; k < NDIM; k++) st.sumT[i * NDIM + k] = 0;
|
|
41638
42258
|
for (let j = 0; j < n; j++) {
|
|
41639
42259
|
if (i === j) continue;
|
|
41640
|
-
const
|
|
42260
|
+
const dist5 = distvec(vi.info.pos, st.nodes[j].info.pos, del);
|
|
41641
42261
|
for (let k = 0; k < NDIM; k++) {
|
|
41642
|
-
const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] /
|
|
42262
|
+
const tij = st.spring[i * n + j] * (del[k] - st.dist[i * n + j] * del[k] / dist5);
|
|
41643
42263
|
st.t[(i * n + j) * NDIM + k] = tij;
|
|
41644
42264
|
st.sumT[i * NDIM + k] += tij;
|
|
41645
42265
|
const old = st.t[(j * n + i) * NDIM + k];
|
|
@@ -41706,7 +42326,7 @@ function moveNode(st, m) {
|
|
|
41706
42326
|
function solveModel(g, st) {
|
|
41707
42327
|
for (let m = chooseNode(st); m >= 0; m = chooseNode(st)) moveNode(st, m);
|
|
41708
42328
|
if (st.move === st.maxIter) {
|
|
41709
|
-
|
|
42329
|
+
agwarningf(`Max. iterations (${st.maxIter}) reached on graph ${g.name}`);
|
|
41710
42330
|
}
|
|
41711
42331
|
}
|
|
41712
42332
|
function mdsEdges(g, nodes, lens) {
|
|
@@ -41719,84 +42339,852 @@ function kkNeato(g, nG, model) {
|
|
|
41719
42339
|
if (nG < 2 || maxIter < 0) return;
|
|
41720
42340
|
const { st, adj, ini, lens } = scanGraphMode(g, maxIter);
|
|
41721
42341
|
shortestPath2(newPathState(st.n, st.dist, adj, ini));
|
|
41722
|
-
if (model === MODEL_MDS2)
|
|
42342
|
+
if (model === MODEL_MDS2) mdsModel2(st.dist, st.n, mdsEdges(g, st.nodes, lens));
|
|
41723
42343
|
initialPositions2(g, st);
|
|
41724
42344
|
diffeqModel(g, st);
|
|
41725
42345
|
solveModel(g, st);
|
|
41726
42346
|
}
|
|
41727
42347
|
|
|
41728
|
-
// src/layout/neato/
|
|
41729
|
-
var
|
|
41730
|
-
|
|
41731
|
-
|
|
41732
|
-
|
|
41733
|
-
|
|
41734
|
-
for (
|
|
42348
|
+
// src/layout/neato/make-graph-data.ts
|
|
42349
|
+
var MODE_IPSEP2 = 3;
|
|
42350
|
+
var EDIST_IN = 1;
|
|
42351
|
+
var EDIST_OUT = -1;
|
|
42352
|
+
var EDIST_NONE = 0;
|
|
42353
|
+
function graphHasLen(g) {
|
|
42354
|
+
for (const e of g.edges) {
|
|
42355
|
+
if (e.attrs.has("len")) return true;
|
|
42356
|
+
}
|
|
42357
|
+
return false;
|
|
41735
42358
|
}
|
|
41736
|
-
|
|
41737
|
-
|
|
41738
|
-
|
|
41739
|
-
|
|
41740
|
-
|
|
42359
|
+
var edistsOf = (v) => v.edists;
|
|
42360
|
+
function reverseBackEdge(graph, i, e, mode) {
|
|
42361
|
+
const node = graph[i];
|
|
42362
|
+
const j = node.edges[e];
|
|
42363
|
+
edistsOf(node)[e] = mode === MODE_IPSEP2 ? EDIST_OUT : EDIST_IN;
|
|
42364
|
+
const target = graph[j];
|
|
42365
|
+
let f = 1;
|
|
42366
|
+
while (f < target.nedges && target.edges[f] !== i) f++;
|
|
42367
|
+
if (f >= target.nedges) throw new Error(`neato: edge ${i}-${j} has no reverse entry`);
|
|
42368
|
+
edistsOf(target)[f] = EDIST_OUT;
|
|
42369
|
+
}
|
|
42370
|
+
function dfsCycle(graph, start, st) {
|
|
42371
|
+
const { mode, mark, onstack } = st;
|
|
42372
|
+
const stack = [{ i: start, e: 1 }];
|
|
42373
|
+
mark[start] = 1;
|
|
42374
|
+
onstack[start] = 1;
|
|
42375
|
+
for (let frame = stack.at(-1); frame !== void 0; frame = stack.at(-1)) {
|
|
42376
|
+
const { i } = frame;
|
|
42377
|
+
const node = graph[i];
|
|
42378
|
+
if (frame.e >= node.nedges) {
|
|
42379
|
+
onstack[i] = 0;
|
|
42380
|
+
stack.pop();
|
|
42381
|
+
continue;
|
|
42382
|
+
}
|
|
42383
|
+
const e = frame.e++;
|
|
42384
|
+
if (edistsOf(node)[e] === EDIST_IN) continue;
|
|
42385
|
+
const j = node.edges[e];
|
|
42386
|
+
if (onstack[j]) {
|
|
42387
|
+
reverseBackEdge(graph, i, e, mode);
|
|
42388
|
+
} else if (!mark[j]) {
|
|
42389
|
+
mark[j] = 1;
|
|
42390
|
+
onstack[j] = 1;
|
|
42391
|
+
stack.push({ i: j, e: 1 });
|
|
42392
|
+
}
|
|
42393
|
+
}
|
|
41741
42394
|
}
|
|
41742
|
-
function
|
|
42395
|
+
function acyclic2(graph, nv, mode) {
|
|
42396
|
+
const st = { mode, mark: new Uint8Array(nv), onstack: new Uint8Array(nv) };
|
|
42397
|
+
for (let i = 0; i < nv; i++) {
|
|
42398
|
+
if (st.mark[i]) continue;
|
|
42399
|
+
dfsCycle(graph, i, st);
|
|
42400
|
+
}
|
|
42401
|
+
}
|
|
42402
|
+
function edgeDist2(dir, np, head) {
|
|
42403
|
+
if (dir !== void 0 && dir.startsWith("none")) return EDIST_NONE;
|
|
42404
|
+
return np === head ? EDIST_IN : EDIST_OUT;
|
|
42405
|
+
}
|
|
42406
|
+
function addNeighbours(g, np, entry, o) {
|
|
42407
|
+
const seen2 = /* @__PURE__ */ new Map();
|
|
42408
|
+
for (const ep of [...np.outEdges(g), ...np.inEdges(g)]) {
|
|
42409
|
+
if (ep.head === ep.tail) continue;
|
|
42410
|
+
const vp = ep.tail === np ? ep.head : ep.tail;
|
|
42411
|
+
const vid = vp.info.id;
|
|
42412
|
+
const dist5 = o.haveLen ? lateDouble(ep.attrs.get("len"), 1, 0) : 1;
|
|
42413
|
+
const idx = seen2.get(vid);
|
|
42414
|
+
if (idx !== void 0) {
|
|
42415
|
+
if (o.haveLen) entry.ewgts[idx] = Math.max(entry.ewgts[idx], dist5);
|
|
42416
|
+
continue;
|
|
42417
|
+
}
|
|
42418
|
+
seen2.set(vid, entry.nedges);
|
|
42419
|
+
entry.edges.push(vid);
|
|
42420
|
+
if (o.haveLen || o.haveDir) entry.ewgts.push(dist5);
|
|
42421
|
+
if (o.haveDir) edistsOf(entry).push(edgeDist2(ep.attrs.get("dir"), np, ep.head));
|
|
42422
|
+
entry.nedges++;
|
|
42423
|
+
}
|
|
42424
|
+
}
|
|
42425
|
+
function makeGraphDataC(g, nodeList, haveLen, haveDir, mode = -1) {
|
|
42426
|
+
const vtx = nodeList.map((_, i) => ({
|
|
42427
|
+
nedges: 1,
|
|
42428
|
+
edges: [i],
|
|
42429
|
+
ewgts: haveLen || haveDir ? [0] : [],
|
|
42430
|
+
...haveDir ? { edists: [0] } : {}
|
|
42431
|
+
}));
|
|
42432
|
+
for (const np of nodeList) addNeighbours(g, np, vtx[np.info.id], { haveLen, haveDir });
|
|
42433
|
+
if (haveDir) acyclic2(vtx, nodeList.length, mode);
|
|
42434
|
+
return vtx;
|
|
42435
|
+
}
|
|
42436
|
+
|
|
42437
|
+
// src/layout/neato/kkutils.ts
|
|
42438
|
+
function compareKeys(a, b) {
|
|
42439
|
+
if (a < b) return -1;
|
|
42440
|
+
if (a > b) return 1;
|
|
42441
|
+
return 0;
|
|
42442
|
+
}
|
|
42443
|
+
function gvSortByPlace(place, ordering, first, count) {
|
|
42444
|
+
const slice = Array.from(ordering.subarray(first, first + count));
|
|
42445
|
+
gvQsort(slice, (x, y) => compareKeys(place[x], place[y]));
|
|
42446
|
+
for (let i = 0; i < count; i++) ordering[first + i] = slice[i];
|
|
42447
|
+
}
|
|
42448
|
+
function quicksortPlace(place, ordering, size) {
|
|
42449
|
+
gvSortByPlace(place, ordering, 0, size);
|
|
42450
|
+
}
|
|
42451
|
+
function quicksortPlacef(place, ordering, first, last) {
|
|
42452
|
+
if (first < last) {
|
|
42453
|
+
gvSortByPlace(place, ordering, first, last - first + 1);
|
|
42454
|
+
}
|
|
42455
|
+
}
|
|
42456
|
+
function computeApspDijkstra(graph, n) {
|
|
42457
|
+
const dij = [];
|
|
42458
|
+
for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
|
|
42459
|
+
for (let i = 0; i < n; i++) ngdijkstra(i, graph, n, dij[i]);
|
|
42460
|
+
return dij;
|
|
42461
|
+
}
|
|
42462
|
+
function computeApspSimple(graph, n) {
|
|
42463
|
+
const dij = [];
|
|
42464
|
+
for (let i = 0; i < n; i++) dij.push(new Int32Array(n));
|
|
42465
|
+
for (let i = 0; i < n; i++) bfs(i, graph, n, dij[i]);
|
|
42466
|
+
return dij;
|
|
42467
|
+
}
|
|
42468
|
+
function computeApsp(graph, n) {
|
|
42469
|
+
return graph[0].ewgts.length > 0 ? computeApspDijkstra(graph, n) : computeApspSimple(graph, n);
|
|
42470
|
+
}
|
|
42471
|
+
|
|
42472
|
+
// src/layout/neato/quad-prog-solve.ts
|
|
42473
|
+
var fr2 = Math.fround;
|
|
42474
|
+
var TOLERANCE = fr2(0.01);
|
|
42475
|
+
var BOUND = 1e9;
|
|
42476
|
+
var BLOCK_EPSILON = 1e-9;
|
|
42477
|
+
var NO_SPLIT = -1;
|
|
42478
|
+
var BITS = new DataView(new ArrayBuffer(8));
|
|
42479
|
+
function oddNeighbour(s, awayFromZero) {
|
|
42480
|
+
BITS.setFloat64(0, s);
|
|
42481
|
+
const hi = BITS.getUint32(0);
|
|
42482
|
+
const lo = BITS.getUint32(4);
|
|
42483
|
+
if (awayFromZero) {
|
|
42484
|
+
BITS.setUint32(4, lo + 1);
|
|
42485
|
+
} else if (lo === 0) {
|
|
42486
|
+
BITS.setUint32(0, hi - 1);
|
|
42487
|
+
BITS.setUint32(4, 4294967295);
|
|
42488
|
+
} else {
|
|
42489
|
+
BITS.setUint32(4, lo - 1);
|
|
42490
|
+
}
|
|
42491
|
+
return BITS.getFloat64(0);
|
|
42492
|
+
}
|
|
42493
|
+
function fmaf(a, b, c) {
|
|
42494
|
+
const p = a * b;
|
|
42495
|
+
const s = p + c;
|
|
42496
|
+
const bv = s - p;
|
|
42497
|
+
const err = p - (s - bv) + (c - bv);
|
|
42498
|
+
if (err === 0 || !Number.isFinite(s)) return fr2(s);
|
|
42499
|
+
BITS.setFloat64(0, s);
|
|
42500
|
+
if ((BITS.getUint32(4) & 1) !== 0) return fr2(s);
|
|
42501
|
+
return fr2(oddNeighbour(s, err > 0 === s > 0));
|
|
42502
|
+
}
|
|
42503
|
+
function blockPlaceNumerator(blockDeg, desPlaceBlock, negLapTimesDesired, toBlockConnectivity, curPlace) {
|
|
42504
|
+
const t = fmaf(blockDeg, desPlaceBlock, negLapTimesDesired);
|
|
42505
|
+
return fmaf(toBlockConnectivity, curPlace, t);
|
|
42506
|
+
}
|
|
42507
|
+
function equals(a, b) {
|
|
42508
|
+
return Math.abs(fr2(a - b)) < TOLERANCE;
|
|
42509
|
+
}
|
|
42510
|
+
function fminf(a, b) {
|
|
42511
|
+
if (Number.isNaN(a)) return b;
|
|
42512
|
+
if (Number.isNaN(b)) return a;
|
|
42513
|
+
return a < b ? a : b;
|
|
42514
|
+
}
|
|
42515
|
+
function fmaxf(a, b) {
|
|
42516
|
+
if (Number.isNaN(a)) return b;
|
|
42517
|
+
if (Number.isNaN(b)) return a;
|
|
42518
|
+
return a > b ? a : b;
|
|
42519
|
+
}
|
|
42520
|
+
function unpackMatrix(packedMat, n) {
|
|
42521
|
+
const flat = new Float32Array(n * n);
|
|
42522
|
+
const mat = new Array(n);
|
|
42523
|
+
for (let i = 0; i < n; i++) mat[i] = flat.subarray(i * n, (i + 1) * n);
|
|
42524
|
+
for (let i = 0, k = 0; i < n; i++) {
|
|
42525
|
+
for (let j = i; j < n; j++, k++) {
|
|
42526
|
+
mat[j][i] = mat[i][j] = packedMat[k];
|
|
42527
|
+
}
|
|
42528
|
+
}
|
|
42529
|
+
return mat;
|
|
42530
|
+
}
|
|
42531
|
+
function ensureMonotonicOrderingWithGaps(place, n, ordering, levels, numLevels, levelsGap) {
|
|
42532
|
+
let lowerBound = fr2(-1e9);
|
|
42533
|
+
let level = -1;
|
|
42534
|
+
let maxInLevel = 0;
|
|
42535
|
+
for (let i = 0; i < n; i++) {
|
|
42536
|
+
if (i >= maxInLevel) {
|
|
42537
|
+
level++;
|
|
42538
|
+
maxInLevel = level === numLevels ? n : levels[level];
|
|
42539
|
+
lowerBound = i > 0 ? fr2(place[ordering[i - 1]] + levelsGap) : fr2(-1e9);
|
|
42540
|
+
quicksortPlacef(place, ordering, i, maxInLevel - 1);
|
|
42541
|
+
}
|
|
42542
|
+
const node = ordering[i];
|
|
42543
|
+
if (place[node] < lowerBound) place[node] = lowerBound;
|
|
42544
|
+
}
|
|
42545
|
+
}
|
|
42546
|
+
function computeNodeLevels(e) {
|
|
42547
|
+
const lev = new Int32Array(e.n);
|
|
42548
|
+
let level = -1;
|
|
42549
|
+
let maxInLevel = 0;
|
|
42550
|
+
for (let i = 0; i < e.n; i++) {
|
|
42551
|
+
if (i >= maxInLevel) {
|
|
42552
|
+
level++;
|
|
42553
|
+
maxInLevel = level === e.numLevels ? e.n : e.levels[level];
|
|
42554
|
+
}
|
|
42555
|
+
lev[e.ordering[i]] = level;
|
|
42556
|
+
}
|
|
42557
|
+
return lev;
|
|
42558
|
+
}
|
|
42559
|
+
function growBlock(c, left2, curPlace) {
|
|
42560
|
+
const { place, lev, levelsGap, e } = c;
|
|
42561
|
+
const gap = e.fArray4;
|
|
42562
|
+
let targetPlace = curPlace;
|
|
42563
|
+
gap[e.ordering[left2]] = 0;
|
|
42564
|
+
let right2;
|
|
42565
|
+
for (right2 = left2 + 1; right2 < e.n; right2++) {
|
|
42566
|
+
if (lev[right2] > lev[right2 - 1]) {
|
|
42567
|
+
targetPlace = fr2(targetPlace + levelsGap);
|
|
42568
|
+
}
|
|
42569
|
+
const node = e.ordering[right2];
|
|
42570
|
+
if (Math.abs(fr2(place[node] - targetPlace)) > BLOCK_EPSILON) break;
|
|
42571
|
+
gap[node] = fr2(place[node] - curPlace);
|
|
42572
|
+
}
|
|
42573
|
+
return right2;
|
|
42574
|
+
}
|
|
42575
|
+
function computeDesiredPlaces(c, left2, right2) {
|
|
42576
|
+
const { e, place, b } = c;
|
|
42577
|
+
for (let i = left2; i < right2; i++) {
|
|
42578
|
+
const node = e.ordering[i];
|
|
42579
|
+
let newPlaceI = -b[node];
|
|
42580
|
+
const lapNode = e.A[node];
|
|
42581
|
+
for (let j = 0; j < e.n; j++) {
|
|
42582
|
+
if (j === node) continue;
|
|
42583
|
+
newPlaceI = fmaf(lapNode[j], place[j], newPlaceI);
|
|
42584
|
+
}
|
|
42585
|
+
e.fArray1[node] = fr2(fr2(newPlaceI / -lapNode[node]) - e.fArray4[node]);
|
|
42586
|
+
}
|
|
42587
|
+
}
|
|
42588
|
+
function collectWhere(c, from, to, test) {
|
|
42589
|
+
for (let j = from; j < to; j++) {
|
|
42590
|
+
const node = c.e.ordering[j];
|
|
42591
|
+
if (test(c.e.fArray1[node])) c.block.push(node);
|
|
42592
|
+
}
|
|
42593
|
+
}
|
|
42594
|
+
function orderBlockByLevels(c, left2, right2, curPlace) {
|
|
42595
|
+
const { e } = c;
|
|
42596
|
+
c.block.length = 0;
|
|
42597
|
+
let firstNextLevel = 0;
|
|
42598
|
+
for (let i = left2; i < right2; i = firstNextLevel) {
|
|
42599
|
+
const level = c.lev[e.ordering[i]];
|
|
42600
|
+
firstNextLevel = level === e.numLevels ? right2 : Math.min(right2, e.levels[level]);
|
|
42601
|
+
collectWhere(c, i, firstNextLevel, (d) => d < curPlace);
|
|
42602
|
+
collectWhere(c, i, firstNextLevel, (d) => d === curPlace);
|
|
42603
|
+
collectWhere(c, i, firstNextLevel, (d) => d > curPlace);
|
|
42604
|
+
}
|
|
42605
|
+
}
|
|
42606
|
+
function computePrefixDesiredPlaces(c, curPlace) {
|
|
42607
|
+
const { e, block } = c;
|
|
42608
|
+
let desPlaceBlock = 0;
|
|
42609
|
+
let blockDeg = 0;
|
|
42610
|
+
for (let i = 0; i < block.length; i++) {
|
|
42611
|
+
const node = block[i];
|
|
42612
|
+
let toBlockConnectivity = 0;
|
|
42613
|
+
const lapNode = e.A[node];
|
|
42614
|
+
for (let j = 0; j < i; j++) {
|
|
42615
|
+
toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
|
|
42616
|
+
}
|
|
42617
|
+
toBlockConnectivity = fr2(toBlockConnectivity * 2);
|
|
42618
|
+
const num2 = blockPlaceNumerator(
|
|
42619
|
+
blockDeg,
|
|
42620
|
+
desPlaceBlock,
|
|
42621
|
+
fr2(-lapNode[node] * e.fArray1[node]),
|
|
42622
|
+
toBlockConnectivity,
|
|
42623
|
+
curPlace
|
|
42624
|
+
);
|
|
42625
|
+
desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
|
|
42626
|
+
e.fArray2[i] = desPlaceBlock;
|
|
42627
|
+
blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
|
|
42628
|
+
}
|
|
42629
|
+
if (e.n >= 0 && block.length === e.n) {
|
|
42630
|
+
e.fArray2[e.n - 1] = curPlace;
|
|
42631
|
+
}
|
|
42632
|
+
}
|
|
42633
|
+
function computeSuffixDesiredPlaces(c, curPlace) {
|
|
42634
|
+
const { e, block } = c;
|
|
42635
|
+
let desPlaceBlock = 0;
|
|
42636
|
+
let blockDeg = 0;
|
|
42637
|
+
for (let i = block.length - 1; i >= 0; i--) {
|
|
42638
|
+
const node = block[i];
|
|
42639
|
+
let toBlockConnectivity = 0;
|
|
42640
|
+
const lapNode = e.A[node];
|
|
42641
|
+
for (let j = i + 1; j < block.length; j++) {
|
|
42642
|
+
toBlockConnectivity = fr2(toBlockConnectivity - lapNode[block[j]]);
|
|
42643
|
+
}
|
|
42644
|
+
toBlockConnectivity = fr2(toBlockConnectivity * 2);
|
|
42645
|
+
const num2 = blockPlaceNumerator(
|
|
42646
|
+
blockDeg,
|
|
42647
|
+
desPlaceBlock,
|
|
42648
|
+
fr2(-lapNode[node] * e.fArray1[node]),
|
|
42649
|
+
toBlockConnectivity,
|
|
42650
|
+
curPlace
|
|
42651
|
+
);
|
|
42652
|
+
desPlaceBlock = fr2(num2 / fr2(fr2(blockDeg - lapNode[node]) + toBlockConnectivity));
|
|
42653
|
+
e.fArray3[i] = desPlaceBlock;
|
|
42654
|
+
blockDeg = fr2(blockDeg + fr2(toBlockConnectivity - lapNode[node]));
|
|
42655
|
+
}
|
|
42656
|
+
if (e.n >= 0 && block.length === e.n) {
|
|
42657
|
+
e.fArray3[0] = curPlace;
|
|
42658
|
+
}
|
|
42659
|
+
}
|
|
42660
|
+
var LIMITED = new Float64Array(2);
|
|
42661
|
+
function limitMoves(prefix, suffix, curPlace) {
|
|
42662
|
+
if (suffix < prefix) {
|
|
42663
|
+
if (suffix < curPlace) {
|
|
42664
|
+
if (prefix > curPlace) prefix = curPlace;
|
|
42665
|
+
suffix = prefix;
|
|
42666
|
+
} else if (prefix > curPlace) {
|
|
42667
|
+
prefix = suffix;
|
|
42668
|
+
}
|
|
42669
|
+
}
|
|
42670
|
+
LIMITED[0] = prefix;
|
|
42671
|
+
LIMITED[1] = suffix;
|
|
42672
|
+
}
|
|
42673
|
+
function findBestSplit(c, curPlace) {
|
|
42674
|
+
const { e, block } = c;
|
|
42675
|
+
let bestI = NO_SPLIT;
|
|
42676
|
+
let maxMovement = 0;
|
|
42677
|
+
for (let i = 0; i < block.length; i++) {
|
|
42678
|
+
const suffixDesPlace = e.fArray3[i];
|
|
42679
|
+
const prefixDesPlace = i > 0 ? e.fArray2[i - 1] : suffixDesPlace;
|
|
42680
|
+
limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
|
|
42681
|
+
const movement = (block.length - i) * Math.abs(fr2(LIMITED[1] - curPlace)) + i * Math.abs(fr2(LIMITED[0] - curPlace));
|
|
42682
|
+
if (movement > maxMovement) {
|
|
42683
|
+
maxMovement = movement;
|
|
42684
|
+
bestI = i;
|
|
42685
|
+
}
|
|
42686
|
+
}
|
|
42687
|
+
return bestI;
|
|
42688
|
+
}
|
|
42689
|
+
function computeUpperBound(c, right2) {
|
|
42690
|
+
const { e, place, lev, levelsGap, block } = c;
|
|
42691
|
+
if (right2 >= e.n) return BOUND;
|
|
42692
|
+
const lastGap = e.fArray4[block[block.length - 1]];
|
|
42693
|
+
const nextPlace = place[e.ordering[right2]];
|
|
42694
|
+
if (lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
|
|
42695
|
+
return fr2(fr2(nextPlace - levelsGap) - lastGap);
|
|
42696
|
+
}
|
|
42697
|
+
return fr2(nextPlace - lastGap);
|
|
42698
|
+
}
|
|
42699
|
+
function nextLowerBound(c, right2) {
|
|
42700
|
+
const { e, place, lev, levelsGap, block } = c;
|
|
42701
|
+
const last = place[block[block.length - 1]];
|
|
42702
|
+
if (right2 < e.n && lev[e.ordering[right2]] > lev[e.ordering[right2 - 1]]) {
|
|
42703
|
+
return fr2(last + levelsGap);
|
|
42704
|
+
}
|
|
42705
|
+
return last;
|
|
42706
|
+
}
|
|
42707
|
+
function moveSplitBlock(c, bestI, left2, right2, curPlace) {
|
|
42708
|
+
const { e, place, block } = c;
|
|
42709
|
+
let suffixDesPlace = e.fArray3[bestI];
|
|
42710
|
+
let prefixDesPlace = bestI > 0 ? e.fArray2[bestI - 1] : suffixDesPlace;
|
|
42711
|
+
suffixDesPlace = fminf(suffixDesPlace, computeUpperBound(c, right2));
|
|
42712
|
+
prefixDesPlace = fmaxf(prefixDesPlace, c.lowerBound);
|
|
42713
|
+
limitMoves(prefixDesPlace, suffixDesPlace, curPlace);
|
|
42714
|
+
prefixDesPlace = LIMITED[0];
|
|
42715
|
+
suffixDesPlace = LIMITED[1];
|
|
42716
|
+
for (let i = 0; i < bestI; i++) {
|
|
42717
|
+
place[block[i]] = fr2(prefixDesPlace + e.fArray4[block[i]]);
|
|
42718
|
+
}
|
|
42719
|
+
for (let i = bestI; i < block.length; i++) {
|
|
42720
|
+
place[block[i]] = fr2(suffixDesPlace + e.fArray4[block[i]]);
|
|
42721
|
+
}
|
|
42722
|
+
c.lowerBound = nextLowerBound(c, right2);
|
|
42723
|
+
for (let i = left2; i < right2; i++) e.ordering[i] = block[i - left2];
|
|
42724
|
+
c.converged = c.converged && equals(prefixDesPlace, curPlace) && equals(suffixDesPlace, curPlace);
|
|
42725
|
+
}
|
|
42726
|
+
function processBlock(c, left2) {
|
|
42727
|
+
const curPlace = c.place[c.e.ordering[left2]];
|
|
42728
|
+
const right2 = growBlock(c, left2, curPlace);
|
|
42729
|
+
computeDesiredPlaces(c, left2, right2);
|
|
42730
|
+
orderBlockByLevels(c, left2, right2, curPlace);
|
|
42731
|
+
computePrefixDesiredPlaces(c, curPlace);
|
|
42732
|
+
computeSuffixDesiredPlaces(c, curPlace);
|
|
42733
|
+
const bestI = findBestSplit(c, curPlace);
|
|
42734
|
+
if (bestI !== NO_SPLIT) {
|
|
42735
|
+
moveSplitBlock(c, bestI, left2, right2, curPlace);
|
|
42736
|
+
} else {
|
|
42737
|
+
c.lowerBound = nextLowerBound(c, right2);
|
|
42738
|
+
}
|
|
42739
|
+
return right2;
|
|
42740
|
+
}
|
|
42741
|
+
function constrainedMajorizationNewWithGaps(e, b, coords, curAxis, maxIterations, levelsGap) {
|
|
42742
|
+
const place = coords[curAxis];
|
|
42743
|
+
if (maxIterations <= 0) return;
|
|
42744
|
+
const gap = fr2(levelsGap);
|
|
42745
|
+
ensureMonotonicOrderingWithGaps(place, e.n, e.ordering, e.levels, e.numLevels, gap);
|
|
42746
|
+
const c = {
|
|
42747
|
+
e,
|
|
42748
|
+
place,
|
|
42749
|
+
b,
|
|
42750
|
+
lev: computeNodeLevels(e),
|
|
42751
|
+
levelsGap: gap,
|
|
42752
|
+
block: [],
|
|
42753
|
+
lowerBound: fr2(-BOUND),
|
|
42754
|
+
converged: false
|
|
42755
|
+
};
|
|
42756
|
+
for (let counter = 0; counter < maxIterations && !c.converged; counter++) {
|
|
42757
|
+
c.converged = true;
|
|
42758
|
+
c.lowerBound = fr2(-BOUND);
|
|
42759
|
+
for (let left2 = 0, right2; left2 < e.n; left2 = right2) {
|
|
42760
|
+
right2 = processBlock(c, left2);
|
|
42761
|
+
}
|
|
42762
|
+
orthog1f(e.n, place);
|
|
42763
|
+
}
|
|
42764
|
+
}
|
|
42765
|
+
function initConstrainedMajorization(packedMat, n, ordering, levels, numLevels) {
|
|
42766
|
+
return {
|
|
42767
|
+
A: unpackMatrix(packedMat, n),
|
|
42768
|
+
n,
|
|
42769
|
+
fArray1: new Float32Array(n),
|
|
42770
|
+
fArray2: new Float32Array(n),
|
|
42771
|
+
fArray3: new Float32Array(n),
|
|
42772
|
+
fArray4: new Float32Array(n),
|
|
42773
|
+
ordering,
|
|
42774
|
+
levels,
|
|
42775
|
+
numLevels
|
|
42776
|
+
};
|
|
42777
|
+
}
|
|
42778
|
+
|
|
42779
|
+
// src/layout/neato/conjgrad-mkernel.ts
|
|
42780
|
+
var fr3 = Math.fround;
|
|
42781
|
+
var RIGHT_MULT_BLOCK = 16;
|
|
42782
|
+
var ZERO_LENGTH_MESSAGE = "conjugate_gradient: unexpected length 0 vector\n";
|
|
42783
|
+
function rightMultWithVectorFFFused(m, n, vector, result) {
|
|
41743
42784
|
for (let i = 0; i < n; i++) result[i] = 0;
|
|
41744
42785
|
let index = 0;
|
|
41745
42786
|
for (let i = 0; i < n; i++) {
|
|
41746
42787
|
const vi = vector[i];
|
|
41747
|
-
let res =
|
|
42788
|
+
let res = fmaf(m[index++], vi, 0);
|
|
42789
|
+
const len = n - i - 1;
|
|
42790
|
+
const blockEnd = i + 1 + (len - len % RIGHT_MULT_BLOCK);
|
|
41748
42791
|
for (let j = i + 1; j < n; j++, index++) {
|
|
41749
|
-
|
|
41750
|
-
|
|
42792
|
+
const mij = m[index];
|
|
42793
|
+
res = j < blockEnd ? fr3(res + fr3(mij * vector[j])) : fmaf(mij, vector[j], res);
|
|
42794
|
+
result[j] = fmaf(mij, vi, result[j]);
|
|
41751
42795
|
}
|
|
41752
42796
|
result[i] = result[i] + res;
|
|
41753
42797
|
}
|
|
41754
42798
|
}
|
|
41755
|
-
function
|
|
41756
|
-
for (let i = 0; i < n; i++)
|
|
42799
|
+
function vectorsMultAdditionFused(n, v1, alpha, v2) {
|
|
42800
|
+
for (let i = 0; i < n; i++) v1[i] = fmaf(alpha, v2[i], v1[i]);
|
|
41757
42801
|
}
|
|
41758
|
-
|
|
41759
|
-
|
|
41760
|
-
|
|
42802
|
+
var CgStep = { CONTINUE: 0, STOP: 1, ERROR: 2 };
|
|
42803
|
+
function initialState(A3, x, b, n) {
|
|
42804
|
+
const Ax = new Float32Array(n);
|
|
42805
|
+
const st = { n, r: new Float32Array(n), p: new Float32Array(n), Ap: new Float32Array(n), rR: 0 };
|
|
42806
|
+
orthog1f(n, x);
|
|
42807
|
+
orthog1f(n, b);
|
|
42808
|
+
rightMultWithVectorFFFused(A3, n, x, Ax);
|
|
42809
|
+
orthog1f(n, Ax);
|
|
42810
|
+
vectorsSubtractionF(n, b, Ax, st.r);
|
|
42811
|
+
copyVectorF(n, st.r, st.p);
|
|
42812
|
+
st.rR = vectorsInnerProductF(n, st.r, st.r);
|
|
42813
|
+
return st;
|
|
41761
42814
|
}
|
|
41762
|
-
function
|
|
41763
|
-
|
|
41764
|
-
|
|
41765
|
-
|
|
42815
|
+
function cgIteration(A3, x, st, last) {
|
|
42816
|
+
const { n, r, p, Ap } = st;
|
|
42817
|
+
orthog1f(n, p);
|
|
42818
|
+
orthog1f(n, x);
|
|
42819
|
+
orthog1f(n, r);
|
|
42820
|
+
rightMultWithVectorFFFused(A3, n, p, Ap);
|
|
42821
|
+
orthog1f(n, Ap);
|
|
42822
|
+
const pAp = vectorsInnerProductF(n, p, Ap);
|
|
42823
|
+
if (pAp === 0) return CgStep.STOP;
|
|
42824
|
+
const alpha = st.rR / pAp;
|
|
42825
|
+
vectorsMultAdditionFused(n, x, fr3(alpha), p);
|
|
42826
|
+
if (last) return CgStep.CONTINUE;
|
|
42827
|
+
vectorsMultAdditionFused(n, r, fr3(-alpha), Ap);
|
|
42828
|
+
const rRNew = vectorsInnerProductF(n, r, r);
|
|
42829
|
+
if (st.rR === 0) {
|
|
42830
|
+
agerrorf(ZERO_LENGTH_MESSAGE);
|
|
42831
|
+
return CgStep.ERROR;
|
|
42832
|
+
}
|
|
42833
|
+
const beta = fr3(rRNew / st.rR);
|
|
42834
|
+
st.rR = rRNew;
|
|
42835
|
+
for (let j = 0; j < n; j++) p[j] = fmaf(beta, p[j], r[j]);
|
|
42836
|
+
return CgStep.CONTINUE;
|
|
42837
|
+
}
|
|
42838
|
+
function conjugateGradientMkernelFused(A3, x, b, n, o) {
|
|
42839
|
+
const st = initialState(A3, x, b, n);
|
|
42840
|
+
for (let i = 0; i < o.maxIterations && maxAbsF(n, st.r) > o.tol; i++) {
|
|
42841
|
+
const step = cgIteration(A3, x, st, i >= o.maxIterations - 1);
|
|
42842
|
+
if (step === CgStep.STOP) break;
|
|
42843
|
+
if (step === CgStep.ERROR) return 1;
|
|
42844
|
+
}
|
|
42845
|
+
return 0;
|
|
41766
42846
|
}
|
|
41767
|
-
|
|
41768
|
-
|
|
42847
|
+
|
|
42848
|
+
// src/layout/neato/opt-arrangement.ts
|
|
42849
|
+
var HIERARCHY_CG_TOL = 1e-3;
|
|
42850
|
+
function constructB(graph, n, b) {
|
|
42851
|
+
for (let i = 0; i < n; i++) {
|
|
42852
|
+
if (graph[0].edists == null) continue;
|
|
42853
|
+
let bI = 0;
|
|
42854
|
+
const node = graph[i];
|
|
42855
|
+
for (let j = 1; j < node.nedges; j++) {
|
|
42856
|
+
bI += Math.fround(Math.fround(node.ewgts[j]) * node.edists[j]);
|
|
42857
|
+
}
|
|
42858
|
+
b[i] = bI;
|
|
42859
|
+
}
|
|
41769
42860
|
}
|
|
41770
|
-
function
|
|
41771
|
-
|
|
42861
|
+
function setUniformWeights(graph, n) {
|
|
42862
|
+
const old = [];
|
|
41772
42863
|
for (let i = 0; i < n; i++) {
|
|
41773
|
-
const
|
|
41774
|
-
|
|
42864
|
+
const node = graph[i];
|
|
42865
|
+
old.push(node.ewgts);
|
|
42866
|
+
const weights = new Array(node.nedges).fill(1);
|
|
42867
|
+
weights[0] = -(node.nedges - 1);
|
|
42868
|
+
node.ewgts = weights;
|
|
41775
42869
|
}
|
|
41776
|
-
return
|
|
42870
|
+
return old;
|
|
41777
42871
|
}
|
|
41778
|
-
function
|
|
41779
|
-
|
|
42872
|
+
function computeYCoords(graph, n, yCoords, maxIterations) {
|
|
42873
|
+
let rv = 0;
|
|
42874
|
+
const b = new Float64Array(n);
|
|
42875
|
+
constructB(graph, n, b);
|
|
42876
|
+
initVecOrth1(n, yCoords);
|
|
42877
|
+
const oldEwgts = setUniformWeights(graph, n);
|
|
42878
|
+
if (conjugateGradient(graph, yCoords, b, n, HIERARCHY_CG_TOL, maxIterations) < 0) {
|
|
42879
|
+
rv = 1;
|
|
42880
|
+
}
|
|
42881
|
+
for (let i = 0; i < n; i++) graph[i].ewgts = oldEwgts[i];
|
|
42882
|
+
return rv;
|
|
41780
42883
|
}
|
|
41781
|
-
|
|
42884
|
+
|
|
42885
|
+
// src/layout/neato/compute-hierarchy.ts
|
|
42886
|
+
function countLevels(y, ordering, n, tol) {
|
|
42887
|
+
let numLevels = 0;
|
|
42888
|
+
for (let i = 1; i < n; i++) {
|
|
42889
|
+
if (y[ordering[i]] - y[ordering[i - 1]] > tol) numLevels++;
|
|
42890
|
+
}
|
|
42891
|
+
return numLevels;
|
|
42892
|
+
}
|
|
42893
|
+
function fillLevels(y, ordering, n, tol, numLevels) {
|
|
42894
|
+
if (numLevels === 0) {
|
|
42895
|
+
const levels2 = new Int32Array(1);
|
|
42896
|
+
levels2[0] = n;
|
|
42897
|
+
return levels2;
|
|
42898
|
+
}
|
|
42899
|
+
const levels = new Int32Array(numLevels);
|
|
42900
|
+
let count = 0;
|
|
42901
|
+
for (let i = 1; i < n; i++) {
|
|
42902
|
+
if (y[ordering[i]] - y[ordering[i - 1]] > tol) levels[count++] = i;
|
|
42903
|
+
}
|
|
42904
|
+
return levels;
|
|
42905
|
+
}
|
|
42906
|
+
function computeHierarchy(graph, n, absTol, relTol, given) {
|
|
42907
|
+
let y;
|
|
42908
|
+
if (given) {
|
|
42909
|
+
y = given;
|
|
42910
|
+
} else {
|
|
42911
|
+
y = new Float64Array(n);
|
|
42912
|
+
if (computeYCoords(graph, n, y, n)) return null;
|
|
42913
|
+
}
|
|
42914
|
+
const ordering = new Int32Array(n);
|
|
42915
|
+
for (let i = 0; i < n; i++) ordering[i] = i;
|
|
42916
|
+
quicksortPlace(y, ordering, n);
|
|
42917
|
+
const hierarchySpan = y[ordering[n - 1]] - y[ordering[0]];
|
|
42918
|
+
const relative = relTol * hierarchySpan / (n - 1);
|
|
42919
|
+
const tol = absTol > relative ? absTol : relative;
|
|
42920
|
+
const numLevels = countLevels(y, ordering, n, tol);
|
|
42921
|
+
return { ordering, levels: fillLevels(y, ordering, n, tol, numLevels), numLevels };
|
|
42922
|
+
}
|
|
42923
|
+
|
|
42924
|
+
// src/layout/neato/smart-ini-x.ts
|
|
42925
|
+
var fr4 = Math.fround;
|
|
42926
|
+
var SCALE_FACTOR = 256;
|
|
42927
|
+
var DBL_EPSILON = 2220446049250313e-31;
|
|
42928
|
+
var POWER_LENGTH_FLOOR = 1e-10;
|
|
42929
|
+
var BLOCK_STANDARDIZE_NORM = 4;
|
|
42930
|
+
var BLOCK_MAT_MULT_ROW = 4;
|
|
42931
|
+
var BLOCK_MAT_MULT_ORTHOG = 8;
|
|
42932
|
+
var BLOCK_GUESS_ORTHOG = 8;
|
|
42933
|
+
var BLOCK_GUESS_LEN = BLOCK_NONE;
|
|
42934
|
+
var BLOCK_LOOP_LEN = BLOCK_NONE;
|
|
42935
|
+
var BLOCK_ANGLE = 8;
|
|
42936
|
+
var BLOCK_UNIFORM_SUMS = 4;
|
|
42937
|
+
var BLOCK_AVGS = 4;
|
|
42938
|
+
function standardize(orthog, nvtxs) {
|
|
42939
|
+
let avg = 0;
|
|
42940
|
+
for (let i = 0; i < nvtxs; i++) avg += orthog[i];
|
|
42941
|
+
avg /= nvtxs;
|
|
42942
|
+
for (let i = 0; i < nvtxs; i++) orthog[i] = orthog[i] - avg;
|
|
42943
|
+
const len = norm(orthog, nvtxs - 1, BLOCK_STANDARDIZE_NORM);
|
|
42944
|
+
if (Math.abs(len) < DBL_EPSILON) return;
|
|
42945
|
+
vectorsScalarMult(nvtxs, orthog, 1 / len, orthog);
|
|
42946
|
+
}
|
|
42947
|
+
function matMultVecOrthog(mat, dim, vec, result, orthog) {
|
|
42948
|
+
const blocked = dim - dim % BLOCK_MAT_MULT_ROW;
|
|
42949
|
+
for (let i = 0; i < dim; i++) {
|
|
42950
|
+
const row = mat[i];
|
|
42951
|
+
let sum = 0;
|
|
42952
|
+
let j = 0;
|
|
42953
|
+
for (; j < blocked; j++) sum += row[j] * vec[j];
|
|
42954
|
+
for (; j < dim; j++) sum = fma2(row[j], vec[j], sum);
|
|
42955
|
+
result[i] = sum;
|
|
42956
|
+
}
|
|
42957
|
+
const alpha = -innerProduct(dim, result, orthog, BLOCK_MAT_MULT_ORTHOG);
|
|
42958
|
+
scadd(result, dim - 1, alpha, orthog);
|
|
42959
|
+
}
|
|
42960
|
+
function orthogonalizeAgainstEigs(p, vec, count, block) {
|
|
42961
|
+
for (let j = 0; j < count; j++) {
|
|
42962
|
+
const alpha = -innerProduct(p.n, p.eigs[j], vec, block);
|
|
42963
|
+
scadd(vec, p.n - 1, alpha, p.eigs[j]);
|
|
42964
|
+
}
|
|
42965
|
+
}
|
|
42966
|
+
function chooseStartVector(p, i) {
|
|
42967
|
+
const curr = p.eigs[i];
|
|
42968
|
+
for (; ; ) {
|
|
42969
|
+
for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
|
|
42970
|
+
const alpha = -innerProduct(p.n, p.orthog, curr, BLOCK_GUESS_ORTHOG);
|
|
42971
|
+
scadd(curr, p.n - 1, alpha, p.orthog);
|
|
42972
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
42973
|
+
const len = norm(curr, p.n - 1, BLOCK_GUESS_LEN);
|
|
42974
|
+
if (len < POWER_LENGTH_FLOOR) continue;
|
|
42975
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
42976
|
+
return;
|
|
42977
|
+
}
|
|
42978
|
+
}
|
|
42979
|
+
function iterateEigenvector(p, i, tol, work) {
|
|
42980
|
+
const curr = p.eigs[i];
|
|
42981
|
+
for (; ; ) {
|
|
42982
|
+
copyVector(p.n, curr, work.last);
|
|
42983
|
+
matMultVecOrthog(p.mat, p.n, curr, work.tmp, p.orthog);
|
|
42984
|
+
copyVector(p.n, work.tmp, curr);
|
|
42985
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
42986
|
+
const len = norm(curr, p.n - 1, BLOCK_LOOP_LEN);
|
|
42987
|
+
if (len < POWER_LENGTH_FLOOR) {
|
|
42988
|
+
return { nullSpace: true, eval: 0 };
|
|
42989
|
+
}
|
|
42990
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
42991
|
+
const angle = innerProduct(p.n, curr, work.last, BLOCK_ANGLE);
|
|
42992
|
+
if (!(Math.abs(angle) < tol)) {
|
|
42993
|
+
return { nullSpace: false, eval: angle * len };
|
|
42994
|
+
}
|
|
42995
|
+
}
|
|
42996
|
+
}
|
|
42997
|
+
function fillNullSpaceEigenvectors(p, from, neigs) {
|
|
42998
|
+
for (let i = from; i < neigs; i++) {
|
|
42999
|
+
const curr = p.eigs[i];
|
|
43000
|
+
for (let j = 0; j < p.n; j++) curr[j] = crand() % 100;
|
|
43001
|
+
orthogonalizeAgainstEigs(p, curr, i, BLOCK_NONE);
|
|
43002
|
+
const len = norm(curr, p.n - 1, BLOCK_NONE);
|
|
43003
|
+
vectorsScalarMult(p.n, curr, 1 / len, curr);
|
|
43004
|
+
p.evals[i] = 0;
|
|
43005
|
+
}
|
|
43006
|
+
}
|
|
43007
|
+
function sortEigenvectors(p, neigs, tmp) {
|
|
43008
|
+
for (let i = 0; i < neigs - 1; i++) {
|
|
43009
|
+
let largestIndex = i;
|
|
43010
|
+
let largestEval = p.evals[largestIndex];
|
|
43011
|
+
for (let j = i + 1; j < neigs; j++) {
|
|
43012
|
+
if (largestEval < p.evals[j]) {
|
|
43013
|
+
largestIndex = j;
|
|
43014
|
+
largestEval = p.evals[largestIndex];
|
|
43015
|
+
}
|
|
43016
|
+
}
|
|
43017
|
+
if (largestIndex !== i) {
|
|
43018
|
+
copyVector(p.n, p.eigs[i], tmp);
|
|
43019
|
+
copyVector(p.n, p.eigs[largestIndex], p.eigs[i]);
|
|
43020
|
+
copyVector(p.n, tmp, p.eigs[largestIndex]);
|
|
43021
|
+
p.evals[largestIndex] = p.evals[i];
|
|
43022
|
+
p.evals[i] = largestEval;
|
|
43023
|
+
}
|
|
43024
|
+
}
|
|
43025
|
+
}
|
|
43026
|
+
function powerIterationOrthog(p, neigsIn, pIterationThreshold) {
|
|
43027
|
+
const work = { tmp: new Float64Array(p.n), last: new Float64Array(p.n) };
|
|
43028
|
+
const tol = 1 - pIterationThreshold;
|
|
43029
|
+
const neigs = neigsIn >= p.n ? p.n : neigsIn;
|
|
43030
|
+
let i = 0;
|
|
43031
|
+
for (; i < neigs; i++) {
|
|
43032
|
+
chooseStartVector(p, i);
|
|
43033
|
+
const res = iterateEigenvector(p, i, tol, work);
|
|
43034
|
+
if (res.nullSpace) break;
|
|
43035
|
+
p.evals[i] = res.eval;
|
|
43036
|
+
}
|
|
43037
|
+
fillNullSpaceEigenvectors(p, i, neigs);
|
|
43038
|
+
sortEigenvectors(p, neigs, work.tmp);
|
|
43039
|
+
}
|
|
43040
|
+
function computeAvgs(Dij, n) {
|
|
43041
|
+
const rowAvg = new Float32Array(n);
|
|
43042
|
+
let sum = 0;
|
|
43043
|
+
const blocked = n - n % BLOCK_AVGS;
|
|
41782
43044
|
for (let i = 0; i < n; i++) {
|
|
41783
|
-
|
|
43045
|
+
let sumRow = 0;
|
|
43046
|
+
const row = Dij[i];
|
|
43047
|
+
let j = 0;
|
|
43048
|
+
for (; j < blocked; j++) {
|
|
43049
|
+
sum += row[j] * row[j];
|
|
43050
|
+
sumRow += row[j] * row[j];
|
|
43051
|
+
}
|
|
43052
|
+
for (; j < n; j++) {
|
|
43053
|
+
sum = fma2(row[j], row[j], sum);
|
|
43054
|
+
sumRow = fma2(row[j], row[j], sumRow);
|
|
43055
|
+
}
|
|
43056
|
+
rowAvg[i] = fr4(fr4(sumRow) / n);
|
|
41784
43057
|
}
|
|
43058
|
+
return { rowAvg, allAvg: fr4(fr4(sum) / (n * n)) };
|
|
41785
43059
|
}
|
|
41786
|
-
function
|
|
43060
|
+
function computeBij(Dij, n) {
|
|
43061
|
+
const Bij = [];
|
|
43062
|
+
for (let i = 0; i < n; i++) Bij.push(new Float32Array(n));
|
|
43063
|
+
const { rowAvg, allAvg } = computeAvgs(Dij, n);
|
|
41787
43064
|
for (let i = 0; i < n; i++) {
|
|
41788
|
-
|
|
43065
|
+
for (let j = 0; j <= i; j++) {
|
|
43066
|
+
const fD = fr4(Dij[i][j]);
|
|
43067
|
+
const t = fr4(fma2(-fD, fD, rowAvg[i]));
|
|
43068
|
+
Bij[i][j] = fr4(fr4(t + rowAvg[j]) - allAvg);
|
|
43069
|
+
Bij[j][i] = Bij[i][j];
|
|
43070
|
+
}
|
|
43071
|
+
}
|
|
43072
|
+
return Bij;
|
|
43073
|
+
}
|
|
43074
|
+
function cmdsOrthog(n, dim, eigs, tol, input) {
|
|
43075
|
+
const { orthog, Dij } = input;
|
|
43076
|
+
const Bij = computeBij(Dij, n);
|
|
43077
|
+
const evals = new Float64Array(dim);
|
|
43078
|
+
const orthogAux = Float64Array.from(orthog.subarray(0, n));
|
|
43079
|
+
standardize(orthogAux, n);
|
|
43080
|
+
powerIterationOrthog({ mat: Bij, n, eigs, evals, orthog: orthogAux }, dim, tol);
|
|
43081
|
+
for (let i = 0; i < dim; i++) {
|
|
43082
|
+
for (let j = 0; j < n; j++) eigs[i][j] = eigs[i][j] * Math.sqrt(Math.abs(evals[i]));
|
|
41789
43083
|
}
|
|
41790
43084
|
}
|
|
41791
|
-
function
|
|
43085
|
+
function scaleGivenCoords(Dij, n, x) {
|
|
43086
|
+
let sum1 = 0;
|
|
43087
|
+
let sum2 = 0;
|
|
43088
|
+
for (let i = 1; i < n; i++) {
|
|
43089
|
+
const blocked = i - i % BLOCK_UNIFORM_SUMS;
|
|
43090
|
+
for (let j = 0; j < i; j++) {
|
|
43091
|
+
const d = Dij[i][j];
|
|
43092
|
+
const f = Math.abs(x[i] - x[j]);
|
|
43093
|
+
const t1 = 1 / d;
|
|
43094
|
+
const t2 = 1 / Math.imul(d, d) * f;
|
|
43095
|
+
if (j < blocked) {
|
|
43096
|
+
sum1 += t1 * f;
|
|
43097
|
+
sum2 += t2 * f;
|
|
43098
|
+
} else {
|
|
43099
|
+
sum1 = fma2(t1, f, sum1);
|
|
43100
|
+
sum2 = fma2(t2, f, sum2);
|
|
43101
|
+
}
|
|
43102
|
+
}
|
|
43103
|
+
}
|
|
43104
|
+
const uniLength = Math.abs(sum2) === Infinity ? 0 : sum1 / sum2;
|
|
43105
|
+
for (let i = 0; i < n; i++) x[i] = x[i] * uniLength;
|
|
43106
|
+
return uniLength;
|
|
43107
|
+
}
|
|
43108
|
+
function computeLaplacian(Dij, n) {
|
|
43109
|
+
const lap = [];
|
|
41792
43110
|
for (let i = 0; i < n; i++) {
|
|
41793
|
-
|
|
43111
|
+
const row = new Float32Array(n);
|
|
43112
|
+
let degree = fr4(0);
|
|
43113
|
+
for (let j = 0; j < n; j++) {
|
|
43114
|
+
if (j === i) continue;
|
|
43115
|
+
const w = fr4(fr4(-1) / fr4(fr4(Dij[i][j]) * fr4(Dij[i][j])));
|
|
43116
|
+
row[j] = w;
|
|
43117
|
+
degree = fr4(degree - w);
|
|
43118
|
+
}
|
|
43119
|
+
row[i] = degree;
|
|
43120
|
+
lap.push(row);
|
|
43121
|
+
}
|
|
43122
|
+
return lap;
|
|
43123
|
+
}
|
|
43124
|
+
function computeResidualDistances(Dij, n, x) {
|
|
43125
|
+
for (let i = 1; i < n; i++) {
|
|
43126
|
+
const posI = x[i];
|
|
43127
|
+
for (let j = 0; j < i; j++) {
|
|
43128
|
+
const t = posI - x[j];
|
|
43129
|
+
const d = Dij[i][j];
|
|
43130
|
+
const diff = fma2(d, d, -(t * t));
|
|
43131
|
+
const v = diff > 0 ? Math.sqrt(diff) : 0;
|
|
43132
|
+
Dij[i][j] = v;
|
|
43133
|
+
Dij[j][i] = v;
|
|
43134
|
+
}
|
|
43135
|
+
}
|
|
43136
|
+
}
|
|
43137
|
+
function balanceOf(i, n, y, ctx) {
|
|
43138
|
+
const posI = y[i];
|
|
43139
|
+
let b = 0;
|
|
43140
|
+
for (let j = 0; j < n; j++) {
|
|
43141
|
+
if (j === i) continue;
|
|
43142
|
+
const term = fr4(fr4(ctx.Dij[i][j]) * -ctx.lap[i][j]);
|
|
43143
|
+
if (posI >= y[j]) b += term;
|
|
43144
|
+
else b -= term;
|
|
41794
43145
|
}
|
|
43146
|
+
return b;
|
|
43147
|
+
}
|
|
43148
|
+
function solveBalanced(ctx, n, y, balance, convTol) {
|
|
43149
|
+
let converged = false;
|
|
43150
|
+
for (let iterations2 = 0; iterations2 < 200 && !converged; iterations2++) {
|
|
43151
|
+
if (conjugateGradientF(ctx.lap, y, balance, n, { tol: convTol, maxIterations: n, ortho1: true }) < 0) return 1;
|
|
43152
|
+
converged = true;
|
|
43153
|
+
for (let i = 0; i < n; i++) {
|
|
43154
|
+
const b = balanceOf(i, n, y, ctx);
|
|
43155
|
+
if (b !== balance[i] && Math.abs(1 - b / balance[i]) > 1e-5) {
|
|
43156
|
+
converged = false;
|
|
43157
|
+
balance[i] = b;
|
|
43158
|
+
}
|
|
43159
|
+
}
|
|
43160
|
+
}
|
|
43161
|
+
return 0;
|
|
43162
|
+
}
|
|
43163
|
+
function imdsGivenDim(graph, n, givenCoords, newCoords, conjTol) {
|
|
43164
|
+
const x = givenCoords;
|
|
43165
|
+
const y = newCoords;
|
|
43166
|
+
const Dij = computeApsp(graph, n);
|
|
43167
|
+
for (let i = 0; i < n; i++) {
|
|
43168
|
+
for (let j = 0; j < n; j++) Dij[i][j] = Dij[i][j] * SCALE_FACTOR;
|
|
43169
|
+
}
|
|
43170
|
+
const uniLength = scaleGivenCoords(Dij, n, x);
|
|
43171
|
+
cmdsOrthog(n, 1, [y], conjTol, { orthog: x, Dij });
|
|
43172
|
+
const lap = computeLaplacian(Dij, n);
|
|
43173
|
+
computeResidualDistances(Dij, n, x);
|
|
43174
|
+
const ctx = { Dij, lap };
|
|
43175
|
+
const balance = new Float64Array(n);
|
|
43176
|
+
for (let i = 0; i < n; i++) balance[i] = balanceOf(i, n, y, ctx);
|
|
43177
|
+
if (solveBalanced(ctx, n, y, balance, conjTol) === 1) return 1;
|
|
43178
|
+
for (let i = 0; !(Math.abs(uniLength) < DBL_EPSILON) && i < n; i++) {
|
|
43179
|
+
x[i] = x[i] / uniLength;
|
|
43180
|
+
y[i] = y[i] / uniLength;
|
|
43181
|
+
}
|
|
43182
|
+
return 0;
|
|
41795
43183
|
}
|
|
41796
43184
|
|
|
41797
43185
|
// src/layout/neato/stress-kernel.ts
|
|
41798
|
-
var
|
|
41799
|
-
var
|
|
43186
|
+
var fr5 = Math.fround;
|
|
43187
|
+
var TOLERANCE_CG2 = 1e-3;
|
|
41800
43188
|
var OPT_EXP_FLAG = 2;
|
|
41801
43189
|
function computeApspPacked2(graph, n) {
|
|
41802
43190
|
const Dij = new Float32Array(n * (n + 1) / 2);
|
|
@@ -41856,9 +43244,9 @@ function cgStep(st, last) {
|
|
|
41856
43244
|
vectorsMultAdditionF(n, st.r, -alpha, st.Ap);
|
|
41857
43245
|
const rRNew = vectorsInnerProductF(n, st.r, st.r);
|
|
41858
43246
|
if (st.rR === 0) return false;
|
|
41859
|
-
const betaF =
|
|
43247
|
+
const betaF = fr5(rRNew / st.rR);
|
|
41860
43248
|
st.rR = rRNew;
|
|
41861
|
-
for (let j = 0; j < n; j++) st.p[j] =
|
|
43249
|
+
for (let j = 0; j < n; j++) st.p[j] = fr5(betaF * st.p[j]) + st.r[j];
|
|
41862
43250
|
}
|
|
41863
43251
|
return true;
|
|
41864
43252
|
}
|
|
@@ -41920,8 +43308,8 @@ function buildLap1(lap1, lap2, coords, shape) {
|
|
|
41920
43308
|
for (let k = 0; k < dim; k++) {
|
|
41921
43309
|
const ck = coords[k];
|
|
41922
43310
|
for (let x = 0; x < len; x++) {
|
|
41923
|
-
const tmp =
|
|
41924
|
-
distAccumulator[x] = distAccumulator[x] +
|
|
43311
|
+
const tmp = fr5(ck[i] + fr5(-1 * ck[i + 1 + x]));
|
|
43312
|
+
distAccumulator[x] = distAccumulator[x] + fr5(tmp * tmp);
|
|
41925
43313
|
}
|
|
41926
43314
|
}
|
|
41927
43315
|
invertSqrtVec(len, distAccumulator);
|
|
@@ -41933,7 +43321,7 @@ function buildLap1(lap1, lap2, coords, shape) {
|
|
|
41933
43321
|
let degree = 0;
|
|
41934
43322
|
if (exp === 2) {
|
|
41935
43323
|
for (let j = 0; j < len; j++, count++) {
|
|
41936
|
-
const val2 = lap1[count] =
|
|
43324
|
+
const val2 = lap1[count] = fr5(lap1[count] * distAccumulator[j]);
|
|
41937
43325
|
degree += val2;
|
|
41938
43326
|
degrees[i + j + 1] = degrees[i + j + 1] - val2;
|
|
41939
43327
|
}
|
|
@@ -41967,10 +43355,10 @@ function computeStress(st) {
|
|
|
41967
43355
|
}
|
|
41968
43356
|
function solveAxis(st, k, havePinned, nodes) {
|
|
41969
43357
|
if (!havePinned) {
|
|
41970
|
-
return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n,
|
|
43358
|
+
return conjugateGradientMkernel2(st.lap2, st.coords[k], st.b[k], st.n, TOLERANCE_CG2, st.n);
|
|
41971
43359
|
}
|
|
41972
43360
|
copyVectorF(st.n, st.coords[k], st.tmpCoords);
|
|
41973
|
-
const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n,
|
|
43361
|
+
const rc = conjugateGradientMkernel2(st.lap2, st.tmpCoords, st.b[k], st.n, TOLERANCE_CG2, st.n);
|
|
41974
43362
|
if (rc < 0) return rc;
|
|
41975
43363
|
for (let i = 0; i < st.n; i++) {
|
|
41976
43364
|
if (!isFixed(nodes[i])) st.coords[k][i] = st.tmpCoords[i];
|
|
@@ -41986,10 +43374,10 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
|
|
|
41986
43374
|
const coords = [];
|
|
41987
43375
|
for (let i = 0; i < dim; i++) {
|
|
41988
43376
|
const c = new Float32Array(n);
|
|
41989
|
-
for (let j = 0; j < n; j++) c[j] =
|
|
43377
|
+
for (let j = 0; j < n; j++) c[j] = fr5(dCoords[i][j]);
|
|
41990
43378
|
coords.push(c);
|
|
41991
43379
|
}
|
|
41992
|
-
const constantTerm =
|
|
43380
|
+
const constantTerm = fr5(n * (n - 1) / 2);
|
|
41993
43381
|
const lap2 = Dij;
|
|
41994
43382
|
buildLap2(lap2, n, exp);
|
|
41995
43383
|
const lapLength = n * (n + 1) / 2;
|
|
@@ -42024,6 +43412,261 @@ function stressMajorizationKDMkernel(Dij, n, dCoords, nodes, o) {
|
|
|
42024
43412
|
return iterations;
|
|
42025
43413
|
}
|
|
42026
43414
|
|
|
43415
|
+
// src/layout/neato/constrained-majorization.ts
|
|
43416
|
+
var fr6 = Math.fround;
|
|
43417
|
+
var LOCAL_CONSTR_MAJOR_ITERATIONS = 15;
|
|
43418
|
+
var LEVELS_SEP_TOL = 0.1;
|
|
43419
|
+
var ABS_TOL = 0.01;
|
|
43420
|
+
var SUBSPACE_ITERATIONS = 15;
|
|
43421
|
+
var FLT_MAX3 = 34028234663852886e22;
|
|
43422
|
+
var DBL_MAX = Number.MAX_VALUE;
|
|
43423
|
+
var MIN_LEVELS = 1;
|
|
43424
|
+
var Y_AXIS = 1;
|
|
43425
|
+
function unsupported2(what) {
|
|
43426
|
+
throw new RenderError(`hierarchical stress majorization: ${what} is not supported yet`, "UNSUPPORTED_FEATURE");
|
|
43427
|
+
}
|
|
43428
|
+
function modelDistances(graph, n, model) {
|
|
43429
|
+
if (model === MODEL_SUBSET) unsupported2("the subset distance model");
|
|
43430
|
+
if (model === MODEL_CIRCUIT) unsupported2("the circuit distance model");
|
|
43431
|
+
return model === MODEL_MDS2 ? mdsModel(graph, n) : null;
|
|
43432
|
+
}
|
|
43433
|
+
function unconstrainedMajorization(graph, n, dCoords, nodes, o) {
|
|
43434
|
+
if (o.maxi < 0) return 0;
|
|
43435
|
+
const weighted = (graph[0]?.ewgts.length ?? 0) > 0;
|
|
43436
|
+
const Dij = modelDistances(graph, n, o.model) ?? (weighted ? computeWeightedApspPacked2(graph, n) : computeApspPacked2(graph, n));
|
|
43437
|
+
if ((o.opts & OPT_SMART_INIT) !== 0 && n > 1) unsupported2("the smart initial layout");
|
|
43438
|
+
return stressMajorizationKDMkernel(Dij, n, dCoords, nodes, {
|
|
43439
|
+
dim: o.dim,
|
|
43440
|
+
opts: o.opts,
|
|
43441
|
+
maxi: o.maxi,
|
|
43442
|
+
epsilon: o.epsilon
|
|
43443
|
+
});
|
|
43444
|
+
}
|
|
43445
|
+
function hasDirectionality(graph, n) {
|
|
43446
|
+
if (!graph[0]?.edists) return false;
|
|
43447
|
+
let directionalityExist = false;
|
|
43448
|
+
for (let i = 0; i < n; i++) {
|
|
43449
|
+
const edists = graph[i].edists;
|
|
43450
|
+
for (let j = 1; j < graph[i].nedges; j++) {
|
|
43451
|
+
directionalityExist ||= edists[j] !== 0;
|
|
43452
|
+
}
|
|
43453
|
+
}
|
|
43454
|
+
return directionalityExist;
|
|
43455
|
+
}
|
|
43456
|
+
function separateLevels(y, h, n, levelsGap) {
|
|
43457
|
+
const { ordering, levels, numLevels } = h;
|
|
43458
|
+
let displacement = 0;
|
|
43459
|
+
for (let i = 0; i < numLevels; i++) {
|
|
43460
|
+
const shortfall = levelsGap - (y[ordering[levels[i]]] + displacement - y[ordering[levels[i] - 1]]);
|
|
43461
|
+
displacement += 0 > shortfall ? 0 : shortfall;
|
|
43462
|
+
const stop = i < numLevels - 1 ? levels[i + 1] : n;
|
|
43463
|
+
for (let j = levels[i]; j < stop; j++) y[ordering[j]] += displacement;
|
|
43464
|
+
}
|
|
43465
|
+
}
|
|
43466
|
+
function smartInitLayers(graph, n, dCoords, nodes, o) {
|
|
43467
|
+
const { dim } = o;
|
|
43468
|
+
if (dim > 2) {
|
|
43469
|
+
const sub = { dim: dim - 1, opts: o.opts, model: o.model, maxi: SUBSPACE_ITERATIONS, epsilon: o.epsilon };
|
|
43470
|
+
if (unconstrainedMajorization(graph, n, dCoords.slice(1), nodes, sub) < 0) return -1;
|
|
43471
|
+
dCoords[dim - 1].set(dCoords[1].subarray(0, n));
|
|
43472
|
+
}
|
|
43473
|
+
const x = dCoords[0];
|
|
43474
|
+
const y = dCoords[1];
|
|
43475
|
+
if (computeYCoords(graph, n, y, n)) return -1;
|
|
43476
|
+
const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, y);
|
|
43477
|
+
if (h === null) return -1;
|
|
43478
|
+
if (h.numLevels < MIN_LEVELS) {
|
|
43479
|
+
return unconstrainedMajorization(graph, n, dCoords, nodes, o);
|
|
43480
|
+
}
|
|
43481
|
+
if (o.levelsGap > 0) separateLevels(y, h, n, o.levelsGap);
|
|
43482
|
+
if (dim === 2 && imdsGivenDim(graph, n, y, x, o.epsilon)) return -1;
|
|
43483
|
+
return h;
|
|
43484
|
+
}
|
|
43485
|
+
function plainInitLayers(graph, n, dCoords, nodes, dim) {
|
|
43486
|
+
initLayout(n, dim, dCoords, nodes);
|
|
43487
|
+
const h = computeHierarchy(graph, n, ABS_TOL, LEVELS_SEP_TOL, null);
|
|
43488
|
+
return h === null ? -1 : h;
|
|
43489
|
+
}
|
|
43490
|
+
function distanceKD(coords, dim, i, j) {
|
|
43491
|
+
let sum = 0;
|
|
43492
|
+
for (let k = 0; k < dim; k++) {
|
|
43493
|
+
const d = coords[k][i] - coords[k][j];
|
|
43494
|
+
sum = fma2(d, d, sum);
|
|
43495
|
+
}
|
|
43496
|
+
return Math.sqrt(sum);
|
|
43497
|
+
}
|
|
43498
|
+
function scaleDownLayout(dCoords, n, dim) {
|
|
43499
|
+
let max = 1;
|
|
43500
|
+
for (let i = 0; i < dim; i++) {
|
|
43501
|
+
for (let j = 0; j < n; j++) {
|
|
43502
|
+
const a = Math.abs(dCoords[i][j]);
|
|
43503
|
+
if (a > max) max = a;
|
|
43504
|
+
}
|
|
43505
|
+
}
|
|
43506
|
+
for (let i = 0; i < dim; i++) {
|
|
43507
|
+
for (let j = 0; j < n; j++) dCoords[i][j] *= 10 / max;
|
|
43508
|
+
}
|
|
43509
|
+
}
|
|
43510
|
+
function scaleDistances(Dij, dCoords, n, dim) {
|
|
43511
|
+
const length = n + Math.trunc(n * (n - 1) / 2);
|
|
43512
|
+
const sum1 = Math.trunc(n * (n - 1) / 2);
|
|
43513
|
+
let sum2 = 0;
|
|
43514
|
+
for (let count = 0, i = 0; i < n - 1; i++) {
|
|
43515
|
+
count++;
|
|
43516
|
+
for (let j = i + 1; j < n; j++, count++) {
|
|
43517
|
+
sum2 += distanceKD(dCoords, dim, i, j) / Dij[count];
|
|
43518
|
+
}
|
|
43519
|
+
}
|
|
43520
|
+
const scaleRatio = fr6(sum2 / sum1);
|
|
43521
|
+
for (let i = 0; i < length; i++) Dij[i] = Dij[i] * scaleRatio;
|
|
43522
|
+
}
|
|
43523
|
+
function centerLayout(dCoords, n, dim) {
|
|
43524
|
+
for (let i = 0; i < dim; i++) orthog1(n, dCoords[i]);
|
|
43525
|
+
const y0 = dCoords[Y_AXIS][0];
|
|
43526
|
+
for (let i = 0; i < n; i++) dCoords[Y_AXIS][i] -= y0;
|
|
43527
|
+
}
|
|
43528
|
+
function negatedDegrees(lap2, n) {
|
|
43529
|
+
const degrees = new Float64Array(n);
|
|
43530
|
+
for (let i = 0, count = 0; i < n - 1; i++) {
|
|
43531
|
+
let degree = 0;
|
|
43532
|
+
count++;
|
|
43533
|
+
for (let j = 1; j < n - i; j++, count++) {
|
|
43534
|
+
const val2 = lap2[count];
|
|
43535
|
+
degree += val2;
|
|
43536
|
+
degrees[i + j] -= val2;
|
|
43537
|
+
}
|
|
43538
|
+
degrees[i] -= degree;
|
|
43539
|
+
}
|
|
43540
|
+
return degrees;
|
|
43541
|
+
}
|
|
43542
|
+
function buildLap22(lap2, n) {
|
|
43543
|
+
const lapLength = n + Math.trunc(n * (n - 1) / 2);
|
|
43544
|
+
squareVec(lapLength, lap2);
|
|
43545
|
+
invertVec(lapLength, lap2);
|
|
43546
|
+
const degrees = negatedDegrees(lap2, n);
|
|
43547
|
+
for (let step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
|
|
43548
|
+
lap2[count] = degrees[i];
|
|
43549
|
+
}
|
|
43550
|
+
}
|
|
43551
|
+
function inverseDistances(st, i, len) {
|
|
43552
|
+
const { coords, tmpCoords, distAccumulator } = st;
|
|
43553
|
+
distAccumulator.fill(0, 0, st.n);
|
|
43554
|
+
for (let k = 0; k < st.dim; k++) {
|
|
43555
|
+
const ck = coords[k];
|
|
43556
|
+
for (let j = 0; j < len; j++) tmpCoords[j] = ck[i] - ck[i + 1 + j];
|
|
43557
|
+
for (let j = 0; j < len; j++) tmpCoords[j] = tmpCoords[j] * tmpCoords[j];
|
|
43558
|
+
for (let j = 0; j < len; j++) distAccumulator[j] = tmpCoords[j] + distAccumulator[j];
|
|
43559
|
+
}
|
|
43560
|
+
invertSqrtVec(len, distAccumulator);
|
|
43561
|
+
for (let j = 0; j < len; j++) {
|
|
43562
|
+
if (distAccumulator[j] >= FLT_MAX3 || distAccumulator[j] < 0) distAccumulator[j] = 0;
|
|
43563
|
+
}
|
|
43564
|
+
}
|
|
43565
|
+
function buildLap12(st) {
|
|
43566
|
+
const { n, lap1, lap2, degrees, distAccumulator } = st;
|
|
43567
|
+
degrees.fill(0);
|
|
43568
|
+
sqrtVecF(n + Math.trunc(n * (n - 1) / 2), lap2, lap1);
|
|
43569
|
+
let count = 0;
|
|
43570
|
+
for (let i = 0; i < n - 1; i++) {
|
|
43571
|
+
const len = n - i - 1;
|
|
43572
|
+
inverseDistances(st, i, len);
|
|
43573
|
+
count++;
|
|
43574
|
+
let degree = 0;
|
|
43575
|
+
for (let j = 0; j < len; j++, count++) {
|
|
43576
|
+
const val2 = fr6(lap1[count] * distAccumulator[j]);
|
|
43577
|
+
lap1[count] = val2;
|
|
43578
|
+
degree += val2;
|
|
43579
|
+
degrees[i + j + 1] -= val2;
|
|
43580
|
+
}
|
|
43581
|
+
degrees[i] -= degree;
|
|
43582
|
+
}
|
|
43583
|
+
for (let step = n, count2 = 0, i = 0; i < n; i++, count2 += step, step--) {
|
|
43584
|
+
lap1[count2] = degrees[i];
|
|
43585
|
+
}
|
|
43586
|
+
}
|
|
43587
|
+
function computeNewStress(st, constantTerm) {
|
|
43588
|
+
const { n, dim, lap1, lap2, coords, b, tmpCoords } = st;
|
|
43589
|
+
for (let k = 0; k < dim; k++) rightMultWithVectorFFFused(lap1, n, coords[k], b[k]);
|
|
43590
|
+
let newStress = 0;
|
|
43591
|
+
for (let k = 0; k < dim; k++) newStress += vectorsInnerProductF(n, coords[k], b[k]);
|
|
43592
|
+
newStress *= 2;
|
|
43593
|
+
newStress += constantTerm;
|
|
43594
|
+
for (let k = 0; k < dim; k++) {
|
|
43595
|
+
rightMultWithVectorFFFused(lap2, n, coords[k], tmpCoords);
|
|
43596
|
+
newStress -= vectorsInnerProductF(n, coords[k], tmpCoords);
|
|
43597
|
+
}
|
|
43598
|
+
return newStress;
|
|
43599
|
+
}
|
|
43600
|
+
function solveAxes(st, ctx) {
|
|
43601
|
+
for (let k = 0; k < st.dim; k++) {
|
|
43602
|
+
if (k === Y_AXIS) {
|
|
43603
|
+
constrainedMajorizationNewWithGaps(
|
|
43604
|
+
ctx.cMajEnv,
|
|
43605
|
+
st.b[k],
|
|
43606
|
+
st.coords,
|
|
43607
|
+
k,
|
|
43608
|
+
LOCAL_CONSTR_MAJOR_ITERATIONS,
|
|
43609
|
+
ctx.levelsGap
|
|
43610
|
+
);
|
|
43611
|
+
} else if (conjugateGradientMkernelFused(st.lap2, st.coords[k], st.b[k], st.n, { tol: TOLERANCE_CG, maxIterations: st.n })) {
|
|
43612
|
+
return true;
|
|
43613
|
+
}
|
|
43614
|
+
}
|
|
43615
|
+
return false;
|
|
43616
|
+
}
|
|
43617
|
+
function majorize(st, ctx, dCoords) {
|
|
43618
|
+
const constantTerm = Math.trunc(st.n * (st.n - 1) / 2);
|
|
43619
|
+
let oldStress = DBL_MAX;
|
|
43620
|
+
let iterations = 0;
|
|
43621
|
+
for (let converged = false; iterations < ctx.maxi && !converged; iterations++) {
|
|
43622
|
+
buildLap12(st);
|
|
43623
|
+
const newStress = computeNewStress(st, constantTerm);
|
|
43624
|
+
converged = Math.abs(newStress - oldStress) / Math.abs(oldStress + 1e-10) < ctx.epsilon;
|
|
43625
|
+
converged ||= iterations > 1 && newStress > oldStress;
|
|
43626
|
+
oldStress = newStress;
|
|
43627
|
+
if (solveAxes(st, ctx)) return -1;
|
|
43628
|
+
}
|
|
43629
|
+
for (let i = 0; i < st.dim; i++) {
|
|
43630
|
+
for (let j = 0; j < st.n; j++) dCoords[i][j] = st.coords[i][j];
|
|
43631
|
+
}
|
|
43632
|
+
return iterations;
|
|
43633
|
+
}
|
|
43634
|
+
function toFloatCoords(dCoords, n, dim) {
|
|
43635
|
+
const coords = [];
|
|
43636
|
+
for (let i = 0; i < dim; i++) coords.push(Float32Array.from(dCoords[i].subarray(0, n)));
|
|
43637
|
+
return coords;
|
|
43638
|
+
}
|
|
43639
|
+
function newLoopState(lap2, coords, n) {
|
|
43640
|
+
const dim = coords.length;
|
|
43641
|
+
return {
|
|
43642
|
+
n,
|
|
43643
|
+
dim,
|
|
43644
|
+
lap2,
|
|
43645
|
+
coords,
|
|
43646
|
+
lap1: new Float32Array(n + Math.trunc(n * (n - 1) / 2)),
|
|
43647
|
+
b: Array.from({ length: dim }, () => new Float32Array(n)),
|
|
43648
|
+
tmpCoords: new Float32Array(n),
|
|
43649
|
+
distAccumulator: new Float32Array(n),
|
|
43650
|
+
degrees: new Float64Array(n)
|
|
43651
|
+
};
|
|
43652
|
+
}
|
|
43653
|
+
function stressMajorizationWithHierarchy(graph, n, dCoords, nodes, o) {
|
|
43654
|
+
if (!hasDirectionality(graph, n)) return unconstrainedMajorization(graph, n, dCoords, nodes, o);
|
|
43655
|
+
const smartIni = (o.opts & OPT_SMART_INIT) !== 0;
|
|
43656
|
+
const layers = smartIni ? smartInitLayers(graph, n, dCoords, nodes, o) : plainInitLayers(graph, n, dCoords, nodes, o.dim);
|
|
43657
|
+
if (typeof layers === "number") return layers;
|
|
43658
|
+
if (n === 1) return 0;
|
|
43659
|
+
if (o.maxi === 0) return 0;
|
|
43660
|
+
const Dij = modelDistances(graph, n, o.model) ?? computeApspPacked2(graph, n);
|
|
43661
|
+
if (!smartIni) scaleDownLayout(dCoords, n, o.dim);
|
|
43662
|
+
if (o.levelsGap > 0) scaleDistances(Dij, dCoords, n, o.dim);
|
|
43663
|
+
centerLayout(dCoords, n, o.dim);
|
|
43664
|
+
const st = newLoopState(Dij, toFloatCoords(dCoords, n, o.dim), n);
|
|
43665
|
+
buildLap22(Dij, n);
|
|
43666
|
+
const cMajEnv = initConstrainedMajorization(Dij, n, layers.ordering, layers.levels, layers.numLevels);
|
|
43667
|
+
return majorize(st, { cMajEnv, levelsGap: o.levelsGap, maxi: o.maxi, epsilon: o.epsilon }, dCoords);
|
|
43668
|
+
}
|
|
43669
|
+
|
|
42027
43670
|
// src/common/utils-inputscale.ts
|
|
42028
43671
|
var POINTS_PER_INCH3 = 72;
|
|
42029
43672
|
function getInputscale(g) {
|
|
@@ -42210,61 +43853,47 @@ function neatoMaxIter(maxiter, mode, n) {
|
|
|
42210
43853
|
if (mode === MODE_MAJOR) return DFLT_ITERATIONS;
|
|
42211
43854
|
return mode === MODE_SGD ? SGD_ITERATIONS : 100 * n;
|
|
42212
43855
|
}
|
|
42213
|
-
|
|
42214
|
-
|
|
42215
|
-
const
|
|
43856
|
+
var levelsGapOf = (g) => lateDouble(g.root.attrs.get("levelsgap"), 0, -Number.MAX_VALUE);
|
|
43857
|
+
function solveStress(c, vtx, dCoords, nodeList) {
|
|
43858
|
+
const { g, mode, model, haveLen, opts } = c;
|
|
42216
43859
|
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
43860
|
const maxi = neatoMaxIter(g.attrs.get("maxiter"), mode, n);
|
|
42221
43861
|
const epsilon = lateDouble(g.attrs.get("epsilon"), 1e-4, 0);
|
|
43862
|
+
if (mode === MODE_HIER) {
|
|
43863
|
+
return stressMajorizationWithHierarchy(vtx, n, dCoords, nodeList, {
|
|
43864
|
+
dim: DFLT_DIM,
|
|
43865
|
+
opts,
|
|
43866
|
+
model,
|
|
43867
|
+
maxi,
|
|
43868
|
+
epsilon,
|
|
43869
|
+
levelsGap: levelsGapOf(g)
|
|
43870
|
+
});
|
|
43871
|
+
}
|
|
42222
43872
|
const weighted = haveLen && mode !== MODE_IPSEP;
|
|
42223
43873
|
const Dij = weighted ? computeWeightedApspPacked2(vtx, n) : computeApspPacked2(vtx, n);
|
|
42224
|
-
|
|
42225
|
-
stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
43874
|
+
return stressMajorizationKDMkernel(Dij, n, dCoords, nodeList, {
|
|
42226
43875
|
dim: DFLT_DIM,
|
|
42227
|
-
opts
|
|
43876
|
+
opts,
|
|
42228
43877
|
maxi,
|
|
42229
43878
|
epsilon
|
|
42230
43879
|
});
|
|
42231
|
-
for (let i = 0; i < n; i++) {
|
|
42232
|
-
nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
|
|
42233
|
-
}
|
|
42234
43880
|
}
|
|
42235
|
-
function
|
|
42236
|
-
|
|
42237
|
-
|
|
43881
|
+
function runMajorization(g, mode, model) {
|
|
43882
|
+
const nodeList = assignNodeIds2(g);
|
|
43883
|
+
const n = nodeList.length;
|
|
43884
|
+
const haveLen = graphHasLen(g);
|
|
43885
|
+
const init = checkStart(g, n, mode === MODE_HIER ? INIT_SELF : INIT_RANDOM);
|
|
43886
|
+
const opts = init === INIT_SELF ? OPT_EXP_FLAG | OPT_SMART_INIT : OPT_EXP_FLAG;
|
|
43887
|
+
const haveDir = mode === MODE_HIER || mode === MODE_IPSEP;
|
|
43888
|
+
const vtx = makeGraphDataC(g, nodeList, haveLen, haveDir, mode);
|
|
43889
|
+
const dCoords = [new Float64Array(n), new Float64Array(n)];
|
|
43890
|
+
if (solveStress({ g, mode, model, haveLen, opts }, vtx, dCoords, nodeList) < 0) {
|
|
43891
|
+
agerr("prev", "layout aborted");
|
|
43892
|
+
return;
|
|
42238
43893
|
}
|
|
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
|
-
}
|
|
43894
|
+
for (let i = 0; i < n; i++) {
|
|
43895
|
+
nodeList[i].info.pos = [dCoords[0][i], dCoords[1][i]];
|
|
42266
43896
|
}
|
|
42267
|
-
return vtx;
|
|
42268
43897
|
}
|
|
42269
43898
|
function solveModel2(g, mode, model) {
|
|
42270
43899
|
if (g.nodes.size < 2) return;
|
|
@@ -42456,6 +44085,25 @@ function esepFactor(g) {
|
|
|
42456
44085
|
return { x: SEPFACT * DFLT_MARGIN, y: SEPFACT * DFLT_MARGIN, doAdd: true };
|
|
42457
44086
|
}
|
|
42458
44087
|
|
|
44088
|
+
// src/common/libm-trig.ts
|
|
44089
|
+
var OCTAGON_TRIG = /* @__PURE__ */ new Map([
|
|
44090
|
+
[-0.39269908169872414, [0.9238795325112867, -0.3826834323650898]],
|
|
44091
|
+
[0.39269908169872414, [0.9238795325112867, 0.3826834323650898]],
|
|
44092
|
+
[1.1780972450961724, [0.38268343236508984, 0.9238795325112867]],
|
|
44093
|
+
[1.9634954084936207, [-0.3826834323650897, 0.9238795325112867]],
|
|
44094
|
+
[2.748893571891069, [-0.9238795325112867, 0.3826834323650899]],
|
|
44095
|
+
[3.5342917352885173, [-0.9238795325112868, -0.38268343236508967]],
|
|
44096
|
+
[4.319689898685965, [-0.38268343236509034, -0.9238795325112865]],
|
|
44097
|
+
[5.105088062083414, [0.38268343236509, -0.9238795325112866]],
|
|
44098
|
+
[5.890486225480862, [0.9238795325112865, -0.3826834323650904]]
|
|
44099
|
+
]);
|
|
44100
|
+
function libmCos(x) {
|
|
44101
|
+
return OCTAGON_TRIG.get(x)?.[0] ?? Math.cos(x);
|
|
44102
|
+
}
|
|
44103
|
+
function libmSin(x) {
|
|
44104
|
+
return OCTAGON_TRIG.get(x)?.[1] ?? Math.sin(x);
|
|
44105
|
+
}
|
|
44106
|
+
|
|
42459
44107
|
// src/layout/neato/delaunay.ts
|
|
42460
44108
|
var ICCERRBOUND_A = (10 + 96 * 2 ** -53) * 2 ** -53;
|
|
42461
44109
|
function ulpExp(v) {
|
|
@@ -42624,6 +44272,32 @@ function delaunayTri(xv, yv, n) {
|
|
|
42624
44272
|
return edges;
|
|
42625
44273
|
}
|
|
42626
44274
|
|
|
44275
|
+
// src/layout/neato/gts-triangle.ts
|
|
44276
|
+
var SQRT3 = 1.73205080757;
|
|
44277
|
+
function gtsTriangleEnclosing(px, py, n, scale) {
|
|
44278
|
+
let xmin = px[0];
|
|
44279
|
+
let xmax = px[0];
|
|
44280
|
+
let ymin = py[0];
|
|
44281
|
+
let ymax = py[0];
|
|
44282
|
+
for (let i = 1; i < n; i++) {
|
|
44283
|
+
if (px[i] > xmax) xmax = px[i];
|
|
44284
|
+
else if (px[i] < xmin) xmin = px[i];
|
|
44285
|
+
if (py[i] > ymax) ymax = py[i];
|
|
44286
|
+
else if (py[i] < ymin) ymin = py[i];
|
|
44287
|
+
}
|
|
44288
|
+
const xo = (xmax + xmin) / 2;
|
|
44289
|
+
const yo = (ymax + ymin) / 2;
|
|
44290
|
+
const dx = xmax - xo;
|
|
44291
|
+
const dy = ymax - yo;
|
|
44292
|
+
let r = scale * Math.sqrt(fma(dx, dx, dy * dy));
|
|
44293
|
+
if (r === 0) r = scale;
|
|
44294
|
+
return [
|
|
44295
|
+
[fma(r, SQRT3, xo), yo - r],
|
|
44296
|
+
[xo, fma(r, 2, yo)],
|
|
44297
|
+
[fma(-r, SQRT3, xo), yo - r]
|
|
44298
|
+
];
|
|
44299
|
+
}
|
|
44300
|
+
|
|
42627
44301
|
// src/layout/neato/cdt-surface.ts
|
|
42628
44302
|
var pairKey = (u, v) => u < v ? u * 1048576 + v : v * 1048576 + u;
|
|
42629
44303
|
var Cdt = class {
|
|
@@ -43134,27 +44808,15 @@ var Cdt = class {
|
|
|
43134
44808
|
return { nfaces: kept.length, faces, neigh };
|
|
43135
44809
|
}
|
|
43136
44810
|
};
|
|
43137
|
-
var SQRT3 = 1.7320508075688772;
|
|
43138
44811
|
function mkSurface(x, y, n, segs, nsegs) {
|
|
43139
44812
|
const px = x.slice(0, n);
|
|
43140
44813
|
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
44814
|
const s0 = n;
|
|
43156
|
-
|
|
43157
|
-
|
|
44815
|
+
const enc = gtsTriangleEnclosing(px, py, n, 100);
|
|
44816
|
+
for (const [ex, ey] of enc) {
|
|
44817
|
+
px.push(ex);
|
|
44818
|
+
py.push(ey);
|
|
44819
|
+
}
|
|
43158
44820
|
const cdt = new Cdt(px, py);
|
|
43159
44821
|
const cons = [];
|
|
43160
44822
|
for (let k = 0; k < nsegs; k++) {
|
|
@@ -43201,9 +44863,9 @@ function sharedEdge(faces, p3, q3) {
|
|
|
43201
44863
|
return { i: p1, j: p2 };
|
|
43202
44864
|
}
|
|
43203
44865
|
function addTriEdge(g, t, h, seg2) {
|
|
43204
|
-
const
|
|
44866
|
+
const dist5 = Math.sqrt(dist2(g.nodes[t].ctr, g.nodes[h].ctr));
|
|
43205
44867
|
const idx = g.edges.length;
|
|
43206
|
-
g.edges.push({ t, h, seg: seg2, dist:
|
|
44868
|
+
g.edges.push({ t, h, seg: seg2, dist: dist5 });
|
|
43207
44869
|
g.nodes[t].edges.push(idx);
|
|
43208
44870
|
g.nodes[h].edges.push(idx);
|
|
43209
44871
|
}
|
|
@@ -44007,8 +45669,8 @@ function ellipseTangentSlope(a, b, p) {
|
|
|
44007
45669
|
function circumscribedCorner(a, b, i, nsides) {
|
|
44008
45670
|
const angle0 = 2 * Math.PI * (i - 0.5) / nsides;
|
|
44009
45671
|
const angle1 = 2 * Math.PI * (i + 0.5) / nsides;
|
|
44010
|
-
const p0 = { x: a *
|
|
44011
|
-
const p1 = { x: a *
|
|
45672
|
+
const p0 = { x: a * libmCos(angle0), y: b * libmSin(angle0) };
|
|
45673
|
+
const p1 = { x: a * libmCos(angle1), y: b * libmSin(angle1) };
|
|
44012
45674
|
const m0 = ellipseTangentSlope(a, b, p0);
|
|
44013
45675
|
const m1 = ellipseTangentSlope(a, b, p1);
|
|
44014
45676
|
const x = (fms(p1.x, m1, fma(m0, p0.x, -p0.y)) + p1.y) / (m0 - m1);
|
|
@@ -46344,52 +48006,14 @@ function armPow(x, y) {
|
|
|
46344
48006
|
return expInline(ehi, elo, signBias);
|
|
46345
48007
|
}
|
|
46346
48008
|
|
|
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
48009
|
// src/layout/sfdp/quadtree.ts
|
|
46386
48010
|
function pointDistance(p1, o1, p2, o2, dim) {
|
|
46387
|
-
let
|
|
48011
|
+
let dist5 = 0;
|
|
46388
48012
|
for (let i = 0; i < dim; i++) {
|
|
46389
48013
|
const d = p1[o1 + i] - p2[o2 + i];
|
|
46390
|
-
|
|
48014
|
+
dist5 = fma(d, d, dist5);
|
|
46391
48015
|
}
|
|
46392
|
-
return Math.sqrt(
|
|
48016
|
+
return Math.sqrt(dist5);
|
|
46393
48017
|
}
|
|
46394
48018
|
function quadTreeNew(dim, center, width2, maxLevel) {
|
|
46395
48019
|
return {
|
|
@@ -46524,8 +48148,8 @@ function getSupernodesInternal(qt, bh, pt, ptOff, nodeid, out) {
|
|
|
46524
48148
|
l = l.next;
|
|
46525
48149
|
}
|
|
46526
48150
|
if (qt.qts !== null) {
|
|
46527
|
-
const
|
|
46528
|
-
if (qt.width < bh *
|
|
48151
|
+
const dist5 = pointDistance(qt.center, 0, pt, ptOff, dim);
|
|
48152
|
+
if (qt.width < bh * dist5) {
|
|
46529
48153
|
for (let i = 0; i < dim; i++) {
|
|
46530
48154
|
out.center[dim * out.nsuper + i] = qt.average[i];
|
|
46531
48155
|
}
|
|
@@ -46623,12 +48247,12 @@ function onedOptimizerTrain(opt, work) {
|
|
|
46623
48247
|
else optHill(opt, i);
|
|
46624
48248
|
}
|
|
46625
48249
|
function distance(x, dim, i, j) {
|
|
46626
|
-
let
|
|
48250
|
+
let dist5 = 0;
|
|
46627
48251
|
for (let k = 0; k < dim; k++) {
|
|
46628
48252
|
const d = x[i * dim + k] - x[j * dim + k];
|
|
46629
|
-
|
|
48253
|
+
dist5 = fma(d, d, dist5);
|
|
46630
48254
|
}
|
|
46631
|
-
return Math.sqrt(
|
|
48255
|
+
return Math.sqrt(dist5);
|
|
46632
48256
|
}
|
|
46633
48257
|
function distanceCropped(x, dim, i, j) {
|
|
46634
48258
|
return Math.max(distance(x, dim, i, j), MINDIST);
|
|
@@ -46636,16 +48260,16 @@ function distanceCropped(x, dim, i, j) {
|
|
|
46636
48260
|
function gatherLeaves(A3, p, checked, x, dim) {
|
|
46637
48261
|
const { ia, ja } = A3;
|
|
46638
48262
|
const leaves = [];
|
|
46639
|
-
let
|
|
48263
|
+
let dist5 = 0;
|
|
46640
48264
|
for (let j = ia[p]; j < ia[p + 1]; j++) {
|
|
46641
48265
|
const c = ja[j];
|
|
46642
48266
|
if (ia[c + 1] - ia[c] === 1) {
|
|
46643
48267
|
checked[c] = true;
|
|
46644
|
-
|
|
48268
|
+
dist5 += distance(x, dim, p, c);
|
|
46645
48269
|
leaves.push(c);
|
|
46646
48270
|
}
|
|
46647
48271
|
}
|
|
46648
|
-
return { leaves, avgDist:
|
|
48272
|
+
return { leaves, avgDist: dist5 / leaves.length };
|
|
46649
48273
|
}
|
|
46650
48274
|
function beautifyLeaves(dim, A3, x) {
|
|
46651
48275
|
const { ia, ja, m } = A3;
|
|
@@ -46668,7 +48292,7 @@ function beautifyLeaves(dim, A3, x) {
|
|
|
46668
48292
|
}
|
|
46669
48293
|
}
|
|
46670
48294
|
function averageEdgeLength(A3, dim, coord) {
|
|
46671
|
-
let
|
|
48295
|
+
let dist5 = 0;
|
|
46672
48296
|
const { ia, ja } = A3;
|
|
46673
48297
|
if (ia[A3.m] === 0) return 1;
|
|
46674
48298
|
for (let i = 0; i < A3.m; i++) {
|
|
@@ -46678,10 +48302,10 @@ function averageEdgeLength(A3, dim, coord) {
|
|
|
46678
48302
|
const dd = coord[dim * i + k] - coord[dim * ja[j]];
|
|
46679
48303
|
d = fma(dd, dd, d);
|
|
46680
48304
|
}
|
|
46681
|
-
|
|
48305
|
+
dist5 += Math.sqrt(d);
|
|
46682
48306
|
}
|
|
46683
48307
|
}
|
|
46684
|
-
return
|
|
48308
|
+
return dist5 / ia[A3.m];
|
|
46685
48309
|
}
|
|
46686
48310
|
function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
|
|
46687
48311
|
if (!adaptiveCooling) return COOL * step;
|
|
@@ -46692,18 +48316,18 @@ function updateStep(adaptiveCooling, step, fnorm, fnorm0) {
|
|
|
46692
48316
|
}
|
|
46693
48317
|
return 0.99 * step / COOL;
|
|
46694
48318
|
}
|
|
46695
|
-
function repulsivePow(
|
|
46696
|
-
return armPow(
|
|
48319
|
+
function repulsivePow(dist5, p) {
|
|
48320
|
+
return armPow(dist5, 1 - p);
|
|
46697
48321
|
}
|
|
46698
48322
|
function attractiveForce(ctx, i) {
|
|
46699
48323
|
const { A: A3, x, dim, fp, f } = ctx;
|
|
46700
48324
|
const { ia, ja } = A3;
|
|
46701
48325
|
for (let j = ia[i]; j < ia[i + 1]; j++) {
|
|
46702
48326
|
if (ja[j] === i) continue;
|
|
46703
|
-
const
|
|
48327
|
+
const dist5 = distance(x, dim, i, ja[j]);
|
|
46704
48328
|
for (let k = 0; k < dim; k++) {
|
|
46705
48329
|
const t = fp.CRK * (x[i * dim + k] - x[ja[j] * dim + k]);
|
|
46706
|
-
f[k] = fma(-t,
|
|
48330
|
+
f[k] = fma(-t, dist5, f[k]);
|
|
46707
48331
|
}
|
|
46708
48332
|
}
|
|
46709
48333
|
}
|
|
@@ -46711,9 +48335,9 @@ function repulsiveForceDirect(ctx, i) {
|
|
|
46711
48335
|
const { x, dim, n, fp, f } = ctx;
|
|
46712
48336
|
for (let j = 0; j < n; j++) {
|
|
46713
48337
|
if (j === i) continue;
|
|
46714
|
-
const
|
|
48338
|
+
const dist5 = distanceCropped(x, dim, i, j);
|
|
46715
48339
|
for (let k = 0; k < dim; k++) {
|
|
46716
|
-
f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(
|
|
48340
|
+
f[k] += fp.KP * (x[i * dim + k] - x[j * dim + k]) / repulsivePow(dist5, fp.p);
|
|
46717
48341
|
}
|
|
46718
48342
|
}
|
|
46719
48343
|
}
|
|
@@ -46723,9 +48347,9 @@ function repulsiveForceQT(ctx, qt, i, acc) {
|
|
|
46723
48347
|
acc.countsAvg += counts;
|
|
46724
48348
|
acc.nsuperAvg += nsuper;
|
|
46725
48349
|
for (let j = 0; j < nsuper; j++) {
|
|
46726
|
-
const
|
|
48350
|
+
const dist5 = Math.max(distances[j], MINDIST);
|
|
46727
48351
|
for (let k = 0; k < dim; k++) {
|
|
46728
|
-
f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(
|
|
48352
|
+
f[k] += supernodeWgts[j] * fp.KP * (x[i * dim + k] - center[j * dim + k]) / repulsivePow(dist5, fp.p);
|
|
46729
48353
|
}
|
|
46730
48354
|
}
|
|
46731
48355
|
}
|
|
@@ -46981,7 +48605,7 @@ function diagPreconNew(A3) {
|
|
|
46981
48605
|
}
|
|
46982
48606
|
return diag;
|
|
46983
48607
|
}
|
|
46984
|
-
function
|
|
48608
|
+
function conjugateGradient2(A3, precon, n, x, rhs, tol, maxit) {
|
|
46985
48609
|
let rho = 0;
|
|
46986
48610
|
let rhoOld = 1;
|
|
46987
48611
|
let iter = 0;
|
|
@@ -47022,7 +48646,7 @@ function smSolve(A3, dim, x0, rhs, tol, maxit) {
|
|
|
47022
48646
|
x[i] = x0[i * dim + k];
|
|
47023
48647
|
b[i] = rhs[i * dim + k];
|
|
47024
48648
|
}
|
|
47025
|
-
res +=
|
|
48649
|
+
res += conjugateGradient2(A3, precond, n, x, b, tol, maxit);
|
|
47026
48650
|
for (let i = 0; i < n; i++) {
|
|
47027
48651
|
rhs[i * dim + k] = x[i];
|
|
47028
48652
|
}
|
|
@@ -47376,7 +49000,7 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
|
47376
49000
|
for (let j = ia[i]; j < ia[i + 1]; j++) {
|
|
47377
49001
|
const jj = ja[j];
|
|
47378
49002
|
if (jj === i) continue;
|
|
47379
|
-
const
|
|
49003
|
+
const dist5 = distance(x, dim, i, jj);
|
|
47380
49004
|
const dx = Math.abs(x[i * dim] - x[jj * dim]);
|
|
47381
49005
|
const dy = Math.abs(x[i * dim + 1] - x[jj * dim + 1]);
|
|
47382
49006
|
const wx = width2[i * dim] + width2[jj * dim];
|
|
@@ -47399,9 +49023,9 @@ function idealDistanceAvoidOverlap(dim, A3, x, width2, idealDistance) {
|
|
|
47399
49023
|
t = Math.min(expandmax, t);
|
|
47400
49024
|
t = Math.max(expandmin, t);
|
|
47401
49025
|
if (t > 1) {
|
|
47402
|
-
idealDistance[j] = t *
|
|
49026
|
+
idealDistance[j] = t * dist5;
|
|
47403
49027
|
} else {
|
|
47404
|
-
idealDistance[j] = -t *
|
|
49028
|
+
idealDistance[j] = -t * dist5;
|
|
47405
49029
|
}
|
|
47406
49030
|
}
|
|
47407
49031
|
}
|
|
@@ -47496,9 +49120,9 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
|
47496
49120
|
w[j] = -1 / d[j] / d[j];
|
|
47497
49121
|
d[j] = -d[j];
|
|
47498
49122
|
}
|
|
47499
|
-
const
|
|
49123
|
+
const dist5 = d[j];
|
|
47500
49124
|
diagW += w[j];
|
|
47501
|
-
d[j] = w[j] *
|
|
49125
|
+
d[j] = w[j] * dist5;
|
|
47502
49126
|
diagD += d[j];
|
|
47503
49127
|
}
|
|
47504
49128
|
w[jdiag] = -diagW;
|
|
@@ -47509,11 +49133,11 @@ function overlapSmootherNew(m, dim, x, width2, neighborhoodOnly, shrink) {
|
|
|
47509
49133
|
function totalDistance(m, dim, x, y) {
|
|
47510
49134
|
let total = 0;
|
|
47511
49135
|
for (let i = 0; i < m; i++) {
|
|
47512
|
-
let
|
|
49136
|
+
let dist5 = 0;
|
|
47513
49137
|
for (let j = 0; j < dim; j++) {
|
|
47514
|
-
|
|
49138
|
+
dist5 += (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] - x[i * dim + j]);
|
|
47515
49139
|
}
|
|
47516
|
-
total += Math.sqrt(
|
|
49140
|
+
total += Math.sqrt(dist5);
|
|
47517
49141
|
}
|
|
47518
49142
|
return total;
|
|
47519
49143
|
}
|
|
@@ -47546,18 +49170,18 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
|
|
|
47546
49170
|
idiag = j;
|
|
47547
49171
|
continue;
|
|
47548
49172
|
}
|
|
47549
|
-
let
|
|
49173
|
+
let dist5 = distance(x, dim, i, jd[j]);
|
|
47550
49174
|
if (d[j] === 0) {
|
|
47551
49175
|
dd[j] = 0;
|
|
47552
49176
|
} else {
|
|
47553
|
-
if (
|
|
49177
|
+
if (dist5 === 0) {
|
|
47554
49178
|
const dij = d[j] / Lw.a[j];
|
|
47555
49179
|
for (let k = 0; k < dim; k++) {
|
|
47556
49180
|
x[jd[j] * dim + k] += 1e-4 * (cdrand() + 1e-4) * dij;
|
|
47557
49181
|
}
|
|
47558
|
-
|
|
49182
|
+
dist5 = distance(x, dim, i, jd[j]);
|
|
47559
49183
|
}
|
|
47560
|
-
dd[j] = d[j] /
|
|
49184
|
+
dd[j] = d[j] / dist5;
|
|
47561
49185
|
}
|
|
47562
49186
|
diag += dd[j];
|
|
47563
49187
|
}
|
|
@@ -47576,9 +49200,9 @@ function stressMajorizationSmooth(sm, dim, x, maxitSm) {
|
|
|
47576
49200
|
return diff;
|
|
47577
49201
|
}
|
|
47578
49202
|
function scaleToEdgeLength(dim, A3, x, avgLabelSize) {
|
|
47579
|
-
let
|
|
47580
|
-
|
|
47581
|
-
for (let i = 0; i < dim * A3.m; i++) x[i] *=
|
|
49203
|
+
let dist5 = averageEdgeLength(A3, dim, x);
|
|
49204
|
+
dist5 = avgLabelSize / Math.max(dist5, MACHINEACC);
|
|
49205
|
+
for (let i = 0; i < dim * A3.m; i++) x[i] *= dist5;
|
|
47582
49206
|
}
|
|
47583
49207
|
function removeOverlapPrism(dim, A3, x, labelSizes, ntry, initialScaling, doShrinking) {
|
|
47584
49208
|
if (!labelSizes) return;
|
|
@@ -47945,7 +49569,7 @@ function makeHasEdge(g) {
|
|
|
47945
49569
|
}
|
|
47946
49570
|
return (a, b) => pairs.get(a)?.has(b) === true || undirected && pairs.get(b)?.has(a) === true;
|
|
47947
49571
|
}
|
|
47948
|
-
function mkNConstraintG(g, list, intersect,
|
|
49572
|
+
function mkNConstraintG(g, list, intersect, dist5) {
|
|
47949
49573
|
const cg = newCg();
|
|
47950
49574
|
const flat = flatten(list);
|
|
47951
49575
|
let lastn;
|
|
@@ -47962,7 +49586,7 @@ function mkNConstraintG(g, list, intersect, dist4) {
|
|
|
47962
49586
|
const nxp = flat[j];
|
|
47963
49587
|
if (!intersect(p, nxp)) continue;
|
|
47964
49588
|
const e = cgEdge(cg, cnodeOf(p), cnodeOf(nxp));
|
|
47965
|
-
e.info.minlen =
|
|
49589
|
+
e.info.minlen = dist5(p.bb, nxp.bb);
|
|
47966
49590
|
e.info.weight = hasEdge(p.np, nxp.np) ? 100 : 1;
|
|
47967
49591
|
created.push(e);
|
|
47968
49592
|
}
|
|
@@ -48009,12 +49633,12 @@ function buildVisibility(flat, intersect) {
|
|
|
48009
49633
|
}
|
|
48010
49634
|
return vg;
|
|
48011
49635
|
}
|
|
48012
|
-
function mapGraphs(vg, flat, cg,
|
|
49636
|
+
function mapGraphs(vg, flat, cg, dist5) {
|
|
48013
49637
|
for (let i = 0; i < flat.length; i++) {
|
|
48014
49638
|
const tp = flat[i];
|
|
48015
49639
|
for (const j of vg[i]) {
|
|
48016
49640
|
const hp = flat[j];
|
|
48017
|
-
const delta2 =
|
|
49641
|
+
const delta2 = dist5(tp.bb, hp.bb);
|
|
48018
49642
|
const ce = cgEdge(cg, cnodeOf(tp), cnodeOf(hp));
|
|
48019
49643
|
ce.info.weight = 1;
|
|
48020
49644
|
if ((ce.info.minlen ?? 0) < delta2) {
|
|
@@ -48024,15 +49648,15 @@ function mapGraphs(vg, flat, cg, dist4) {
|
|
|
48024
49648
|
}
|
|
48025
49649
|
}
|
|
48026
49650
|
}
|
|
48027
|
-
function mkConstraintG(list, intersect,
|
|
49651
|
+
function mkConstraintG(list, intersect, dist5) {
|
|
48028
49652
|
const cg = newCg();
|
|
48029
49653
|
const flat = flatten(list);
|
|
48030
49654
|
buildChain(cg, flat);
|
|
48031
|
-
mapGraphs(buildVisibility(flat, intersect), flat, cg,
|
|
49655
|
+
mapGraphs(buildVisibility(flat, intersect), flat, cg, dist5);
|
|
48032
49656
|
return cg;
|
|
48033
49657
|
}
|
|
48034
|
-
function buildConstraintGraph(g, list, ifn,
|
|
48035
|
-
return ortho ? mkConstraintG(list, ifn,
|
|
49658
|
+
function buildConstraintGraph(g, list, ifn, dist5, ortho) {
|
|
49659
|
+
return ortho ? mkConstraintG(list, ifn, dist5) : mkNConstraintG(g, list, ifn, dist5);
|
|
48036
49660
|
}
|
|
48037
49661
|
function newItems() {
|
|
48038
49662
|
return new DtBag((p) => p.val, cmpitem);
|
|
@@ -48173,7 +49797,7 @@ function inflatePts(verts, xmargin, ymargin) {
|
|
|
48173
49797
|
v.y *= ymargin;
|
|
48174
49798
|
}
|
|
48175
49799
|
}
|
|
48176
|
-
function
|
|
49800
|
+
function isBox3(verts) {
|
|
48177
49801
|
if (verts.length !== 4) return false;
|
|
48178
49802
|
const [v0, v1, v2, v3] = verts;
|
|
48179
49803
|
if (v0.y === v1.y) {
|
|
@@ -48233,7 +49857,7 @@ function clusterVerts(n, xmargin, ymargin) {
|
|
|
48233
49857
|
function polyKind(n, poly, verts) {
|
|
48234
49858
|
const name = shapeName(n);
|
|
48235
49859
|
if (name === "box") return POLY_BOX;
|
|
48236
|
-
if (name === "polygon" &&
|
|
49860
|
+
if (name === "polygon" && isBox3(verts)) return POLY_BOX;
|
|
48237
49861
|
if (poly.sides < 3 && poly.regular) return POLY_CIRCLE;
|
|
48238
49862
|
return 0;
|
|
48239
49863
|
}
|
|
@@ -48741,7 +50365,7 @@ function heapSiftUp(h, i) {
|
|
|
48741
50365
|
i = parent2;
|
|
48742
50366
|
}
|
|
48743
50367
|
}
|
|
48744
|
-
function
|
|
50368
|
+
function heapSiftDown2(h, i) {
|
|
48745
50369
|
const n = h.length;
|
|
48746
50370
|
for (; ; ) {
|
|
48747
50371
|
let smallest = i;
|
|
@@ -48758,7 +50382,7 @@ function heapSiftDown3(h, i) {
|
|
|
48758
50382
|
}
|
|
48759
50383
|
function makeHeap(h) {
|
|
48760
50384
|
for (let i = (h.length >> 1) - 1; i >= 0; i--) {
|
|
48761
|
-
|
|
50385
|
+
heapSiftDown2(h, i);
|
|
48762
50386
|
}
|
|
48763
50387
|
}
|
|
48764
50388
|
function heapFindMin(h) {
|
|
@@ -48767,7 +50391,7 @@ function heapFindMin(h) {
|
|
|
48767
50391
|
function heapDeleteMin(h) {
|
|
48768
50392
|
h[0] = h[h.length - 1];
|
|
48769
50393
|
h.pop();
|
|
48770
|
-
if (h.length > 0)
|
|
50394
|
+
if (h.length > 0) heapSiftDown2(h, 0);
|
|
48771
50395
|
}
|
|
48772
50396
|
function heapInsert(h, c) {
|
|
48773
50397
|
h.push(c);
|
|
@@ -48851,27 +50475,27 @@ var Block = class _Block {
|
|
|
48851
50475
|
* @see lib/vpsc/block.cpp: Block::merge(Block* b, Constraint* c)
|
|
48852
50476
|
*/
|
|
48853
50477
|
mergeTwoArg(b, c) {
|
|
48854
|
-
const
|
|
50478
|
+
const dist5 = c.right.offset - c.left.offset - c.gap;
|
|
48855
50479
|
let l = c.left.block;
|
|
48856
50480
|
let r = c.right.block;
|
|
48857
50481
|
if (this.vars.length < b.vars.length) {
|
|
48858
|
-
r.mergeInto(l, c,
|
|
50482
|
+
r.mergeInto(l, c, dist5);
|
|
48859
50483
|
} else {
|
|
48860
|
-
l.mergeInto(r, c, -
|
|
50484
|
+
l.mergeInto(r, c, -dist5);
|
|
48861
50485
|
}
|
|
48862
50486
|
}
|
|
48863
50487
|
/**
|
|
48864
50488
|
* Merge block b into this across constraint c by dist.
|
|
48865
50489
|
* @see lib/vpsc/block.cpp: Block::merge(Block *b, Constraint *c, double dist)
|
|
48866
50490
|
*/
|
|
48867
|
-
mergeInto(b, c,
|
|
50491
|
+
mergeInto(b, c, dist5) {
|
|
48868
50492
|
c.active = true;
|
|
48869
|
-
this.wposn += b.wposn -
|
|
50493
|
+
this.wposn += b.wposn - dist5 * b.weight;
|
|
48870
50494
|
this.weight += b.weight;
|
|
48871
50495
|
this.posn = this.wposn / this.weight;
|
|
48872
50496
|
for (const v of b.vars) {
|
|
48873
50497
|
v.block = this;
|
|
48874
|
-
v.offset +=
|
|
50498
|
+
v.offset += dist5;
|
|
48875
50499
|
this.vars.push(v);
|
|
48876
50500
|
}
|
|
48877
50501
|
b.deleted = true;
|
|
@@ -49160,13 +50784,13 @@ var Blocks = class {
|
|
|
49160
50784
|
r.deleteMinInConstraint();
|
|
49161
50785
|
let l = c.left.block;
|
|
49162
50786
|
if (l.in.length === 0) l.setUpInConstraints();
|
|
49163
|
-
let
|
|
50787
|
+
let dist5 = c.right.offset - c.left.offset - c.gap;
|
|
49164
50788
|
if (r.vars.length < l.vars.length) {
|
|
49165
|
-
|
|
50789
|
+
dist5 = -dist5;
|
|
49166
50790
|
[l, r] = [r, l];
|
|
49167
50791
|
}
|
|
49168
50792
|
this.timeCtr.value++;
|
|
49169
|
-
r.mergeInto(l, c,
|
|
50793
|
+
r.mergeInto(l, c, dist5);
|
|
49170
50794
|
r.mergeIn(l);
|
|
49171
50795
|
r.timeStamp = this.timeCtr.value;
|
|
49172
50796
|
this.removeBlock(l);
|
|
@@ -49184,12 +50808,12 @@ var Blocks = class {
|
|
|
49184
50808
|
l.deleteMinOutConstraint();
|
|
49185
50809
|
let r = c.right.block;
|
|
49186
50810
|
r.setUpOutConstraints();
|
|
49187
|
-
let
|
|
50811
|
+
let dist5 = c.left.offset + c.gap - c.right.offset;
|
|
49188
50812
|
if (l.vars.length > r.vars.length) {
|
|
49189
|
-
|
|
50813
|
+
dist5 = -dist5;
|
|
49190
50814
|
[l, r] = [r, l];
|
|
49191
50815
|
}
|
|
49192
|
-
l.mergeInto(r, c,
|
|
50816
|
+
l.mergeInto(r, c, dist5);
|
|
49193
50817
|
l.mergeOut(r);
|
|
49194
50818
|
this.removeBlock(r);
|
|
49195
50819
|
c = l.findMinOutConstraint();
|
|
@@ -49705,7 +51329,7 @@ function warnUnrecognizedOverlap(flag) {
|
|
|
49705
51329
|
const s = flag.toLowerCase();
|
|
49706
51330
|
if (s.startsWith("prism") || NAMED_MODES.has(s)) return;
|
|
49707
51331
|
if (mapBoolDflt(flag, false) === mapBoolDflt(flag, true)) return;
|
|
49708
|
-
|
|
51332
|
+
agwarningf(`Unrecognized overlap value "${flag}" - using false`);
|
|
49709
51333
|
}
|
|
49710
51334
|
function getAdjustMode(flag) {
|
|
49711
51335
|
warnUnrecognizedOverlap(flag);
|
|
@@ -49738,7 +51362,7 @@ function adjustLate(g, am) {
|
|
|
49738
51362
|
case AM_VPSC:
|
|
49739
51363
|
return vpscAdjust(g);
|
|
49740
51364
|
default:
|
|
49741
|
-
|
|
51365
|
+
agwarningf(`Unhandled adjust option ${am.print}`);
|
|
49742
51366
|
return 0;
|
|
49743
51367
|
}
|
|
49744
51368
|
}
|
|
@@ -50712,20 +52336,20 @@ function coincidentDelta() {
|
|
|
50712
52336
|
} while (xdelta === 0 && ydelta === 0);
|
|
50713
52337
|
return { xdelta, ydelta };
|
|
50714
52338
|
}
|
|
50715
|
-
function doRep(p, q, xdelta, ydelta,
|
|
52339
|
+
function doRep(p, q, xdelta, ydelta, dist5) {
|
|
50716
52340
|
let force;
|
|
50717
|
-
if (!(
|
|
52341
|
+
if (!(dist5 > 0)) {
|
|
50718
52342
|
const d = coincidentDelta();
|
|
50719
52343
|
xdelta = d.xdelta;
|
|
50720
52344
|
ydelta = d.ydelta;
|
|
50721
|
-
|
|
52345
|
+
dist5 = libmHypot(xdelta, ydelta);
|
|
50722
52346
|
}
|
|
50723
|
-
if (
|
|
52347
|
+
if (dist5 > fdpParms.Mlimit) {
|
|
50724
52348
|
force = 0;
|
|
50725
52349
|
} else if (parms.useNew) {
|
|
50726
|
-
force = parms.K * parms.K / (
|
|
52350
|
+
force = parms.K * parms.K / (dist5 * dist5 * dist5);
|
|
50727
52351
|
} else {
|
|
50728
|
-
force = parms.K * parms.K / (
|
|
52352
|
+
force = parms.K * parms.K / (dist5 * dist5);
|
|
50729
52353
|
}
|
|
50730
52354
|
if (isPort(p) && isPort(q)) force *= 10;
|
|
50731
52355
|
const dq = disp(q);
|
|
@@ -50747,8 +52371,8 @@ function doNeighbor(grid2, i, j, nodes) {
|
|
|
50747
52371
|
for (const q of cellp.nodes) {
|
|
50748
52372
|
const xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50749
52373
|
const ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50750
|
-
const
|
|
50751
|
-
if (
|
|
52374
|
+
const dist5 = libmHypot(xdelta, ydelta);
|
|
52375
|
+
if (dist5 < parms.Cell) doRep(p, q, xdelta, ydelta, dist5);
|
|
50752
52376
|
}
|
|
50753
52377
|
}
|
|
50754
52378
|
}
|
|
@@ -50780,12 +52404,12 @@ function applyAttr(p, q, e) {
|
|
|
50780
52404
|
ydelta = d.ydelta;
|
|
50781
52405
|
dist22 = fma(xdelta, xdelta, ydelta * ydelta);
|
|
50782
52406
|
}
|
|
50783
|
-
const
|
|
52407
|
+
const dist5 = Math.sqrt(dist22);
|
|
50784
52408
|
let force;
|
|
50785
52409
|
if (parms.useNew) {
|
|
50786
|
-
force = (e.info.factor ?? 1) * (
|
|
52410
|
+
force = (e.info.factor ?? 1) * (dist5 - (e.info.dist ?? 1)) / dist5;
|
|
50787
52411
|
} else {
|
|
50788
|
-
force = (e.info.factor ?? 1) *
|
|
52412
|
+
force = (e.info.factor ?? 1) * dist5 / (e.info.dist ?? 1);
|
|
50789
52413
|
}
|
|
50790
52414
|
const dq = disp(q);
|
|
50791
52415
|
const dp = disp(p);
|
|
@@ -50960,16 +52584,16 @@ function cntOverlaps(g) {
|
|
|
50960
52584
|
function applyRep2(p, q, rs) {
|
|
50961
52585
|
let xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50962
52586
|
let ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50963
|
-
let
|
|
50964
|
-
if (!(
|
|
52587
|
+
let dist5 = libmHypot(xdelta, ydelta);
|
|
52588
|
+
if (!(dist5 > 0)) {
|
|
50965
52589
|
const d = coincidentDelta();
|
|
50966
52590
|
xdelta = d.xdelta;
|
|
50967
52591
|
ydelta = d.ydelta;
|
|
50968
|
-
|
|
52592
|
+
dist5 = libmHypot(xdelta, ydelta);
|
|
50969
52593
|
}
|
|
50970
52594
|
const ov = overlap4(p, q) ? 1 : 0;
|
|
50971
|
-
let force = ov ? rs.ov / (
|
|
50972
|
-
if (
|
|
52595
|
+
let force = ov ? rs.ov / (dist5 * dist5) : rs.nonov / (dist5 * dist5);
|
|
52596
|
+
if (dist5 > fdpParms.Mlimit) force = 0;
|
|
50973
52597
|
const dq = disp(q);
|
|
50974
52598
|
const dp = disp(p);
|
|
50975
52599
|
dq[0] = fma(xdelta, force, dq[0]);
|
|
@@ -50982,10 +52606,10 @@ function applyAttr2(p, q) {
|
|
|
50982
52606
|
if (overlap4(p, q)) return;
|
|
50983
52607
|
const xdelta = q.info.pos[0] - p.info.pos[0];
|
|
50984
52608
|
const ydelta = q.info.pos[1] - p.info.pos[1];
|
|
50985
|
-
const
|
|
52609
|
+
const dist5 = libmHypot(xdelta, ydelta);
|
|
50986
52610
|
const din = rad(p) + rad(q);
|
|
50987
|
-
const dout =
|
|
50988
|
-
const force = dout * dout / ((xParams.K + din) *
|
|
52611
|
+
const dout = dist5 - din;
|
|
52612
|
+
const force = dout * dout / ((xParams.K + din) * dist5);
|
|
50989
52613
|
const dq = disp(q);
|
|
50990
52614
|
const dp = disp(p);
|
|
50991
52615
|
dq[0] = fms(xdelta, force, dq[0]);
|
|
@@ -52140,9 +53764,9 @@ function pcpRotate(n, dim, x) {
|
|
|
52140
53764
|
axis[0] = -(-y[0] + y[3] - Math.sqrt(radicand)) / (2 * y[1]);
|
|
52141
53765
|
axis[1] = 1;
|
|
52142
53766
|
}
|
|
52143
|
-
const
|
|
52144
|
-
axis[0] = axis[0] /
|
|
52145
|
-
axis[1] = axis[1] /
|
|
53767
|
+
const dist5 = Math.sqrt(fma(axis[0], axis[0], 1));
|
|
53768
|
+
axis[0] = axis[0] / dist5;
|
|
53769
|
+
axis[1] = axis[1] / dist5;
|
|
52146
53770
|
for (let i = 0; i < n; i++) {
|
|
52147
53771
|
const x0 = fma(x[dim * i], axis[0], x[dim * i + 1] * axis[1]);
|
|
52148
53772
|
const x1 = fma(-x[dim * i], axis[1], x[dim * i + 1] * axis[0]);
|
|
@@ -52555,10 +54179,10 @@ function buildSpanTree(nodes, edges) {
|
|
|
52555
54179
|
}
|
|
52556
54180
|
return map;
|
|
52557
54181
|
}
|
|
52558
|
-
function measureDist(leaf, anc,
|
|
54182
|
+
function measureDist(leaf, anc, dist5, change) {
|
|
52559
54183
|
const p = anc.tparent;
|
|
52560
54184
|
if (!p) return;
|
|
52561
|
-
const d =
|
|
54185
|
+
const d = dist5 + 1;
|
|
52562
54186
|
if (p.distone === 0) {
|
|
52563
54187
|
p.leafone = leaf;
|
|
52564
54188
|
p.distone = d;
|
|
@@ -54058,11 +55682,11 @@ var DEFAULT_COLOR5 = "black";
|
|
|
54058
55682
|
var PENWIDTH_NORMAL4 = 1;
|
|
54059
55683
|
var PENWIDTH_THRESHOLD4 = 5e-3;
|
|
54060
55684
|
var EPS3 = 1e-5;
|
|
54061
|
-
function
|
|
55685
|
+
function dist4(a, b) {
|
|
54062
55686
|
return Math.sqrt(dist2(a, b));
|
|
54063
55687
|
}
|
|
54064
55688
|
function approxLen(list, off) {
|
|
54065
|
-
return
|
|
55689
|
+
return dist4(list[off], list[off + 1]) + dist4(list[off + 1], list[off + 2]) + dist4(list[off + 2], list[off + 3]);
|
|
54066
55690
|
}
|
|
54067
55691
|
function splitCubic(v, t) {
|
|
54068
55692
|
const left2 = [];
|
|
@@ -54141,7 +55765,7 @@ function drawSplitSpline(list, segs, job) {
|
|
|
54141
55765
|
return endColor;
|
|
54142
55766
|
}
|
|
54143
55767
|
function emitSplitEdgePaths(e, job, colorList) {
|
|
54144
|
-
const segs = parseSegs(colorList).segs;
|
|
55768
|
+
const segs = parseSegs(colorList, edgeSegsContext(e)).segs;
|
|
54145
55769
|
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR5;
|
|
54146
55770
|
const spl = e.info.spl;
|
|
54147
55771
|
let endColor = firstColor2;
|
|
@@ -54162,8 +55786,8 @@ var forfunc = (cur, total, init) => (1 - cur / total) * init / 2;
|
|
|
54162
55786
|
var revfunc = (cur, total, init) => cur / total * init / 2;
|
|
54163
55787
|
var nonefunc = (_cur, _total, init) => init / 2;
|
|
54164
55788
|
var bothfunc = (cur, total, init) => {
|
|
54165
|
-
const
|
|
54166
|
-
return
|
|
55789
|
+
const fr7 = cur / total;
|
|
55790
|
+
return fr7 <= 0.5 ? fr7 * init : (1 - fr7) * init;
|
|
54167
55791
|
};
|
|
54168
55792
|
function taperfun(dir, directed) {
|
|
54169
55793
|
if (dir === "forward") return forfunc;
|
|
@@ -55597,7 +57221,7 @@ var DotWriterBase = class {
|
|
|
55597
57221
|
|
|
55598
57222
|
// src/render/dot/edge-draw.ts
|
|
55599
57223
|
var DEFAULT_COLOR6 = "black";
|
|
55600
|
-
var
|
|
57224
|
+
var DEFAULT_LINE_STYLE2 = ["solid", "setlinewidth(1)"];
|
|
55601
57225
|
function emitArrowOp(buf, op, pen) {
|
|
55602
57226
|
switch (op.kind) {
|
|
55603
57227
|
case "polygon":
|
|
@@ -55632,8 +57256,9 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55632
57256
|
*/
|
|
55633
57257
|
attachmentPolyline(pts, pencolor, job) {
|
|
55634
57258
|
const obj = job.obj;
|
|
57259
|
+
gvrenderSetStyle(DEFAULT_LINE_STYLE2);
|
|
55635
57260
|
if (obj !== null) {
|
|
55636
|
-
obj.rawStyle = [...
|
|
57261
|
+
obj.rawStyle = [...DEFAULT_LINE_STYLE2];
|
|
55637
57262
|
obj.pen = 3 /* Solid */;
|
|
55638
57263
|
obj.penWidth = 1;
|
|
55639
57264
|
obj.penColor = resolveRenderColor(pencolor.split(":")[0]);
|
|
@@ -55687,8 +57312,8 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55687
57312
|
* under that segment's pen. Reuses the same split geometry
|
|
55688
57313
|
* (splitSplineByColor) as the SVG path. @see lib/common/emit.c:1975 multicolor
|
|
55689
57314
|
*/
|
|
55690
|
-
emitSplitSpline(bzList, colorAttr, edraw, job) {
|
|
55691
|
-
const segs = parseSegs(colorAttr).segs;
|
|
57315
|
+
emitSplitSpline(bzList, e, colorAttr, edraw, job) {
|
|
57316
|
+
const segs = parseSegs(colorAttr, edgeSegsContext(e)).segs;
|
|
55692
57317
|
const firstColor2 = segs[0]?.color ?? DEFAULT_COLOR6;
|
|
55693
57318
|
let endColor = firstColor2;
|
|
55694
57319
|
for (const bz of bzList) {
|
|
@@ -55711,7 +57336,7 @@ var EdgeDrawBase = class extends DotWriterBase {
|
|
|
55711
57336
|
const segData = bzList.map(
|
|
55712
57337
|
(bz) => bz !== void 0 && bz.size >= 4 ? buildOffsetLists(bz.list, (2 + numc) / 2) : { offlist: [], tmplist: [] }
|
|
55713
57338
|
);
|
|
55714
|
-
const colors =
|
|
57339
|
+
const colors = parseSegsSilent(colorAttr).segs.map((s) => s.color ?? DEFAULT_COLOR6);
|
|
55715
57340
|
for (const color of colors) {
|
|
55716
57341
|
const pen = xdotPenColor(resolveRenderColor(color));
|
|
55717
57342
|
for (const sd of segData) {
|
|
@@ -55867,7 +57492,7 @@ var XdotRenderer = class extends EdgeDrawBase {
|
|
|
55867
57492
|
let tailArrowColor;
|
|
55868
57493
|
let headArrowColor;
|
|
55869
57494
|
if (numsemi > 0 && numc > 0) {
|
|
55870
|
-
const c = this.emitSplitSpline(spl.list, colorAttr, edraw, job);
|
|
57495
|
+
const c = this.emitSplitSpline(spl.list, e, colorAttr, edraw, job);
|
|
55871
57496
|
tailArrowColor = c.firstColor;
|
|
55872
57497
|
headArrowColor = c.endColor;
|
|
55873
57498
|
} else if (edgeIsTapered(e)) {
|
|
@@ -56103,72 +57728,6 @@ function svgTaperedEdge(e, job) {
|
|
|
56103
57728
|
svgArrowPolygons(e, job);
|
|
56104
57729
|
}
|
|
56105
57730
|
|
|
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
57731
|
// src/render/svg.ts
|
|
56173
57732
|
function emitMulticolorArrows(e, job, headColor, tailColor) {
|
|
56174
57733
|
const obj = job.obj;
|