(function () { "use strict"; let config = { calendar: null, baseWeekOptions: null, defaultSettings: null, latEl: null, lngEl: null, nowElements: null, calendarVisualsUi: null, homeUi: null, onStatus: null, services: {}, ensure: {} }; let referenceData = null; let magickDataset = null; let currentGeo = null; let nowInterval = null; let centeredDayKey = ""; let renderInProgress = false; let currentTimeFormat = "minutes"; let currentSettings = null; function setStatus(text) { config.onStatus?.(text); } function getReferenceData() { return referenceData; } function getMagickDataset() { return magickDataset; } function getCurrentGeo() { return currentGeo; } function getCurrentTimeFormat() { return currentTimeFormat; } function getCurrentSettings() { return currentSettings ? { ...currentSettings } : null; } function parseGeoInput() { const latitude = Number(config.latEl?.value); const longitude = Number(config.lngEl?.value); if (Number.isNaN(latitude) || Number.isNaN(longitude)) { throw new Error("Latitude/Longitude must be valid numbers."); } return { latitude, longitude }; } function applyCenteredWeekWindow(date) { const startDayOfWeek = config.services.getCenteredWeekStartDay?.(date) ?? 0; config.calendar?.setOptions?.({ week: { ...(config.baseWeekOptions || {}), startDayOfWeek } }); config.calendarVisualsUi?.applyTimeFormatTemplates?.(); config.calendar?.changeView?.("week"); config.calendar?.setDate?.(date); } function startNowTicker() { if (nowInterval) { clearInterval(nowInterval); } const tick = async () => { if (!referenceData || !currentGeo || renderInProgress) { return; } const now = new Date(); config.homeUi?.syncNowPanelTheme?.(now); const currentDayKey = config.services.getDateKey?.(now) || ""; if (currentDayKey !== centeredDayKey) { centeredDayKey = currentDayKey; void renderWeek(); return; } try { await config.services.updateNowPanel?.(referenceData, currentGeo, config.nowElements, currentTimeFormat); config.calendarVisualsUi?.applyDynamicNowIndicatorVisual?.(now); } catch (_error) { } }; void tick(); nowInterval = setInterval(() => { void tick(); }, 1000); } async function renderWeek() { if (renderInProgress) { return; } renderInProgress = true; try { currentGeo = parseGeoInput(); config.homeUi?.syncNowPanelTheme?.(new Date()); config.homeUi?.syncNowSkyBackground?.(currentGeo); if (!referenceData || !magickDataset) { setStatus("Loading planetary, sign and decan tarot correspondences..."); const [loadedReference, loadedMagick] = await Promise.all([ referenceData ? Promise.resolve(referenceData) : config.services.loadReferenceData?.(), magickDataset ? Promise.resolve(magickDataset) : config.services.loadMagickDataset?.().catch(() => null) ]); referenceData = loadedReference; magickDataset = loadedMagick; } config.ensure.ensureTarotSection?.(referenceData, magickDataset); config.ensure.ensurePlanetSection?.(referenceData, magickDataset); config.ensure.ensureCyclesSection?.(referenceData); config.ensure.ensureIChingSection?.(referenceData); config.ensure.ensureCalendarSection?.(referenceData, magickDataset); config.ensure.ensureHolidaySection?.(referenceData, magickDataset); config.ensure.ensureNatalPanel?.(referenceData); config.ensure.ensureQuizSection?.(referenceData, magickDataset); const anchorDate = new Date(); centeredDayKey = config.services.getDateKey?.(anchorDate) || ""; applyCenteredWeekWindow(anchorDate); const events = await config.services.buildWeekEvents?.(currentGeo, referenceData, anchorDate) || []; config.calendar?.clear?.(); config.calendar?.createEvents?.(events); config.calendarVisualsUi?.applySunRulerGradient?.(anchorDate); config.calendarVisualsUi?.updateMonthStrip?.(); requestAnimationFrame(() => { config.calendarVisualsUi?.updateMonthStrip?.(); }); setStatus(`Rendered ${events.length} planetary + tarot events for lat ${currentGeo.latitude}, lng ${currentGeo.longitude}.`); startNowTicker(); } catch (error) { setStatus(error?.message || "Failed to render calendar."); } finally { renderInProgress = false; } } function applySettings(settings) { currentTimeFormat = settings?.timeFormat || "minutes"; currentSettings = settings ? { ...settings } : { ...(config.defaultSettings || {}) }; } function init(nextConfig = {}) { config = { ...config, ...nextConfig, services: { ...(config.services || {}), ...(nextConfig.services || {}) }, ensure: { ...(config.ensure || {}), ...(nextConfig.ensure || {}) } }; if (!currentSettings) { currentSettings = { ...(config.defaultSettings || {}) }; currentTimeFormat = currentSettings.timeFormat || "minutes"; } centeredDayKey = config.services.getDateKey?.(new Date()) || centeredDayKey; } window.TarotAppRuntime = { ...(window.TarotAppRuntime || {}), init, parseGeoInput, applyCenteredWeekWindow, renderWeek, applySettings, getReferenceData, getMagickDataset, getCurrentGeo, getCurrentTimeFormat, getCurrentSettings }; })();