import { state } from './state.js'; import { ldoc } from './i18n.js'; export function tOff(g) { return Math.round((state.TODAY - new Date(g.start)) / 86400000); } export function o2d(g, i) { const d = new Date(new Date(g.start).getTime() + i * 86400000); d.setHours(0,0,0,0); return d; } export function dTot(g, o) { return (g.sets[String(o)] || []).reduce((a, b) => a + b.amount, 0); } export function fd(d) { return d.toLocaleDateString(ldoc(), { weekday: 'short', day: 'numeric', month: 'short' }); } export function fs(d) { return d.toLocaleDateString(ldoc(), { day: 'numeric', month: 'short' }); } export function editable(g, o) { const t = tOff(g); return o === t || o === t - 1; } export function now() { const n = new Date(); return String(n.getHours()).padStart(2, '0') + ':' + String(n.getMinutes()).padStart(2, '0'); } export function heuteColor(tdone, daily) { if (tdone === 0) return 'var(--red)'; if (tdone >= daily * 1.1) return 'var(--blue)'; if (tdone >= daily) return 'var(--green)'; return 'var(--amber)'; } export function isCollapsed(id) { return state.collapsed[id] !== false; } export function toggleCollapse(id) { const wasCollapsed = isCollapsed(id); state.collapsed[id] = !wasCollapsed; if (wasCollapsed) { const g = state.goals.find(x => x.id === id); if (g) state.selDay[id] = tOff(g); } } export function calc(g) { const t = tOff(g), tot = g.daily * g.days; const dr = Math.max(0, g.days - t - 1); const sd = new Date(g.start); sd.setHours(0,0,0,0); const end = new Date(sd.getTime() + g.days * 86400000); let past = 0; for (let i = 0; i < Math.min(t, g.days); i++) past += dTot(g, i); const tdone = dTot(g, t), tot2 = past + tdone; const dl = dr + 1; const remaining = Math.max(0, tot - past); const pd = Math.ceil(remaining / Math.max(1, dl)); const st = Math.max(0, pd - tdone); const expectedPast = Math.min(t, g.days) * g.daily; const buf = Math.floor((past - expectedPast) + Math.max(0, tdone - g.daily)); const deficit = Math.min(0, buf); const surplus = Math.max(0, buf); const dailyDelta = pd - g.daily; const pct = Math.min(100, Math.round((tot2 / tot) * 100)); return { tot, tOff: t, end, dr, done: tot2, tdone, pd, st, buf, deficit, surplus, dailyDelta, net: tdone - pd, pct, ok: tdone >= pd }; } export function dcls(g, i) { const t = tOff(g); if (i > t) return 'dot df'; const v = dTot(g, i); const c = v === 0 ? 'dot dm' : v >= g.daily * 1.1 ? 'dot db' : v >= g.daily ? 'dot dd' : 'dot dp'; return c + (editable(g, i) ? ' de' : ' dl'); } export function dlbl(g, i) { const t = tOff(g); if (i > t) return String(i + 1); const v = dTot(g, i); if (v === 0) return '✕'; if (v >= g.daily * 1.1) return '+'; if (v >= g.daily) return '✓'; return Math.round(v / g.daily * 100) + '%'; }