import {
  spliceevent_exonskip_getdefault_default
} from "./chunk-O3JB4PIX.js";
import {
  legend_newrow
} from "./chunk-UJKW42DI.js";
import "./chunk-V2OJLJSK.js";
import "./chunk-VGYTAYFK.js";
import {
  appear2 as appear,
  axisstyle,
  disappear2 as disappear,
  font,
  newpane,
  sayerror,
  tkt
} from "./chunk-SA7APTJR.js";
import "./chunk-HJ6L54YS.js";
import "./chunk-LSEFWW72.js";
import "./chunk-SKREEF3H.js";
import {
  Menu
} from "./chunk-HYOEWQ5P.js";
import "./chunk-HBW42TDT.js";
import "./chunk-G6O3URDN.js";
import "./chunk-FN5XPUPH.js";
import "./chunk-IIT367QZ.js";
import "./chunk-RZGEKL77.js";
import "./chunk-UI7OCM2A.js";
import "./chunk-YZK37YCC.js";
import {
  dofetch2,
  dofetch3
} from "./chunk-7EMWHCVW.js";
import "./chunk-7IYJZZQI.js";
import "./chunk-M3J4MINX.js";
import "./chunk-PF4DSFDR.js";
import "./chunk-QH6W3NVF.js";
import "./chunk-NOEAT6CX.js";
import {
  IN_frame,
  bplen
} from "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import {
  collide_default,
  simulation_default,
  x_default,
  y_default
} from "./chunk-KSGA62R2.js";
import {
  axisRight
} from "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import {
  linear,
  log
} from "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import {
  select_default
} from "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import "./chunk-HFNDKYVF.js";

// src/block.mds.js
function makeLegend_cohort_hierarchy(arg) {
  for (const hierarchyname in arg.hash) {
    const tr = arg.tk.cohortFilter.holderTable.append("tr");
    tr.append("td").style("vertical-align", "top").append("div").text(hierarchyname).style("color", "#858585").style("margin-top", "7px");
    const treeholder = tr.append("td").append("div").style("display", "inline-block");
    let folderstack = [];
    const nodesofhierarchy = [];
    for (const node of arg.hash[hierarchyname]) {
      if (node.depth == 0) {
        continue;
      }
      if (node.depth == 1) {
        const [folder2, showhidebutton2] = make_one_node(arg, node, treeholder, hierarchyname);
        if (folder2) {
          folderstack = [folder2];
        }
        nodesofhierarchy.push({
          nodeid: node.id,
          showhidebutton: showhidebutton2
        });
        continue;
      }
      const itsholder = folderstack[node.depth - 2];
      const [folder, showhidebutton] = make_one_node(arg, node, itsholder, hierarchyname);
      if (folder) {
        folderstack[node.depth - 1] = folder;
      }
      nodesofhierarchy.push({
        nodeid: node.id,
        showhidebutton
      });
    }
    arg.tk.cohortFilter.hierarchies.keys[hierarchyname].allnodes = nodesofhierarchy;
  }
}
function make_one_node(arg, node, holder, hierarchyname) {
  const row = holder.append("div");
  const labeldiv = row.append("div").style("display", "inline-block").style("margin-right", "10px");
  arg.makenodelabel(node, labeldiv);
  const showhidebutton = row.append("div").style("display", "inline-block").attr("class", "sja_handle_green").text("SHOW").style("font-size", ".8em").on("mousedown", (event) => {
    event.stopPropagation();
  }).on("click", (event) => {
    event.stopPropagation();
    arg.clicknode(node, hierarchyname);
  });
  if (arg.tk.subTracks.find((i) => i.permanentHierarchy.nodeid == node.id)) {
    showhidebutton.text("HIDE").attr("class", "sja_handle_red");
  }
  let folder;
  if (node.isleaf) {
    row.style("padding", "5px 10px");
  } else {
    row.attr("class", "sja_clb").on("click", () => {
      if (folder.style("display") == "none") {
        arg.tk.cohortFilter.hierarchies.keys[hierarchyname].opennodeids.add(node.id);
        appear(folder);
        return;
      }
      disappear(folder);
      arg.tk.cohortFilter.hierarchies.keys[hierarchyname].opennodeids.delete(node.id);
    });
    folder = holder.append("div").style("display", arg.tk.cohortFilter.hierarchies.keys[hierarchyname].opennodeids.has(node.id) ? "block" : "none").style("margin-left", "20px").style("border-left", "solid 1px " + arg.block.legend.legendcolor).style("padding-left", "5px").style("background", "white");
  }
  return [folder, showhidebutton];
}
function showHideSubtrack_byHierarchyLevel(parentTk, block, hierarchy) {
  const arridx = parentTk.subTracks.findIndex((i) => i.permanentHierarchy.nodeid == hierarchy.nodeid);
  if (arridx != -1) {
    const subtkid = parentTk.subTracks[arridx].tkid;
    parentTk.subTracks.splice(arridx, 1);
    block.tk_remove(block.tklst.findIndex((i) => i.tkid == subtkid));
    parentTk.cohortFilter.hierarchies.keys[hierarchy.hierarchyname].allnodes.find((i) => i.nodeid == hierarchy.nodeid).showhidebutton.text("SHOW").attr("class", "sja_handle_green");
    return;
  }
  const tktemp = {};
  {
    const tk0 = parentTk.mds.queries[parentTk.querykey];
    for (const k in tk0) {
      tktemp[k] = tk0[k];
    }
    switch (tk0.type) {
      case tkt.mdsjunction:
        tktemp.readcountCutoff = parentTk.readcountCutoff;
        tktemp.axisheight = parentTk.axisheight;
        tktemp.legheight = parentTk.legheight;
        tktemp.yscaleUseLog = parentTk.yscaleUseLog;
        break;
    }
  }
  const subtk = block.block_addtk_template(tktemp);
  subtk.permanentHierarchy = hierarchy;
  delete subtk.subTracks;
  parentTk.subTracks.push(subtk);
  subtk.querykey = parentTk.querykey;
  subtk.mds = parentTk.mds;
  subtk.parentTk = parentTk;
  delete subtk.infoFilter;
  delete subtk.cohortFilter;
  block.tk_load(subtk);
  parentTk.cohortFilter.hierarchies.keys[hierarchy.hierarchyname].allnodes.find((i) => i.nodeid == hierarchy.nodeid).showhidebutton.text("HIDE").attr("class", "sja_handle_red");
}
function subtrackclosehandle(tk, block, y) {
  return block.maketklefthandle(tk, y || 0).text("Close").on("click", () => {
    tk.parentTk.subTracks.splice(
      tk.parentTk.subTracks.findIndex((i) => i.tkid == tk.tkid),
      1
    );
    block.tk_remove(block.tklst.findIndex((i) => i.tkid == tk.tkid));
    tk.parentTk.cohortFilter.hierarchies.keys[tk.permanentHierarchy.hierarchyname].allnodes.find((i) => i.nodeid == tk.permanentHierarchy.nodeid).showhidebutton.text("SHOW").attr("class", "sja_handle_green");
  });
}

