/** * App — Hash router, component lifecycle, navigation, event bus */ const App = (() => { let currentComponent = null; let appEl = null; const routes = [ { pattern: /^\/$/, handler: showHome }, { pattern: /^\/exercises$/, handler: showExercises }, { pattern: /^\/exercise\/(.+)$/, handler: showExercise }, { pattern: /^\/workspace$/, handler: showWorkspace }, { pattern: /^\/workspace\/matrix$/, handler: showMatrixBuilder }, { pattern: /^\/workspace\/system$/, handler: showSystemSolver } ]; // ── Event Bus ── const bus = {}; function on(event, fn) { (bus[event] = bus[event] || []).push(fn); } function emit(event, data) { (bus[event] || []).forEach(fn => fn(data)); } // ── Theme ── function initTheme() { const saved = localStorage.getItem('algebra-theme'); if (saved === 'dark') { document.documentElement.setAttribute('data-theme', 'dark'); } } function toggleTheme() { const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; if (isDark) { document.documentElement.removeAttribute('data-theme'); localStorage.setItem('algebra-theme', 'light'); } else { document.documentElement.setAttribute('data-theme', 'dark'); localStorage.setItem('algebra-theme', 'dark'); } } // ── Navigation ── function navigate(path) { window.location.hash = '#' + path; } function getHash() { return window.location.hash.slice(1) || '/'; } function matchRoute(hash) { for (const route of routes) { const match = hash.match(route.pattern); if (match) { return { handler: route.handler, params: match.slice(1) }; } } return { handler: showHome, params: [] }; } function updateActiveNav() { const hash = getHash(); document.querySelectorAll('.navbar__link').forEach(link => { const route = link.getAttribute('data-route'); link.classList.remove('navbar__link--active'); if (route === 'home' && (hash === '/' || hash === '')) { link.classList.add('navbar__link--active'); } else if (route === 'exercises' && hash.startsWith('/exercise')) { link.classList.add('navbar__link--active'); } else if (route === 'workspace' && hash.startsWith('/workspace')) { link.classList.add('navbar__link--active'); } }); } // ── Component Lifecycle ── function destroyCurrent() { if (currentComponent && typeof currentComponent.destroy === 'function') { currentComponent.destroy(); } currentComponent = null; if (appEl) appEl.innerHTML = ''; } function mountComponent(componentObj, initArgs) { destroyCurrent(); currentComponent = componentObj; componentObj.init(appEl, initArgs); } // ── Page Handlers ── function showHome() { destroyCurrent(); appEl.innerHTML = `
Practicá los ejercicios de Vectores, Recta, Plano, Matrices, Determinantes y Sistemas de Ecuaciones. Paso a paso, con verificación automática.
Operá con matrices y resolvé sistemas de ecuaciones