/* ui-cube-detail.js — Cube detail pane rendering */ (function () { "use strict"; function toDisplayText(value) { return String(value ?? "").trim(); } function escapeHtml(value) { return String(value) .replace(/&/g, "&") .replace(//g, ">") .replace(/\"/g, """) .replace(/'/g, "'"); } function toDetailValueMarkup(value) { const text = toDisplayText(value); return text ? escapeHtml(text) : '!'; } function createMetaCard(title, bodyContent) { const card = document.createElement("div"); card.className = "planet-meta-card"; const titleEl = document.createElement("strong"); titleEl.textContent = title; card.appendChild(titleEl); if (typeof bodyContent === "string") { const bodyEl = document.createElement("p"); bodyEl.className = "planet-text"; bodyEl.textContent = bodyContent; card.appendChild(bodyEl); } else if (bodyContent instanceof Node) { card.appendChild(bodyContent); } return card; } function createNavButton(label, eventName, detail) { const button = document.createElement("button"); button.type = "button"; button.className = "kab-god-link"; button.textContent = `${label} ↗`; button.addEventListener("click", () => { document.dispatchEvent(new CustomEvent(eventName, { detail })); }); return button; } function renderCenterDetail(context) { const { state, elements, getCubeCenterData, getCenterLetterId, getCenterLetterSymbol, toFiniteNumber } = context; if (!state.showPrimalPoint) { return false; } const center = getCubeCenterData(); if (!center || !elements?.detailNameEl || !elements?.detailSubEl || !elements?.detailBodyEl) { return false; } const centerLetterId = getCenterLetterId(center); const centerLetter = getCenterLetterSymbol(center); const centerLetterText = centerLetterId ? `${centerLetter ? `${centerLetter} ` : ""}${toDisplayText(centerLetterId)}` : ""; const centerElement = toDisplayText(center?.element); elements.detailNameEl.textContent = "Primal Point"; elements.detailSubEl.textContent = [centerLetterText, centerElement].filter(Boolean).join(" · ") || "Center of the Cube"; const bodyEl = elements.detailBodyEl; bodyEl.innerHTML = ""; const summary = document.createElement("div"); summary.className = "planet-text"; summary.innerHTML = `
Name
${toDetailValueMarkup(center?.name)}
Letter
${toDetailValueMarkup(centerLetterText)}
Element
${toDetailValueMarkup(center?.element)}
`; bodyEl.appendChild(createMetaCard("Center Details", summary)); if (Array.isArray(center?.keywords) && center.keywords.length) { bodyEl.appendChild(createMetaCard("Keywords", center.keywords.join(", "))); } if (center?.description) { bodyEl.appendChild(createMetaCard("Description", center.description)); } const associations = center?.associations || {}; const links = document.createElement("div"); links.className = "kab-god-links"; if (centerLetterId) { links.appendChild(createNavButton(centerLetter || "!", "nav:alphabet", { alphabet: "hebrew", hebrewLetterId: centerLetterId })); } const centerTrumpNo = toFiniteNumber(associations?.tarotTrumpNumber); const centerTarotCard = toDisplayText(associations?.tarotCard); if (centerTarotCard || centerTrumpNo != null) { links.appendChild(createNavButton(centerTarotCard || `Trump ${centerTrumpNo}`, "nav:tarot-trump", { cardName: centerTarotCard, trumpNumber: centerTrumpNo })); } const centerPathNo = toFiniteNumber(associations?.kabbalahPathNumber); if (centerPathNo != null) { links.appendChild(createNavButton(`Path ${centerPathNo}`, "nav:kabbalah-path", { pathNo: centerPathNo })); } if (links.childElementCount) { const linksCard = document.createElement("div"); linksCard.className = "planet-meta-card"; linksCard.innerHTML = "Correspondence Links"; linksCard.appendChild(links); bodyEl.appendChild(linksCard); } return true; } function renderConnectorDetail(context) { const { state, elements, walls, normalizeId, normalizeLetterKey, formatDirectionName, getWallById, getConnectorById, getConnectorPathEntry, getHebrewLetterSymbol, toFiniteNumber } = context; const connector = getConnectorById(state.selectedConnectorId); if (!connector || !elements?.detailNameEl || !elements?.detailSubEl || !elements?.detailBodyEl) { return false; } const fromWallId = normalizeId(connector?.fromWallId); const toWallId = normalizeId(connector?.toWallId); const fromWall = getWallById(fromWallId) || walls.find((entry) => normalizeId(entry?.id) === fromWallId) || null; const toWall = getWallById(toWallId) || walls.find((entry) => normalizeId(entry?.id) === toWallId) || null; const connectorPath = getConnectorPathEntry(connector); const letterId = normalizeLetterKey(connector?.hebrewLetterId); const letterSymbol = getHebrewLetterSymbol(letterId); const letterText = letterId ? `${letterSymbol ? `${letterSymbol} ` : ""}${toDisplayText(letterId)}` : ""; const pathNo = toFiniteNumber(connectorPath?.pathNumber); const tarotCard = toDisplayText(connectorPath?.tarot?.card); const tarotTrumpNumber = toFiniteNumber(connectorPath?.tarot?.trumpNumber); const astrologyType = toDisplayText(connectorPath?.astrology?.type); const astrologyName = toDisplayText(connectorPath?.astrology?.name); const astrologySummary = [astrologyType, astrologyName].filter(Boolean).join(": "); elements.detailNameEl.textContent = connector?.name || "Mother Connector"; elements.detailSubEl.textContent = ["Mother Letter", letterText].filter(Boolean).join(" · ") || "Mother Letter"; const bodyEl = elements.detailBodyEl; bodyEl.innerHTML = ""; const summary = document.createElement("div"); summary.className = "planet-text"; summary.innerHTML = `
Letter
${toDetailValueMarkup(letterText)}
From
${toDetailValueMarkup(fromWall?.name || formatDirectionName(fromWallId))}
To
${toDetailValueMarkup(toWall?.name || formatDirectionName(toWallId))}
Tarot
${toDetailValueMarkup(tarotCard || (tarotTrumpNumber != null ? `Trump ${tarotTrumpNumber}` : ""))}
`; bodyEl.appendChild(createMetaCard("Connector Details", summary)); if (astrologySummary) { bodyEl.appendChild(createMetaCard("Astrology", astrologySummary)); } const links = document.createElement("div"); links.className = "kab-god-links"; if (letterId) { links.appendChild(createNavButton(letterSymbol || "!", "nav:alphabet", { alphabet: "hebrew", hebrewLetterId: letterId })); } if (pathNo != null) { links.appendChild(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })); } if (tarotCard || tarotTrumpNumber != null) { links.appendChild(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", { cardName: tarotCard, trumpNumber: tarotTrumpNumber })); } if (links.childElementCount) { const linksCard = document.createElement("div"); linksCard.className = "planet-meta-card"; linksCard.innerHTML = "Correspondence Links"; linksCard.appendChild(links); bodyEl.appendChild(linksCard); } return true; } function renderEdgeCard(context, wall, detailBodyEl, wallEdgeDirections) { const { state, normalizeId, normalizeEdgeId, formatDirectionName, formatEdgeName, getEdgeById, getEdgesForWall, getEdges, getEdgeWalls, getEdgeLetterId, getEdgeLetter, getEdgePathEntry, getEdgeAstrologySymbol, toFiniteNumber } = context; const wallId = normalizeId(wall?.id); const selectedEdge = getEdgeById(state.selectedEdgeId) || getEdgesForWall(wallId)[0] || getEdges()[0] || null; if (!selectedEdge) { return; } state.selectedEdgeId = normalizeEdgeId(selectedEdge.id); const edgeDirection = wallEdgeDirections.get(normalizeEdgeId(selectedEdge.id)); const edgeName = edgeDirection ? formatDirectionName(edgeDirection) : (toDisplayText(selectedEdge.name) || formatEdgeName(selectedEdge.id)); const edgeWalls = getEdgeWalls(selectedEdge) .map((entry) => entry.charAt(0).toUpperCase() + entry.slice(1)) .join(" · "); const edgeLetterId = getEdgeLetterId(selectedEdge); const edgeLetter = getEdgeLetter(selectedEdge); const edgePath = getEdgePathEntry(selectedEdge); const astrologyType = toDisplayText(edgePath?.astrology?.type); const astrologyName = toDisplayText(edgePath?.astrology?.name); const astrologySymbol = getEdgeAstrologySymbol(selectedEdge); const astrologyText = astrologySymbol && astrologyName ? `${astrologySymbol} ${astrologyName}` : astrologySymbol || astrologyName; const pathNo = toFiniteNumber(edgePath?.pathNumber); const tarotCard = toDisplayText(edgePath?.tarot?.card); const tarotTrumpNumber = toFiniteNumber(edgePath?.tarot?.trumpNumber); const edgeCard = document.createElement("div"); edgeCard.className = "planet-meta-card"; const title = document.createElement("strong"); title.textContent = `Edge · ${edgeName}`; edgeCard.appendChild(title); const dlWrap = document.createElement("div"); dlWrap.className = "planet-text"; dlWrap.innerHTML = `
Direction
${toDetailValueMarkup(edgeName)}
Edge
${toDetailValueMarkup(edgeWalls)}
Letter
${toDetailValueMarkup(edgeLetter)}
Astrology
${toDetailValueMarkup(astrologyText)}
Tarot
${toDetailValueMarkup(tarotCard)}
`; edgeCard.appendChild(dlWrap); if (Array.isArray(selectedEdge.keywords) && selectedEdge.keywords.length) { const keywords = document.createElement("p"); keywords.className = "planet-text"; keywords.textContent = selectedEdge.keywords.join(", "); edgeCard.appendChild(keywords); } if (selectedEdge.description) { const description = document.createElement("p"); description.className = "planet-text"; description.textContent = selectedEdge.description; edgeCard.appendChild(description); } const links = document.createElement("div"); links.className = "kab-god-links"; if (edgeLetterId) { links.appendChild(createNavButton(edgeLetter || "!", "nav:alphabet", { alphabet: "hebrew", hebrewLetterId: edgeLetterId })); } if (astrologyType === "zodiac" && astrologyName) { links.appendChild(createNavButton(astrologyName, "nav:zodiac", { signId: normalizeId(astrologyName) })); } if (tarotCard) { links.appendChild(createNavButton(tarotCard, "nav:tarot-trump", { cardName: tarotCard, trumpNumber: tarotTrumpNumber })); } if (pathNo != null) { links.appendChild(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })); } if (links.childElementCount) { edgeCard.appendChild(links); } detailBodyEl.appendChild(edgeCard); } function renderWallDetail(context) { const { state, elements, walls, normalizeId, normalizeEdgeId, formatDirectionName, formatEdgeName, getWallById, getEdgesForWall, getWallEdgeDirections, getWallFaceLetterId, getWallFaceLetter, getHebrewLetterName, getEdgeLetter, localDirectionOrder, localDirectionRank, onSelectWall, onSelectEdge } = context; const wall = getWallById(state.selectedWallId) || walls[0] || null; if (!wall || !elements?.detailNameEl || !elements?.detailSubEl || !elements?.detailBodyEl) { if (elements?.detailNameEl) { elements.detailNameEl.textContent = "Cube data unavailable"; } if (elements?.detailSubEl) { elements.detailSubEl.textContent = "Could not load cube dataset."; } if (elements?.detailBodyEl) { elements.detailBodyEl.innerHTML = ""; } return; } state.selectedWallId = normalizeId(wall.id); const wallPlanet = toDisplayText(wall?.planet) || "!"; const wallElement = toDisplayText(wall?.element) || "!"; const wallFaceLetterId = getWallFaceLetterId(wall); const wallFaceLetter = getWallFaceLetter(wall); const wallFaceLetterText = wallFaceLetterId ? `${wallFaceLetter ? `${wallFaceLetter} ` : ""}${toDisplayText(wallFaceLetterId)}` : ""; elements.detailNameEl.textContent = `${wall.name} Wall`; elements.detailSubEl.textContent = `${wallElement} · ${wallPlanet}`; const bodyEl = elements.detailBodyEl; bodyEl.innerHTML = ""; const summary = document.createElement("div"); summary.className = "planet-text"; summary.innerHTML = `
Opposite
${toDetailValueMarkup(wall.opposite)}
Face Letter
${toDetailValueMarkup(wallFaceLetterText)}
Element
${toDetailValueMarkup(wall.element)}
Planet
${toDetailValueMarkup(wall.planet)}
Archangel
${toDetailValueMarkup(wall.archangel)}
`; bodyEl.appendChild(createMetaCard("Wall Details", summary)); if (Array.isArray(wall.keywords) && wall.keywords.length) { bodyEl.appendChild(createMetaCard("Keywords", wall.keywords.join(", "))); } if (wall.description) { bodyEl.appendChild(createMetaCard("Description", wall.description)); } const wallLinksCard = document.createElement("div"); wallLinksCard.className = "planet-meta-card"; wallLinksCard.innerHTML = "Correspondence Links"; const wallLinks = document.createElement("div"); wallLinks.className = "kab-god-links"; if (wallFaceLetterId) { const wallFaceLetterName = getHebrewLetterName(wallFaceLetterId) || toDisplayText(wallFaceLetterId); const faceLetterText = [wallFaceLetter, wallFaceLetterName].filter(Boolean).join(" "); const faceLetterLabel = faceLetterText ? `Face ${faceLetterText}` : "Face !"; wallLinks.appendChild(createNavButton(faceLetterLabel, "nav:alphabet", { alphabet: "hebrew", hebrewLetterId: wallFaceLetterId })); } const wallAssociations = wall.associations || {}; if (wallAssociations.planetId) { wallLinks.appendChild(createNavButton(toDisplayText(wall.planet) || "!", "nav:planet", { planetId: wallAssociations.planetId })); } if (wallAssociations.godName) { wallLinks.appendChild(createNavButton(wallAssociations.godName, "nav:gods", { godName: wallAssociations.godName })); } if (wall.oppositeWallId) { const oppositeWall = getWallById(wall.oppositeWallId); const internal = document.createElement("button"); internal.type = "button"; internal.className = "kab-god-link"; internal.textContent = `Opposite: ${oppositeWall?.name || wall.oppositeWallId}`; internal.addEventListener("click", () => { onSelectWall(wall.oppositeWallId); }); wallLinks.appendChild(internal); } if (wallLinks.childElementCount) { wallLinksCard.appendChild(wallLinks); bodyEl.appendChild(wallLinksCard); } const edgesCard = document.createElement("div"); edgesCard.className = "planet-meta-card"; edgesCard.innerHTML = "Wall Edges"; const chips = document.createElement("div"); chips.className = "kab-chips"; const wallEdgeDirections = getWallEdgeDirections(wall); const wallEdges = getEdgesForWall(wall) .slice() .sort((left, right) => { const leftDirection = wallEdgeDirections.get(normalizeEdgeId(left?.id)); const rightDirection = wallEdgeDirections.get(normalizeEdgeId(right?.id)); const leftRank = localDirectionRank[leftDirection] ?? localDirectionOrder.length; const rightRank = localDirectionRank[rightDirection] ?? localDirectionOrder.length; if (leftRank !== rightRank) { return leftRank - rightRank; } return normalizeEdgeId(left?.id).localeCompare(normalizeEdgeId(right?.id)); }); wallEdges.forEach((edge) => { const id = normalizeEdgeId(edge.id); const chipLetter = getEdgeLetter(edge); const chipIsMissing = !chipLetter; const direction = wallEdgeDirections.get(id); const directionLabel = direction ? formatDirectionName(direction) : (toDisplayText(edge.name) || formatEdgeName(edge.id)); const chip = document.createElement("span"); chip.className = `kab-chip${id === normalizeEdgeId(state.selectedEdgeId) ? " is-active" : ""}${chipIsMissing ? " is-missing" : ""}`; chip.setAttribute("role", "button"); chip.setAttribute("tabindex", "0"); chip.textContent = `${directionLabel} · ${chipLetter || "!"}`; const selectEdge = () => { onSelectEdge(id, wall.id); }; chip.addEventListener("click", selectEdge); chip.addEventListener("keydown", (event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); selectEdge(); } }); chips.appendChild(chip); }); edgesCard.appendChild(chips); bodyEl.appendChild(edgesCard); renderEdgeCard(context, wall, bodyEl, wallEdgeDirections); } function renderDetail(context) { if (context.state.selectedNodeType === "connector" && renderConnectorDetail(context)) { return; } if (context.state.selectedNodeType === "center" && renderCenterDetail(context)) { return; } renderWallDetail(context); } window.CubeDetailUi = { renderDetail }; })();