// Small DOM + state helpers used by the rest of the panel. UMD-style (attaches // to window.UI) because UXP loads scripts as classic scripts, not modules. (function () { const UI = {}; UI.$ = function (sel) { return document.querySelector(sel); }; UI.setHidden = function (sel, hidden) { const el = typeof sel === 'string' ? UI.$(sel) : sel; if (!el) return; el.classList.toggle('hidden', !!hidden); }; UI.showPane = function (name) { // name in {connect, library} UI.setHidden('#connect-pane', name !== 'connect'); UI.setHidden('#library-pane', name !== 'library'); }; UI.setStatus = function (sel, text, kind) { const el = typeof sel === 'string' ? UI.$(sel) : sel; if (!el) return; el.textContent = text || ''; el.classList.remove('error', 'muted'); if (kind === 'error') el.classList.add('error'); if (kind === 'muted') el.classList.add('muted'); }; UI.toast = function (msg, kind) { const el = UI.$('#toast'); if (!el) return; el.textContent = msg; el.classList.remove('hidden', 'ok', 'error'); if (kind) el.classList.add(kind); clearTimeout(UI._toastTimer); UI._toastTimer = setTimeout(() => el.classList.add('hidden'), 6000); }; UI.showProgress = function (label, pct) { UI.setHidden('#progress-row', false); UI.$('#progress-label').textContent = label; UI.$('#progress-fill').style.width = Math.max(0, Math.min(100, pct || 0)) + '%'; }; UI.hideProgress = function () { UI.setHidden('#progress-row', true); }; UI.formatBytes = function (n) { if (!Number.isFinite(n)) return ''; const u = ['B', 'KB', 'MB', 'GB', 'TB']; let i = 0; while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; } return n.toFixed(n < 10 && i > 0 ? 1 : 0) + ' ' + u[i]; }; UI.sanitizeFilename = function (s) { return String(s || 'asset').replace(/[\\/:*?"<>|]/g, '_').slice(0, 120); }; window.UI = UI; })();