const root = element.querySelector(".labs-progress"); const label = root.querySelector(".labs-progress-label"); const track = root.querySelector(".labs-progress-track"); const fill = root.querySelector(".labs-progress-fill"); const {op, source, done} = root.dataset; const stages = JSON.parse(root.dataset.stages); const LEVEL = /([^/]+?)\s+-\s+([\d.]+)%/g; let timer = null; let started = 0; let seconds = Number(root.dataset.seconds); let shown = 0; let floor = 0; let stageLabel = null; let waiting = false; const WAITING_LABEL = "Spinning up GPU cluster…"; function serverProgress() { const text = source ? document.querySelector(source)?.textContent || "" : ""; for (const [, desc, pct] of text.matchAll(LEVEL)) { const name = desc.replace(/[.…\s]+$/, "").trim(); if (name && !/zero\s*gpu|hugging/i.test(name)) return {name, pct: Number(pct)}; } return null; } function showWaiting() { label.textContent = WAITING_LABEL; track.hidden = true; } function beginGpuWork() { waiting = false; started = performance.now(); } function draw(text, pct) { track.hidden = false; label.textContent = `${text} ${Math.floor(pct)}%`; fill.style.width = `${pct}%`; track.setAttribute("aria-valuenow", String(Math.floor(pct))); } function tick() { const server = serverProgress(); if (waiting) { if (!server) return showWaiting(); beginGpuWork(); } const elapsed = (performance.now() - started) / 1000; const estimate = 95 * (1 - Math.exp(-2 * elapsed / seconds)); if (server) stageLabel = server.name; shown = Math.min(99, Math.max(shown, floor, estimate, server ? Math.min(server.pct, 95) : 0)); const fallback = stages.filter(([at]) => shown >= at).pop()[1]; draw(`${stageLabel || fallback}…`, shown); } function stop() { clearInterval(timer); timer = null; } const bar = { get running() { return timer !== null; }, start(options = {}) { stop(); seconds = options.seconds || Number(root.dataset.seconds); started = performance.now(); shown = floor = 0; stageLabel = null; waiting = root.dataset.gpu === "1"; root.hidden = false; tick(); timer = setInterval(tick, 200); }, stage(name, pct) { if (!timer) return; if (waiting) beginGpuWork(); stageLabel = name; floor = pct; tick(); }, finish(ok) { if (!timer) return; stop(); if (!ok) { root.hidden = true; return; } draw(done, 100); setTimeout(() => { if (!timer) root.hidden = true; }, 900); }, cancel() { stop(); root.hidden = true; }, }; (window.labsProgressBars ||= {})[op] = bar;