const _weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; const _months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const _monthsLong = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; String inr(int n) { final neg = n < 0; final s = n.abs().toString(); if (s.length <= 3) return '${neg ? '-' : ''}$s'; final last = s.substring(s.length - 3); var rest = s.substring(0, s.length - 3); final parts = []; while (rest.length > 2) { parts.insert(0, rest.substring(rest.length - 2)); rest = rest.substring(0, rest.length - 2); } if (rest.isNotEmpty) parts.insert(0, rest); return '${neg ? '-' : ''}${parts.join(',')},$last'; } String rupees(int n) => '₹${inr(n)}'; DateTime dateOnly(DateTime d) => DateTime(d.year, d.month, d.day); bool sameDay(DateTime a, DateTime b) => a.year == b.year && a.month == b.month && a.day == b.day; DateTime addDays(DateTime d, int n) => DateTime(d.year, d.month, d.day + n); /// Fri, 16 Oct 2026 String dateLong(DateTime d) => '${_weekdays[d.weekday - 1]}, ${d.day} ${_months[d.month - 1]} ${d.year}'; /// Fri, 16 Oct String dateShort(DateTime d) => '${_weekdays[d.weekday - 1]}, ${d.day} ${_months[d.month - 1]}'; /// October 2026 String monthYear(DateTime d) => '${_monthsLong[d.month - 1]} ${d.year}'; /// 12:41 PM String time12(DateTime d) { final h = d.hour % 12 == 0 ? 12 : d.hour % 12; final m = d.minute.toString().padLeft(2, '0'); return '$h:$m ${d.hour >= 12 ? 'PM' : 'AM'}'; } String isoDate(DateTime d) => '${d.year.toString().padLeft(4, '0')}-${d.month.toString().padLeft(2, '0')}-${d.day.toString().padLeft(2, '0')}'; String plural(int n, String one, [String? many]) => '${inr(n)} ${n == 1 ? one : (many ?? '${one}s')}'; /// 919000012345 -> +91 90000 12345 String fmtPhone(String? digits) { if (digits == null || digits.isEmpty) return ''; if (digits.length == 12 && digits.startsWith('91')) { return '+91 ${digits.substring(2, 7)} ${digits.substring(7)}'; } return '+$digits'; } String initials(String name) { final parts = name.split(RegExp(r'[._\- ]+')).where((p) => p.isNotEmpty); final list = parts.toList(); if (list.isEmpty) return '?'; if (list.length == 1) { final w = list.first; return w.substring(0, w.length >= 2 ? 2 : 1).toUpperCase(); } return (list[0][0] + list[1][0]).toUpperCase(); } String tierLabel(int tier) => '${tier}th prize'; /// "5th prize", or "5th + 8th prize" for an ending in two tiers. String tiersLabel(List tiers) { final sorted = [...tiers]..sort(); if (sorted.length < 2) return sorted.isEmpty ? '' : tierLabel(sorted.first); return '${sorted.map((t) => '${t}th').join(' + ')} prize'; } /// A server instant (UTC) as the Indian wall-clock time the screens show. DateTime istWallClock(DateTime instant) { final t = instant.toUtc().add(const Duration(hours: 5, minutes: 30)); return DateTime(t.year, t.month, t.day, t.hour, t.minute, t.second); } /// Parses a YYYY-MM-DD calendar date. DateTime parseDate(String iso) => DateTime( int.parse(iso.substring(0, 4)), int.parse(iso.substring(5, 7)), int.parse(iso.substring(8, 10)), );