/** * DOM references and shared application state. * Element refs are resolved lazily via getters so modules can be imported before DOM is ready. */ /** @returns {HTMLDivElement|null} */ export function getCalendarEl() { return document.getElementById("calendar"); } /** @returns {HTMLElement|null} */ export function getMonthTitleEl() { return document.getElementById("monthTitle"); } /** @returns {HTMLDivElement|null} */ export function getDutyListEl() { return document.getElementById("dutyList"); } /** @returns {HTMLElement|null} */ export function getLoadingEl() { return document.getElementById("loading"); } /** @returns {HTMLElement|null} */ export function getErrorEl() { return document.getElementById("error"); } /** @returns {HTMLElement|null} */ export function getAccessDeniedEl() { return document.getElementById("accessDenied"); } /** @returns {HTMLElement|null} */ export function getHeaderEl() { return document.querySelector(".header"); } /** @returns {HTMLElement|null} */ export function getWeekdaysEl() { return document.querySelector(".weekdays"); } /** @returns {HTMLButtonElement|null} */ export function getPrevBtn() { return document.getElementById("prevMonth"); } /** @returns {HTMLButtonElement|null} */ export function getNextBtn() { return document.getElementById("nextMonth"); } /** @returns {HTMLDivElement|null} */ export function getCurrentDutyViewEl() { return document.getElementById("currentDutyView"); } /** Currently viewed month (mutable). */ export const state = { /** @type {Date} */ current: new Date(), /** @type {object[]} */ lastDutiesForList: [], /** @type {ReturnType|null} */ todayRefreshInterval: null, /** @type {'ru'|'en'} */ lang: "ru", /** One-time bind flag for sticky scroll shadow listener. */ stickyScrollBound: false, /** One-time bind flag for calendar (info button) hint document listeners. */ calendarHintBound: false, /** One-time bind flag for duty marker hint document listeners. */ dutyMarkerHintBound: false, /** Whether initData retry after ACCESS_DENIED has been attempted. */ initDataRetried: false };