// src/block.mds.junction.js
var minfontsize = 12;
var lineopacity = 0.5;
var discopacity = 0.5;
var invalidCategoryColor = "#8EA399";
var cohortLegendDotColor = "#858585";
var notAnnotatedLabel = "Unannotated";
var labyspace = 5;
var hardcode_infoKey_type = "type";
async function loadTk(tk, block, noViewRangeChange) {
  if (noViewRangeChange) {
    delete block.pannedpx;
    if (tk.subTracks) {
      for (const t of tk.subTracks) {
        loadTk(t, block, true);
      }
    }
  }
  block.tkcloakon(tk);
  block.block_setheight();
  if (tk.uninitialized) {
    makeTk(tk, block);
  }
  if (tk.mds.mdsIsUninitiated) {
    const d = await dofetch3(`getDataset?genome=${block.genome.name}&dsname=${tk.mds.label}`);
    if (d.error) throw d.error;
    if (!d.ds) throw "ds missing";
    Object.assign(tk.mds, d.ds);
    delete tk.mds.mdsIsUninitiated;
  }
  const par = {
    genome: block.genome.name,
    rglst: block.tkarg_maygm(tk),
    dslabel: tk.mds.label,
    querykey: tk.querykey
  };
  if (block.subpanels.length == tk.subpanels.length) {
    for (const r of block.subpanels) {
      par.rglst.push({
        chr: r.chr,
        start: r.start,
        stop: r.stop
      });
    }
  }
  addLoadParameter(par, tk);
  if (tk.uninitialized) {
    delete tk.uninitialized;
  }
  let data;
  try {
    data = await dofetch2("mdsjunction", {
      method: "POST",
      body: JSON.stringify(par)
    });
    if (data.error) throw data.error;
    if (!data.lst) ".lst[] missing";
    if (data.sample2client) tk.samples = data.sample2client;
    if (data.lst.length == 0) throw "no data";
    if (!data.maxreadcount) throw "got junctions but no maxreadcount";
    const err = rawdata2track(data.lst, tk, block);
    if (err) throw err;
    tk.maxReadCount = data.maxreadcount;
    renderTk(tk, block);
    block.tkcloakoff(tk, {});
  } catch (e) {
    tk.data = [];
    tk.leftaxis.selectAll("*").remove();
    tk.glider.selectAll("*").remove();
    block.tkcloakoff(tk, { error: tk.name + ": " + (e.message || e) });
    if (e.stack) console.log(e.stack);
  }
  if (data.junctiontotalnumber) {
    tk.junctionCountLabel.text(
      (tk.data.length == data.junctiontotalnumber ? tk.data.length : tk.data.length + " of " + data.junctiontotalnumber) + " junction" + (data.junctiontotalnumber > 1 ? "s" : "")
    );
  } else {
    tk.junctionCountLabel.text("");
  }
  if (data.samplecount) {
    tk.sampleCountLabel.text(data.samplecount + " sample" + (data.samplecount > 1 ? "s" : ""));
  } else {
    tk.sampleCountLabel.text("");
  }
  if (tk.parentTk) {
  } else {
    makeLegend_cohort(data, tk, block);
    for (const info of tk.infoFilter.lst) {
      makeLegend_infoFilter(info, tk, block);
    }
  }
  block.block_setheight();
  updateLabel(tk, block);
}
function addLoadParameter(par, tk) {
  if (tk.iscustom) {
    if (tk.uninitialized) {
      par.getsamples = 1;
    }
    par.iscustom = 1;
    par.file = tk.file;
    par.file2 = tk.file2;
    par.url = tk.url;
  }
  if (tk.readcountCutoff) {
    par.readcountCutoff = tk.readcountCutoff;
  }
  if (tk.permanentHierarchy) {
    par.permanentHierarchy = tk.permanentHierarchy;
  } else if (tk.cohortFilter && tk.cohortFilter.hiddenAttr) {
    const a = {};
    let hasfilter = false;
    for (const key in tk.cohortFilter.hiddenAttr) {
      let count = 0;
      const b = {};
      for (const value in tk.cohortFilter.hiddenAttr[key]) {
        count++;
        b[value] = 1;
      }
      if (count) {
        hasfilter = true;
        a[key] = b;
      }
    }
    if (hasfilter) {
      par.cohortHiddenAttr = a;
    }
  }
  {
    let infoFilter = (tk.parentTk || tk).infoFilter;
    const a = {};
    let hasfilter = false;
    for (const info of infoFilter.lst) {
      let count = 0;
      const b2 = {};
      for (const k in info.hiddenCategories) {
        count++;
        b2[k] = 1;
      }
      if (count) {
        hasfilter = true;
        a[info.key] = b2;
      }
    }
    if (hasfilter) {
      par.infoFilter = a;
    }
    const b = {};
    hasfilter = false;
    for (const info of infoFilter.lst) {
      for (const eventcode in info.categories) {
        const obj = info.categories[eventcode];
        if (obj.valuePerSample && obj.valuePerSample.cutoffValueUseIdx != void 0) {
          const cutoff = obj.valuePerSample.cutoffValueLst[obj.valuePerSample.cutoffValueUseIdx];
          if (cutoff) {
            hasfilter = true;
            b[eventcode] = cutoff;
          }
        }
      }
    }
    if (hasfilter) {
      par.spliceEventPercentage = b;
    }
  }
}
function updateLabel(tk, block) {
  const lst = [];
  tk.tklabel.each(function() {
    lst.push(this.getBBox().width);
  });
  if (tk.subhierarchylabel) {
    tk.subhierarchylabel.each(function() {
      lst.push(this.getBBox().width);
    });
  }
  tk.junctionCountLabel.each(function() {
    lst.push(this.getBBox().width);
  });
  tk.sampleCountLabel.each(function() {
    lst.push(this.getBBox().width);
  });
  tk.leftLabelMaxwidth = Math.max(...lst);
  block.setllabel();
}
function rawdata2track(raw, tk, block) {
  const viewpxwidth = block.width + block.subpanels.reduce((i, j) => i + j.leftpad + j.width, 0);
  const junctions = [];
  for (const j of raw) {
    if (j.sv && j.chr == j.sv.mate.chr) {
      if (j.start > j.sv.mate.start) {
        const p = j.start;
        j.start = j.stop = j.sv.mate.start;
        j.sv.mate.start = j.sv.mate.stop = p;
        const q = j.strand;
        j.strand = j.sv.mate.strand;
        j.sv.mate.strand = q;
      }
    }
    const e = j2block(j, block, viewpxwidth);
    if (e) {
      console.log(
        "junction not in view range: " + j.chr + ":" + j.start + "-" + (j.sv ? j.sv.mate.chr + ":" + j.sv.mate.start : j.stop)
      );
      continue;
    }
    junctions.push(j);
  }
  if (tk.data) {
    const map = /* @__PURE__ */ new Map();
    tk.data.forEach((j) => map.set(j.chr + "." + j.start + "." + j.stop, j));
    const pannedpx = Number.isInteger(block.pannedpx) ? block.pannedpx : 0;
    for (const i of junctions) {
      const j = map.get(i.chr + "." + i.start + "." + i.stop);
      if (j) {
        i.x = j.x + pannedpx;
        i.axisy = j.axisy;
      }
    }
  }
  if (junctions.length == 0) {
    return "no junctions in view range";
  }
  tk.data = junctions;
}
function j2block(j, block, viewpxwidth) {
  let starthit;
  let stophit;
  {
    const l = block.seekcoord(j.chr, j.start);
    for (const hit of l) {
      if (hit.ridx != void 0 && block.subpanels) {
        if (hit.x < 0 || hit.x > block.width) {
          continue;
        }
      }
      starthit = hit;
    }
  }
  {
    const l = block.seekcoord(j.sv ? j.sv.mate.chr : j.chr, j.sv ? j.sv.mate.start : j.stop);
    for (const hit of l) {
      if (hit.ridx != void 0 && block.subpanels) {
        if (hit.x < 0 || hit.x > block.width) {
          continue;
        }
      }
      stophit = hit;
    }
  }
  if (starthit) {
    if (!stophit) {
      stophit = starthit;
    }
  } else {
    if (stophit) {
      starthit = stophit;
    } else {
      return true;
    }
  }
  let startout = starthit.x < 0 || starthit.x > viewpxwidth;
  let stopout = stophit.x < 0 || stophit.x > viewpxwidth;
  if (startout && stopout) {
    return true;
  }
  j.x0 = starthit.x;
  j.x1 = stophit.x;
  j.x = (j.x0 + j.x1) / 2;
  j._x = j.x;
  return false;
}
function infoFilter_inuse(tk) {
  const a = (tk.parentTk || tk).infoFilter;
  if (a.useFilterIndex == void 0) {
    a.useFilterIndex = 0;
  }
  return a.lst[a.useFilterIndex];
}
function renderTk(tk, block) {
  const viewpxwidth = block.width + block.subpanels.reduce((i, j) => i + j.leftpad + j.width, 0);
  setColor(tk);
  tk.glider.selectAll("*").remove();
  const mg = tk.glider.append("g");
  tk.data.sort((a, b) => {
    return a._x - b._x;
  });
  const maxsamplecount = tk.data.reduce((max, j) => Math.max(max, j.sampleCount), 0);
  {
    const radius = 5;
    let mrd = 0;
    const w = Math.pow(radius, 2) * Math.PI;
    if (maxsamplecount <= 10) {
      mrd = w * maxsamplecount * 0.9;
    } else if (maxsamplecount <= 100) {
      mrd = w * 10;
    } else if (maxsamplecount <= 1e3) {
      mrd = w * 14;
    } else {
      mrd = w * 20;
    }
    const sf_discradius = linear().domain([
      1,
      maxsamplecount * 0.5 + 0.1,
      maxsamplecount * 0.6 + 0.1,
      maxsamplecount * 0.7 + 0.1,
      maxsamplecount * 0.8 + 0.1,
      maxsamplecount
    ]).range([w, w + (mrd - w) * 0.8, w + (mrd - w) * 0.85, w + (mrd - w) * 0.9, w + (mrd - w) * 0.95, mrd]);
    let maxradius = 0;
    for (const j of tk.data) {
      j.radius = Math.sqrt(sf_discradius(j.sampleCount) / Math.PI);
      if (j.sampleCount > 1) {
        mg.append("text").attr("font-family", font).attr("font-size", Math.max(minfontsize, j.radius)).text(j.sampleCount).each(function() {
          const b = this.getBBox();
          const newrad = Math.sqrt(Math.pow(b.width, 2) + Math.pow(b.height, 2)) / 2;
          j.radius = Math.max(j.radius, newrad);
        }).remove();
      }
      j.rimwidth = j.rimcount ? Math.max(2, j.radius / 6) : 0;
      j.radius2 = j.radius + j.rimwidth + (j.rimwidth > 0 ? 1 : 0);
      maxradius = Math.max(maxradius, j.radius2);
    }
    tk.maxradius = maxradius;
  }
  const maxmedian = tk.data.reduce((c, j) => Math.max(c, j.medianReadCount), 0);
  tk.yscale = (tk.yscaleUseLog ? log() : linear()).domain([tk.readcountCutoff || 1, tk.maxReadCount]).range([tk.axisheight, 0]);
  for (const j of tk.data) {
    if (j.axisy == void 0) {
      j.axisy = tk.axisheight - tk.yscale(j.medianReadCount);
    }
  }
  tk.height_main = tk.toppad + tk.axisheight + tk.neckheight + tk.legheight + tk.bottompad;
  tk.eventsg = tk.glider.append("g").attr("transform", "translate(0," + (tk.height_main - tk.toppad) + ")");
  mg.attr("transform", "translate(0," + (tk.height_main - tk.toppad - tk.bottompad) + ")");
  {
    const topy = -tk.legheight - tk.neckheight - tk.axisheight;
    mg.append("line").attr("x1", 0).attr("y1", topy).attr("y2", topy).attr("x2", viewpxwidth).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("shape-rendering", "crispEdges");
    mg.append("line").attr("x1", 0).attr("y1", topy + tk.axisheight).attr("y2", topy + tk.axisheight).attr("x2", viewpxwidth).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("shape-rendering", "crispEdges");
    let v = 10;
    while (v <= tk.maxReadCount) {
      mg.append("line").attr("x1", 0).attr("y1", topy + tk.yscale(v)).attr("y2", topy + tk.yscale(v)).attr("x2", viewpxwidth).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("stroke-dasharray", "4,4").attr("shape-rendering", "crispEdges");
      v *= 10;
    }
  }
  const jug = mg.selectAll().data(tk.data).enter().append("g").attr("transform", (d) => set_jug(d)).each(function(j) {
    j.jugg = this;
  });
  tk.jug = jug;
  if (tk.hljunctions) {
    jug.attr("class", (d) => {
      for (const j of tk.hljunctions) {
        if (d.chr == j.chr && d.start == j.start && d.stop == j.stop) {
          return "sja_pulse";
        }
      }
      return null;
    });
  }
  jug.append("line").attr("stroke", (d) => d.color).attr("x1", (d) => set_leg_x1(d)).attr("y2", -tk.legheight).attr("stroke-opacity", lineopacity).attr("class", "sja_jug_leg1").each(function(d) {
    d.leg1 = this;
  });
  jug.append("line").attr("stroke", (d) => d.color).attr("x2", (d) => set_leg_x2(d)).attr("y1", -tk.legheight).attr("stroke-opacity", lineopacity).attr("class", "sja_jug_leg2").each(function(d) {
    d.leg2 = this;
  });
  const jug2 = jug.append("g").attr("class", "sja_jug_jug2").attr("transform", (d) => set_jug2(d, tk));
  jug2.append("line").attr("stroke", (d) => d.color).attr("class", "sja_jug_stem").attr("stroke-dasharray", "2,2").attr("shape-rendering", "crispEdges").attr("y1", (d) => d.radius).attr("y2", (d) => {
    return tk.neckheight + d.axisy;
  }).attr("stroke-opacity", lineopacity).each(function(d) {
    d.stem = this;
  });
  jug2.append("circle").each(function(d) {
    d.disc = this;
  }).attr("r", (d) => d.radius).attr("fill", (d) => d.color).attr("stroke", "white").attr("fill-opacity", discopacity);
  jug2.filter((d) => d.sampleCount > 1).append("text").text((d) => d.sampleCount).attr("font-size", (d) => Math.max(minfontsize, d.radius)).attr("class", "sja_jug_discnum").attr("fill", "white").attr("font-family", font).attr("text-anchor", "middle").attr("dominant-baseline", "central");
  jug2.append("circle").attr("r", (d) => d.radius).attr("stroke", (d) => d.color).attr("fill", "white").attr("fill-opacity", 0).attr("stroke-opacity", 0).on("mouseover", (event, d) => {
    event.stopPropagation();
    select_default(d.disc).attr("fill-opacity", 0.8);
    select_default(d.stem).attr("stroke-opacity", 1);
    select_default(d.leg1).attr("stroke-opacity", 1);
    select_default(d.leg2).attr("stroke-opacity", 1);
    mouseoverSpanBackground(d, tk, block, viewpxwidth);
    mouseoverBoxplot(d, tk);
    const p = event.target.getBoundingClientRect();
    tk.tktip.clear().show(p.left + p.width, p.top - 50);
    showOneJunction(d, tk, tk.tktip.d, block);
  }).on("mouseout", (event, d) => {
    tk.tktip.hide();
    tk.pica.g.selectAll("*").remove();
    block.cursorhlbar.attr("fill", block.cursorhlbarFillColor);
    select_default(d.disc).attr("fill-opacity", discopacity);
    select_default(d.stem).attr("stroke-opacity", lineopacity);
    select_default(d.leg1).attr("stroke-opacity", lineopacity);
    select_default(d.leg2).attr("stroke-opacity", lineopacity);
  }).on("mousedown", (event) => {
    event.stopPropagation();
  }).on("mousemove", (event) => {
    event.stopPropagation();
  }).on("click", (event, j) => {
    tk.tktip.hide();
    const pane = newpane({ x: event.clientX, y: event.clientY });
    if (!tk.iscustom) {
      pane.header.append("span").style("color", "#858585").style("font-size", ".8em").text(tk.mds.queries[tk.querykey].name);
    }
    pane.header.append("text").text(j.chr + ":" + j.start + "-" + j.stop);
    const div1 = pane.body.append("div").style("margin-top", "15px");
    showOneJunction(j, tk, div1, block, true);
    const div2 = pane.body.append("div");
    queryOneJunction(j, tk, block, div2);
  });
  doForceLayout(tk, block, viewpxwidth).then(() => {
    set_all(tk);
    axisstyle({
      axis: tk.leftaxis.transition().call(
        axisRight().scale(tk.yscale).ticks(Math.floor(tk.axisheight / 20), ".0f")
      ),
      color: "black",
      showline: true
    });
  });
}
function setColor(tk) {
  const info = infoFilter_inuse(tk);
  let datastructureerror = 0;
  let invalidinfovalue = 0;
  for (const j of tk.data) {
    delete j.color;
    if (!j.info) {
      datastructureerror++;
      continue;
    }
    const infovalue = j.info[info.key];
    if (!infovalue) {
      continue;
    }
    if (!infovalue.lst) {
      datastructureerror++;
      continue;
    }
    const value2count = /* @__PURE__ */ new Map();
    for (const i of infovalue.lst) {
      const v = i.attrValue;
      if (v == void 0) {
        datastructureerror++;
        continue;
      }
      if (!info.categories[v]) {
        invalidinfovalue++;
        continue;
      }
      if (!value2count.has(v)) {
        value2count.set(v, 0);
      }
      value2count.set(v, value2count.get(v));
    }
    if (value2count.size) {
      const k = [...value2count].sort((a, b) => b[1] - a[1])[0][0];
      j.color = info.categories[k].color;
    }
  }
  for (const j of tk.data) {
    if (!j.color) {
      j.color = invalidCategoryColor;
    }
  }
  const err = [];
  if (datastructureerror) err.push("data structure error in " + datastructureerror + " junctions");
  if (invalidinfovalue) err.push("invalid annotation value used in " + invalidinfovalue + " junctions");
  if (err.length) {
    console.log(err.join("\n"));
  }
}
function set_jug(d) {
  return "translate(" + d.x + ",0)";
}
function set_leg_x1(d) {
  return d.x0 - d.x;
}
function set_leg_x2(d) {
  return d.x1 - d.x;
}
function set_jug2(d, tk) {
  return "translate(0,-" + (tk.legheight + tk.neckheight + d.axisy) + ")";
}
function set_all(tk) {
  tk.data.forEach((j) => j.axisy = tk.axisheight - tk.yscale(j.medianReadCount));
  const dur = 500;
  tk.jug.selectAll(".sja_jug_leg1").transition().duration(dur).attr("y2", -tk.legheight).attr("x1", (d) => set_leg_x1(d));
  tk.jug.selectAll(".sja_jug_leg2").transition().duration(dur).attr("y1", -tk.legheight).attr("x2", (d) => set_leg_x2(d));
  tk.jug.selectAll(".sja_jug_jug2").transition().duration(dur).attr("transform", (d) => set_jug2(d, tk));
  tk.jug.transition().duration(dur).attr("transform", (d) => set_jug(d));
  tk.jug.selectAll(".sja_jug_stem").transition().duration(dur).attr("y2", (d) => tk.neckheight + d.axisy);
}
function doForceLayout(tk, block, viewpxwidth) {
  const nodes = [];
  let sumdiscwidth = 0;
  tk.data.map((j) => {
    let tox;
    if (j.x0 < 0) {
      tox = j.x1 - j.radius2 * 2;
    } else if (j.x1 > viewpxwidth) {
      tox = j.x0 + j.radius2 * 2;
    } else {
      tox = j._x;
    }
    nodes.push({
      junction: j,
      tox,
      x: tox,
      y: tk.axisheight - tk.yscale(j.medianReadCount)
    });
    sumdiscwidth += j.radius2 * 2;
  });
  nodes.sort((i, j) => i.tox - j.tox);
  nodes.forEach((n, i) => n.index = i);
  const collidestrength = sumdiscwidth <= viewpxwidth ? 1 : viewpxwidth / sumdiscwidth;
  return new Promise((resolve, reject) => {
    simulation_default(nodes).force(
      "y",
      y_default((d) => {
        return tk.axisheight - tk.yscale(d.junction.medianReadCount);
      }).strength(1)
    ).force("x", x_default((d) => d.tox).strength(0.1)).force(
      "collide",
      collide_default((d) => {
        return d.junction.radius2 + 2;
      }).strength(collidestrength)
    ).alphaMin(0.5).on("end", () => {
      nodes.forEach((n) => {
        n.junction.x = n.x;
      });
      resolve();
    });
  });
}
function mouseoverSpanBackground(j, tk, block, viewpxwidth) {
  let xleft = Math.min(j.x0, j.x1);
  let xright = Math.max(j.x0, j.x1);
  if (block.usegm && block.usegm.strand == "-") {
    xleft = j.x1;
    xright = j.x0;
  }
  if (xleft >= 0 && xright <= viewpxwidth) {
    block.cursorhlbar.attr("x", block.leftheadw + block.lpad + xleft).attr("y", 0).attr("width", xright - xleft).attr("height", block.totalheight()).attr("fill", "url(#" + tk.gradient4spanBackground.mid.id + ")");
    return;
  }
  const boxwidth = 50;
  if (xleft >= 0) {
    block.cursorhlbar.attr("x", block.leftheadw + block.lpad + xleft).attr("fill", "url(#" + tk.gradient4spanBackground.left.id + ")");
  } else {
    block.cursorhlbar.attr("x", block.leftheadw + block.lpad + xright - boxwidth).attr("fill", "url(#" + tk.gradient4spanBackground.right.id + ")");
  }
  block.cursorhlbar.attr("y", 0).attr("width", boxwidth).attr("height", block.totalheight());
}
function mouseoverBoxplot(j, tk) {
  if (!j.readcountBoxplot) return;
  const color = "black";
  const p5 = tk.yscale(j.readcountBoxplot.percentile[0]);
  const p25 = tk.yscale(j.readcountBoxplot.percentile[1]);
  const p50 = tk.yscale(j.readcountBoxplot.percentile[2]);
  const p75 = tk.yscale(j.readcountBoxplot.percentile[3]);
  const p95 = tk.yscale(j.readcountBoxplot.percentile[4]);
  const w = 10;
  tk.pica.g.selectAll("*").remove();
  tk.pica.g.attr("transform", "translate(" + j.x + "," + p50 + ")");
  const g = tk.pica.g.append("g").attr("transform", "translate(" + (-5 - w - j.radius2) + ",0)");
  g.append("line").attr("x1", w / 2).attr("x2", w / 2).attr("y1", p95 - p50).attr("y2", p5 - p50).attr("stroke", color).attr("shape-rendering", "crispEdges");
  g.append("line").attr("x1", 0).attr("x2", w).attr("y1", p5 - p50).attr("y2", p5 - p50).attr("stroke", color).attr("shape-rendering", "crispEdges");
  g.append("line").attr("x1", 0).attr("x2", w).attr("y1", p95 - p50).attr("y2", p95 - p50).attr("stroke", color).attr("shape-rendering", "crispEdges");
  g.append("rect").attr("y", p75 - p50).attr("width", w).attr("height", p25 - p75).attr("stroke", color).attr("fill", "white").attr("shape-rendering", "crispEdges");
  if (p25 - p75 > 3) {
    g.append("line").attr("x2", w).attr("stroke", color).attr("shape-rendering", "crispEdges");
  }
}
function makeLegend_cohort(result, tk, block) {
  tk.cohortFilter.holderTable.selectAll("*").remove();
  if (result.attributeSummary) {
    makeLegend_cohort_attribute(result.attributeSummary, tk, block);
  }
  if (result.hierarchySummary) {
    if (!tk.cohortFilter.hierarchies) {
      tk.cohortFilter.hierarchies = {
        keys: {}
        // to enable other attributes about hierarchies
      };
      for (const k in result.hierarchySummary) {
        tk.cohortFilter.hierarchies.keys[k] = {
          // allnodes[] will be added here, for collecting all nodes from view range, so existance of subtracks can be shown by different node style in parent tk
          // refresh each time parent track loads
          // in parent tk, nodes that are currently unfolded
          opennodeids: /* @__PURE__ */ new Set()
        };
      }
    }
    makeLegend_cohort_hierarchy({
      hash: result.hierarchySummary,
      tk,
      block,
      makenodelabel: (node, row) => {
        row.append("span").style("margin-right", "5px").attr("class", "sja_mcdot").style("background", "#858585").style("padding", "1px 6px").text(node.count);
        const color = node.isleaf ? "#858585" : "inherit";
        row.append("span").style("margin-right", "5px").style("color", color).text(node.label || node.name);
        if (node.totalCount) {
          row.append("span").style("font-size", ".7em").style("color", color).text(Math.ceil(100 * node.count / node.totalCount) + "%");
        }
      },
      clicknode: (node, hierarchyname) => {
        showHideSubtrack_byHierarchyLevel(tk, block, {
          hierarchyname,
          levelidx: node.depth - 1,
          valuekey: node.name,
          valuelabel: node.label,
          nodeid: node.id
        });
      }
    });
  }
}
function makeLegend_cohort_attribute(lst, tk, block) {
  for (const attr of lst) {
    const tr = tk.cohortFilter.holderTable.append("tr").style("border-spacing", "5px").style("border-collapse", "separate");
    tr.append("td").text(attr.label).style("color", "#858585");
    const td = tr.append("td");
    for (const item of attr.values) {
      const div = td.append("div").style("display", "inline-block").style("padding", "10px").attr("class", "sja_clb").on("click", () => {
        showMenu_cohortFilter(tk, block, attr, item, div);
      });
      if (item.label) {
        div.property("title", item.label);
      }
      div.append("div").style("display", "inline-block").style("padding", "0px 5px").style("margin-right", "5px").attr("class", "sja_mcdot").style("background", cohortLegendDotColor).html(item.count > 1 ? item.count : "&nbsp;");
      div.append("div").style("display", "inline-block").text(item.name);
      if (item.totalCount) {
        div.append("div").style("display", "inline-block").style("font-size", ".7em").style("color", "#858585").html("&nbsp;" + Math.ceil(100 * item.count / item.totalCount) + "%");
      }
    }
    if (tk.cohortFilter.hiddenAttr[attr.key]) {
      for (const value in tk.cohortFilter.hiddenAttr[attr.key]) {
        const div = td.append("div").style("display", "inline-block").style("padding", "8px").style("color", "#858585").attr("class", "sja_clb").style("text-decoration", "line-through").text(value).on("click", () => {
          showMenu_cohortFilter(tk, block, attr, { name: value }, div);
        });
      }
    }
  }
  for (const key in tk.cohortFilter.hiddenAttr) {
    if (lst.findIndex((i) => i.key == key) != -1) {
      continue;
    }
    const tr = tk.cohortFilter.holderTable.append("tr").style("border-spacing", "5px").style("border-collapse", "separate");
    tr.append("td").text(key).style("color", "#858585");
    const td = tr.append("td");
    for (const value in tk.cohortFilter.hiddenAttr[key]) {
      const div = td.append("div").style("display", "inline-block").style("padding", "8px").style("color", "#858585").attr("class", "sja_clb").style("text-decoration", "line-through").text(value).on("click", () => {
        showMenu_cohortFilter(tk, block, { key }, { name: value }, div);
      });
    }
  }
}
function showMenu_cohortFilter(tk, block, attr, item, div) {
  const tip = tk.legendMenu;
  tip.clear().showunder(div.node());
  if (item.count) {
    tip.d.append("div").html(
      item.totalCount ? '<span style="font-size:1.5em">' + item.count + "</span> / " + item.totalCount + " sample" + (item.count > 1 ? "s" : "") : item.count + " sample" + (item.count > 1 ? "s" : "")
    ).style("margin", "10px").style("font-size", ".8em").style("color", "#858585");
  }
  if (item.label) {
    tip.d.append("div").text(item.label).style("margin", "10px").style("font-size", ".8em").style("color", "#858585");
  }
  if (tk.cohortFilter.hiddenAttr[attr.key] && tk.cohortFilter.hiddenAttr[attr.key][item.name]) {
    tip.d.append("div").attr("class", "sja_menuoption").text("Show").on("click", () => {
      tip.hide();
      div.text("Loading ...");
      delete tk.cohortFilter.hiddenAttr[attr.key][item.name];
      loadTk(tk, block, true);
    });
  } else {
    tip.d.append("div").attr("class", "sja_menuoption").text("Hide").on("click", () => {
      tip.hide();
      div.text("Loading ...");
      if (!tk.cohortFilter.hiddenAttr[attr.key]) {
        tk.cohortFilter.hiddenAttr[attr.key] = {};
      }
      tk.cohortFilter.hiddenAttr[attr.key][item.name] = 1;
      loadTk(tk, block, true);
    });
  }
  tip.d.append("div").attr("class", "sja_menuoption").text("Show only").on("click", () => {
    tip.hide();
    div.text("Loading ...");
    if (!tk.cohortFilter.hiddenAttr[attr.key]) {
      tk.cohortFilter.hiddenAttr[attr.key] = {};
    }
    for (const v of attr.values) {
      tk.cohortFilter.hiddenAttr[attr.key][v.name] = 1;
    }
    delete tk.cohortFilter.hiddenAttr[attr.key][item.name];
    loadTk(tk, block, true);
  });
  if (tk.cohortFilter.hiddenAttr[attr.key]) {
    let count = 0;
    for (const k in tk.cohortFilter.hiddenAttr[attr.key]) {
      count++;
    }
    if (count) {
      tip.d.append("div").attr("class", "sja_menuoption").text("Show all").on("click", () => {
        tip.hide();
        div.text("Loading ...");
        delete tk.cohortFilter.hiddenAttr[attr.key];
        loadTk(tk, block, true);
      });
    }
  }
}
function makeLegend_infoFilter(info, tk, block) {
  info.holder.selectAll("*").remove();
  info.value2junctioncount = /* @__PURE__ */ new Map();
  info.value2junctioncount.set(notAnnotatedLabel, 0);
  let err_missinginfo = 0;
  for (const j of tk.data) {
    if (!j.info) {
      err_missinginfo++;
      continue;
    }
    const infovalue = j.info[info.key];
    if (!infovalue || !infovalue.lst) {
      info.value2junctioncount.set(notAnnotatedLabel, info.value2junctioncount.get(notAnnotatedLabel) + 1);
      continue;
    }
    const valueset = /* @__PURE__ */ new Set();
    for (const i of infovalue.lst) {
      const v = i.attrValue;
      if (v == void 0) {
        continue;
      }
      if (!info.categories[v]) {
        continue;
      }
      valueset.add(v);
    }
    if (valueset.size == 0) {
      info.value2junctioncount.set(notAnnotatedLabel, info.value2junctioncount.get(notAnnotatedLabel) + 1);
    } else {
      for (const v of valueset) {
        if (!info.value2junctioncount.has(v)) {
          info.value2junctioncount.set(v, 0);
        }
        info.value2junctioncount.set(v, info.value2junctioncount.get(v) + 1);
      }
    }
  }
  if (err_missinginfo) {
    console.error(".info missing in " + err_missinginfo + " junctions");
  }
  if (info.value2junctioncount.get(notAnnotatedLabel) == 0) {
    info.value2junctioncount.delete(notAnnotatedLabel);
  }
  const lst = [...info.value2junctioncount];
  lst.sort((i, j) => j[1] - i[1]);
  for (const [value, count] of lst) {
    const category = value == notAnnotatedLabel ? { label: value, color: invalidCategoryColor } : info.categories[value];
    const cell = info.holder.append("div").style("display", "inline-block").style("padding", "10px").attr("class", "sja_clb").on("click", () => {
      tk.legendMenu.showunder(cell.node());
      showMenu_infoFilter(info, value, tk, block);
    });
    cell.append("div").style("display", "inline-block").attr("class", "sja_mcdot").style("padding", "1px 5px").style("background-color", category.color).style("color", "white").html(count > 1 ? count : "&nbsp;").style("margin-right", "5px");
    const lab = cell.append("span").style("color", category.color);
    if (category.valuePerSample && category.valuePerSample.cutoffValueUseIdx != void 0) {
      const cutoff = category.valuePerSample.cutoffValueLst[category.valuePerSample.cutoffValueUseIdx];
      if (cutoff) {
        lab.text(category.label + ", " + cutoff.label);
      } else {
        lab.text(category.label + " (invalid cutoff index)");
      }
    } else {
      lab.text(category.label);
    }
  }
  for (const value in info.hiddenCategories) {
    const div = info.holder.append("div").style("display", "inline-block").style("padding", "8px").style("color", "#858585").attr("class", "sja_clb").style("text-decoration", "line-through").text(info.categories[value].label).on("click", () => {
      tk.legendMenu.showunder(div.node());
      showMenu_infoFilter(info, value, tk, block);
    });
  }
  for (const value in info.categories) {
    if (info.value2junctioncount.has(value) || info.hiddenCategories[value]) {
      continue;
    }
    const category = info.categories[value];
    const div = info.holder.append("div").style("display", "inline-block").style("padding", "8px").style("color", category.color).attr("class", "sja_clb").on("click", () => {
      tk.legendMenu.showunder(div.node());
      showMenu_infoFilter(info, value, tk, block);
    });
    if (category.valuePerSample && category.valuePerSample.cutoffValueUseIdx != void 0) {
      const cutoff = category.valuePerSample.cutoffValueLst[category.valuePerSample.cutoffValueUseIdx];
      if (cutoff) {
        div.text(category.label + ", " + cutoff.label);
      } else {
        div.text(category.label + " (invalid cutoff index)");
      }
    } else {
      div.text(category.label);
    }
  }
}
function showMenu_infoFilter(info, value, tk, block) {
  const tip = tk.legendMenu;
  tip.clear();
  const jcount4thisvalue = info.value2junctioncount.get(value);
  tip.d.append("div").text(jcount4thisvalue ? jcount4thisvalue + " junction" + (jcount4thisvalue > 1 ? "s" : "") : "no junction").style("font-size", ".8em").style("color", "#858585").style("margin", "10px");
  const thisvalueishidden = info.hiddenCategories[value];
  const category = info.categories[value];
  if (category) {
    if (category.description) {
      tip.d.append("div").style("padding", "10px").html(info.categories[value].description);
    }
    if (!thisvalueishidden && category.valuePerSample) {
      const row = tip.d.append("div").style("margin", "2px 10px 2px 10px");
      for (const [i, cutoff] of category.valuePerSample.cutoffValueLst.entries()) {
        const button = row.append("div").style("display", "inline-block").style("padding", "10px").text(cutoff.label);
        if (i == category.valuePerSample.cutoffValueUseIdx) {
          button.attr("class", "sja_clb_selected");
        } else {
          button.attr("class", "sja_clb");
        }
        button.on("click", () => {
          tip.hide();
          if (i == category.valuePerSample.cutoffValueUseIdx) {
            delete category.valuePerSample.cutoffValueUseIdx;
          } else {
            category.valuePerSample.cutoffValueUseIdx = i;
          }
          loadTk(tk, block, true);
        });
      }
      tip.d.append("div").text("Drop junctions with event percetage lower than selected cutoff.").style("margin", "2px 10px 10px 10px").style("font-size", ".7em").style("color", "#858585");
    }
  }
  if (thisvalueishidden) {
    tip.d.append("div").attr("class", "sja_menuoption").html("Show").on("click", () => {
      tip.hide();
      delete info.hiddenCategories[value];
      loadTk(tk, block, true);
    });
  } else {
    tip.d.append("div").attr("class", "sja_menuoption").html("Hide").on("click", () => {
      tip.hide();
      info.hiddenCategories[value] = 1;
      loadTk(tk, block, true);
    });
  }
  tip.d.append("div").attr("class", "sja_menuoption").html("Show only").on("click", () => {
    tip.hide();
    info.hiddenCategories = {};
    for (const k in info.categories) {
      if (k != value) {
        info.hiddenCategories[k] = 1;
      }
    }
    if (value != notAnnotatedLabel) {
      info.hiddenCategories[notAnnotatedLabel] = 1;
    }
    loadTk(tk, block, true);
  });
  let hidenum = 0;
  for (const k in info.hiddenCategories) {
    hidenum++;
  }
  if (hidenum) {
    tip.d.append("div").attr("class", "sja_menuoption").html("Show all").on("click", () => {
      tip.hide();
      info.hiddenCategories = {};
      loadTk(tk, block, true);
    });
  }
}
function makeTk(tk, block) {
  if (tk.dslabel) {
    if (block.genome.datasets[tk.dslabel]) {
      tk.mds = block.genome.datasets[tk.dslabel];
      delete tk.iscustom;
    }
  }
  {
    const pale = "#FFFEAB";
    const dark = "#F7F69E";
    const id1 = Math.random().toString();
    const id2 = Math.random().toString();
    const id3 = Math.random().toString();
    const defs = tk.gleft.append("defs");
    const left = defs.append("linearGradient").attr("id", id1);
    left.append("stop").attr("offset", 0).attr("stop-color", dark);
    left.append("stop").attr("offset", 1).attr("stop-color", "white");
    const mid = defs.append("linearGradient").attr("id", id2);
    mid.append("stop").attr("offset", 0).attr("stop-color", pale);
    mid.append("stop").attr("offset", 0.5).attr("stop-color", "white");
    mid.append("stop").attr("offset", 1).attr("stop-color", pale);
    const right = defs.append("linearGradient").attr("id", id3);
    right.append("stop").attr("offset", 0).attr("stop-color", "white");
    right.append("stop").attr("offset", 1).attr("stop-color", dark);
    tk.gradient4spanBackground = {
      left: { id: id1, gradient: left },
      mid: { id: id2, gradient: mid },
      right: { id: id3, gradient: right }
    };
  }
  let laby = labyspace + block.labelfontsize;
  if (tk.permanentHierarchy) {
    tk.subhierarchylabel = block.maketklefthandle(tk, laby).text(tk.permanentHierarchy.hierarchyname + ": " + tk.permanentHierarchy.valuelabel).attr("class", null).attr("fill", "#858585");
    laby += labyspace + block.labelfontsize;
  }
  {
    const tip = new Menu({ padding: "none" });
    tk.junctionCountLabel = block.maketklefthandle(tk, laby).on("click", () => {
    });
  }
  laby += labyspace + block.labelfontsize;
  {
    const tip = new Menu({ padding: "none" });
    tk.sampleCountLabel = block.maketklefthandle(tk, laby).on("click", () => {
    });
  }
  laby += labyspace + block.labelfontsize;
  if (tk.permanentHierarchy) {
    subtrackclosehandle(tk, block, laby);
  }
  tk.config_handle = block.maketkconfighandle(tk).on("click", () => {
    configPanel(tk, block);
  });
  if (tk.parentTk) {
  } else {
    tk.legendMenu = new Menu({ padding: "0px" });
    const [tr, td] = legend_newrow(block, tk.name);
    tk.tr_legend = tr;
    tk.td_legend = td;
    tk.infoFilter.holderTable = tk.td_legend.append("table");
    tk.infoFilter.useFilterIndex = 0;
    for (const [i, info] of tk.infoFilter.lst.entries()) {
      const tr2 = tk.infoFilter.holderTable.append("tr");
      info.labelButton = tr2.append("td").text(info.label).attr("class", i == tk.infoFilter.useFilterIndex ? "sja_clb_selected" : "sja_clb").on("click", () => {
        if (tk.infoFilter.useFilterIndex == i) {
          return;
        }
        tk.infoFilter.useFilterIndex = i;
        tk.infoFilter.lst.forEach((j) => j.labelButton.attr("class", "sja_clb"));
        info.labelButton.attr("class", "sja_clb_selected");
        renderTk(tk, block);
      });
      info.holder = tr2.append("td");
    }
    tk.cohortFilter = {
      holderTable: tk.td_legend.append("table"),
      hiddenAttr: {}
    };
    if (tk.mds.cohortHiddenAttr) {
      for (const k in tk.mds.cohortHiddenAttr) {
        tk.cohortFilter.hiddenAttr[k] = {};
        for (const v in tk.mds.cohortHiddenAttr[k]) {
          tk.cohortFilter.hiddenAttr[k][v] = 1;
        }
      }
    }
  }
}
function configPanel(tk, block) {
  tk.tkconfigtip.clear().showunder(tk.config_handle.node());
  const holder = tk.tkconfigtip.d;
  {
    const row = holder.append("div").style("margin-bottom", "15px");
    row.append("span").html("Read count cutoff&nbsp;");
    row.append("input").property("value", tk.readcountCutoff || 0).attr("type", "number").style("width", "50px").on("keyup", (event) => {
      if (event.code != "Enter" && event.code != "NumpadEnter") return;
      let v = event.target.value;
      if (!v || v < 0) {
        v = 0;
      }
      if (v == 0) {
        if (tk.readcountCutoff) {
          tk.readcountCutoff = 0;
          loadTk(tk, block, true);
        } else {
        }
        return;
      }
      if (tk.readcountCutoff) {
        if (tk.readcountCutoff == v) {
        } else {
          tk.readcountCutoff = v;
          loadTk(tk, block, true);
        }
      } else {
        tk.readcountCutoff = v;
        loadTk(tk, block, true);
      }
    });
    row.append("div").style("font-size", ".7em").style("color", "#858585").text("For a junction, samples with read count lower than cutoff will not be shown.");
  }
  {
    const row = holder.append("div").style("margin-bottom", "15px");
    row.append("span").text("Track height");
    row.append("button").html("&nbsp;&nbsp;+&nbsp;&nbsp;").style("margin-left", "10px").on("click", () => {
      tk.axisheight += 30;
      tk.legheight = tk.axisheight / 4;
      renderTk(tk, block);
      block.block_setheight();
    });
    row.append("button").html("&nbsp;&nbsp;-&nbsp;&nbsp;").style("margin-left", "5px").on("click", () => {
      if (tk.axisheight <= 90) return;
      tk.axisheight -= 30;
      tk.legheight = tk.axisheight / 4;
      renderTk(tk, block);
      block.block_setheight();
    });
  }
  {
    const row = holder.append("div").style("margin-bottom", "1px");
    const id = Math.random();
    const input = row.append("input").attr("type", "checkbox").style("margin-right", "10px").attr("id", id).on("change", () => {
      tk.yscaleUseLog = !tk.yscaleUseLog;
      renderTk(tk, block);
    });
    if (tk.yscaleUseLog) {
      input.property("checked", 1);
    }
    row.append("label").text("Use log10 for Y scale read count").attr("for", id);
  }
}
function showOneJunction(j, tk, holder, block, ifeventdetails) {
  const row1 = holder.append("div").style("margin-bottom", "5px").style("white-space", "nowrap");
  {
    const info = infoFilter_inuse(tk);
    const valueobj = j.info[info.key];
    if (valueobj) {
      const values = /* @__PURE__ */ new Set();
      valueobj.lst.forEach((i) => values.add(i.attrValue));
      for (const value of values) {
        const anno = info.categories[value];
        row1.append("span").attr("class", "sja_mcdot").style("padding", "1px 5px").style("background-color", anno ? anno.color : invalidCategoryColor).style("margin-right", "5px").text(anno ? anno.label : value);
      }
    }
  }
  {
    const d = row1.append("div").style("display", "inline-block").style("margin-right", "10px");
    if (!j.sv || j.chr == j.sv.mate.chr) {
      d.html(
        bplen(Math.abs(j.start - (j.sv ? j.sv.mate.start : j.stop))) + ' <span style="font-size:.8em;">' + j.chr + ":" + (j.start + 1) + "-" + ((j.sv ? j.sv.mate.start : j.stop) + 1) + "</span>"
      );
    } else {
      d.html(
        '<span style="font-size:.8em;">' + j.chr + ":" + (j.start + 1) + "-" + j.sv.mate.chr + ":" + (j.sv.mate.start + 1) + "</span>"
      );
    }
  }
  const row2 = holder.append("div").style("white-space", "nowrap");
  if (j.sampleCount == 1) {
    row2.append("div").html(j.medianReadCount + ' <span style="font-size:.8em;color:#858585">read count, single sample</span>');
  } else {
    row2.append("div").style("display", "inline-block").style("margin-right", "10px").html(j.medianReadCount + ' <span style="font-size:.8em;color:#858585">median read count</span>');
    row2.append("div").style("display", "inline-block").style("margin-right", "10px").html(j.sampleCount + ' <span style="font-size:.8em;color:#858585">samples</span>');
  }
  const events_exonskipalt = [];
  const events_a53ss = [];
  if (j.info && j.info[hardcode_infoKey_type]) {
    for (const e of j.info[hardcode_infoKey_type].lst) {
      if (e.isskipexon || e.isaltexon) {
        events_exonskipalt.push(e);
      } else if (e.a5ss || e.a3ss) {
        events_a53ss.push(e);
      }
    }
  }
  const div = holder.append("div");
  if (events_exonskipalt.length + events_a53ss.length > 0) {
    if (ifeventdetails) {
      if (events_exonskipalt.length) {
        listAllEvents(events_exonskipalt, div, j, tk, block);
      }
      if (events_a53ss.length) {
        listAllEvents(events_a53ss, div, j, tk, block);
      }
      return;
    }
    if (events_exonskipalt.length) {
      const showidx = spliceevent_exonskip_getdefault_default(events_exonskipalt);
      const e = events_exonskipalt[showidx];
      showEventdiagram_skipalt_fetchreadcount(j, e, tk, div, block);
    }
    if (events_a53ss.length) {
      const e = events_a53ss[0];
      showEventdiagram_a53ss(j, e, tk, div, block);
    }
  } else {
    showJunctionDiagram(j, tk, div);
  }
}
function showJunctionDiagram(j, tk, holder) {
  if (!j.ongene) {
    return;
  }
  const leftgenes = /* @__PURE__ */ new Map();
  if (j.ongene.exonleft) j.ongene.exonleft.forEach((i) => leftgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  if (j.ongene.exonleftin)
    j.ongene.exonleftin.forEach((i) => leftgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  if (j.ongene.intronleft)
    j.ongene.intronleft.forEach((i) => leftgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  const rightgenes = /* @__PURE__ */ new Map();
  if (j.ongene.exonright) j.ongene.exonright.forEach((i) => rightgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  if (j.ongene.exonrightin)
    j.ongene.exonrightin.forEach((i) => rightgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  if (j.ongene.intronright)
    j.ongene.intronright.forEach((i) => rightgenes.set(i.isoform, { gene: i.gene, strand: i.strand }));
  let isoform;
  let strand;
  if (leftgenes.size) {
    if (rightgenes.size) {
      for (const [n, a] of leftgenes) {
        if (rightgenes.has(n)) {
          isoform = n;
          strand = a.strand;
          break;
        }
      }
    } else {
      const a = [...leftgenes][0];
      isoform = a[0];
      strand = a[1].strand;
    }
  } else if (rightgenes.size) {
    const a = [...rightgenes][0];
    isoform = a[0];
    strand = a[1].strand;
  }
  if (isoform) {
    if (strand != "+" && strand != "-") {
      holder.text("unknown strand for " + isoform);
      return;
    }
    import("./spliceevent.noeventdiagram-MVA7Q3HT.js").then((p) => {
      p.samegene({
        isoform,
        reverse: strand == "-",
        ongene: j.ongene,
        holder
      });
    });
    return;
  }
  import("./spliceevent.noeventdiagram-MVA7Q3HT.js").then((p) => {
    p.differentgenes({
      ongene: j.ongene,
      holder
    });
  });
}
function showEventdiagram_a53ss(j, e, tk, holder, block) {
  const e2 = {
    junctionB: {
      start: j.start,
      stop: j.stop,
      v: j.medianReadCount
    },
    a5ss: e.a5ss,
    a3ss: e.a3ss,
    altinintron: e.altinintron,
    altinexon: e.altinexon,
    frame: e.frame,
    exon5idx: e.exon5idx,
    strand: e.strand,
    sitedist: e.sitedist
  };
  if (e.junctionA) {
    e2.junctionA = { start: e.junctionA.start, stop: e.junctionA.stop, v: "..." };
  }
  import("./spliceevent.a53ss.diagram-LLJSPV7M.js").then((p) => {
    const text = p.default({
      event: e2,
      holder
    });
    if (!text) return;
    setTimeout(() => {
      if (text.node().getBoundingClientRect().top == 0) return;
      fetchReadcount4junctionAbyjunctionBsamples(
        tk,
        block,
        j,
        /* @__PURE__ */ new Map([[e.junctionA.start + "." + e.junctionA.stop, text]]),
        [[e.junctionA.start, e.junctionA.stop]]
      );
    }, 1e3);
  });
}
function showEventdiagram_skipalt_fetchreadcount(j, e, tk, holder, block) {
  const e2 = {
    gm: {
      name: e.gene,
      isoform: e.isoform
    },
    junctionB: {
      data: [{ v: j.medianReadCount }]
    },
    skippedexon: e.skippedexon,
    isskipexon: e.isskipexon,
    isaltexon: e.isaltexon,
    frame: e.frame,
    junctionAlst: [],
    color: "#99004d"
  };
  if (e.junctionAlst) {
    for (const jA of e.junctionAlst) {
      if (jA) {
        jA.data = [{ v: "..." }];
        e2.junctionAlst.push(jA);
        continue;
      }
      e2.junctionAlst.push(null);
    }
  }
  if (e.up1junction) {
    e.up1junction.data = [{ v: "..." }];
    e2.up1junction = e.up1junction;
  }
  if (e.down1junction) {
    e.down1junction.data = [{ v: "..." }];
    e2.down1junction = e.down1junction;
  }
  import("./spliceevent.exonskip.diagram-LAOIOIST.js").then((p) => {
    const [junction2readcounttext, junctionlst] = p.default({
      event: e2,
      holder,
      nophrase: true
    });
    setTimeout(() => {
      for (const [k, text] of junction2readcounttext) {
        if (text.node().getBoundingClientRect().top == 0) {
          return;
        }
      }
      fetchReadcount4junctionAbyjunctionBsamples(tk, block, j, junction2readcounttext, junctionlst);
    }, 1e3);
  });
}
async function fetchReadcount4junctionAbyjunctionBsamples(tk, block, jB, junction2readcounttext, jAlst) {
  const par = {
    genome: block.genome.name,
    dslabel: tk.mds.label,
    querykey: tk.querykey,
    readcountByjBsamples: true,
    junctionB: { chr: jB.chr, start: jB.start, stop: jB.stop },
    junctionAposlst: jAlst
  };
  addLoadParameter(par, tk);
  try {
    const data = await dofetch2("mdsjunction", {
      method: "POST",
      body: JSON.stringify(par)
    });
    if (data.error) throw data.error;
    if (!data.lst) throw ".lst[] missing";
    for (const j of data.lst) {
      const key = j.start + "." + j.stop;
      if (junction2readcounttext.has(key)) {
        junction2readcounttext.get(key).text(j.v);
      }
    }
  } catch (e) {
    console.error(e.message || e);
  }
}
function listAllEvents(lst, holder, j, tk, block) {
  if (lst.length == 1) {
    showEventdetail(lst[0], holder, j, tk, block);
    return;
  }
  const div = holder.append("div").style("display", "inline-block").style("font-size", ".8em");
  for (const e of lst) {
    div.append("div").html(eventlabel(e)).attr("class", "sja_menuoption").on("click", (event) => {
      tk.tktip.clear().show(event.clientX + 20, event.clientY - 40);
      showEventdetail(e, tk.tktip.d, j, tk, block);
    });
  }
}
function showEventdetail(e, holder, j, tk, block) {
  const tr = holder.append("table").append("tr");
  const td1 = tr.append("td");
  const p = td1.append("p");
  if (e.isskipexon || e.isaltexon) {
    p.html(eventlabel(e));
    showEventdiagram_skipalt_fetchreadcount(j, e, tk, td1, block);
  } else {
    p.html(eventlabel(e));
    showEventdiagram_a53ss(j, e, tk, td1, block);
  }
  const td2 = tr.append("td");
}
function eventlabel(e) {
  if (e.isskipexon || e.isaltexon) {
    return (e.isskipexon ? "Exon skip" : "Exon alt") + " " + e.gene + " " + e.isoform + " " + (e.frame == void 0 ? "" : e.frame == IN_frame ? "IN frame" : "OUT of frame");
  }
  return (e.a5ss ? "A5SS" : "A3SS") + " " + e.gene + " " + e.isoform + " " + (e.frame == void 0 ? "" : e.frame == IN_frame ? "IN frame" : "OUT of frame");
}
async function queryOneJunction(j, tk, block, holder) {
  const par = {
    genome: block.genome.name,
    dslabel: tk.mds.label,
    querykey: tk.querykey,
    junction: {
      chr: j.chr,
      start: j.start,
      stop: j.stop
    }
  };
  addLoadParameter(par, tk);
  const wait = holder.append("div").text("Loading ...");
  try {
    const data = await dofetch2("mdsjunction", {
      method: "POST",
      body: JSON.stringify(par)
    });
    if (data.error) throw data.error;
    wait.remove();
    if (data.readcountboxplotpercohort) {
      const row = holder.append("div");
      for (const group of data.readcountboxplotpercohort) {
        const div = row.append("div").style("margin", "10px").style("display", "inline-block").style("vertical-align", "top");
        div.append("h3").text(group.label).style("text-align", "center");
        const p = await import("./plot.boxplot-OHEJDPTW.js");
        const err = p.default({
          holder: div,
          list: group.boxplots,
          axislabel: "Read count"
        });
        if (err) {
          sayerror(div, "Boxplot error: " + err);
        }
      }
    } else if (data.samples) {
      if (data.sampletotalnumber) {
        holder.append("p").text("Displaying top " + data.samples.length + " samples").style("opacity", 0.5);
      }
      const div = holder.append("div").style("margin-top", "20px").style("display", "grid").style("grid-template-columns", "auto auto").style("gap-row-gap", "1px").style("align-items", "center").style("justify-items", "left");
      const [c1, c2] = get_list_cells(div);
      c1.text("Sample").style("opacity", 0.5).style("font-size", ".7em");
      c2.text("Read count").style("opacity", 0.5).style("font-size", ".7em");
      for (const s of data.samples) {
        const [c12, c22] = get_list_cells(div);
        c12.text(s.sample_name ? s.sample_name : tk.samples[s.i]);
        c22.text(s.readcount);
      }
    }
  } catch (e) {
    if (e.stack) console.log(e.stack);
    wait.text("Error: " + (e.message || e));
  }
}
function get_list_cells(table) {
  return [
    table.append("div").style("width", "100%").style("padding", "5px 20px 5px 0px").style("border-bottom", "solid 1px #ededed"),
    table.append("div").style("width", "100%").style("border-bottom", "solid 1px #ededed").style("padding", "5px 20px 5px 0px")
  ];
}
export {
  loadTk
};
//# sourceMappingURL=block.mds.junction-XRUIHAF5.js.map
