import max from "../node_modules/d3-array/src/max.js";
import min from "../node_modules/d3-array/src/min.js";
import sum from "../node_modules/d3-array/src/sum.js";
import { justify } from "./align.js";
import constant from "./constant.js";
function ascendingSourceBreadth(i, l) {
	return ascendingBreadth(i.source, l.source) || i.index - l.index;
}
function ascendingTargetBreadth(i, l) {
	return ascendingBreadth(i.target, l.target) || i.index - l.index;
}
function ascendingBreadth(i, l) {
	return i.y0 - l.y0;
}
function value(i) {
	return i.value;
}
function defaultId(i) {
	return i.index;
}
function defaultNodes(i) {
	return i.nodes;
}
function defaultLinks(i) {
	return i.links;
}
function find(i, l) {
	let u = i.get(l);
	if (!u) throw Error("missing: " + l);
	return u;
}
function computeLinkBreadths({ nodes: i }) {
	for (let l of i) {
		let i = l.y0, u = i;
		for (let u of l.sourceLinks) u.y0 = i + u.width / 2, i += u.width;
		for (let i of l.targetLinks) i.y1 = u + i.width / 2, u += i.width;
	}
}
function Sankey() {
	let m = 0, h = 0, g = 1, _ = 1, v = 24, y = 8, b, x = defaultId, S = justify, C, w, T = defaultNodes, E = defaultLinks, D = 6;
	function O() {
		let i = {
			nodes: T.apply(null, arguments),
			links: E.apply(null, arguments)
		};
		return k(i), A(i), j(i), M(i), F(i), computeLinkBreadths(i), i;
	}
	O.update = function(i) {
		return computeLinkBreadths(i), i;
	}, O.nodeId = function(i) {
		return arguments.length ? (x = typeof i == "function" ? i : constant(i), O) : x;
	}, O.nodeAlign = function(i) {
		return arguments.length ? (S = typeof i == "function" ? i : constant(i), O) : S;
	}, O.nodeSort = function(i) {
		return arguments.length ? (C = i, O) : C;
	}, O.nodeWidth = function(i) {
		return arguments.length ? (v = +i, O) : v;
	}, O.nodePadding = function(i) {
		return arguments.length ? (y = b = +i, O) : y;
	}, O.nodes = function(i) {
		return arguments.length ? (T = typeof i == "function" ? i : constant(i), O) : T;
	}, O.links = function(i) {
		return arguments.length ? (E = typeof i == "function" ? i : constant(i), O) : E;
	}, O.linkSort = function(i) {
		return arguments.length ? (w = i, O) : w;
	}, O.size = function(i) {
		return arguments.length ? (m = h = 0, g = +i[0], _ = +i[1], O) : [g - m, _ - h];
	}, O.extent = function(i) {
		return arguments.length ? (m = +i[0][0], g = +i[1][0], h = +i[0][1], _ = +i[1][1], O) : [[m, h], [g, _]];
	}, O.iterations = function(i) {
		return arguments.length ? (D = +i, O) : D;
	};
	function k({ nodes: i, links: l }) {
		for (let [l, u] of i.entries()) u.index = l, u.sourceLinks = [], u.targetLinks = [];
		let u = new Map(i.map((l, u) => [x(l, u, i), l]));
		for (let [i, d] of l.entries()) {
			d.index = i;
			let { source: l, target: f } = d;
			typeof l != "object" && (l = d.source = find(u, l)), typeof f != "object" && (f = d.target = find(u, f)), l.sourceLinks.push(d), f.targetLinks.push(d);
		}
		if (w != null) for (let { sourceLinks: l, targetLinks: u } of i) l.sort(w), u.sort(w);
	}
	function A({ nodes: i }) {
		for (let l of i) l.value = l.fixedValue === void 0 ? Math.max(sum(l.sourceLinks, value), sum(l.targetLinks, value)) : l.fixedValue;
	}
	function j({ nodes: i }) {
		let l = i.length, u = new Set(i), d = /* @__PURE__ */ new Set(), f = 0;
		for (; u.size;) {
			for (let i of u) {
				i.depth = f;
				for (let { target: l } of i.sourceLinks) d.add(l);
			}
			if (++f > l) throw Error("circular link");
			u = d, d = /* @__PURE__ */ new Set();
		}
	}
	function M({ nodes: i }) {
		let l = i.length, u = new Set(i), d = /* @__PURE__ */ new Set(), f = 0;
		for (; u.size;) {
			for (let i of u) {
				i.height = f;
				for (let { source: l } of i.targetLinks) d.add(l);
			}
			if (++f > l) throw Error("circular link");
			u = d, d = /* @__PURE__ */ new Set();
		}
	}
	function N({ nodes: l }) {
		let u = max(l, (i) => i.depth) + 1, d = (g - m - v) / (u - 1), f = Array(u);
		for (let i of l) {
			let l = Math.max(0, Math.min(u - 1, Math.floor(S.call(null, i, u))));
			i.layer = l, i.x0 = m + l * d, i.x1 = i.x0 + v, f[l] ? f[l].push(i) : f[l] = [i];
		}
		if (C) for (let i of f) i.sort(C);
		return f;
	}
	function P(i) {
		let d = min(i, (i) => (_ - h - (i.length - 1) * b) / sum(i, value));
		for (let l of i) {
			let i = h;
			for (let u of l) {
				u.y0 = i, u.y1 = i + u.value * d, i = u.y1 + b;
				for (let i of u.sourceLinks) i.width = i.value * d;
			}
			i = (_ - i + b) / (l.length + 1);
			for (let u = 0; u < l.length; ++u) {
				let d = l[u];
				d.y0 += i * (u + 1), d.y1 += i * (u + 1);
			}
			H(l);
		}
	}
	function F(l) {
		let u = N(l);
		b = Math.min(y, (_ - h) / (max(u, (i) => i.length) - 1)), P(u);
		for (let i = 0; i < D; ++i) {
			let l = .99 ** i, d = Math.max(1 - l, (i + 1) / D);
			L(u, l, d), I(u, l, d);
		}
	}
	function I(i, l, u) {
		for (let d = 1, f = i.length; d < f; ++d) {
			let f = i[d];
			for (let i of f) {
				let u = 0, d = 0;
				for (let { source: l, value: f } of i.targetLinks) {
					let p = f * (i.layer - l.layer);
					u += U(l, i) * p, d += p;
				}
				if (!(d > 0)) continue;
				let f = (u / d - i.y0) * l;
				i.y0 += f, i.y1 += f, V(i);
			}
			C === void 0 && f.sort(ascendingBreadth), R(f, u);
		}
	}
	function L(i, l, u) {
		for (let d = i.length - 2; d >= 0; --d) {
			let f = i[d];
			for (let i of f) {
				let u = 0, d = 0;
				for (let { target: l, value: f } of i.sourceLinks) {
					let p = f * (l.layer - i.layer);
					u += W(i, l) * p, d += p;
				}
				if (!(d > 0)) continue;
				let f = (u / d - i.y0) * l;
				i.y0 += f, i.y1 += f, V(i);
			}
			C === void 0 && f.sort(ascendingBreadth), R(f, u);
		}
	}
	function R(i, l) {
		let u = i.length >> 1, d = i[u];
		B(i, d.y0 - b, u - 1, l), z(i, d.y1 + b, u + 1, l), B(i, _, i.length - 1, l), z(i, h, 0, l);
	}
	function z(i, l, u, d) {
		for (; u < i.length; ++u) {
			let f = i[u], p = (l - f.y0) * d;
			p > 1e-6 && (f.y0 += p, f.y1 += p), l = f.y1 + b;
		}
	}
	function B(i, l, u, d) {
		for (; u >= 0; --u) {
			let f = i[u], p = (f.y1 - l) * d;
			p > 1e-6 && (f.y0 -= p, f.y1 -= p), l = f.y0 - b;
		}
	}
	function V({ sourceLinks: i, targetLinks: l }) {
		if (w === void 0) {
			for (let { source: { sourceLinks: i } } of l) i.sort(ascendingTargetBreadth);
			for (let { target: { targetLinks: l } } of i) l.sort(ascendingSourceBreadth);
		}
	}
	function H(i) {
		if (w === void 0) for (let { sourceLinks: l, targetLinks: u } of i) l.sort(ascendingTargetBreadth), u.sort(ascendingSourceBreadth);
	}
	function U(i, l) {
		let u = i.y0 - (i.sourceLinks.length - 1) * b / 2;
		for (let { target: d, width: f } of i.sourceLinks) {
			if (d === l) break;
			u += f + b;
		}
		for (let { source: d, width: f } of l.targetLinks) {
			if (d === i) break;
			u -= f;
		}
		return u;
	}
	function W(i, l) {
		let u = l.y0 - (l.targetLinks.length - 1) * b / 2;
		for (let { source: d, width: f } of l.targetLinks) {
			if (d === i) break;
			u += f + b;
		}
		for (let { target: d, width: f } of i.sourceLinks) {
			if (d === l) break;
			u -= f;
		}
		return u;
	}
	return O;
}
export { Sankey as default };
