Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>QIMMA - Open Arabic LLM Leaderboard</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://unpkg.com/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" /> | |
| <script src="https://unpkg.com/gridjs/dist/gridjs.umd.js"></script> | |
| <script src="https://unpkg.com/lucide@latest"></script> | |
| <script> | |
| tailwind.config = { darkMode: 'class', theme: { extend: { colors: { darkbg: '#0f172a' }, animation: { 'fade-in': 'fadeIn 0.5s ease-out' }, keyframes: { fadeIn: { '0%': { opacity: '0', transform: 'translateY(10px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } } } } } } | |
| </script> | |
| <style> | |
| html[dir="rtl"] body { | |
| text-align: right; | |
| } | |
| html[dir="rtl"] #appControls { | |
| left: 1.5rem; | |
| right: auto; | |
| } | |
| html[dir="rtl"] #appTabs nav { | |
| direction: rtl; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-50 text-slate-800 font-sans transition-colors duration-300 dark:bg-darkbg dark:text-slate-100"> | |
| <div id="appControls" class="absolute top-6 right-6 z-50 flex items-center gap-3"> | |
| <button onclick="toggleLanguage()" | |
| class="flex items-center gap-2 rounded-full bg-white px-4 py-2 text-sm font-semibold text-slate-600 shadow-md hover:bg-slate-100 dark:bg-slate-800 dark:text-sky-300 dark:hover:bg-slate-700 transition-all"> | |
| <i data-lucide="languages" class="h-4 w-4"></i> | |
| <span id="languageToggleLabel">AR</span> | |
| </button> | |
| <button onclick="toggleDarkMode()" | |
| class="p-2 rounded-full bg-white text-slate-600 shadow-md hover:bg-slate-100 dark:bg-slate-800 dark:text-yellow-400 dark:hover:bg-slate-700 transition-all"> | |
| <i data-lucide="moon" id="themeIcon" class="h-5 w-5"></i> | |
| </button> | |
| </div> | |
| <div class="max-w-[98%] mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
| <div id="dynamic-header-container"> | |
| <div class="p-12 flex justify-center"><i data-lucide="loader-2" | |
| class="w-10 h-10 animate-spin text-indigo-600"></i></div> | |
| </div> | |
| <div id="appTabs" class="border-b border-slate-200 dark:border-slate-700 mb-6"> | |
| <nav class="-mb-px flex gap-8 justify-center"> | |
| <button onclick="switchTab('about')" id="tab-btn-about" | |
| class="border-transparent text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200 border-b-2 py-4 px-1 font-medium text-sm transition-colors">ⓘ | |
| <span id="tabLabelAbout">About</span></button> | |
| <button onclick="switchTab('leaderboard')" id="tab-btn-leaderboard" | |
| class="border-indigo-500 text-indigo-600 dark:text-indigo-400 dark:border-indigo-400 border-b-2 py-4 px-1 font-medium text-sm transition-colors">🏅 | |
| <span id="tabLabelLeaderboard">Leaderboard</span></button> | |
| <button onclick="switchTab('submit')" id="tab-btn-submit" | |
| class="border-transparent text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200 border-b-2 py-4 px-1 font-medium text-sm transition-colors">🚀 | |
| <span id="tabLabelSubmit">Submit Model</span></button> | |
| </nav> | |
| </div> | |
| <div id="tab-content-leaderboard" class="block animate-fade-in"> | |
| <div class="flex justify-center p-12"><i data-lucide="loader-2" | |
| class="w-8 h-8 animate-spin text-indigo-600"></i></div> | |
| </div> | |
| <div id="tab-content-submit" class="hidden max-w-5xl mx-auto animate-fade-in"></div> | |
| <div id="tab-content-about" class="hidden max-w-[97%] mx-auto animate-fade-in"></div> | |
| <div class="mt-16 text-center border-t border-slate-200 dark:border-slate-700 pt-8"> | |
| <p class="text-slate-500 dark:text-slate-400 text-sm" id="footerText">© 2026 QIMMA. Built for the Arabic AI community.</p> | |
| </div> | |
| </div> | |
| <script id="eval-columns-data" type="application/json"> | |
| </script> | |
| <script id="benchmark-metadata-data" type="application/json"> | |
| </script> | |
| <script> | |
| window.EVAL_COLUMNS = JSON.parse(document.getElementById('eval-columns-data').textContent); | |
| window.BENCHMARK_METADATA = JSON.parse(document.getElementById('benchmark-metadata-data').textContent); | |
| const $ = s => document.querySelector(s); | |
| const SHELL_TRANSLATIONS = { | |
| ar: { | |
| title: "QIMMA - لوحة صدارة عربية مفتوحة لتقييم النماذج اللغوية", | |
| language_toggle: "EN", | |
| tab_about: "حول", | |
| tab_leaderboard: "لوحة الصدارة", | |
| tab_submit: "تسليم نموذج", | |
| footer: "© 2026 QIMMA. صُمّم هذا المشروع لخدمة مجتمع الذكاء الاصطناعي العربي.", | |
| load_error: "تعذّر تحميل لوحة الصدارة.", | |
| }, | |
| en: { | |
| title: "QIMMA - Open Arabic LLM Leaderboard", | |
| language_toggle: "AR", | |
| tab_about: "About", | |
| tab_leaderboard: "Leaderboard", | |
| tab_submit: "Submit Model", | |
| footer: "© 2026 QIMMA. Built for the Arabic AI community.", | |
| load_error: "Error loading leaderboard.", | |
| } | |
| }; | |
| let currentLanguage = localStorage.getItem('language') || 'en'; | |
| const languageListeners = []; | |
| const BASE_URL = window.self !== window.top | |
| ? 'https://qimma-leaderboard.hf.space' | |
| : ''; | |
| window.getCurrentLanguage = () => currentLanguage; | |
| window.registerLanguageListener = (fn) => { | |
| if (typeof fn === 'function') languageListeners.push(fn); | |
| }; | |
| window.notifyLanguageChanged = () => { | |
| languageListeners.forEach(fn => { | |
| try { fn(currentLanguage); } catch (err) { console.error('language listener failed', err); } | |
| }); | |
| }; | |
| function applyShellTranslations() { | |
| const t = SHELL_TRANSLATIONS[currentLanguage] || SHELL_TRANSLATIONS.en; | |
| document.title = t.title; | |
| document.documentElement.lang = currentLanguage === 'ar' ? 'ar' : 'en'; | |
| document.documentElement.dir = currentLanguage === 'ar' ? 'rtl' : 'ltr'; | |
| document.body?.classList.toggle('rtl-ui', currentLanguage === 'ar'); | |
| document.getElementById('languageToggleLabel').innerText = t.language_toggle; | |
| document.getElementById('tabLabelAbout').innerText = t.tab_about; | |
| document.getElementById('tabLabelLeaderboard').innerText = t.tab_leaderboard; | |
| document.getElementById('tabLabelSubmit').innerText = t.tab_submit; | |
| document.getElementById('footerText').innerText = t.footer; | |
| } | |
| function setLanguage(lang) { | |
| currentLanguage = lang === 'en' ? 'en' : 'ar'; | |
| localStorage.setItem('language', currentLanguage); | |
| applyShellTranslations(); | |
| window.notifyLanguageChanged(); | |
| } | |
| function toggleLanguage() { | |
| setLanguage(currentLanguage === 'ar' ? 'en' : 'ar'); | |
| } | |
| window.toggleLanguage = toggleLanguage; | |
| window.setLanguage = setLanguage; | |
| function toggleDarkMode() { | |
| const isDark = document.documentElement.classList.toggle('dark'); | |
| localStorage.theme = isDark ? 'dark' : 'light'; | |
| $('#themeIcon').setAttribute('data-lucide', isDark ? 'sun' : 'moon'); | |
| lucide.createIcons(); | |
| } | |
| if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) toggleDarkMode(); | |
| async function init() { | |
| try { | |
| const res = await fetch(BASE_URL + '/api/leaderboard'); | |
| const json = await res.json(); | |
| window.allData = json.data || []; | |
| await Promise.all([ | |
| loadTabContent(BASE_URL + '/header.html', '#dynamic-header-container'), | |
| loadTabContent(BASE_URL + '/leaderboard.html', '#tab-content-leaderboard') | |
| ]); | |
| if (window.initLeaderboard) { | |
| window.initLeaderboard(allData); | |
| } | |
| loadTabContent(BASE_URL + '/about.html', '#tab-content-about'); | |
| loadTabContent(BASE_URL + '/submit.html', '#tab-content-submit'); | |
| } catch (err) { | |
| console.error(err); | |
| const t = SHELL_TRANSLATIONS[currentLanguage] || SHELL_TRANSLATIONS.en; | |
| $('#tab-content-leaderboard').innerHTML = `<div class="p-8 text-center text-rose-500">${t.load_error}</div>`; | |
| } | |
| } | |
| async function loadTabContent(url, selector) { | |
| const container = $(selector); | |
| if (!container || container.dataset.loaded) return; | |
| try { | |
| // const res = await fetch(url); | |
| const res = await fetch(url + '?v=' + Date.now()); // leen: added this to see changes reflecting in header | |
| if (!res.ok) throw new Error(`Status: ${res.status}`); | |
| const html = await res.text(); | |
| const parser = new DOMParser(); | |
| const doc = parser.parseFromString(html, 'text/html'); | |
| container.innerHTML = doc.body.innerHTML; | |
| container.dataset.loaded = "true"; | |
| if (window.lucide) lucide.createIcons(); | |
| doc.body.querySelectorAll('script').forEach(oldScript => { | |
| const newScript = document.createElement('script'); | |
| Array.from(oldScript.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value)); | |
| newScript.textContent = oldScript.textContent; | |
| document.body.appendChild(newScript); | |
| }); | |
| window.notifyLanguageChanged(); | |
| } catch (err) { console.error(`Failed to load ${url}:`, err); } | |
| } | |
| function switchTab(tab) { | |
| ['leaderboard', 'submit', 'about'].forEach(t => { | |
| $(`#tab-content-${t}`).classList[t === tab ? 'remove' : 'add']('hidden'); | |
| $(`#tab-btn-${t}`).className = t === tab | |
| ? "border-indigo-500 text-indigo-600 dark:text-indigo-400 dark:border-indigo-400 border-b-2 py-4 px-1 font-medium text-sm transition-colors" | |
| : "border-transparent text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200 border-b-2 py-4 px-1 font-medium text-sm transition-colors"; | |
| }); | |
| } | |
| applyShellTranslations(); | |
| init(); | |
| lucide.createIcons(); | |
| </script> | |
| </body> | |
| </html> | |