import { o as map_default } from "./min-Ds3gG0Ff.js";
import { r as isUndefined_default } from "./_baseUniq-C87CckHL.js";
import { t as layout } from "./dagre-QVd-lCXU.js";
import { t as clone_default } from "./clone-DZFQCtFJ.js";
import { t as Graph } from "./graphlib-BV1_gi0C.js";
import "./purify.es-hTCfRGdl.js";
import "./chunk-S3R3BYOJ-B0UOFJwq.js";
import { i as log, r as __name } from "./src-DbP20yFZ.js";
import { b as getConfig2 } from "./chunk-ABZYJK2D-CZYCCtLy.js";
import "./chunk-HN2XXSSU-DAhNp1ig.js";
import { t as getSubGraphTitleMargins } from "./chunk-CVBHYZKI-BXHgce-x.js";
import "./chunk-ATLVNIR6-DaOzLLgN.js";
import "./dist-BjWd_Ei9.js";
import "./chunk-JA3XYJ7Z-BcPEfxk_.js";
import { a as insertNode, c as positionNode, i as insertCluster, l as setNodeElem, n as clear2, t as clear$1, u as updateNodeBounds } from "./chunk-JZLCHNYA-2bnLL3xL.js";
import { a as positionEdgeLabel, i as markers_default, n as insertEdge, r as insertEdgeLabel, t as clear } from "./chunk-QXUST7PY-Ch6F5Obl.js";
function write(r) {
  var w = {
    options: {
      directed: r.isDirected(),
      multigraph: r.isMultigraph(),
      compound: r.isCompound()
    },
    nodes: writeNodes(r),
    edges: writeEdges(r)
  };
  return isUndefined_default(r.graph()) || (w.value = clone_default(r.graph())), w;
}
function writeNodes(w) {
  return map_default(w.nodes(), function(r) {
    var T = w.node(r), E = w.parent(r), D = { v: r };
    return isUndefined_default(T) || (D.value = T), isUndefined_default(E) || (D.parent = E), D;
  });
}
function writeEdges(w) {
  return map_default(w.edges(), function(r) {
    var T = w.edge(r), E = {
      v: r.v,
      w: r.w
    };
    return isUndefined_default(r.name) || (E.name = r.name), isUndefined_default(T) || (E.value = T), E;
  });
}
var clusterDb = /* @__PURE__ */ new Map(), descendants = /* @__PURE__ */ new Map(), parents = /* @__PURE__ */ new Map(), clear4 = /* @__PURE__ */ __name(() => {
  descendants.clear(), parents.clear(), clusterDb.clear();
}, "clear"), isDescendant = /* @__PURE__ */ __name((r, C) => {
  let w = descendants.get(C) || [];
  return log.trace("In isDescendant", C, " ", r, " = ", w.includes(r)), w.includes(r);
}, "isDescendant"), edgeInCluster = /* @__PURE__ */ __name((r, C) => {
  let w = descendants.get(C) || [];
  return log.info("Descendants of ", C, " is ", w), log.info("Edge is ", r), r.v === C || r.w === C ? false : w ? w.includes(r.v) || isDescendant(r.v, C) || isDescendant(r.w, C) || w.includes(r.w) : (log.debug("Tilt, ", C, ",not in descendants"), false);
}, "edgeInCluster"), copy = /* @__PURE__ */ __name((r, C, w, T) => {
  log.warn("Copying children of ", r, "root", T, "data", C.node(r), T);
  let E = C.children(r) || [];
  r !== T && E.push(r), log.warn("Copying (nodes) clusterId", r, "nodes", E), E.forEach((E2) => {
    if (C.children(E2).length > 0) copy(E2, C, w, T);
    else {
      let O = C.node(E2);
      log.info("cp ", E2, " to ", T, " with parent ", r), w.setNode(E2, O), T !== C.parent(E2) && (log.warn("Setting parent", E2, C.parent(E2)), w.setParent(E2, C.parent(E2))), r !== T && E2 !== r ? (log.debug("Setting parent", E2, r), w.setParent(E2, r)) : (log.info("In copy ", r, "root", T, "data", C.node(r), T), log.debug("Not Setting parent for node=", E2, "cluster!==rootId", r !== T, "node!==clusterId", E2 !== r));
      let k = C.edges(E2);
      log.debug("Copying Edges", k), k.forEach((E3) => {
        log.info("Edge", E3);
        let O2 = C.edge(E3.v, E3.w, E3.name);
        log.info("Edge data", O2, T);
        try {
          edgeInCluster(E3, T) ? (log.info("Copying as ", E3.v, E3.w, O2, E3.name), w.setEdge(E3.v, E3.w, O2, E3.name), log.info("newGraph edges ", w.edges(), w.edge(w.edges()[0]))) : log.info("Skipping copy of edge ", E3.v, "-->", E3.w, " rootId: ", T, " clusterId:", r);
        } catch (r2) {
          log.error(r2);
        }
      });
    }
    log.debug("Removing node", E2), C.removeNode(E2);
  });
}, "copy"), extractDescendants = /* @__PURE__ */ __name((r, C) => {
  let w = C.children(r), T = [...w];
  for (let E of w) parents.set(E, r), T = [...T, ...extractDescendants(E, C)];
  return T;
}, "extractDescendants"), findCommonEdges = /* @__PURE__ */ __name((r, C, w) => {
  let T = r.edges().filter((r2) => r2.v === C || r2.w === C), E = r.edges().filter((r2) => r2.v === w || r2.w === w), D = T.map((r2) => ({
    v: r2.v === C ? w : r2.v,
    w: r2.w === C ? C : r2.w
  })), O = E.map((r2) => ({
    v: r2.v,
    w: r2.w
  }));
  return D.filter((r2) => O.some((C2) => r2.v === C2.v && r2.w === C2.w));
}, "findCommonEdges"), findNonClusterChild = /* @__PURE__ */ __name((r, C, w) => {
  let T = C.children(r);
  if (log.trace("Searching children of id ", r, T), T.length < 1) return r;
  let E;
  for (let r2 of T) {
    let T2 = findNonClusterChild(r2, C, w), D = findCommonEdges(C, w, T2);
    if (T2) if (D.length > 0) E = T2;
    else return T2;
  }
  return E;
}, "findNonClusterChild"), getAnchorId = /* @__PURE__ */ __name((r) => !clusterDb.has(r) || !clusterDb.get(r).externalConnections ? r : clusterDb.has(r) ? clusterDb.get(r).id : r, "getAnchorId"), adjustClustersAndEdges = /* @__PURE__ */ __name((r, C) => {
  if (!r || C > 10) {
    log.debug("Opting out, no graph ");
    return;
  } else log.debug("Opting in, graph ");
  r.nodes().forEach(function(C2) {
    r.children(C2).length > 0 && (log.warn("Cluster identified", C2, " Replacement id in edges: ", findNonClusterChild(C2, r, C2)), descendants.set(C2, extractDescendants(C2, r)), clusterDb.set(C2, {
      id: findNonClusterChild(C2, r, C2),
      clusterData: r.node(C2)
    }));
  }), r.nodes().forEach(function(C2) {
    let w = r.children(C2), T = r.edges();
    w.length > 0 ? (log.debug("Cluster identified", C2, descendants), T.forEach((r2) => {
      isDescendant(r2.v, C2) ^ isDescendant(r2.w, C2) && (log.warn("Edge: ", r2, " leaves cluster ", C2), log.warn("Descendants of XXX ", C2, ": ", descendants.get(C2)), clusterDb.get(C2).externalConnections = true);
    })) : log.debug("Not a cluster ", C2, descendants);
  });
  for (let C2 of clusterDb.keys()) {
    let w = clusterDb.get(C2).id, T = r.parent(w);
    T !== C2 && clusterDb.has(T) && !clusterDb.get(T).externalConnections && (clusterDb.get(C2).id = T);
  }
  r.edges().forEach(function(C2) {
    let w = r.edge(C2);
    log.warn("Edge " + C2.v + " -> " + C2.w + ": " + JSON.stringify(C2)), log.warn("Edge " + C2.v + " -> " + C2.w + ": " + JSON.stringify(r.edge(C2)));
    let T = C2.v, E = C2.w;
    if (log.warn("Fix XXX", clusterDb, "ids:", C2.v, C2.w, "Translating: ", clusterDb.get(C2.v), " --- ", clusterDb.get(C2.w)), clusterDb.get(C2.v) || clusterDb.get(C2.w)) {
      if (log.warn("Fixing and trying - removing XXX", C2.v, C2.w, C2.name), T = getAnchorId(C2.v), E = getAnchorId(C2.w), r.removeEdge(C2.v, C2.w, C2.name), T !== C2.v) {
        let E2 = r.parent(T);
        clusterDb.get(E2).externalConnections = true, w.fromCluster = C2.v;
      }
      if (E !== C2.w) {
        let T2 = r.parent(E);
        clusterDb.get(T2).externalConnections = true, w.toCluster = C2.w;
      }
      log.warn("Fix Replacing with XXX", T, E, C2.name), r.setEdge(T, E, w, C2.name);
    }
  }), log.warn("Adjusted Graph", write(r)), extractor(r, 0), log.trace(clusterDb);
}, "adjustClustersAndEdges"), extractor = /* @__PURE__ */ __name((r, C) => {
  var _a, _b;
  if (log.warn("extractor - ", C, write(r), r.children("D")), C > 10) {
    log.error("Bailing out");
    return;
  }
  let w = r.nodes(), T = false;
  for (let C2 of w) {
    let w2 = r.children(C2);
    T || (T = w2.length > 0);
  }
  if (!T) {
    log.debug("Done, no node has children", r.nodes());
    return;
  }
  log.debug("Nodes = ", w, C);
  for (let T2 of w) if (log.debug("Extracting node", T2, clusterDb, clusterDb.has(T2) && !clusterDb.get(T2).externalConnections, !r.parent(T2), r.node(T2), r.children("D"), " Depth ", C), !clusterDb.has(T2)) log.debug("Not a cluster", T2, C);
  else if (!clusterDb.get(T2).externalConnections && r.children(T2) && r.children(T2).length > 0) {
    log.warn("Cluster without external connections, without a parent and with children", T2, C);
    let w2 = r.graph().rankdir === "TB" ? "LR" : "TB";
    ((_b = (_a = clusterDb.get(T2)) == null ? void 0 : _a.clusterData) == null ? void 0 : _b.dir) && (w2 = clusterDb.get(T2).clusterData.dir, log.warn("Fixing dir", clusterDb.get(T2).clusterData.dir, w2));
    let O = new Graph({
      multigraph: true,
      compound: true
    }).setGraph({
      rankdir: w2,
      nodesep: 50,
      ranksep: 50,
      marginx: 8,
      marginy: 8
    }).setDefaultEdgeLabel(function() {
      return {};
    });
    log.warn("Old graph before copy", write(r)), copy(T2, r, O, T2), r.setNode(T2, {
      clusterNode: true,
      id: T2,
      clusterData: clusterDb.get(T2).clusterData,
      label: clusterDb.get(T2).label,
      graph: O
    }), log.warn("New graph after copy node: (", T2, ")", write(O)), log.debug("Old graph after copy", write(r));
  } else log.warn("Cluster ** ", T2, " **not meeting the criteria !externalConnections:", !clusterDb.get(T2).externalConnections, " no parent: ", !r.parent(T2), " children ", r.children(T2) && r.children(T2).length > 0, r.children("D"), C), log.debug(clusterDb);
  w = r.nodes(), log.warn("New list of nodes", w);
  for (let T2 of w) {
    let w2 = r.node(T2);
    log.warn(" Now next level", T2, w2), (w2 == null ? void 0 : w2.clusterNode) && extractor(w2.graph, C + 1);
  }
}, "extractor"), sorter = /* @__PURE__ */ __name((r, C) => {
  if (C.length === 0) return [];
  let w = Object.assign([], C);
  return C.forEach((C2) => {
    let T = sorter(r, r.children(C2));
    w = [...w, ...T];
  }), w;
}, "sorter"), sortNodesByHierarchy = /* @__PURE__ */ __name((r) => sorter(r, r.children()), "sortNodesByHierarchy"), recursiveRender = /* @__PURE__ */ __name(async (r, C, T, E, k, M) => {
  log.warn("Graph in recursive render:XAX", write(C), k);
  let N = C.graph().rankdir;
  log.trace("Dir in recursive render - dir:", N);
  let P = r.insert("g").attr("class", "root");
  C.nodes() ? log.info("Recursive render XXX", C.nodes()) : log.info("No nodes found for", C), C.edges().length > 0 && log.info("Recursive edges", C.edge(C.edges()[0]));
  let F = P.insert("g").attr("class", "clusters"), I = P.insert("g").attr("class", "edgePaths"), L = P.insert("g").attr("class", "edgeLabels"), R = P.insert("g").attr("class", "nodes");
  await Promise.all(C.nodes().map(async function(r2) {
    let w = C.node(r2);
    if (k !== void 0) {
      let w2 = JSON.parse(JSON.stringify(k.clusterData));
      log.trace("Setting data for parent cluster XXX\n Node.id = ", r2, "\n data=", w2.height, "\nParent cluster", k.height), C.setNode(k.id, w2), C.parent(r2) || (log.trace("Setting parent", r2, k.id), C.setParent(r2, k.id, w2));
    }
    if (log.info("(Insert) Node XXX" + r2 + ": " + JSON.stringify(C.node(r2))), w == null ? void 0 : w.clusterNode) {
      log.info("Cluster identified XBX", r2, w.width, C.node(r2));
      let { ranksep: O, nodesep: k2 } = C.graph();
      w.graph.setGraph({
        ...w.graph.graph(),
        ranksep: O + 25,
        nodesep: k2
      });
      let A = await recursiveRender(R, w.graph, T, E, C.node(r2), M), j = A.elem;
      updateNodeBounds(w, j), w.diff = A.diff || 0, log.info("New compound node after recursive render XAX", r2, "width", w.width, "height", w.height), setNodeElem(j, w);
    } else C.children(r2).length > 0 ? (log.trace("Cluster - the non recursive path XBX", r2, w.id, w, w.width, "Graph:", C), log.trace(findNonClusterChild(w.id, C)), clusterDb.set(w.id, {
      id: findNonClusterChild(w.id, C),
      node: w
    })) : (log.trace("Node - the non recursive path XAX", r2, R, C.node(r2), N), await insertNode(R, C.node(r2), {
      config: M,
      dir: N
    }));
  })), await (/* @__PURE__ */ __name(async () => {
    let r2 = C.edges().map(async function(r3) {
      let w = C.edge(r3.v, r3.w, r3.name);
      log.info("Edge " + r3.v + " -> " + r3.w + ": " + JSON.stringify(r3)), log.info("Edge " + r3.v + " -> " + r3.w + ": ", r3, " ", JSON.stringify(C.edge(r3))), log.info("Fix", clusterDb, "ids:", r3.v, r3.w, "Translating: ", clusterDb.get(r3.v), clusterDb.get(r3.w)), await insertEdgeLabel(L, w);
    });
    await Promise.all(r2);
  }, "processEdges"))(), log.info("Graph before layout:", JSON.stringify(write(C))), log.info("############################################# XXX"), log.info("###                Layout                 ### XXX"), log.info("############################################# XXX"), layout(C), log.info("Graph after layout:", JSON.stringify(write(C)));
  let z = 0, { subGraphTitleTotalMargin: B } = getSubGraphTitleMargins(M);
  return await Promise.all(sortNodesByHierarchy(C).map(async function(r2) {
    var _a;
    let w = C.node(r2);
    if (log.info("Position XBX => " + r2 + ": (" + w.x, "," + w.y, ") width: ", w.width, " height: ", w.height), w == null ? void 0 : w.clusterNode) w.y += B, log.info("A tainted cluster node XBX1", r2, w.id, w.width, w.height, w.x, w.y, C.parent(r2)), clusterDb.get(w.id).node = w, positionNode(w);
    else if (C.children(r2).length > 0) {
      log.info("A pure cluster node XBX1", r2, w.id, w.x, w.y, w.width, w.height, C.parent(r2)), w.height += B, C.node(w.parentId);
      let T2 = (w == null ? void 0 : w.padding) / 2 || 0, E2 = ((_a = w == null ? void 0 : w.labelBBox) == null ? void 0 : _a.height) || 0, O = E2 - T2 || 0;
      log.debug("OffsetY", O, "labelHeight", E2, "halfPadding", T2), await insertCluster(F, w), clusterDb.get(w.id).node = w;
    } else {
      let r3 = C.node(w.parentId);
      w.y += B / 2, log.info("A regular node XBX1 - using the padding", w.id, "parent", w.parentId, w.width, w.height, w.x, w.y, "offsetY", w.offsetY, "parent", r3, r3 == null ? void 0 : r3.offsetY, w), positionNode(w);
    }
  })), C.edges().forEach(function(r2) {
    let w = C.edge(r2);
    log.info("Edge " + r2.v + " -> " + r2.w + ": " + JSON.stringify(w), w), w.points.forEach((r3) => r3.y += B / 2), positionEdgeLabel(w, insertEdge(I, w, clusterDb, T, C.node(r2.v), C.node(r2.w), E));
  }), C.nodes().forEach(function(r2) {
    let w = C.node(r2);
    log.info(r2, w.type, w.diff), w.isGroup && (z = w.diff);
  }), log.warn("Returning from recursive render XAX", P, z), {
    elem: P,
    diff: z
  };
}, "recursiveRender"), render = /* @__PURE__ */ __name(async (r, C) => {
  var _a, _b, _c, _d, _e, _f;
  let w = new Graph({
    multigraph: true,
    compound: true
  }).setGraph({
    rankdir: r.direction,
    nodesep: ((_a = r.config) == null ? void 0 : _a.nodeSpacing) || ((_c = (_b = r.config) == null ? void 0 : _b.flowchart) == null ? void 0 : _c.nodeSpacing) || r.nodeSpacing,
    ranksep: ((_d = r.config) == null ? void 0 : _d.rankSpacing) || ((_f = (_e = r.config) == null ? void 0 : _e.flowchart) == null ? void 0 : _f.rankSpacing) || r.rankSpacing,
    marginx: 8,
    marginy: 8
  }).setDefaultEdgeLabel(function() {
    return {};
  }), T = C.select("g");
  markers_default(T, r.markers, r.type, r.diagramId), clear2(), clear(), clear$1(), clear4(), r.nodes.forEach((r2) => {
    w.setNode(r2.id, { ...r2 }), r2.parentId && w.setParent(r2.id, r2.parentId);
  }), log.debug("Edges:", r.edges), r.edges.forEach((r2) => {
    if (r2.start === r2.end) {
      let C2 = r2.start, T2 = C2 + "---" + C2 + "---1", E = C2 + "---" + C2 + "---2", D = w.node(C2);
      w.setNode(T2, {
        domId: T2,
        id: T2,
        parentId: D.parentId,
        labelStyle: "",
        label: "",
        padding: 0,
        shape: "labelRect",
        style: "",
        width: 10,
        height: 10
      }), w.setParent(T2, D.parentId), w.setNode(E, {
        domId: E,
        id: E,
        parentId: D.parentId,
        labelStyle: "",
        padding: 0,
        shape: "labelRect",
        label: "",
        style: "",
        width: 10,
        height: 10
      }), w.setParent(E, D.parentId);
      let O2 = structuredClone(r2), k = structuredClone(r2), A = structuredClone(r2);
      O2.label = "", O2.arrowTypeEnd = "none", O2.id = C2 + "-cyclic-special-1", k.arrowTypeStart = "none", k.arrowTypeEnd = "none", k.id = C2 + "-cyclic-special-mid", A.label = "", D.isGroup && (O2.fromCluster = C2, A.toCluster = C2), A.id = C2 + "-cyclic-special-2", A.arrowTypeStart = "none", w.setEdge(C2, T2, O2, C2 + "-cyclic-special-0"), w.setEdge(T2, E, k, C2 + "-cyclic-special-1"), w.setEdge(E, C2, A, C2 + "-cyc<lic-special-2");
    } else w.setEdge(r2.start, r2.end, { ...r2 }, r2.id);
  }), log.warn("Graph at first:", JSON.stringify(write(w))), adjustClustersAndEdges(w), log.warn("Graph after XAX:", JSON.stringify(write(w)));
  let O = getConfig2();
  await recursiveRender(T, w, r.type, r.diagramId, void 0, O);
}, "render");
export {
  render
};
