window.App = { healthInterval: null, init: function () { // API key setup var keyInput = Utils.$('#api-key-input'); Api._apiKey = Api.getApiKey(); keyInput.value = Api.getApiKey(); keyInput.addEventListener('change', function () { Api.setApiKey(keyInput.value.trim()); keyInput.classList.remove('error'); Utils.showToast('API key updated', 'info'); }); // Toggle key visibility Utils.$('#toggle-key-vis').addEventListener('click', function () { var type = keyInput.type === 'password' ? 'text' : 'password'; keyInput.type = type; }); // Initialize modules History.init(); Stats.init(); Upload.init(); Results.showEmpty(); // Health check polling this.checkHealth(); var self = this; this.healthInterval = setInterval(function () { self.checkHealth(); }, 30000); // Warm up models on first load this.warmUp(); }, checkHealth: function () { var indicator = Utils.$('#health-indicator'); Api.checkHealth() .then(function (data) { if (data.status === 'healthy') { indicator.className = 'health-dot healthy'; indicator.title = 'Healthy | Uptime: ' + Math.floor(data.uptime_seconds) + 's'; } else { indicator.className = 'health-dot unhealthy'; indicator.title = 'Unhealthy'; } }) .catch(function () { indicator.className = 'health-dot offline'; indicator.title = 'Server unreachable'; }); }, warmUp: function () { Api.warmUp() .then(function (data) { if (data.status === 'warm') { Utils.showToast('Models loaded', 'success'); } }) .catch(function () { // Warm-up failed silently — models will load on first request }); }, }; document.addEventListener('DOMContentLoaded', function () { App.init(); });