fixed linking

This commit is contained in:
2026-03-07 14:15:09 -08:00
parent d44483de5e
commit ed9b3bb257
8 changed files with 784 additions and 516 deletions

View File

@@ -122,6 +122,7 @@
const cubeDetailUi = window.CubeDetailUi || {};
const cubeChassisUi = window.CubeChassisUi || {};
const cubeMathHelpers = window.CubeMathHelpers || {};
const cubeSelectionHelpers = window.CubeSelectionHelpers || {};
function getElements() {
return {
@@ -256,6 +257,10 @@
throw new Error("CubeMathHelpers.createCubeMathHelpers is unavailable. Ensure app/ui-cube-math.js loads before app/ui-cube.js.");
}
if (typeof cubeSelectionHelpers.createCubeSelectionHelpers !== "function") {
throw new Error("CubeSelectionHelpers.createCubeSelectionHelpers is unavailable. Ensure app/ui-cube-selection.js loads before app/ui-cube.js.");
}
function normalizeAngle(angle) {
return cubeMathUi.normalizeAngle(angle);
}
@@ -432,6 +437,27 @@
getCubeCenterData
});
const cubeSelectionUi = cubeSelectionHelpers.createCubeSelectionHelpers({
state,
normalizeId,
normalizeEdgeId,
normalizeLetterKey,
toFiniteNumber,
getWalls,
getWallById,
getEdges,
getEdgeById,
getEdgeWalls,
getEdgesForWall,
getEdgeLetterId,
getWallFaceLetterId,
getEdgePathEntry,
getConnectorById,
snapRotationToWall,
render,
getElements
});
function getEdgeAstrologySymbol(edge) {
return cubeMathUi.getEdgeAstrologySymbol(edge);
}
@@ -488,26 +514,7 @@
}
function applyPlacement(placement) {
const fallbackWallId = normalizeId(getWalls()[0]?.id);
const nextWallId = normalizeId(placement?.wallId || placement?.wall?.id || state.selectedWallId || fallbackWallId);
const wall = getWallById(nextWallId);
if (!wall) {
return false;
}
state.selectedWallId = normalizeId(wall.id);
const candidateEdgeId = normalizeEdgeId(placement?.edgeId || placement?.edge?.id);
const wallEdges = getEdgesForWall(state.selectedWallId);
const resolvedEdgeId = candidateEdgeId && getEdgeById(candidateEdgeId)
? candidateEdgeId
: normalizeEdgeId(wallEdges[0]?.id || getEdges()[0]?.id);
state.selectedEdgeId = resolvedEdgeId;
state.selectedNodeType = "wall";
state.selectedConnectorId = null;
render(getElements());
return true;
return cubeSelectionUi.applyPlacement(placement);
}
function toDisplayText(value) {
@@ -559,33 +566,7 @@
}
function selectEdgeById(edgeId, preferredWallId = "") {
const edge = getEdgeById(edgeId);
if (!edge) {
return false;
}
const currentWallId = normalizeId(state.selectedWallId);
const preferredId = normalizeId(preferredWallId);
const edgeWalls = getEdgeWalls(edge);
const nextWallId = preferredId && edgeWalls.includes(preferredId)
? preferredId
: (edgeWalls.includes(currentWallId) ? currentWallId : (edgeWalls[0] || currentWallId));
state.selectedEdgeId = normalizeEdgeId(edge.id);
state.selectedNodeType = "wall";
state.selectedConnectorId = null;
if (nextWallId) {
if (nextWallId !== currentWallId) {
state.selectedWallId = nextWallId;
snapRotationToWall(nextWallId);
} else if (!state.selectedWallId) {
state.selectedWallId = nextWallId;
}
}
render(getElements());
return true;
return cubeSelectionUi.selectEdgeById(edgeId, preferredWallId);
}
function renderDetail(elements, walls) {
@@ -710,195 +691,19 @@
}
function selectWallById(wallId) {
if (!state.initialized) {
return false;
}
const wall = getWallById(wallId);
if (!wall) {
return false;
}
state.selectedWallId = normalizeId(wall.id);
state.selectedEdgeId = normalizeEdgeId(getEdgesForWall(state.selectedWallId)[0]?.id || getEdges()[0]?.id);
state.selectedNodeType = "wall";
state.selectedConnectorId = null;
snapRotationToWall(state.selectedWallId);
render(getElements());
return true;
return cubeSelectionUi.selectWallById(wallId);
}
function selectConnectorById(connectorId) {
if (!state.initialized) {
return false;
}
const connector = getConnectorById(connectorId);
if (!connector) {
return false;
}
const fromWallId = normalizeId(connector.fromWallId);
if (fromWallId && getWallById(fromWallId)) {
state.selectedWallId = fromWallId;
state.selectedEdgeId = normalizeEdgeId(getEdgesForWall(fromWallId)[0]?.id || getEdges()[0]?.id);
snapRotationToWall(fromWallId);
}
state.showConnectorLines = true;
state.selectedNodeType = "connector";
state.selectedConnectorId = normalizeId(connector.id);
render(getElements());
return true;
return cubeSelectionUi.selectConnectorById(connectorId);
}
function selectCenterNode() {
if (!state.initialized) {
return false;
}
state.showPrimalPoint = true;
state.selectedNodeType = "center";
state.selectedConnectorId = null;
render(getElements());
return true;
return cubeSelectionUi.selectCenterNode();
}
function selectPlacement(criteria = {}) {
if (!state.initialized) {
return false;
}
const wallId = normalizeId(criteria.wallId);
const connectorId = normalizeId(criteria.connectorId);
const edgeId = normalizeEdgeId(criteria.edgeId || criteria.directionId);
const hebrewLetterId = normalizeLetterKey(criteria.hebrewLetterId);
const signId = normalizeId(criteria.signId || criteria.zodiacSignId);
const planetId = normalizeId(criteria.planetId);
const pathNo = toFiniteNumber(criteria.pathNo || criteria.kabbalahPathNumber);
const trumpNo = toFiniteNumber(criteria.trumpNumber || criteria.tarotTrumpNumber);
const nodeType = normalizeId(criteria.nodeType);
const centerRequested = nodeType === "center"
|| Boolean(criteria.center)
|| Boolean(criteria.primalPoint)
|| normalizeId(criteria.centerId) === "primal-point";
const edges = getEdges();
const findEdgeBy = (predicate) => edges.find((edge) => predicate(edge)) || null;
const findWallForEdge = (edge, preferredWallId) => {
const edgeWalls = getEdgeWalls(edge);
if (preferredWallId && edgeWalls.includes(preferredWallId)) {
return preferredWallId;
}
return edgeWalls[0] || normalizeId(getWalls()[0]?.id);
};
if (connectorId) {
return selectConnectorById(connectorId);
}
if (centerRequested) {
return selectCenterNode();
}
if (edgeId) {
const edge = getEdgeById(edgeId);
if (!edge) {
return false;
}
return applyPlacement({
wallId: findWallForEdge(edge, wallId),
edgeId
});
}
if (wallId) {
const wall = getWallById(wallId);
if (!wall) {
return false;
}
// if an explicit edge id was not provided (or was empty) we treat this
// as a request to show the wall/face itself rather than any particular
// edge direction. `applyPlacement` only knows how to highlight edges,
// so we fall back to selecting the wall directly in that case. this
// is the behaviour we want when navigating from a "face" letter like
// dalet, where the placement computed by ui-alphabet leaves edgeId
// blank.
if (!edgeId) {
return selectWallById(wallId);
}
const firstEdge = getEdgesForWall(wallId)[0] || null;
return applyPlacement({ wallId, edgeId: firstEdge?.id });
}
if (hebrewLetterId) {
const byHebrew = findEdgeBy((edge) => getEdgeLetterId(edge) === hebrewLetterId);
if (byHebrew) {
return applyPlacement({
wallId: findWallForEdge(byHebrew),
edgeId: byHebrew.id
});
}
const byWallFace = getWalls().find((wall) => getWallFaceLetterId(wall) === hebrewLetterId) || null;
if (byWallFace) {
const byWallFaceId = normalizeId(byWallFace.id);
const firstEdge = getEdgesForWall(byWallFaceId)[0] || null;
return applyPlacement({ wallId: byWallFaceId, edgeId: firstEdge?.id });
}
}
if (signId) {
const bySign = findEdgeBy((edge) => {
const astrology = getEdgePathEntry(edge)?.astrology || {};
return normalizeId(astrology.type) === "zodiac" && normalizeId(astrology.name) === signId;
});
if (bySign) {
return applyPlacement({
wallId: findWallForEdge(bySign),
edgeId: bySign.id
});
}
}
if (pathNo != null) {
const byPath = findEdgeBy((edge) => toFiniteNumber(getEdgePathEntry(edge)?.pathNumber) === pathNo);
if (byPath) {
return applyPlacement({
wallId: findWallForEdge(byPath),
edgeId: byPath.id
});
}
}
if (trumpNo != null) {
const byTrump = findEdgeBy((edge) => {
const tarot = getEdgePathEntry(edge)?.tarot || {};
return toFiniteNumber(tarot.trumpNumber) === trumpNo;
});
if (byTrump) {
return applyPlacement({
wallId: findWallForEdge(byTrump),
edgeId: byTrump.id
});
}
}
if (planetId) {
const wall = getWalls().find((entry) => normalizeId(entry?.associations?.planetId) === planetId);
if (wall) {
const wallIdByPlanet = normalizeId(wall.id);
return applyPlacement({
wallId: wallIdByPlanet,
edgeId: getEdgesForWall(wallIdByPlanet)[0]?.id
});
}
}
return false;
return cubeSelectionUi.selectPlacement(criteria);
}
function selectByHebrewLetterId(hebrewLetterId) {