document.addEventListener("DOMContentLoaded", () => {
  const root = document.querySelector("main") || document.body;
  const headings = Array.from(root.querySelectorAll("h2, h3, h4, h5, h6"));

  const isHeading = (el) => el && /^H[1-6]$/.test(el.tagName);
  const levelOf = (el) => parseInt(el.tagName[1], 10);

  const sectionMap = new WeakMap();

	function setCollapsed(h, collapsed) {
	  h.classList.toggle("collapsed", collapsed);

	  for (const x of (sectionMap.get(h) || [])) {
		x.classList.toggle("collapsed-content", collapsed);
	  }

	  const innerHeadings = (sectionMap.get(h) || []).filter(el => /^H[2-6]$/.test(el.tagName));
	  for (const childH of innerHeadings) {
		childH.classList.toggle("collapsed", collapsed);
	  }
	}

  for (const h of headings) {
    const myLevel = levelOf(h);

	let stop = null;
	{
	  const w = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
	  w.currentNode = h;

	  // Skip descendants of the heading itself (e.g. <h2><a>...</a></h2>)
	  let el = w.nextNode();
	  while (el && h.contains(el)) el = w.nextNode();

	  for (; el; el = w.nextNode()) {
		if (isHeading(el) && levelOf(el) <= myLevel) { stop = el; break; }
	  }
	}

	const els = [];
	{
	  const w = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
	  w.currentNode = h;

	  // Skip descendants of the heading itself
	  let el = w.nextNode();
	  while (el && h.contains(el)) el = w.nextNode();

	  for (; el; el = w.nextNode()) {
		if (el === stop) break;

		// Don't hide any element that contains the boundary heading
		if (stop && el.contains(stop)) continue;

		els.push(el);
	  }
	}

    sectionMap.set(h, els);

    h.classList.add("collapsible-heading");

	h.addEventListener("click", (ev) => {
	  if (ev.target.closest("a")) return;
		
	  ev.preventDefault();
	  const nowCollapsed = !h.classList.contains("collapsed");
	  setCollapsed(h, nowCollapsed);
	});

    if (h.tagName === "H2") {
      setCollapsed(h, true);
    }
  }

  const expandAll = document.getElementById("expandAll");
  const collapseAll = document.getElementById("collapseAll");

  if (expandAll) expandAll.addEventListener("click", (ev) => {
    ev.preventDefault();
    for (const h of headings) setCollapsed(h, false);
  });

  if (collapseAll) collapseAll.addEventListener("click", (ev) => {
    ev.preventDefault();
    for (const h of headings) setCollapsed(h, true);
  });
});

document.addEventListener("keydown", (ev) => {
	
  if (ev.shiftKey || ev.ctrlKey || ev.altKey || ev.metaKey) return;
  
  const t = ev.target;
  if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) return;

  if (ev.key === "c") {
    ev.preventDefault();
    document.getElementById("collapseAll")?.click();
  }

  if (ev.key === "x") {
    ev.preventDefault();
    document.getElementById("expandAll")?.click();
  }
});

if (window.self !== window.top) {
  document.documentElement.classList.add("in-iframe");
}