2026-03-07 01:09:00 -08:00
|
|
|
(function () {
|
2026-03-07 13:38:13 -08:00
|
|
|
"use strict";
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
const dataService = window.TarotDataService || {};
|
|
|
|
|
|
2026-03-07 01:09:00 -08:00
|
|
|
const {
|
|
|
|
|
DAY_IN_MS,
|
|
|
|
|
getDateKey,
|
2026-03-07 14:15:09 -08:00
|
|
|
getDecanForDate,
|
2026-03-07 01:09:00 -08:00
|
|
|
getMoonPhaseName,
|
|
|
|
|
calcPlanetaryHoursForDayAndLocation
|
|
|
|
|
} = window.TarotCalc;
|
2026-03-07 13:38:13 -08:00
|
|
|
const nowUiHelpers = window.NowUiHelpers || {};
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
typeof nowUiHelpers.findNextDecanTransition !== "function"
|
|
|
|
|
|| typeof nowUiHelpers.findNextMoonPhaseTransition !== "function"
|
|
|
|
|
|| typeof nowUiHelpers.formatCountdown !== "function"
|
2026-03-07 14:15:09 -08:00
|
|
|
|| typeof nowUiHelpers.getSignStartDate !== "function"
|
2026-03-07 13:38:13 -08:00
|
|
|
|| typeof nowUiHelpers.getDisplayTarotName !== "function"
|
|
|
|
|
|| typeof nowUiHelpers.setNowCardImage !== "function"
|
2026-03-14 00:45:15 -07:00
|
|
|
|| typeof nowUiHelpers.renderNowPlanetPositions !== "function"
|
2026-03-07 13:38:13 -08:00
|
|
|
|| typeof nowUiHelpers.updateNowStats !== "function"
|
|
|
|
|
) {
|
|
|
|
|
throw new Error("NowUiHelpers module must load before ui-now.js");
|
|
|
|
|
}
|
2026-03-07 01:09:00 -08:00
|
|
|
|
|
|
|
|
let moonCountdownCache = null;
|
|
|
|
|
let decanCountdownCache = null;
|
|
|
|
|
|
2026-03-10 14:55:01 -07:00
|
|
|
function joinSabianPhrases(phrases) {
|
|
|
|
|
const parts = (Array.isArray(phrases) ? phrases : [])
|
|
|
|
|
.map((phrase) => String(phrase || "").trim())
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
|
|
|
|
|
if (!parts.length) {
|
|
|
|
|
return "--";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parts.join(" ");
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
function renderNowStatsFromSnapshot(elements, stats) {
|
|
|
|
|
if (elements.nowStatsPlanetsEl) {
|
2026-03-14 00:45:15 -07:00
|
|
|
nowUiHelpers.renderNowPlanetPositions(
|
|
|
|
|
elements.nowStatsPlanetsEl,
|
|
|
|
|
Array.isArray(stats?.planetPositions) ? stats.planetPositions : []
|
|
|
|
|
);
|
2026-03-07 01:09:00 -08:00
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
if (elements.nowStatsSabianEl) {
|
|
|
|
|
const sunSabianSymbol = stats?.sunSabianSymbol || null;
|
|
|
|
|
const moonSabianSymbol = stats?.moonSabianSymbol || null;
|
2026-03-10 14:55:01 -07:00
|
|
|
elements.nowStatsSabianEl.textContent = joinSabianPhrases([
|
|
|
|
|
moonSabianSymbol?.phrase,
|
|
|
|
|
sunSabianSymbol?.phrase
|
|
|
|
|
]);
|
2026-03-08 22:24:34 -07:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-07 01:09:00 -08:00
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
function applyNowSnapshot(elements, snapshot, timeFormat) {
|
|
|
|
|
const timestamp = snapshot?.timestamp ? new Date(snapshot.timestamp) : new Date();
|
|
|
|
|
const dayKey = String(snapshot?.dayKey || getDateKey(timestamp));
|
|
|
|
|
const currentHour = snapshot?.currentHour || null;
|
|
|
|
|
|
|
|
|
|
if (currentHour?.planet) {
|
|
|
|
|
elements.nowHourEl.textContent = `${currentHour.planet.symbol} ${currentHour.planet.name}`;
|
2026-03-07 01:09:00 -08:00
|
|
|
if (elements.nowHourTarotEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
const hourCardName = currentHour.planet?.tarot?.majorArcana || "";
|
|
|
|
|
const hourTrumpNumber = currentHour.planet?.tarot?.number;
|
2026-03-07 01:09:00 -08:00
|
|
|
elements.nowHourTarotEl.textContent = hourCardName
|
2026-03-07 13:38:13 -08:00
|
|
|
? nowUiHelpers.getDisplayTarotName(hourCardName, hourTrumpNumber)
|
2026-03-07 01:09:00 -08:00
|
|
|
: "--";
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
elements.nowCountdownEl.textContent = nowUiHelpers.formatCountdown(currentHour.msRemaining, timeFormat);
|
2026-03-07 01:09:00 -08:00
|
|
|
|
|
|
|
|
if (elements.nowHourNextEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
const nextPlanet = currentHour.nextHourPlanet;
|
|
|
|
|
elements.nowHourNextEl.textContent = nextPlanet
|
|
|
|
|
? `> ${nextPlanet.name}`
|
|
|
|
|
: "> --";
|
2026-03-07 01:09:00 -08:00
|
|
|
}
|
|
|
|
|
|
2026-03-07 13:38:13 -08:00
|
|
|
nowUiHelpers.setNowCardImage(
|
2026-03-07 01:09:00 -08:00
|
|
|
elements.nowHourCardEl,
|
2026-03-08 22:24:34 -07:00
|
|
|
currentHour.planet?.tarot?.majorArcana,
|
2026-03-07 01:09:00 -08:00
|
|
|
"Current planetary hour card",
|
2026-03-08 22:24:34 -07:00
|
|
|
currentHour.planet?.tarot?.number
|
2026-03-07 01:09:00 -08:00
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
elements.nowHourEl.textContent = "--";
|
|
|
|
|
elements.nowCountdownEl.textContent = "--";
|
|
|
|
|
if (elements.nowHourTarotEl) {
|
|
|
|
|
elements.nowHourTarotEl.textContent = "--";
|
|
|
|
|
}
|
|
|
|
|
if (elements.nowHourNextEl) {
|
|
|
|
|
elements.nowHourNextEl.textContent = "> --";
|
|
|
|
|
}
|
2026-03-07 13:38:13 -08:00
|
|
|
nowUiHelpers.setNowCardImage(elements.nowHourCardEl, null, "Current planetary hour card");
|
2026-03-07 01:09:00 -08:00
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
const moon = snapshot?.moon || null;
|
|
|
|
|
const illuminationFraction = Number(moon?.illuminationFraction || 0);
|
|
|
|
|
const moonTarot = moon?.tarot?.majorArcana || "The High Priestess";
|
|
|
|
|
elements.nowMoonEl.textContent = moon
|
|
|
|
|
? `${moon.phase} (${Math.round(illuminationFraction * 100)}%)`
|
|
|
|
|
: "--";
|
|
|
|
|
elements.nowMoonTarotEl.textContent = moon
|
|
|
|
|
? nowUiHelpers.getDisplayTarotName(moonTarot, moon?.tarot?.number)
|
|
|
|
|
: "--";
|
2026-03-07 13:38:13 -08:00
|
|
|
nowUiHelpers.setNowCardImage(
|
2026-03-07 01:09:00 -08:00
|
|
|
elements.nowMoonCardEl,
|
2026-03-08 22:24:34 -07:00
|
|
|
moon?.tarot?.majorArcana,
|
2026-03-07 01:09:00 -08:00
|
|
|
"Current moon phase card",
|
2026-03-08 22:24:34 -07:00
|
|
|
moon?.tarot?.number
|
2026-03-07 01:09:00 -08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (elements.nowMoonCountdownEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
if (moon?.countdown) {
|
|
|
|
|
elements.nowMoonCountdownEl.textContent = nowUiHelpers.formatCountdown(moon.countdown.msRemaining, timeFormat);
|
2026-03-07 01:09:00 -08:00
|
|
|
if (elements.nowMoonNextEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
elements.nowMoonNextEl.textContent = `> ${moon.countdown.nextPhase}`;
|
2026-03-07 01:09:00 -08:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
elements.nowMoonCountdownEl.textContent = "--";
|
|
|
|
|
if (elements.nowMoonNextEl) {
|
|
|
|
|
elements.nowMoonNextEl.textContent = "> --";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
const decanInfo = snapshot?.decan || null;
|
|
|
|
|
if (decanInfo?.sign) {
|
|
|
|
|
const signMajorName = nowUiHelpers.getDisplayTarotName(
|
|
|
|
|
decanInfo.sign?.tarot?.majorArcana,
|
|
|
|
|
decanInfo.sign?.tarot?.number
|
|
|
|
|
);
|
|
|
|
|
const signDegree = Number.isFinite(Number(decanInfo.signDegree))
|
|
|
|
|
? Number(decanInfo.signDegree).toFixed(1)
|
|
|
|
|
: "0.0";
|
|
|
|
|
|
|
|
|
|
elements.nowDecanEl.textContent = `${decanInfo.sign.symbol} ${decanInfo.sign.name} · ${signMajorName} (${signDegree}°)`;
|
2026-03-07 01:09:00 -08:00
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
if (decanInfo.decan?.tarotMinorArcana) {
|
|
|
|
|
elements.nowDecanTarotEl.textContent = nowUiHelpers.getDisplayTarotName(decanInfo.decan.tarotMinorArcana);
|
|
|
|
|
nowUiHelpers.setNowCardImage(elements.nowDecanCardEl, decanInfo.decan.tarotMinorArcana, "Current decan card");
|
2026-03-07 01:09:00 -08:00
|
|
|
} else {
|
2026-03-08 22:24:34 -07:00
|
|
|
const signTarotName = decanInfo.sign?.tarot?.majorArcana || "--";
|
2026-03-07 01:09:00 -08:00
|
|
|
elements.nowDecanTarotEl.textContent = signTarotName === "--"
|
|
|
|
|
? "--"
|
2026-03-08 22:24:34 -07:00
|
|
|
: nowUiHelpers.getDisplayTarotName(signTarotName, decanInfo.sign?.tarot?.number);
|
2026-03-07 13:38:13 -08:00
|
|
|
nowUiHelpers.setNowCardImage(
|
2026-03-07 01:09:00 -08:00
|
|
|
elements.nowDecanCardEl,
|
2026-03-08 22:24:34 -07:00
|
|
|
decanInfo.sign?.tarot?.majorArcana,
|
2026-03-07 01:09:00 -08:00
|
|
|
"Current decan card",
|
2026-03-08 22:24:34 -07:00
|
|
|
decanInfo.sign?.tarot?.number
|
2026-03-07 01:09:00 -08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (elements.nowDecanCountdownEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
if (decanInfo.countdown) {
|
|
|
|
|
elements.nowDecanCountdownEl.textContent = nowUiHelpers.formatCountdown(decanInfo.countdown.msRemaining, timeFormat);
|
2026-03-07 01:09:00 -08:00
|
|
|
if (elements.nowDecanNextEl) {
|
2026-03-08 22:24:34 -07:00
|
|
|
elements.nowDecanNextEl.textContent = `> ${nowUiHelpers.getDisplayTarotName(decanInfo.countdown.nextLabel)}`;
|
2026-03-07 01:09:00 -08:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
elements.nowDecanCountdownEl.textContent = "--";
|
|
|
|
|
if (elements.nowDecanNextEl) {
|
|
|
|
|
elements.nowDecanNextEl.textContent = "> --";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
elements.nowDecanEl.textContent = "--";
|
|
|
|
|
elements.nowDecanTarotEl.textContent = "--";
|
2026-03-07 13:38:13 -08:00
|
|
|
nowUiHelpers.setNowCardImage(elements.nowDecanCardEl, null, "Current decan card");
|
2026-03-07 01:09:00 -08:00
|
|
|
if (elements.nowDecanCountdownEl) {
|
|
|
|
|
elements.nowDecanCountdownEl.textContent = "--";
|
|
|
|
|
}
|
|
|
|
|
if (elements.nowDecanNextEl) {
|
|
|
|
|
elements.nowDecanNextEl.textContent = "> --";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
renderNowStatsFromSnapshot(elements, snapshot?.stats || {});
|
2026-03-07 01:09:00 -08:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
dayKey,
|
2026-03-08 22:24:34 -07:00
|
|
|
skyRefreshKey: String(snapshot?.skyRefreshKey || "")
|
2026-03-07 01:09:00 -08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-08 22:24:34 -07:00
|
|
|
async function updateNowPanel(referenceData, geo, elements, timeFormat = "minutes") {
|
|
|
|
|
if (!referenceData || !geo || !elements) {
|
|
|
|
|
return { dayKey: getDateKey(new Date()), skyRefreshKey: "" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const snapshot = await dataService.fetchNowSnapshot?.(geo, new Date());
|
|
|
|
|
return applyNowSnapshot(elements, snapshot || {}, timeFormat);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 01:09:00 -08:00
|
|
|
window.TarotNowUi = {
|
|
|
|
|
updateNowPanel
|
|
|
|
|
};
|
|
|
|
|
})();
|