UNPKG

kaabalah

Version:

The de-facto library for any esoteric calculations and tooling

1,566 lines (1,563 loc) 58.4 kB
import { calculateKaabalisticLifePath, calculateStraightAcrossReductionLifePath } from './chunk-3UJPBUY4.mjs'; import { PLANET_AND_NODE_NAMES, computeAspects, DEFAULT_ASPECT_SPECS } from './chunk-7YU7TRCG.mjs'; import { calculateGematria } from './chunk-QS5XAAAG.mjs'; import { getTarotArchetype, ARKANNUS } from './chunk-ITESL6GR.mjs'; import { getCanonicalTree } from './chunk-6N5YC2WD.mjs'; import { SPHERES, id, WESTERN_ZODIAC_SIGNS, PLANETS, WESTERN_HOUSES, parseId, WESTERN_ASPECTS } from './chunk-5K4OQ4UB.mjs'; // src/semantic/kaabalistic.ts var canonicalTree = getCanonicalTree({ system: "kaabalah", parts: ["westernAstrology"] }); var orderedSphereIds = [ SPHERES.KETHER, SPHERES.CHOKHMAH, SPHERES.BINAH, SPHERES.DAATH, SPHERES.CHESED, SPHERES.GEBURAH, SPHERES.TIPHARETH, SPHERES.NETZACH, SPHERES.HOD, SPHERES.YESOD, SPHERES.MALKUTH ].map((sphere) => id("sphere" /* SPHERE */, sphere)); var orderedPathIds = Array.from( { length: 22 }, (_, index) => id("path" /* PATH */, index + 1) ); var orderedSpheres = Object.freeze( orderedSphereIds.map((sphereId) => canonicalTree.getNode(sphereId)).filter((node) => Boolean(node)) ); var orderedPaths = Object.freeze( orderedPathIds.map((pathId) => canonicalTree.getNode(pathId)).filter((node) => Boolean(node)) ); var SIGN_SYMBOLS = [ { kind: "sign", key: "aries", label: "Aries", shortLabel: "Aries", glyph: "\u2648", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.ARIES) }, { kind: "sign", key: "taurus", label: "Taurus", shortLabel: "Taurus", glyph: "\u2649", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.TAURUS) }, { kind: "sign", key: "gemini", label: "Gemini", shortLabel: "Gemini", glyph: "\u264A", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.GEMINI) }, { kind: "sign", key: "cancer", label: "Cancer", shortLabel: "Cancer", glyph: "\u264B", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.CANCER) }, { kind: "sign", key: "leo", label: "Leo", shortLabel: "Leo", glyph: "\u264C", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.LEO) }, { kind: "sign", key: "virgo", label: "Virgo", shortLabel: "Virgo", glyph: "\u264D", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.VIRGO) }, { kind: "sign", key: "libra", label: "Libra", shortLabel: "Libra", glyph: "\u264E", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.LIBRA) }, { kind: "sign", key: "scorpio", label: "Scorpio", shortLabel: "Scorpio", glyph: "\u264F", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.SCORPIO) }, { kind: "sign", key: "sagittarius", label: "Sagittarius", shortLabel: "Sagittarius", glyph: "\u2650", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.SAGITTARIUS) }, { kind: "sign", key: "capricorn", label: "Capricorn", shortLabel: "Capricorn", glyph: "\u2651", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.CAPRICORN) }, { kind: "sign", key: "aquarius", label: "Aquarius", shortLabel: "Aquarius", glyph: "\u2652", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.AQUARIUS) }, { kind: "sign", key: "pisces", label: "Pisces", shortLabel: "Pisces", glyph: "\u2653", id: id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, WESTERN_ZODIAC_SIGNS.PISCES) } ]; var PLANET_SYMBOLS = [ { kind: "planet", key: "sun", label: PLANETS.SUN, shortLabel: PLANETS.SUN, glyph: "\u2609", id: id("planet" /* PLANET */, PLANETS.SUN) }, { kind: "planet", key: "moon", label: PLANETS.MOON, shortLabel: PLANETS.MOON, glyph: "\u263D", id: id("planet" /* PLANET */, PLANETS.MOON) }, { kind: "planet", key: "mercury", label: PLANETS.MERCURY, shortLabel: PLANETS.MERCURY, glyph: "\u263F", id: id("planet" /* PLANET */, PLANETS.MERCURY) }, { kind: "planet", key: "venus", label: PLANETS.VENUS, shortLabel: PLANETS.VENUS, glyph: "\u2640", id: id("planet" /* PLANET */, PLANETS.VENUS) }, { kind: "planet", key: "mars", label: PLANETS.MARS, shortLabel: PLANETS.MARS, glyph: "\u2642", id: id("planet" /* PLANET */, PLANETS.MARS) }, { kind: "planet", key: "jupiter", label: PLANETS.JUPITER, shortLabel: PLANETS.JUPITER, glyph: "\u2643", id: id("planet" /* PLANET */, PLANETS.JUPITER) }, { kind: "planet", key: "saturn", label: PLANETS.SATURN, shortLabel: PLANETS.SATURN, glyph: "\u2644", id: id("planet" /* PLANET */, PLANETS.SATURN) }, { kind: "planet", key: "uranus", label: PLANETS.URANUS, shortLabel: PLANETS.URANUS, glyph: "\u2645", id: id("planet" /* PLANET */, PLANETS.URANUS) }, { kind: "planet", key: "neptune", label: PLANETS.NEPTUNE, shortLabel: PLANETS.NEPTUNE, glyph: "\u2646", id: id("planet" /* PLANET */, PLANETS.NEPTUNE) }, { kind: "planet", key: "pluto", label: PLANETS.PLUTO, shortLabel: PLANETS.PLUTO, glyph: "\u2647", id: id("planet" /* PLANET */, PLANETS.PLUTO) }, { kind: "planet", key: "earth", label: PLANETS.EARTH, shortLabel: PLANETS.EARTH, glyph: "\u2295", id: id("planet" /* PLANET */, PLANETS.EARTH) }, { kind: "planet", key: "chiron", label: "Chiron", shortLabel: "Chiron", glyph: "\u26B7", aliases: [PLANET_AND_NODE_NAMES[15]] } ]; var ANGLE_SYMBOLS = [ { kind: "angle", key: "asc", label: "ASC", shortLabel: "ASC", glyph: "ASC", id: id("house" /* HOUSE */, WESTERN_HOUSES.ASCENDANT), aliases: ["ascendant"] }, { kind: "angle", key: "mc", label: "MC", shortLabel: "MC", glyph: "MC", id: id("house" /* HOUSE */, WESTERN_HOUSES.MEDIUM_COELI), aliases: ["medium coeli"] }, { kind: "angle", key: "dc", label: "DC", shortLabel: "DC", glyph: "DC", id: id("house" /* HOUSE */, WESTERN_HOUSES.DESCENDANT), aliases: ["descendant"] }, { kind: "angle", key: "ic", label: "IC", shortLabel: "IC", glyph: "IC", id: id("house" /* HOUSE */, WESTERN_HOUSES.IMUM_COELI), aliases: ["imum coeli"] }, { kind: "angle", key: "vertex", label: "Vertex", shortLabel: "Vertex", glyph: "Vtx" } ]; var NODE_SYMBOLS = [ { kind: "node", key: "wheel of fortune", label: "Wheel of Fortune", shortLabel: "Wheel of Fortune", glyph: "\u{1BC9C}", aliases: [PLANET_AND_NODE_NAMES["parsFortunae" /* PARS_FORTUNAE */], "pars fortunae", "parsfortunae"] }, { kind: "node", key: "mean node", label: "Mean Node", shortLabel: "Mean Node", glyph: "\u260A", aliases: [PLANET_AND_NODE_NAMES[10]] }, { kind: "node", key: "true node", label: "True Node", shortLabel: "True Node", glyph: "\u260A", aliases: [PLANET_AND_NODE_NAMES[11]] }, { kind: "node", key: "lilith mean", label: "Lilith Mean", shortLabel: "Lilith Mean", glyph: "\u26B8", aliases: [PLANET_AND_NODE_NAMES[12]] }, { kind: "node", key: "lilith true", label: "Lilith True", shortLabel: "Lilith True", glyph: "\u26B8", aliases: [PLANET_AND_NODE_NAMES[13]] } ]; var symbolRegistry = createSymbolRegistry([ ...SIGN_SYMBOLS, ...PLANET_SYMBOLS, ...ANGLE_SYMBOLS, ...NODE_SYMBOLS ]); var classicalPlanetKeys = /* @__PURE__ */ new Set([ normalizeLookupKey(PLANETS.SUN), normalizeLookupKey(PLANETS.MOON), normalizeLookupKey(PLANETS.MERCURY), normalizeLookupKey(PLANETS.VENUS), normalizeLookupKey(PLANETS.MARS), normalizeLookupKey(PLANETS.JUPITER), normalizeLookupKey(PLANETS.SATURN) ]); var defaultExcludedAstrologyPoints = /* @__PURE__ */ new Set([ normalizeLookupKey("True Node"), normalizeLookupKey("Lilith True") ]); var planetCarrierSphereIdsByKey = createPlanetCarrierSphereIdsByKey(canonicalTree); var classicalPlanetPathIdsByKey = createClassicalPlanetPathIdsByKey(canonicalTree); var angleCarrierSphereIdsByKey = createAngleCarrierSphereIdsByKey(); function normalizeLookupKey(value) { return value.trim().toLowerCase(); } function createSymbolRegistry(entries) { const byKey = /* @__PURE__ */ new Map(); for (const entry of entries) { const frozen = Object.freeze({ kind: entry.kind, key: entry.key, label: entry.label, shortLabel: entry.shortLabel, glyph: entry.glyph, ...entry.id ? { id: entry.id } : {} }); byKey.set(normalizeLookupKey(entry.key), frozen); byKey.set(normalizeLookupKey(entry.label), frozen); byKey.set(normalizeLookupKey(entry.shortLabel), frozen); for (const alias of entry.aliases ?? []) { byKey.set(normalizeLookupKey(alias), frozen); } if (entry.id) { byKey.set(normalizeLookupKey(entry.id), frozen); byKey.set(normalizeLookupKey(parseId(entry.id)), frozen); } } return Object.freeze({ byKey, planets: Object.freeze(entries.filter((entry) => entry.kind === "planet").map((entry) => byKey.get(normalizeLookupKey(entry.key)))), signs: Object.freeze(entries.filter((entry) => entry.kind === "sign").map((entry) => byKey.get(normalizeLookupKey(entry.key)))), angles: Object.freeze(entries.filter((entry) => entry.kind === "angle").map((entry) => byKey.get(normalizeLookupKey(entry.key)))), nodes: Object.freeze(entries.filter((entry) => entry.kind === "node").map((entry) => byKey.get(normalizeLookupKey(entry.key)))) }); } function createClassicalPlanetPathIdsByKey(tree) { const registry = /* @__PURE__ */ new Map(); const mutable = /* @__PURE__ */ new Map(); for (const pathId of orderedPathIds) { const planet = tree.getCorrespondences(pathId, { type: "planet" /* PLANET */, depth: 1, limit: 1 })[0]?.node; if (!planet) { continue; } const key = normalizeLookupKey(planet.name ?? parseId(planet.id)); if (!classicalPlanetKeys.has(key)) { continue; } const bucket = mutable.get(key) ?? []; bucket.push(pathId); mutable.set(key, bucket); } for (const [key, value] of mutable.entries()) { registry.set(key, Object.freeze([...value])); } return registry; } function createPlanetCarrierSphereIdsByKey(tree) { const registry = /* @__PURE__ */ new Map(); for (const symbol of PLANET_SYMBOLS) { if (!("id" in symbol) || !symbol.id) { continue; } const sphereIds = tree.getCorrespondences(symbol.id, { type: "sphere" /* SPHERE */, depth: 1 }).map((match) => match.node.id); if (!sphereIds.length) { continue; } registry.set( normalizeLookupKey(symbol.label), Object.freeze([...new Set(sphereIds)]) ); } return registry; } function createAngleCarrierSphereIdsByKey() { return /* @__PURE__ */ new Map([ [ normalizeLookupKey("ASC"), Object.freeze([id("sphere" /* SPHERE */, SPHERES.MALKUTH)]) ] ]); } function getTargetType(targetId) { return String(targetId).startsWith(`${"sphere" /* SPHERE */}:`) ? "sphere" : "path"; } function getTargetName(targetId) { return getTargetType(targetId) === "sphere" ? parseId(targetId) : `Path ${parseId(targetId)}`; } function getTargetCountMap(targets) { const reduceMap = {}; for (const target of targets) { reduceMap[target.targetId] = (reduceMap[target.targetId] ?? 0) + 1; } return reduceMap; } function toSummaryTargets(reduceMap) { return Object.entries(reduceMap).map(([targetId, count]) => ({ id: targetId, type: getTargetType(targetId), name: getTargetName(targetId), count: count ?? 0 })); } function groupByKey(items, getKey) { const grouped = {}; for (const item of items) { const key = getKey(item); const bucket = grouped[key] ?? []; bucket.push(item); grouped[key] = bucket; } return grouped; } function normalizeSignName(sign) { const rawSign = typeof sign === "string" && sign.startsWith(`${"westernZodiacSign" /* WESTERN_ZODIAC_SIGN */}:`) ? parseId(sign) : typeof sign === "string" ? sign : parseId(sign); const key = normalizeLookupKey(rawSign); const metadata = symbolRegistry.byKey.get(key); if (!metadata || metadata.kind !== "sign") { return void 0; } return metadata.label; } function normalizePlanetName(planet) { const rawPlanet = planet.startsWith(`${"planet" /* PLANET */}:`) ? parseId(planet) : planet; const key = normalizeLookupKey(rawPlanet); const metadata = symbolRegistry.byKey.get(key); if (metadata?.kind === "planet") { return metadata.label; } return PLANET_AND_NODE_NAMES[rawPlanet] ?? rawPlanet; } function lookupPlanetSymbolMetadata(planet) { const rawPlanet = planet.startsWith(`${"planet" /* PLANET */}:`) ? parseId(planet) : planet; const metadata = symbolRegistry.byKey.get(normalizeLookupKey(rawPlanet)); return metadata?.kind === "planet" ? metadata : void 0; } function lookupSignSymbolMetadata(sign) { const rawSign = typeof sign === "string" && sign.startsWith(`${"westernZodiacSign" /* WESTERN_ZODIAC_SIGN */}:`) ? parseId(sign) : typeof sign === "string" ? sign : parseId(sign); const metadata = symbolRegistry.byKey.get(normalizeLookupKey(rawSign)); return metadata?.kind === "sign" ? metadata : void 0; } function normalizeAngleName(angle) { const rawAngle = angle.startsWith(`${"house" /* HOUSE */}:`) ? parseId(angle) : angle; const metadata = symbolRegistry.byKey.get(normalizeLookupKey(rawAngle)); return metadata?.kind === "angle" ? metadata.label : rawAngle; } function listPlanetSymbolMetadata() { return symbolRegistry.planets; } function listZodiacSignSymbolMetadata() { return symbolRegistry.signs; } function listAngleSymbolMetadata() { return symbolRegistry.angles; } function listNodeSymbolMetadata() { return symbolRegistry.nodes; } function getPlanetSymbolMetadata(lookup) { return lookupPlanetSymbolMetadata(lookup); } function getZodiacSignSymbolMetadata(lookup) { return lookupSignSymbolMetadata(lookup); } function getAngleSymbolMetadata(lookup) { const rawLookup = lookup.startsWith(`${"house" /* HOUSE */}:`) ? parseId(lookup) : lookup; const metadata = symbolRegistry.byKey.get(normalizeLookupKey(rawLookup)); return metadata?.kind === "angle" ? metadata : void 0; } function getNodeSymbolMetadata(lookup) { const metadata = symbolRegistry.byKey.get(normalizeLookupKey(lookup)); return metadata?.kind === "node" ? metadata : void 0; } function normalizeChartInput(input) { const planets = Array.isArray(input.planets) ? [...input.planets] : Object.values(input.planets); const nodes = input.nodes ? Array.isArray(input.nodes) ? [...input.nodes] : Object.values(input.nodes) : []; return { planets, nodes, houses: input.houses, aspects: input.aspects }; } function getAstrologySourceType(name) { return getNodeSymbolMetadata(name) ? "node" : "planet"; } function getAstrologySourceGlyph(sourceType, sourceName) { if (sourceType === "angle") { return getAngleSymbolMetadata(sourceName)?.glyph ?? sourceName; } if (sourceType === "node") { return getNodeSymbolMetadata(sourceName)?.glyph ?? sourceName.slice(0, 1).toUpperCase(); } return lookupPlanetSymbolMetadata(sourceName)?.glyph ?? sourceName.slice(0, 1).toUpperCase(); } function getHouseNodeByNumber(houseNumber) { return canonicalTree.getCorrespondences(id("number" /* NUMBER */, houseNumber), { type: "house" /* HOUSE */, depth: 1, limit: 1 })[0]?.node; } function buildSignTargets(sign) { const signId = id("westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, sign); const result = []; for (const match of canonicalTree.getCorrespondences(signId, { type: ["sphere" /* SPHERE */, "path" /* PATH */, "westernElement" /* WESTERN_ELEMENT */], depth: 1 })) { if (match.node.type === "sphere" /* SPHERE */) { result.push({ targetId: match.node.id, targetType: "sphere", targetName: getTargetName(match.node.id), mapping: "sign-sphere", distance: match.distance, sign }); continue; } if (match.node.type === "path" /* PATH */) { result.push({ targetId: match.node.id, targetType: "path", targetName: getTargetName(match.node.id), mapping: "sign-path", distance: match.distance, sign }); continue; } const element = parseId(match.node.id); for (const elementPath of canonicalTree.getCorrespondences(match.node.id, { type: "path" /* PATH */, depth: 1 })) { result.push({ targetId: elementPath.node.id, targetType: "path", targetName: getTargetName(elementPath.node.id), mapping: "element-path", distance: elementPath.distance + match.distance, sign, element }); } for (const elementSphere of canonicalTree.getCorrespondences(match.node.id, { type: "sphere" /* SPHERE */, depth: 1 })) { result.push({ targetId: elementSphere.node.id, targetType: "sphere", targetName: getTargetName(elementSphere.node.id), mapping: "element-sphere", distance: elementSphere.distance + match.distance, sign, element }); } } return dedupeTargets(result); } function buildCarrierSphereTargets(lookup, sign) { const isPlanetLookup = lookup.kind === "planet"; const sourceLabel = isPlanetLookup ? normalizePlanetName(lookup.planet) : normalizeAngleName(lookup.angle); const sourceKey = normalizeLookupKey(sourceLabel); const sphereIds = isPlanetLookup ? planetCarrierSphereIdsByKey.get(sourceKey) : angleCarrierSphereIdsByKey.get(sourceKey); if (!sphereIds?.length) { return []; } return sphereIds.map((targetId) => ({ targetId, targetType: "sphere", targetName: getTargetName(targetId), mapping: "carrier-sphere", distance: 1, sign, ...isPlanetLookup ? { planet: sourceLabel } : {} })); } function dedupeTargets(targets) { const seen = /* @__PURE__ */ new Set(); return targets.filter((target) => { const key = [ target.targetId, target.mapping, target.sign ?? "", target.element ?? "", target.planet ?? "" ].join("|"); if (seen.has(key)) { return false; } seen.add(key); return true; }); } function createCorrespondenceSource(lookup, sign, element) { if (lookup.kind === "sign") { const symbol = lookupSignSymbolMetadata(sign ?? lookup.sign); return { kind: "sign", key: symbol.key, label: symbol.label, shortLabel: symbol.shortLabel, glyph: symbol.glyph, ...sign ? { sign } : {}, ...element ? { element } : {} }; } if (lookup.kind === "planet") { const symbol = lookupPlanetSymbolMetadata(lookup.planet); const label = normalizePlanetName(lookup.planet); return { kind: "planet", key: normalizeLookupKey(label), label, shortLabel: symbol?.shortLabel ?? label, glyph: symbol?.glyph ?? label.slice(0, 1).toUpperCase(), ...sign ? { sign } : {}, ...element ? { element } : {}, planet: label }; } if (lookup.kind === "angle") { const symbol = getAngleSymbolMetadata(lookup.angle); const label = symbol?.label ?? lookup.angle; return { kind: "angle", key: normalizeLookupKey(label), label, shortLabel: symbol?.shortLabel ?? label, glyph: symbol?.glyph ?? label, ...sign ? { sign } : {}, ...element ? { element } : {} }; } if (lookup.kind === "node") { const symbol = getNodeSymbolMetadata(lookup.node); const label = symbol?.label ?? lookup.node; return { kind: "node", key: normalizeLookupKey(label), label, shortLabel: symbol?.shortLabel ?? label, glyph: symbol?.glyph ?? label.slice(0, 1).toUpperCase(), ...sign ? { sign } : {}, ...element ? { element } : {} }; } if (lookup.kind === "number") { const label = String(lookup.number); return { kind: "number", key: label, label, shortLabel: label, glyph: label, number: lookup.number }; } const letterNode = canonicalTree.getNode(lookup.hebrewLetterId); const letterLabel = letterNode?.name ?? parseId(lookup.hebrewLetterId); const glyph = letterNode?.data?.character ?? letterLabel; return { kind: "hebrewLetter", key: normalizeLookupKey(lookup.hebrewLetterId), label: letterLabel, shortLabel: letterLabel, glyph, hebrewLetterId: lookup.hebrewLetterId }; } function getKaabalisticCorrespondenceTargets(lookup) { if (lookup.kind === "number") { const source = createCorrespondenceSource(lookup); const numberId = id("number" /* NUMBER */, lookup.number); const targets = [ ...canonicalTree.getCorrespondences(numberId, { type: "sphere" /* SPHERE */, depth: 1 }).map((match) => ({ targetId: match.node.id, targetType: "sphere", targetName: getTargetName(match.node.id), mapping: "number-sphere", distance: match.distance })), ...canonicalTree.getCorrespondences(numberId, { type: "path" /* PATH */, depth: 1 }).map((match) => ({ targetId: match.node.id, targetType: "path", targetName: getTargetName(match.node.id), mapping: "number-path", distance: match.distance })) ]; return { source, targets }; } if (lookup.kind === "hebrewLetter") { const source = createCorrespondenceSource(lookup); const targets = canonicalTree.getCorrespondences(lookup.hebrewLetterId, { type: "path" /* PATH */, depth: 1 }).map((match) => ({ targetId: match.node.id, targetType: "path", targetName: getTargetName(match.node.id), mapping: "letter-path", distance: match.distance })); return { source, targets }; } const sign = normalizeSignName(lookup.sign); if (!sign) { return void 0; } const signTargets = buildSignTargets(sign); const element = signTargets.find((target) => target.element)?.element; if (lookup.kind === "sign") { return { source: createCorrespondenceSource(lookup, sign, element), targets: signTargets }; } if (lookup.kind === "planet") { const planet = normalizePlanetName(lookup.planet); const planetKey = normalizeLookupKey(planet); const planetPathTargets = (classicalPlanetPathIdsByKey.get(planetKey) ?? []).map((pathId) => ({ targetId: pathId, targetType: "path", targetName: getTargetName(pathId), mapping: "planet-sign-path", distance: 1, sign, planet })); const carrierSphereTargets = buildCarrierSphereTargets(lookup, sign); return { source: createCorrespondenceSource(lookup, sign, element), targets: dedupeTargets([...signTargets, ...planetPathTargets, ...carrierSphereTargets]) }; } if (lookup.kind === "angle") { const carrierSphereTargets = buildCarrierSphereTargets(lookup, sign); return { source: createCorrespondenceSource(lookup, sign, element), targets: dedupeTargets([...signTargets, ...carrierSphereTargets]) }; } return { source: createCorrespondenceSource(lookup, sign, element), targets: signTargets }; } function toAstrologyMarkers(result, source) { const sourceGlyph = getAstrologySourceGlyph(source.sourceType, source.sourceName); const signGlyph = result.source.sign ? lookupSignSymbolMetadata(result.source.sign)?.glyph ?? sourceGlyph : sourceGlyph; return result.targets.map((target) => ({ kind: "astrology", targetId: target.targetId, targetType: target.targetType, sourceType: source.sourceType, sourceName: source.sourceName, mapping: target.mapping, label: target.mapping === "planet-sign-path" || target.mapping === "carrier-sphere" ? signGlyph : sourceGlyph, ...target.sign ? { sign: target.sign } : {}, ...target.element ? { element: target.element } : {}, ...target.planet ? { planet: target.planet } : {} })); } function dedupeMarkers(markers) { const seen = /* @__PURE__ */ new Set(); return markers.filter((marker) => { const key = [ marker.kind, marker.targetId, marker.sourceType, marker.sourceName, marker.mapping, marker.label, marker.sign ?? "", marker.element ?? "", marker.planet ?? "" ].join("|"); if (seen.has(key)) { return false; } seen.add(key); return true; }); } function getAstrologyTreeMarkers(input) { const chart = normalizeChartInput(input); const markers = []; for (const planet of chart.planets) { const normalizedName = normalizeLookupKey(planet.name); if (defaultExcludedAstrologyPoints.has(normalizedName)) { continue; } const sourceType = getAstrologySourceType(planet.name); const correspondences = getKaabalisticCorrespondenceTargets({ kind: sourceType, [sourceType]: planet.name, sign: planet.zodiacPosition.sign }); if (!correspondences) { continue; } markers.push( ...toAstrologyMarkers(correspondences, { sourceType, sourceName: correspondences.source.label }) ); } for (const node of chart.nodes) { const correspondences = getKaabalisticCorrespondenceTargets({ kind: "node", node: node.name, sign: node.sign }); if (!correspondences) { continue; } markers.push( ...toAstrologyMarkers(correspondences, { sourceType: "node", sourceName: correspondences.source.label }) ); } const angleTargets = [ { angle: "ASC", position: chart.houses.ascendant }, { angle: "MC", position: chart.houses.mc }, { angle: "Vertex", position: chart.houses.ascmc?.vertex } ]; for (const angle of angleTargets) { if (!angle.position?.sign) { continue; } const correspondences = getKaabalisticCorrespondenceTargets({ kind: "angle", angle: angle.angle, sign: angle.position.sign }); if (!correspondences) { continue; } markers.push( ...toAstrologyMarkers(correspondences, { sourceType: "angle", sourceName: correspondences.source.label }) ); } return dedupeMarkers(markers); } function resolveNumerologyInput(input) { const birthDate = input instanceof Date ? input : input.birthDate; const kaabalisticLifePath = input instanceof Date ? calculateKaabalisticLifePath(birthDate) : input.kaabalisticLifePath ?? calculateKaabalisticLifePath(birthDate); const straightAcrossReductionLifePath = input instanceof Date ? calculateStraightAcrossReductionLifePath(birthDate) : input.straightAcrossReductionLifePath ?? calculateStraightAcrossReductionLifePath(birthDate); return { birthDate, kaabalisticLifePath, straightAcrossReductionLifePath }; } function buildNumberMarkers(sourceName, numbers, kind) { const markers = []; for (const number of numbers) { const correspondences = getKaabalisticCorrespondenceTargets({ kind: "number", number}); if (!correspondences) { continue; } for (const target of correspondences.targets) { markers.push({ kind, targetId: target.targetId, targetType: target.targetType, sourceType: "number", sourceName, mapping: target.mapping, label: String(number) }); } } return markers; } function getNumerologyTreeMarkers(input) { const { kaabalisticLifePath, straightAcrossReductionLifePath } = resolveNumerologyInput(input); const markers = []; const sources = [ { sourceName: "Day Energy", numbers: straightAcrossReductionLifePath.dayEnergy.reductionSteps }, { sourceName: "Month Energy", numbers: straightAcrossReductionLifePath.monthEnergy.reductionSteps }, { sourceName: "Year Energy", numbers: straightAcrossReductionLifePath.yearEnergy.reductionSteps }, { sourceName: `Life Path (Kaabalistic) ${kaabalisticLifePath.lifePath.reducedValue}`, numbers: kaabalisticLifePath.lifePath.reductionSteps }, { sourceName: `Life Path (Straight) ${straightAcrossReductionLifePath.lifePath.reducedValue}`, numbers: straightAcrossReductionLifePath.lifePath.reductionSteps } ]; for (const source of sources) { markers.push(...buildNumberMarkers(source.sourceName, source.numbers, "numerology")); } return markers; } function resolveGematriaInput(input) { if (typeof input === "string") { return calculateGematria(input); } if (input.result) { return input.result; } if (input.phrase) { return calculateGematria(input.phrase); } return void 0; } function getGematriaTreeMarkers(input) { const result = resolveGematriaInput(input); if (!result) { return []; } const markers = []; const numericSources = [ { sourceName: "Vowels", numbers: result.vowels.reductionSteps }, { sourceName: "Consonants", numbers: result.consonants.reductionSteps }, { sourceName: "Synthesis", numbers: result.synthesis.reductionSteps } ]; for (const source of numericSources) { markers.push(...buildNumberMarkers(source.sourceName, source.numbers, "gematria")); } for (const letter of result.includedLetters) { const correspondences = getKaabalisticCorrespondenceTargets({ kind: "hebrewLetter", hebrewLetterId: letter.hebrewLetterId}); if (!correspondences) { continue; } for (const target of correspondences.targets) { markers.push({ kind: "gematria", targetId: target.targetId, targetType: target.targetType, sourceType: "letter", sourceName: "Included Letters", mapping: target.mapping, label: letter.hebrewCharacter }); } } return markers; } function incrementCounts(countsById, targetId, bucket) { const current = countsById[targetId] ?? { astro: 0, numerology: 0, gematria: 0, total: 0 }; current[bucket] += 1; current.total += 1; countsById[targetId] = current; } function groupMarkersByTarget(markers, targetType) { const grouped = {}; for (const marker of markers) { if (marker.targetType !== targetType) { continue; } const bucket = grouped[marker.targetId] ?? []; bucket.push(marker); grouped[marker.targetId] = bucket; } return grouped; } function buildAstrologySummary(input, markers, countsById) { const chart = normalizeChartInput(input); const itemConnections = []; for (const marker of markers) { incrementCounts(countsById, marker.targetId, "astro"); } const groupedBySource = groupByKey( markers, (marker) => `${marker.sourceType}|${marker.sourceName}|${marker.sign ?? ""}` ); for (const sourceMarkers of Object.values(groupedBySource)) { if (!sourceMarkers.length) { continue; } const firstMarker = sourceMarkers[0]; const itemLabel = firstMarker.sign ? `${firstMarker.sourceName} in ${firstMarker.sign}` : firstMarker.sourceName; itemConnections.push({ itemLabel, targets: toSummaryTargets(getTargetCountMap(sourceMarkers.map((marker) => ({ targetId: marker.targetId, targetType: marker.targetType, targetName: getTargetName(marker.targetId), mapping: marker.mapping, distance: 1 })))) }); } const planetsByName = Object.fromEntries( chart.planets.filter((planet) => !defaultExcludedAstrologyPoints.has(normalizeLookupKey(planet.name))).map((planet) => [normalizeLookupKey(planet.name), { longitude: planet.longitude }]) ); const aspects = chart.aspects ?? computeAspects(planetsByName, DEFAULT_ASPECT_SPECS); const aspectsByType = {}; for (const aspect of aspects) { const aspectId = id( "aspect" /* ASPECT */, WESTERN_ASPECTS[aspect.aspect.toUpperCase()] ?? aspect.aspect ); const sphere = canonicalTree.getCorrespondences(aspectId, { type: "sphere" /* SPHERE */, depth: 1, limit: 1 })[0]?.node; if (!sphere) { continue; } incrementCounts(countsById, sphere.id, "astro"); const bucket = aspectsByType[aspect.aspect] ?? {}; bucket[sphere.id] = (bucket[sphere.id] ?? 0) + 1; aspectsByType[aspect.aspect] = bucket; } for (const [aspectName, reduceMap] of Object.entries(aspectsByType)) { itemConnections.push({ itemLabel: `Aspects \u2014 ${capitalizeWords(aspectName)}`, targets: toSummaryTargets(reduceMap) }); } for (const planet of chart.planets) { if (defaultExcludedAstrologyPoints.has(normalizeLookupKey(planet.name))) { continue; } const house = getHouseNodeByNumber(planet.zodiacPosition.house); if (!house) { continue; } const sign = canonicalTree.getCorrespondences(house.id, { type: "westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, depth: 1, limit: 1 })[0]?.node; if (!sign) { continue; } const spheres = canonicalTree.getCorrespondences(sign.id, { type: "sphere" /* SPHERE */, depth: 1 }); if (!spheres.length) { continue; } const reduceMap = {}; for (const sphere of spheres) { const sphereId = sphere.node.id; incrementCounts(countsById, sphereId, "astro"); reduceMap[sphereId] = (reduceMap[sphereId] ?? 0) + 1; } itemConnections.push({ itemLabel: `${planet.name} \u2022 House ${planet.zodiacPosition.house}`, targets: toSummaryTargets(reduceMap) }); } return itemConnections; } function buildSourceSummary(markers, bucket, countsById) { const groupedBySource = groupByKey( markers, (marker) => `${marker.sourceType}|${marker.sourceName}` ); const connections = []; for (const sourceMarkers of Object.values(groupedBySource)) { if (!sourceMarkers.length) { continue; } for (const marker of sourceMarkers) { incrementCounts(countsById, marker.targetId, bucket); } connections.push({ itemLabel: sourceMarkers[0].sourceName, targets: toSummaryTargets(getTargetCountMap(sourceMarkers.map((marker) => ({ targetId: marker.targetId, targetType: marker.targetType, targetName: getTargetName(marker.targetId), mapping: marker.mapping, distance: 1 })))) }); } return connections; } function capitalizeWords(value) { return value.split(/\s+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" "); } function buildKaabalisticMapData(input) { const countsById = {}; const allMarkers = []; const astrologyMarkers = input.astrology ? getAstrologyTreeMarkers(input.astrology) : []; const numerologyMarkers = input.numerology ? getNumerologyTreeMarkers(input.numerology) : []; const gematriaMarkers = input.gematria ? getGematriaTreeMarkers(input.gematria) : []; allMarkers.push(...astrologyMarkers, ...numerologyMarkers, ...gematriaMarkers); const itemConnections = { astrology: input.astrology ? buildAstrologySummary(input.astrology, astrologyMarkers, countsById) : [], numerology: numerologyMarkers.length ? buildSourceSummary(numerologyMarkers, "numerology", countsById) : [], gematria: gematriaMarkers.length ? buildSourceSummary(gematriaMarkers, "gematria", countsById) : [] }; const sphereMarkers = groupMarkersByTarget(allMarkers, "sphere"); const pathMarkers = groupMarkersByTarget(allMarkers, "path"); return { spheres: orderedSpheres, paths: orderedPaths, markers: allMarkers, sphereMarkers, pathMarkers, countsById, itemConnections }; } // src/semantic/index.ts var OCCULT_THEME_STOPWORDS = [ "the", "and", "for", "with", "that", "this", "was", "were", "been", "have", "has", "had", "just", "from", "into", "about", "over", "under", "very", "more", "less", "then", "than", "when", "what", "where", "which", "while", "would", "could", "should", "again", "still", "really", "gotta", "lota", "lotta", "para", "com", "sem", "por", "uma", "um", "uns", "das", "dos", "del", "que", "n\xE3o", "nao", "isso", "essa", "este", "esta", "como", "mais", "menos", "muito", "muita", "their", "your", "mine", "ours", "onto", "sobre", "entre", "depois", "antes" ]; var canonicalTree2 = getCanonicalTree({ system: "kaabalah", parts: ["westernAstrology", "tarot"] }); var HOUSE_LABELS_BY_NUMBER = [ WESTERN_HOUSES.ASCENDANT, WESTERN_HOUSES.SECOND_HOUSE, WESTERN_HOUSES.THIRD_HOUSE, WESTERN_HOUSES.IMUM_COELI, WESTERN_HOUSES.FIFTH_HOUSE, WESTERN_HOUSES.SIXTH_HOUSE, WESTERN_HOUSES.DESCENDANT, WESTERN_HOUSES.EIGHTH_HOUSE, WESTERN_HOUSES.NINTH_HOUSE, WESTERN_HOUSES.MEDIUM_COELI, WESTERN_HOUSES.ELEVENTH_HOUSE, WESTERN_HOUSES.TWELFTH_HOUSE ]; var HOUSE_THEME_SEEDS = { 1: { primaryLabel: "Images", scope: "personal", aliases: [ "First House", "House 1", "Casa 1", "Imagens", "Como me vejo e como outros me veem", "Self-image" ], keywords: [ "images", "imagens", "identity", "self-image", "appearance", "body", "personality", "first impression", "persona", "character", "personagem", "how I see myself", "how others see me" ] }, 2: { primaryLabel: "Money", scope: "personal", aliases: ["Second House", "House 2", "Casa 2", "Dinheiro", "Resources"], keywords: [ "money", "dinheiro", "resources", "income", "finances", "possessions", "values", "material values", "self-worth" ] }, 3: { primaryLabel: "Communication", scope: "personal", aliases: ["Third House", "House 3", "Casa 3", "Comunica\xE7\xE3o", "Comunica\xE7\xF5es"], keywords: [ "communication", "comunica\xE7\xE3o", "comunica\xE7\xF5es", "siblings", "writing", "language", "study", "neighborhood", "short trips", "early education", "mind" ] }, 4: { primaryLabel: "Family", scope: "personal", aliases: [ "Fourth House", "House 4", "Casa 4", "IC", "Home Angle", "Fam\xEDlia", "Fam\xEDlias", "Family (not only blood)", "Familia (n\xE3o s\xF3 de sangue)" ], keywords: [ "family", "familia", "families", "fam\xEDlias", "home", "roots", "belonging", "kinship", "chosen family", "vida \xEDntima", "inner foundation", "private life" ] }, 5: { primaryLabel: "Hobbies", scope: "personal", aliases: ["Fifth House", "House 5", "Casa 5", "Hobbies", "Lazer", "Pleasures"], keywords: [ "hobbies", "hobby", "lazer", "pleasure", "fun", "games", "creative leisure", "creativity", "children", "romance", "speculation" ] }, 6: { primaryLabel: "Health", scope: "personal", aliases: ["Sixth House", "House 6", "Casa 6", "Sa\xFAde", "Health"], keywords: [ "health", "sa\xFAde", "routine", "service", "care", "wellbeing", "body maintenance", "daily work", "pets" ] }, 7: { primaryLabel: "Associations", scope: "transition", aliases: [ "Seventh House", "House 7", "Casa 7", "Associa\xE7\xF5es", "Partnerships", "Associations" ], keywords: [ "associations", "associa\xE7\xF5es", "partnerships", "partners", "alliances", "cooperation", "the other", "relationships", "marriage", "contracts", "open enemies" ] }, 8: { primaryLabel: "Sex and Initiations", scope: "transpersonal", aliases: [ "Eighth House", "House 8", "Casa 8", "Sexo", "Inicia\xE7\xF5es", "Sexo / Inicia\xE7\xF5es" ], keywords: [ "sex", "sexo", "initiations", "inicia\xE7\xF5es", "transformation", "transmutations", "taboo", "death", "shared resources", "sexuality", "occult", "death rebirth" ] }, 9: { primaryLabel: "Travel and Knowledge", scope: "transpersonal", aliases: [ "Ninth House", "House 9", "Casa 9", "Viagens", "Travel", "Travel, Religion, Philosophy, Knowledge" ], keywords: [ "travel", "viagens", "religion", "religi\xE3o", "philosophy", "filosofia", "knowledge", "conhecimento", "higher studies", "higher education", "publishing", "law" ] }, 10: { primaryLabel: "Career and Work", scope: "transpersonal", aliases: [ "Tenth House", "House 10", "Casa 10", "Midheaven", "MC", "Carreira", "Trabalho" ], keywords: [ "career", "carreira", "work", "trabalho", "profession", "reputation", "vocation", "public life", "public image", "ambition", "authority", "legacy" ] }, 11: { primaryLabel: "Friends", scope: "transpersonal", aliases: ["Eleventh House", "House 11", "Casa 11", "Friends", "Amigos", "Rela\xE7\xF5es"], keywords: [ "friends", "amigos", "friendships", "relations", "network", "community", "groups", "projects", "ideals", "hopes", "humanitarian goals" ] }, 12: { primaryLabel: "Past Lives", scope: "transpersonal", aliases: [ "Twelfth House", "House 12", "Casa 12", "Vida passada", "Vidas passadas", "Past life", "Past lives", "Oculto" ], keywords: [ "past life", "past lives", "vida passada", "vidas passadas", "karma", "occult", "hidden", "unconscious", "spiritual memory", "isolation", "spirituality", "hidden enemies", "self undoing" ] } }; var TAROT_SUIT_ALIASES = { wands: ["Rods", "Staves", "Paus"], cups: ["Chalices", "Copas"], swords: ["Blades", "Espadas"], pentacles: ["Coins", "Disks", "Discs", "Ouros"] }; var TAROT_SUIT_THEME_KEYWORDS = { wands: [ "paus", "fire", "will", "inspiration", "creation", "force", "vigor", "initiative", "progress", "thinking", "associating ideas", "seeking results", "politicians", "workers", "producers", "salamanders" ], cups: [ "copas", "water", "feelings", "emotions", "receptivity", "sensitivity", "ideals", "love", "artistic creation", "feeling", "affective", "relational", "emotional", "clergy", "spiritual class", "ondines", "mermaids" ], swords: [ "espadas", "air", "thought", "intelligence", "exchanges", "cooperation of opposites", "maturity", "balance", "intuition", "sixth sense", "imagination", "future vision", "military", "warriors", "police", "sylphs", "giants" ], pentacles: [ "ouros", "earth", "concretization", "manifestation", "practical intelligence", "effort", "study", "gains", "business", "sensation", "five senses", "concrete perception", "present", "bourgeoisie", "finances", "commerce", "gnomes" ] }; var TAROT_COURT_RANK_THEME_KEYWORDS = { king: ["dynamic", "active", "lordly", "cardinal"], queen: ["stable", "receptive", "contained", "fixed"], knight: ["volatile", "mutant", "active", "mutable"], page: ["nascent", "fragile", "beginning", "starting"] }; var TAROT_MINOR_PIP_STAGE_KEYWORDS = { ace: ["will", "pure potential", "something new emerging", "first spark"], two: ["imagining", "visualizing", "formulating the idea"], three: ["speaking", "understanding", "verbalizing", "giving form"], four: ["expanding", "planning", "growth", "good feelings"], five: ["restricting", "discipline", "justice", "pruning", "confronting limits"], six: ["harmonizing", "beauty", "ethics", "balance", "heart"], seven: ["winning silently", "emotional control", "quiet victory", "endurance"], eight: ["connecting", "rational control", "linking concepts", "strategy"], nine: ["foundations", "worthy", "solid base"], ten: ["manifesting", "materialized", "completion"] }; var houseThemeProfilesCache; var tarotThemeProfilesCache; function getHouseThemeAxis(houseNumber) { const axisPairs = { 1: { key: "self-other", label: "Self and Other", oppositeHouseNumber: 7 }, 2: { key: "resources-initiation", label: "Resources and Initiation", oppositeHouseNumber: 8 }, 3: { key: "communication-journey", label: "Communication and Journey", oppositeHouseNumber: 9 }, 4: { key: "private-public", label: "Private and Public Life", oppositeHouseNumber: 10 }, 5: { key: "pleasure-friendship", label: "Pleasure and Friendship", oppositeHouseNumber: 11 }, 6: { key: "health-occult", label: "Health and the Occult", oppositeHouseNumber: 12 }, 7: { key: "self-other", label: "Self and Other", oppositeHouseNumber: 1 }, 8: { key: "resources-initiation", label: "Resources and Initiation", oppositeHouseNumber: 2 }, 9: { key: "communication-journey", label: "Communication and Journey", oppositeHouseNumber: 3 }, 10: { key: "private-public", label: "Private and Public Life", oppositeHouseNumber: 4 }, 11: { key: "pleasure-friendship", label: "Pleasure and Friendship", oppositeHouseNumber: 5 }, 12: { key: "health-occult", label: "Health and the Occult", oppositeHouseNumber: 6 } }; return axisPairs[houseNumber]; } function normalizeThemeText(value) { return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase(); } function uniqueStrings(values) { const seen = /* @__PURE__ */ new Set(); const result = []; for (const value of values) { const trimmed = value?.trim(); if (!trimmed || seen.has(trimmed)) { continue; } seen.add(trimmed); result.push(trimmed); } return result; } function titleCase(value) { return value.split(" ").map((part) => part ? `${part[0].toUpperCase()}${part.slice(1)}` : part).join(" "); } function humanizeTarotFilename(filename) { return titleCase( filename.replace(/^\d+_/, "").replace(/_/g, " ") ); } function getNodeDisplayLabel(node) { const parsedId = parseId(node.id); if (node.type === "path" /* PATH */) { return `Path ${parsedId}`; } if (node.type === "tarotSuit" /* TAROT_SUIT */) { return titleCase(parsedId); } return node.name ?? titleCase(parsedId); } function getNodeTextCandidates(node) { const data = node.data; return uniqueStrings([ getNodeDisplayLabel(node), parseId(node.id), typeof data?.englishName === "string" ? data.englishName : void 0, typeof data?.meaning === "string" ? data.meaning : void 0 ]); } function getCorrespondenceRefs(nodeId, type, depth) { return canonicalTree2.getCorrespondences(nodeId, { type, depth }).map((match) => ({ id: match.node.id, label: getNodeDisplayLabel(match.node), distance: match.distance })); } function collectCorrespondenceTexts(correspondences) { const texts = []; for (const correspondence of correspondences) { const node = canonicalTree2.getNode(correspondence.id); if (!node) { continue; } texts.push(...getNodeTextCandidates(node)); } return texts; } function freezeCorrespondences(correspondences) { correspondences.forEach((correspondence) => Object.freeze(correspondence)); return Object.freeze(correspondences); } function createTokenSurface(values) { return tokenizeOccultThemeText([...values]); } function getHouseLabelFromLookup(lookup) { if (typeof lookup === "number") { return HOUSE_LABELS_BY_NUMBER[lookup - 1]; } if (String(lookup).startsWith(`${"house" /* HOUSE */}:`)) { return parseId(lookup); } return void 0; } function buildHouseThemeProfile(houseNumber) { const houseLabel = HOUSE_LABELS_BY_NUMBER[houseNumber - 1]; const houseId = id("house" /* HOUSE */, houseLabel); const seed = HOUSE_THEME_SEEDS[houseNumber]; const primaryLabel = seed.primaryLabel; const axis = getHouseThemeAxis(houseNumber); const aliases = uniqueStrings(seed.aliases); const signs = getCorrespondenceRefs(houseId, "westernZodiacSign" /* WESTERN_ZODIAC_SIGN */, 1); const planets = getCorrespondenceRefs(houseId, "planet" /* PLANET */, 2); const elements = getCorrespondenceRefs(houseId, "westernElement" /* WESTERN_ELEMENT */, 2); const spheres = getCorrespondenceRefs(houseId, "sphere" /* SPHERE */, 2); const paths = getCorrespondenceRefs(houseId, "path" /* PATH */, 2); const correspondenceTexts = [ ...collectCorrespondenceTexts(signs), ...collectCorrespondenceTexts(planets), ...collectCorrespondenceTexts(elements), ...collectCorrespondenceTexts(spheres), ...collectCorrespondenceTexts(paths) ]; const keywords = uniqueStrings(seed.keywords); const tokens = createTokenSurface([ primaryLabel, ...aliases, ...keywords, ...correspondenceTexts ]); const profile = { kind: "house", id: houseId, houseNumber, houseLabel: titleCase(houseLabel), primaryLabel, scope: seed.scope, axis: Object.freeze(axis), aliases: Object.freeze(aliases), keywords: Object.freeze(keywords), tokens: Object.freeze(tokens), correspondences: Object.freeze({ planets: freezeCorrespondences(planets), signs: freezeCorrespondences(signs), elements: freezeCorrespondences(elements), spheres: freezeCorrespondences(spheres), paths: freezeCorrespondences(paths) }) }; return Object.freeze(profile); } function getHouseThemeProfileCache() { if (houseThemeProfilesCache) { return houseThemeProfilesCache; } houseThemeProfilesCache = Object.freeze(HOUSE_LABELS_BY_NUMBER.map( (_, index) => buildHouseThemeProfile(index + 1) )); return houseThemeProfilesCache; } function getTarotRank(card) { if (!card.tarotCard.includes(" of ")) { return void 0;