UNPKG

@eledah/parto

Version:

Framework-agnostic argument map sunburst charts with light/dark themes

713 lines (712 loc) 25 kB
import * as e from "d3"; //#region src/config.ts var t = { legend: "Argument types", center: "Center", support: "Agree", attack: "Disagree", claim: "Claim", unknownSpeaker: "Unknown", intensity: "Intensity", confidence: "Confidence", statusLoading: "Loading map…", statusEmpty: "No map data yet.", statusError: "Could not load this argument map." }, n = { center: "#b08a3e", support: "#3f7652", attack: "#9f4f4f", border: "#ffffff" }, r = { colors: { ...n }, chart: { maxCenterRadius: .4, radiusPadding: 5, minRadius: 10, cornerRadius: 3, strokeWidth: .5 }, spacing: { verticalGap: .01, padAngle: { inner: .025, outer: .012 }, radiusExponent: { base: 1.2, perLevel: .2 }, exponentDepthThreshold: 3 } }, i = { center: "--pam-center", support: "--pam-support", attack: "--pam-attack", border: "--pam-border" }; function a(e) { return !!(e && (e.startsWith("#") || e.startsWith("rgb"))); } function o(e) { let t = getComputedStyle(e); for (let [e, n] of Object.entries(i)) { let i = t.getPropertyValue(n).trim(); a(i) && (r.colors[e] = i); } } function s(e, t) { for (let [n, r] of Object.entries({ center: "--pam-center", support: "--pam-support", attack: "--pam-attack", border: "--pam-border" })) { let i = t[n]; i && e.style.setProperty(r, i); } o(e); } //#endregion //#region src/core/buildTree.ts function c(e) { let t = [], n = /* @__PURE__ */ new Map(); for (let t of e) n.set(t.id, t); let r = e.find((e) => e.type === "thesis"); if (!r) return { tree: null, warnings: ["No thesis node found"] }; let i = /* @__PURE__ */ new Map(); for (let t of e) for (let e of t.relations) { if (!n.has(e.target_node_id)) continue; let r = i.get(e.target_node_id) ?? []; r.push({ childId: t.id, relationType: e.relation_type, reasoning: e.reasoning }), i.set(e.target_node_id, r); } let a = (e, r, o, s, c, l) => { let u = l.join("/"), d = { ...e, children: [], value: 1, relationType: o, relationReasoning: s, parentId: r, pathKey: u }; if (c.has(e.id)) return t.push(`Cycle detected at node ${e.id}; branch skipped`), d; let f = new Set(c); f.add(e.id); let p = i.get(e.id) ?? []; for (let t of p) { let r = n.get(t.childId); if (!r) continue; let i = a(r, e.id, t.relationType, t.reasoning, f, [...l, t.childId]); d.children.push(i); } return d; }; return { tree: a(r, void 0, void 0, void 0, /* @__PURE__ */ new Set(), [r.id]), warnings: t }; } function l(e, t) { if (!e) return null; if (e.id === t) return e; for (let n of e.children) { let e = l(n, t); if (e) return e; } return null; } function u(e, t) { if (!e || t.length === 0) return null; let n = e; for (let e = 1; e < t.length; e++) { let r = t[e]; if (n = n?.children.find((e) => e.id === r) ?? null, !n) return null; } return n; } function d(e, t) { let n = [], r = (e, i) => { let a = [...i, e]; if (e.id === t) return n.push(...a), !0; for (let t of e.children) if (r(t, a)) return !0; return !1; }; return r(e, []), n; } function f(e, t) { return t && e.id === t.id ? "pam-arc--center" : e.relationType === "attack" ? "pam-arc--attack" : "pam-arc--support"; } function p(e, t, n) { return t && e.id === t.id ? n.center : e.relationType === "attack" ? n.attack : n.support; } //#endregion //#region src/errors.ts var m = class extends Error { constructor(e) { super(e), this.name = "ArgumentMapError"; } }, h = class extends m { issues; constructor(e) { super(e.join("; ")), this.name = "ValidationError", this.issues = e; } }; //#endregion //#region src/core/validateMapData.ts function g(e) { let t = [], n = []; if (!e || typeof e != "object") throw new h(["Map data must be an object"]); let r = e; if (!Array.isArray(r.new_nodes)) throw new h(["Map data must include a new_nodes array"]); let i = [], a = /* @__PURE__ */ new Set(), o = 0; for (let e of r.new_nodes) { if (!e || typeof e != "object") { t.push("Each node must be an object"); continue; } let n = e, r = String(n.id ?? ""); if (!r) { t.push("Node is missing id"); continue; } if (a.has(r)) { t.push(`Duplicate node id: ${r}`); continue; } a.add(r); let s = String(n.type ?? ""); s === "thesis" && (o += 1); let c = (Array.isArray(n.relations) ? n.relations : []).map((e) => { let n = e, i = String(n.relation_type ?? ""); return i !== "support" && i !== "attack" && t.push(`Node ${r} has unsupported relation_type: ${i}`), { target_node_id: String(n.target_node_id ?? ""), relation_type: i, reasoning: String(n.reasoning ?? "") }; }), l = { id: r, type: s, title: String(n.title ?? ""), description: String(n.description ?? ""), quote: String(n.quote ?? ""), speaker: String(n.speaker ?? ""), relations: c }; if (n.score && typeof n.score == "object") { let e = n.score; l.score = { intensity: Number(e.intensity ?? 0), confidence: Number(e.confidence ?? 0) }; } i.push(l); } if (t.length > 0) throw new h(t); if (o === 0 || o > 1) throw new h(["Map must include exactly one thesis node"]); let s = new Set(i.map((e) => e.id)); for (let e of i) for (let t of e.relations) s.has(t.target_node_id) || n.push(`Node ${e.id} references missing target ${t.target_node_id}`); return { data: { new_nodes: i }, warnings: n }; } //#endregion //#region src/core/ZoomController.ts var _ = class { fullTree = null; zoomStack = []; setTree(e) { this.fullTree = e, this.zoomStack = e ? [e] : []; } getFocusRoot() { return this.zoomStack.length === 0 ? null : this.zoomStack[this.zoomStack.length - 1] ?? null; } getFullTree() { return this.fullTree; } getZoomPath() { return this.zoomStack.map((e) => ({ id: e.id, title: e.title, type: e.type, relationType: e.relationType })); } resetZoom() { this.fullTree && (this.zoomStack = [this.fullTree]); } zoomTo(e) { if (!this.fullTree) return !1; let t = d(this.fullTree, e); return t.length === 0 || !t[t.length - 1] ? !1 : (this.zoomStack = t, !0); } zoomToPath(e) { if (!this.fullTree || e.length === 0 || !u(this.fullTree, e)) return !1; let t = [], n = this.fullTree; t.push(n); for (let r = 1; r < e.length; r++) { let i = e[r], a = n.children.find((e) => e.id === i); if (!a) return !1; t.push(a), n = a; } return this.zoomStack = t, !0; } zoomIn(e) { return (e.children?.length ?? 0) !== 0 && (this.zoomStack.push(e), !0); } zoomOut() { return this.zoomStack.length <= 1 ? !1 : (this.zoomStack.pop(), !0); } handleClick(e, t, n) { if (t === 0) { this.zoomOut(); return; } if (n) { let t = l(this.getFocusRoot(), e.id); t && this.zoomIn(t); } } }, v = class { container; chartRoot; width = 0; height = 0; radius = 0; svg; g; partition = e.partition(); arc; legend = null; currentRoot = null; highlightId = null; resizeObserver = null; options; tooltipId; touchZoomPathKey = null; touchOutsideHandler = null; constructor(n, i) { this.container = n, this.options = i, this.tooltipId = `pam-tooltip-${Math.random().toString(36).slice(2, 9)}`, this.chartRoot = document.createElement("div"), this.chartRoot.className = "pam-chart__canvas", n.appendChild(this.chartRoot), o(n), this.svg = e.select(this.chartRoot).append("svg").attr("width", "100%").attr("height", "100%").attr("preserveAspectRatio", "xMidYMid meet").attr("role", "img").attr("aria-label", i.ariaLabel), this.g = this.svg.append("g"), (i.legend ?? !0) && (this.legend = this.createLegend(i.labels ?? t), this.chartRoot.appendChild(this.legend)), this.partition = e.partition().size([2 * Math.PI, this.radius]), this.arc = e.arc().startAngle((e) => e.x0).endAngle((e) => e.x1).padAngle(r.spacing.padAngle.inner).innerRadius((e) => e.y0).outerRadius((e) => e.y1), this.resizeObserver = new ResizeObserver(() => this.resize()), this.resizeObserver.observe(n), this.resize(); } destroy() { this.unbindTouchOutsideDismiss(), this.resizeObserver &&= (this.resizeObserver.disconnect(), null), this.chartRoot.remove(); } resize() { let e = this.chartRoot.getBoundingClientRect(); this.width = e.width, this.height = e.height; let t = this.legend?.getBoundingClientRect().height ?? 0, n = this.legend ? Math.max(56, t + 28) : 0, i = Math.max(0, this.height - n); this.radius = Math.min(this.width, i) / 2 - r.chart.radiusPadding, !(this.radius < r.chart.minRadius) && (this.partition.size([2 * Math.PI, this.radius]), this.svg.attr("viewBox", `0 0 ${this.width} ${this.height}`), this.g.attr("transform", `translate(${this.width / 2}, ${i / 2})`), this.currentRoot && this.render(this.currentRoot)); } setHighlight(e) { this.highlightId = e, this.g.selectAll("path").classed("pam-arc--highlighted", (t) => e === t.data.id).classed("pam-arc--dimmed", (t) => e != null && e !== t.data.id); } render(t) { this.touchZoomPathKey = null, this.unbindTouchOutsideDismiss(), this.currentRoot = t, o(this.container); let n = r.colors, i = e.hierarchy(t), a = 0; i.each((e) => { a = Math.max(a, e.depth); }); let s = Math.max(a, 1); this.partition(i); let c = i, l = (e, t, n) => { if (e.x0 = t, e.x1 = n, e.children?.length) { let r = (n - t) / e.children.length; e.children.forEach((e, n) => { l(e, t + n * r, t + (n + 1) * r); }); } }; l(c, 0, 2 * Math.PI); let u = (e) => (e / this.radius) ** +(r.spacing.radiusExponent.base + (s - r.spacing.exponentDepthThreshold) * r.spacing.radiusExponent.perLevel) * this.radius, d = this.radius * r.spacing.verticalGap; this.arc.innerRadius((e) => u(e.y0) + d).outerRadius((e) => e.depth === 0 ? Math.min(u(e.y1) - d, this.radius * r.chart.maxCenterRadius) : u(e.y1) - d).padAngle((e) => { let t = e.depth / s; return r.spacing.padAngle.inner - t * (r.spacing.padAngle.inner - r.spacing.padAngle.outer); }).cornerRadius(r.chart.cornerRadius), this.g.selectAll("*").remove(); let m = this.g.selectAll("path").data(c.descendants()).enter().append("path").attr("d", this.arc).attr("data-node-id", (e) => e.data.id).attr("data-path-key", (e) => e.data.pathKey).attr("class", (e) => f(e.data, t)).attr("tabindex", "0").attr("role", "button").attr("aria-label", (e) => e.data.title).attr("aria-describedby", this.tooltipId).style("stroke", n.border).style("stroke-width", r.chart.strokeWidth).style("stroke-linejoin", "round").style("cursor", this.options.zoomEnabled ? "pointer" : "default").classed("pam-arc--highlighted", (e) => this.highlightId === e.data.id).classed("pam-arc--dimmed", (e) => this.highlightId != null && this.highlightId !== e.data.id), h = (r, i) => { m.classed("pam-arc--dimmed", (e) => e.data.id !== i.data.id), m.classed("pam-arc--highlighted", (e) => e.data.id === i.data.id); try { let a = p(i.data, t, n), o = e.color(a); o && (o.opacity = .28), e.select(r.currentTarget).style("filter", `brightness(${i.depth === 0 ? 1.02 : 1.06}) drop-shadow(0 2px 5px ${o?.formatRgb() ?? a})`); } catch {} this.options.onHover?.(i.data, r); }, g = () => { m.classed("pam-arc--dimmed", !1).classed("pam-arc--highlighted", !1).style("filter", "none"), this.highlightId && this.setHighlight(this.highlightId), this.options.onLeave?.(); }, _ = (e, t) => { if (e.stopPropagation(), e.pointerType === "touch") { this.touchZoomPathKey === t.data.pathKey ? (this.touchZoomPathKey = null, this.unbindTouchOutsideDismiss(), this.options.zoomEnabled && this.options.onClick?.(t.data, t.depth, (t.data.children?.length ?? 0) > 0)) : (this.touchZoomPathKey = t.data.pathKey, h(e, t), this.bindTouchOutsideDismiss(g)); return; } this.options.zoomEnabled && this.options.onClick?.(t.data, t.depth, (t.data.children?.length ?? 0) > 0); }; m.on("pointerenter", (e, t) => { e.pointerType !== "touch" && h(e, t); }).on("pointermove", (e, t) => { e.pointerType !== "touch" && h(e, t); }).on("pointerleave", (e) => { e.pointerType !== "touch" && g(); }).on("focus", (e, t) => h(e, t)).on("blur", () => g()).on("click", (e, t) => _(e, t)).on("keydown", (e, t) => { (e.key === "Enter" || e.key === " ") && (e.preventDefault(), this.options.zoomEnabled && this.options.onClick?.(t.data, t.depth, (t.data.children?.length ?? 0) > 0)); }); } getTooltipElementId() { return this.tooltipId; } createLegend(e) { let t = document.createElement("div"); t.className = "pam-chart__legend", t.setAttribute("role", "list"), t.setAttribute("aria-label", e.legend ?? "Argument types"); let n = [ { type: "center", label: e.center }, { type: "support", label: e.support }, { type: "attack", label: e.attack } ]; for (let e of n) { let n = document.createElement("span"); n.className = "pam-chart__legend-item", n.setAttribute("role", "listitem"); let r = document.createElement("span"); r.className = `pam-chart__legend-swatch pam-chart__legend-swatch--${e.type}`, r.setAttribute("aria-hidden", "true"); let i = document.createElement("span"); i.textContent = e.label, n.append(r, i), t.appendChild(n); } return t; } bindTouchOutsideDismiss(e) { this.unbindTouchOutsideDismiss(), this.touchOutsideHandler = (t) => { let n = t.target; n && this.container.contains(n) || (this.touchZoomPathKey = null, e(), this.unbindTouchOutsideDismiss()); }, window.setTimeout(() => { this.touchOutsideHandler && document.addEventListener("pointerdown", this.touchOutsideHandler, !0); }, 0); } unbindTouchOutsideDismiss() { this.touchOutsideHandler &&= (document.removeEventListener("pointerdown", this.touchOutsideHandler, !0), null); } }; function y(e, t, n) { let r = t.getBoundingClientRect(), i = r.width || 320, a = r.height || 200; if (n === "touch") { let t = e.x - i / 2, n = e.y - a - 56; return t = Math.max(12, Math.min(t, window.innerWidth - i - 12)), n = Math.max(12, Math.min(n, window.innerHeight - a - 12)), { x: t, y: n }; } let o = e.x + 20, s = e.y + 20; return o + i > window.innerWidth && (o = e.x - i - 20), s + a > window.innerHeight && (s = e.y - a - 20), { x: o, y: s }; } //#endregion //#region src/ui/TooltipController.ts function b(e, t) { return e.type === "thesis" ? { text: t.center, className: "center" } : e.relationType === "attack" ? { text: t.attack, className: "attack" } : e.relationType === "support" ? { text: t.support, className: "support" } : { text: t.claim, className: "claim" }; } function x(e, n = t) { let r = document.createElement("div"); r.className = "pam-tooltip"; let i = document.createElement("div"); i.className = "pam-tooltip__header"; let a = b(e, n), o = document.createElement("span"); o.className = `pam-tooltip__type pam-tooltip__type--${a.className}`, o.textContent = a.text; let s = document.createElement("span"); s.className = "pam-tooltip__speaker", s.textContent = e.speaker || n.unknownSpeaker, i.append(o, s); let c = document.createElement("h3"); if (c.className = "pam-tooltip__title", c.textContent = e.title, r.append(i, c), e.description) { let t = document.createElement("p"); t.className = "pam-tooltip__description", t.textContent = e.description, r.append(t); } if (e.relationType && e.relationReasoning) { let t = document.createElement("p"); t.className = "pam-tooltip__reasoning", t.textContent = e.relationReasoning, r.append(t); } if (e.quote) { let t = document.createElement("blockquote"); t.className = "pam-tooltip__quote", t.textContent = `"${e.quote}"`, r.append(t); } if (e.score) { let t = document.createElement("div"); t.className = "pam-tooltip__scores"; let i = document.createElement("span"); i.textContent = `${n.intensity}: ${Math.round(e.score.intensity * 100)}%`; let a = document.createElement("span"); a.textContent = `${n.confidence}: ${Math.round(e.score.confidence * 100)}%`, t.append(i, a), r.append(t); } return r; } function S(e) { if ("clientX" in e && typeof e.clientX == "number") { let t = "pointerType" in e ? e.pointerType : void 0; return { x: e.clientX, y: e.clientY, pointerType: t }; } return { x: 0, y: 0 }; } var C = class { element; rafId = null; position = { x: 0, y: 0 }; pointerType; renderer; labels; visible = !1; constructor(e, t, n, r) { this.renderer = n, this.labels = r, this.element = document.createElement("div"), this.element.id = t, this.element.className = "pam-tooltip-host", this.element.setAttribute("role", "region"), this.element.setAttribute("aria-live", "polite"), e.appendChild(this.element); } show(e, t) { let n = S(t); this.position = { x: n.x, y: n.y }, this.pointerType = n.pointerType, this.element.replaceChildren(this.renderer(e, this.labels)), this.element.classList.toggle("pam-tooltip-host--touch", n.pointerType === "touch"), this.element.classList.add("pam-tooltip-host--visible"), this.visible = !0, this.schedulePosition(); } move(e) { this.visible && (this.position = { x: e.clientX, y: e.clientY }, this.pointerType = e.pointerType, this.element.classList.toggle("pam-tooltip-host--touch", e.pointerType === "touch"), this.schedulePosition()); } hide() { this.visible = !1, this.pointerType = void 0, this.element.classList.remove("pam-tooltip-host--visible", "pam-tooltip-host--touch"), this.element.replaceChildren(), this.rafId != null && (cancelAnimationFrame(this.rafId), this.rafId = null); } setLabels(e) { this.labels = e; } destroy() { this.hide(), this.element.remove(); } schedulePosition() { this.rafId != null && cancelAnimationFrame(this.rafId), this.rafId = requestAnimationFrame(() => { let e = this.element.firstElementChild; if (!e) return; let { x: t, y: n } = y(this.position, e, this.pointerType); this.element.style.left = `${t}px`, this.element.style.top = `${n}px`; }); } }, w = class { element; messages; state = null; constructor(e, t) { this.messages = t, this.element = document.createElement("div"), this.element.className = "pam-chart__status", this.element.setAttribute("role", "status"), this.element.setAttribute("aria-live", "polite"), this.element.hidden = !0, e.appendChild(this.element); } show(e, t) { this.state = e, this.element.hidden = !1, this.element.className = `pam-chart__status pam-chart__status--${e}`; let n = t ?? this.messages[e]; this.element.replaceChildren(); let r = document.createElement("p"); if (r.className = "pam-chart__status-text", r.textContent = n, this.element.append(r), e === "loading") { let e = document.createElement("span"); e.className = "pam-chart__status-spinner", e.setAttribute("aria-hidden", "true"), this.element.prepend(e); } } hide() { this.state = null, this.element.hidden = !0, this.element.replaceChildren(), this.element.className = "pam-chart__status"; } isVisible() { return this.state !== null; } getState() { return this.state; } destroy() { this.element.remove(); } }; //#endregion //#region src/ArgumentMapChart.ts function T(e) { if (typeof e == "string") { let t = document.querySelector(e); if (!t) throw Error(`Container not found: ${e}`); return t; } return e; } function E(e) { return { ...t, ...e }; } var D = class { container; zoom = new _(); renderer; tooltip = null; options; themeMedia = null; themeListener = null; keydownHandler = null; status; constructor(e, t, n = {}) { this.container = T(e), this.container.classList.add("pam-chart"); let r = n.direction ?? "inherit"; if (r !== "inherit" && this.container.setAttribute("dir", r), n.lang && this.container.setAttribute("lang", n.lang), this.options = { theme: n.theme ?? "auto", legend: n.legend ?? !0, zoom: n.zoom ?? !0, direction: r, lang: n.lang ?? "en", ariaLabel: n.ariaLabel ?? "Argument map chart", tooltip: n.tooltip ?? !0, labels: E(n.labels), onNodeHover: n.onNodeHover, onNodeLeave: n.onNodeLeave, onNodeClick: n.onNodeClick, onZoomChange: n.onZoomChange, onWarning: n.onWarning }, n.colors && s(this.container, n.colors), this.status = new w(this.container, { loading: this.options.labels.statusLoading, empty: this.options.labels.statusEmpty, error: this.options.labels.statusError }), this.renderer = new v(this.container, { ariaLabel: this.options.ariaLabel, legend: this.options.legend, labels: this.options.labels, zoomEnabled: this.options.zoom, onHover: (e, t) => this.handleHover(e, t), onLeave: () => this.handleLeave(), onClick: (e, t, n) => this.handleClick(e, t, n) }), this.options.tooltip !== !1) { let e = typeof this.options.tooltip == "function" ? this.options.tooltip : x; this.tooltip = new C(document.body, this.renderer.getTooltipElementId(), e, this.options.labels); } this.applyTheme(this.options.theme), this.bindKeyboard(), t ? this.setData(t) : this.status.show("empty"); } setData(e) { try { let { data: t, warnings: n } = g(e); for (let e of n) this.options.onWarning?.(e); let { tree: r, warnings: i } = c(t.new_nodes); for (let e of i) this.options.onWarning?.(e); if (!r) { this.options.onWarning?.("Could not build tree from map data"), this.status.show("error", this.options.labels.statusError); return; } this.status.hide(), this.zoom.setTree(r), this.render(), this.emitZoomChange(); } catch (e) { let t = e instanceof h ? e.issues.join("; ") : e instanceof Error ? e.message : this.options.labels.statusError; this.options.onWarning?.(t), this.status.show("error", t); } } setLoading(e) { e ? (this.status.show("loading"), this.tooltip?.hide()) : this.status.getState() === "loading" && this.status.hide(); } showError(e) { this.options.onWarning?.(e ?? this.options.labels.statusError), this.status.show("error", e), this.tooltip?.hide(); } setTheme(e) { this.options.theme = e, this.applyTheme(e); } setColors(e) { s(this.container, { center: e.center, support: e.support, attack: e.attack, border: e.border }), o(this.container); let t = this.zoom.getFocusRoot(); t && this.renderer.render(t); } highlight(e) { this.renderer.setHighlight(e); } zoomTo(e) { this.zoom.zoomTo(e) && (this.render(), this.emitZoomChange()); } zoomToPath(e) { this.zoom.zoomToPath(e) && (this.render(), this.emitZoomChange()); } zoomOut() { this.zoom.zoomOut() && (this.render(), this.emitZoomChange()); } resetZoom() { this.zoom.resetZoom(), this.render(), this.emitZoomChange(); } resize() { this.renderer.resize(); } getZoomPath() { return this.zoom.getZoomPath(); } destroy() { this.themeMedia && this.themeListener && this.themeMedia.removeEventListener("change", this.themeListener), this.keydownHandler && document.removeEventListener("keydown", this.keydownHandler), this.tooltip?.destroy(), this.status.destroy(), this.renderer.destroy(), this.container.classList.remove("pam-chart", "pam-chart--light", "pam-chart--dark"), this.options.direction !== "inherit" && this.container.removeAttribute("dir"); } render() { let e = this.zoom.getFocusRoot(); e && this.renderer.render(e); } emitZoomChange() { this.options.onZoomChange?.(this.zoom.getZoomPath()); } handleHover(e, t) { this.tooltip?.show(e, t), this.options.onNodeHover?.(e, t); } handleLeave() { this.tooltip?.hide(), this.options.onNodeLeave?.(); } handleClick(e, t, n) { this.options.zoom && (this.zoom.handleClick(e, t, n), this.render(), this.emitZoomChange()), this.options.onNodeClick?.(e, t, n); } applyTheme(e) { this.container.classList.remove("pam-chart--light", "pam-chart--dark"); let t = (e) => { this.container.classList.add(e === "light" ? "pam-chart--light" : "pam-chart--dark"), r.colors.center = n.center, r.colors.support = n.support, r.colors.attack = n.attack, r.colors.border = n.border, o(this.container); let t = this.zoom.getFocusRoot(); t && this.renderer.render(t); }; if (this.themeMedia && this.themeListener && (this.themeMedia.removeEventListener("change", this.themeListener), this.themeMedia = null, this.themeListener = null), e === "light" || e === "dark") { t(e); return; } this.themeMedia = window.matchMedia("(prefers-color-scheme: dark)"), t(this.themeMedia.matches ? "dark" : "light"), this.themeListener = (e) => t(e.matches ? "dark" : "light"), this.themeMedia.addEventListener("change", this.themeListener); } bindKeyboard() { this.keydownHandler = (e) => { this.options.zoom && (e.key === "Escape" || e.key === "Backspace") && this.zoom.zoomOut() && (e.preventDefault(), this.render(), this.emitZoomChange()); }, document.addEventListener("keydown", this.keydownHandler); } }; function O(e, t, n) { return new D(e, t, n); } //#endregion export { m as ArgumentMapError, n as DEFAULT_COLORS, t as DEFAULT_LABELS, v as SunburstRenderer, h as ValidationError, _ as ZoomController, c as buildTree, r as chartConfig, O as createArgumentMap, x as createDefaultTooltip, l as findNodeById, d as pathToNode, g as validateMapData }; //# sourceMappingURL=index.js.map