{"version":3,"sources":["jsdelivr-header.js","/gh/Developer-Zahid/robustCountdown.js@master/src/robustCountdown.js"],"names":[],"mappings":"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","file":"/gh/Developer-Zahid/robustCountdown.js@master/src/robustCountdown.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /gh/Developer-Zahid/robustCountdown.js@master/src/robustCountdown.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * RobustCountdown Class\n * ----------------------------------------------------------------------\n * A flexible, zero-dependency class for creating countdown timers.\n * Supports both fixed-date targets (e.g., \"New Year 2030\") and relative\n * timers (e.g., \"5 minutes from now\") with pause/resume functionality.\n * * @param {string} selector - CSS selector for the wrapper element(s).\n * @param {Object} options - Configuration object.\n * * Configuration Options:\n * ----------------------\n * 1. Fixed Date (Granular):\n * @param {number} year - Full year (e.g., 2026).\n * @param {number} month - Month (1-12).\n * @param {number} day - Day of month (1-31).\n * @param {number} hours - Hour (0-23).\n * @param {number} minutes - Minute (0-59).\n * @param {number} seconds - Second (0-59).\n * @param {boolean} enableUTC - If true, treats the date as UTC.\n * * 2. Fixed Date (String):\n * @param {string} targetTime - Date string parsable by Date() (e.g., \"2026-01-01T00:00:00\").\n * * 3. Relative Timer:\n * @param {Object} timer - Object containing relative timer settings.\n * @param {number} timer.duration - Duration in milliseconds (e.g., 60000 for 1 min).\n * @param {boolean} timer.disableOnPause - If true (default), pausing the timer \"freezes\" time.\n * If false, time continues to elapse in background.\n * * DOM Selectors (Customizable):\n * -----------------------------\n * @param {string} daysSelector - Selector for days display.\n * @param {string} hoursSelector - Selector for hours display.\n * @param {string} minutesSelector - Selector for minutes display.\n * @param {string} secondsSelector - Selector for seconds display.\n * @param {boolean} zeroPad - Whether to pad numbers with '0' (default: true).\n * * Callbacks:\n * ----------\n * @param {Object} on - Callback functions.\n * @param {Function} on.update - Called every second. Args: (instance, progress[0-1], timeLeft[ms]).\n * @param {Function} on.finish - Called when countdown hits zero. Args: (instance).\n */\nclass RobustCountdown {\n\tconstructor(selector, options = {}) {\n\t\t// Select elements (Support 1-to-many: one instance controlling multiple DOM nodes)\n\t\tthis.elements = document.querySelectorAll(selector);\n\n\t\tif (this.elements.length === 0) {\n\t\t\tconsole.error(`RobustCountdown: No elements found for selector \"${selector}\"`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Default configuration\n\t\tconst defaults = {\n\t\t\t// Option Set A: Granular Date\n\t\t\tyear: new Date().getFullYear(),\n\t\t\tmonth: 1, // 1-12\n\t\t\tday: 1,\n\t\t\thours: 0,\n\t\t\tminutes: 0,\n\t\t\tseconds: 0,\n\t\t\tenableUTC: false,\n\n\t\t\t// Option Set B: Single Date String (legacy support)\n\t\t\ttargetTime: null,\n\n\t\t\t// Option Set C: Relative Duration (ms) with Control Options\n\t\t\ttimer: {\n\t\t\t\tduration: null,\n\t\t\t\tdisableOnPause: true, // If true, pauses \"freeze\" the countdown time. If false, time keeps passing.\n\t\t\t},\n\n\t\t\t// Settings\n\t\t\tzeroPad: true,\n\t\t\tdaysSelector: '[data-countdown-type=\"days\"]',\n\t\t\thoursSelector: '[data-countdown-type=\"hours\"]',\n\t\t\tminutesSelector: '[data-countdown-type=\"minutes\"]',\n\t\t\tsecondsSelector: '[data-countdown-type=\"seconds\"]',\n\n\t\t\t// Callbacks\n\t\t\ton: {\n\t\t\t\tupdate: null, // (instance, progress, timeLeft, individualTimeData) => {}\n\t\t\t\tfinish: null, // (instance) => {}\n\t\t\t},\n\t\t};\n\n\t\t// Deep merge options\n\t\tthis.options = {\n\t\t\t...defaults,\n\t\t\t...options,\n\t\t\ttimer: {\n\t\t\t\t...defaults.timer,\n\t\t\t\t...(options.timer || {}),\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t...defaults.on,\n\t\t\t\t...(options.on || {}),\n\t\t\t},\n\t\t};\n\n\t\t// State\n\t\tthis.intervalId = null;\n\t\tthis.isPaused = false;\n\t\tthis.pauseStart = 0;\n\t\tthis.targetTimestamp = 0;\n\t\tthis.startTimestamp = 0;\n\t\tthis.totalDuration = 0;\n\n\t\t// Initialize\n\t\tthis.init();\n\t}\n\n\tinit() {\n\t\tthis.calculateTarget();\n\t\tthis.start();\n\t}\n\n\tcalculateTarget() {\n\t\tthis.startTimestamp = new Date().getTime();\n\t\tconst opts = this.options;\n\n\t\t// Priority 1: Relative Duration (for loops/restarts)\n\t\tif (opts.timer && opts.timer.duration) {\n\t\t\tthis.targetTimestamp = this.startTimestamp + opts.timer.duration;\n\t\t\tthis.totalDuration = opts.timer.duration;\n\t\t\treturn;\n\t\t}\n\n\t\t// Priority 2: Granular Date OR targetTime\n\t\tlet targetDate;\n\n\t\tif (opts.targetTime) {\n\t\t\ttargetDate = new Date(opts.targetTime);\n\t\t} else {\n\t\t\tconst y = opts.year;\n\t\t\tconst m = (opts.month || 1) - 1;\n\t\t\tconst d = opts.day || 1;\n\t\t\tconst h = opts.hours || 0;\n\t\t\tconst min = opts.minutes || 0;\n\t\t\tconst s = opts.seconds || 0;\n\n\t\t\tif (opts.enableUTC) {\n\t\t\t\ttargetDate = new Date(Date.UTC(y, m, d, h, min, s));\n\t\t\t} else {\n\t\t\t\ttargetDate = new Date(y, m, d, h, min, s);\n\t\t\t}\n\t\t}\n\n\t\tthis.targetTimestamp = targetDate.getTime();\n\t\tthis.totalDuration = Math.max(0, this.targetTimestamp - this.startTimestamp);\n\t}\n\n\tformat(n) {\n\t\treturn this.options.zeroPad === false ? n.toString() : n.toString().padStart(2, \"0\");\n\t}\n\n\ttick() {\n\t\tif (this.isPaused) return;\n\n\t\tconst now = new Date().getTime();\n\t\tconst timeLeft = Math.max(0, this.targetTimestamp - now);\n\n\t\t// --- Time Calculations ---\n\t\tconst days = Math.floor(timeLeft / (1000 * 60 * 60 * 24));\n\t\tconst hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n\t\tconst minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));\n\t\tconst seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);\n\n\t\t// --- Global Progress Calculation (0.0 to 1.0) ---\n\t\tlet globalProgress = 0;\n\t\tif (this.totalDuration > 0) {\n\t\t\tconst elapsed = now - this.startTimestamp;\n\t\t\tglobalProgress = Math.min(1, Math.max(0, elapsed / this.totalDuration));\n\t\t} else {\n\t\t\tglobalProgress = 1;\n\t\t}\n\n\t\t// --- Individual Unit Progress Calculation ---\n\t\t// Constructs the progress object (0.0 to 1.0 for each unit)\n\t\tconst progressObject = {\n\t\t\ttotal: globalProgress,\n\t\t\tdays: this.totalDuration > 0 ? days / (this.totalDuration / (1000 * 60 * 60 * 24)) : 0,\n\t\t\thours: hours / 24,\n\t\t\tminutes: minutes / 60,\n\t\t\tseconds: seconds / 60,\n\t\t};\n\n\t\t// --- DOM Updates ---\n\t\tthis.elements.forEach((el) => {\n\t\t\tconst elDays = el.querySelector(this.options.daysSelector);\n\t\t\tconst elHours = el.querySelector(this.options.hoursSelector);\n\t\t\tconst elMin = el.querySelector(this.options.minutesSelector);\n\t\t\tconst elSec = el.querySelector(this.options.secondsSelector);\n\n\t\t\tif (elDays) elDays.innerText = this.format(days);\n\t\t\tif (elHours) elHours.innerText = this.format(hours);\n\t\t\tif (elMin) elMin.innerText = this.format(minutes);\n\t\t\tif (elSec) elSec.innerText = this.format(seconds);\n\t\t});\n\n\t\t// --- Callback: Update ---\n\t\tif (typeof this.options.on.update === \"function\") {\n\t\t\t// Send progressObject as 2nd arg, individual values as 4th arg\n\t\t\tconst individualTimeData = { days, hours, minutes, seconds };\n\n\t\t\tthis.options.on.update(this, progressObject, timeLeft, individualTimeData);\n\t\t}\n\n\t\t// --- Finish Check ---\n\t\tif (timeLeft <= 0) {\n\t\t\tthis.stop();\n\t\t\tif (typeof this.options.on.finish === \"function\") {\n\t\t\t\tthis.options.on.finish(this);\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- API Control Methods ---\n\n\tstart() {\n\t\tthis.isPaused = false;\n\t\tthis.tick();\n\t\tif (this.intervalId) clearInterval(this.intervalId);\n\t\tthis.intervalId = setInterval(() => this.tick(), 1000);\n\t}\n\n\tpause() {\n\t\tthis.isPaused = true;\n\t\tthis.pauseStart = new Date().getTime();\n\t}\n\n\tresume() {\n\t\tif (!this.isPaused) return;\n\n\t\tif (this.options.timer && this.options.timer.duration && this.options.timer.disableOnPause) {\n\t\t\tconst now = new Date().getTime();\n\t\t\tconst pauseDuration = now - this.pauseStart;\n\t\t\tthis.targetTimestamp += pauseDuration;\n\t\t\tthis.startTimestamp += pauseDuration;\n\t\t}\n\n\t\tthis.start();\n\t}\n\n\tstop() {\n\t\tif (this.intervalId) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = null;\n\t\t}\n\t\tthis.isPaused = true;\n\t}\n\n\trestart() {\n\t\tthis.stop();\n\t\tthis.calculateTarget();\n\t\tthis.start();\n\t}\n\n\tupdate(newOptions) {\n\t\tthis.options = {\n\t\t\t...this.options,\n\t\t\t...newOptions,\n\t\t\ttimer: {\n\t\t\t\t...this.options.timer,\n\t\t\t\t...(newOptions.timer || {}),\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t...this.options.on,\n\t\t\t\t...(newOptions.on || {}),\n\t\t\t},\n\t\t};\n\t\tthis.restart();\n\t}\n}"]}