Spaces:
Running
Running
Update public/index.html
Browse files- public/index.html +33 -37
public/index.html
CHANGED
|
@@ -13,8 +13,8 @@
|
|
| 13 |
|
| 14 |
<style>
|
| 15 |
:root {
|
| 16 |
-
--bg-deep: #1e1b4b;
|
| 17 |
-
--text-yellow: #fbbf24;
|
| 18 |
--text-white: #ffffff;
|
| 19 |
--simba-navy: #0f172a;
|
| 20 |
--border-gold: #dca02a;
|
|
@@ -36,12 +36,8 @@
|
|
| 36 |
a { text-decoration: none; transition: 0.2s; }
|
| 37 |
|
| 38 |
/* --- NAVBAR --- */
|
| 39 |
-
.navbar {
|
| 40 |
-
|
| 41 |
-
}
|
| 42 |
-
.nav-logo {
|
| 43 |
-
color: white; font-family: 'Rubik', sans-serif; font-weight: 700; font-size: 22px; display: flex; align-items: center; gap: 12px;
|
| 44 |
-
}
|
| 45 |
.nav-logo img { height: 40px; }
|
| 46 |
.nav-text { display: flex; flex-direction: column; line-height: 1.1; }
|
| 47 |
.nav-text span:first-child { font-size: 14px; color: var(--text-yellow); }
|
|
@@ -73,15 +69,13 @@
|
|
| 73 |
/* --- MAIN BOARD --- */
|
| 74 |
.main-card { background: white; border-radius: 24px; margin: 0 40px; padding: 40px; color: #0f172a; min-height: 600px; position: relative; z-index: 10; }
|
| 75 |
|
| 76 |
-
|
| 77 |
-
.tabs { display: flex; gap: 10px; border-bottom: 2px solid #e2e8f0; margin-bottom: 30px; padding-bottom: 10px; overflow-x: auto;}
|
| 78 |
.tab-btn { background: none; border: none; font-size: 15px; font-weight: 600; color: #64748b; padding: 10px 20px; cursor: pointer; transition: 0.3s; border-radius: 8px; white-space: nowrap; }
|
| 79 |
.tab-btn:hover { background: #f1f5f9; color: var(--bg-deep); }
|
| 80 |
.tab-btn.active { background: var(--bg-deep); color: white; }
|
| 81 |
.view { display: none !important; animation: fadeIn 0.4s; }
|
| 82 |
.view.active { display: block !important; }
|
| 83 |
|
| 84 |
-
/* Controls */
|
| 85 |
.controls { background: #f8fafc; padding: 20px; border-radius: 12px; display: flex; gap: 20px; align-items: center; margin-bottom: 20px; flex-wrap: wrap; }
|
| 86 |
select { padding: 10px; border-radius: 8px; border: 1px solid #cbd5e1; font-size: 14px; min-width: 250px; cursor:pointer; }
|
| 87 |
.rank-info { font-size: 13px; color: #64748b; margin-top: 5px; font-style: italic; }
|
|
@@ -92,11 +86,10 @@
|
|
| 92 |
th { background: #f1f5f9; color: #0f172a; font-weight: 700; padding: 16px; text-align: center; border-bottom: 2px solid #e2e8f0; white-space: nowrap; vertical-align: bottom; }
|
| 93 |
td { padding: 14px; border-bottom: 1px solid #e2e8f0; text-align: center; color: #334155; }
|
| 94 |
tr:hover td { background: #f8fafc; }
|
| 95 |
-
th:first-child, td:first-child { position: sticky; left: 0; background: white; z-index: 2; text-align: left; font-weight: 700; color: #0f172a; border-right: 2px solid #f1f5f9; min-width:
|
| 96 |
thead th:first-child { background: #f1f5f9; z-index: 3; }
|
| 97 |
th:nth-child(2), td:nth-child(2) { text-align: left; }
|
| 98 |
|
| 99 |
-
/* Section Headings */
|
| 100 |
h4 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 18px; margin: 0 0 15px 0; border-bottom: 1px solid #eee; padding-bottom: 10px; }
|
| 101 |
|
| 102 |
/* Citations */
|
|
@@ -265,12 +258,17 @@
|
|
| 265 |
populate('asr-select-mod', DATA.metadata.models);
|
| 266 |
populate('tts-select', DATA.metadata.tts_models);
|
| 267 |
|
| 268 |
-
//
|
| 269 |
const allLangs = new Set();
|
| 270 |
-
//
|
| 271 |
-
Object.values(DATA.asr.
|
| 272 |
-
|
| 273 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
populate('lang-select', Array.from(allLangs).sort());
|
| 275 |
|
| 276 |
renderASR(); renderTTS(); renderSLID();
|
|
@@ -297,7 +295,6 @@
|
|
| 297 |
document.getElementById('grp-fam').style.display='none';
|
| 298 |
document.getElementById('grp-mod').style.display='none';
|
| 299 |
|
| 300 |
-
// Calculate Global Averages
|
| 301 |
const modelStats = [];
|
| 302 |
Object.keys(DATA.asr.by_model).forEach(modName => {
|
| 303 |
const rows = DATA.asr.by_model[modName];
|
|
@@ -308,10 +305,10 @@
|
|
| 308 |
|
| 309 |
modelStats.sort((a,b) => a.wer - b.wer);
|
| 310 |
|
| 311 |
-
html = `<table><thead><tr><th>
|
| 312 |
modelStats.forEach((m, i) => {
|
| 313 |
-
let
|
| 314 |
-
html += `<tr><td
|
| 315 |
});
|
| 316 |
|
| 317 |
} else if(asrMode==='family'){
|
|
@@ -323,16 +320,15 @@
|
|
| 323 |
const d = DATA.asr.by_family[val];
|
| 324 |
if(!d) return;
|
| 325 |
|
| 326 |
-
// Sort rows by WER
|
| 327 |
d.data.sort((a,b) => a.Avg_WER - b.Avg_WER);
|
| 328 |
|
| 329 |
-
html = `<table><thead><tr><th>
|
| 330 |
d.languages.forEach(l => html += `<th>${getIso(l.name, l.iso)}</th>`);
|
| 331 |
html += `</tr></thead><tbody>`;
|
| 332 |
|
| 333 |
d.data.forEach((r, idx) => {
|
| 334 |
-
let
|
| 335 |
-
html += `<tr><td
|
| 336 |
d.languages.forEach(l => {
|
| 337 |
let w=r[`WER_${l.name}`], c=r[`CER_${l.name}`];
|
| 338 |
html += `<td>${(w!=null)?fmt(w)+'/'+fmt(c):'-'}</td>`;
|
|
@@ -396,11 +392,11 @@
|
|
| 396 |
document.getElementById('slid-table').innerHTML = html;
|
| 397 |
}
|
| 398 |
|
| 399 |
-
// --- RENDER LANGUAGE VIEW
|
| 400 |
function renderLanguageView() {
|
| 401 |
const lang = document.getElementById('lang-select').value;
|
| 402 |
|
| 403 |
-
// 1. ASR
|
| 404 |
let asrRows = [];
|
| 405 |
Object.keys(DATA.asr.by_model).forEach(modName => {
|
| 406 |
const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
|
|
@@ -408,41 +404,41 @@
|
|
| 408 |
});
|
| 409 |
asrRows.sort((a,b) => a.wer - b.wer);
|
| 410 |
|
| 411 |
-
let h1 = `<table><thead><tr><th>
|
| 412 |
if(asrRows.length === 0) h1 += `<tr><td colspan="4">No ASR data for this language.</td></tr>`;
|
| 413 |
else asrRows.forEach((r, i) => {
|
| 414 |
-
let
|
| 415 |
-
h1 += `<tr><td>${
|
| 416 |
});
|
| 417 |
h1 += `</tbody></table>`;
|
| 418 |
document.getElementById('lang-asr-table').innerHTML = h1;
|
| 419 |
|
| 420 |
-
// 2. TTS
|
| 421 |
let h2 = `<table><thead><tr><th>Model</th><th>WER</th><th>MCD</th><th>PESQ</th></tr></thead><tbody>`;
|
| 422 |
let ttsFound = false;
|
| 423 |
Object.keys(DATA.tts).forEach(mod => {
|
| 424 |
const row = DATA.tts[mod].find(r => r.language === lang);
|
| 425 |
if(row) {
|
| 426 |
ttsFound = true;
|
| 427 |
-
h2 += `<tr><td>${mod}</td><td>${fmt(row.wer)}</td><td>${fmt(row.mcd)}</td><td>${fmt(row.pesq)}</td></tr>`;
|
| 428 |
}
|
| 429 |
});
|
| 430 |
if(!ttsFound) h2 += `<tr><td colspan="4">No TTS data.</td></tr>`;
|
| 431 |
h2 += `</tbody></table>`;
|
| 432 |
document.getElementById('lang-tts-table').innerHTML = h2;
|
| 433 |
|
| 434 |
-
// 3. SLID
|
| 435 |
-
let h3 = `<table><thead><tr><th>
|
| 436 |
const slidRow = DATA.slid.find(r => r.Language === lang);
|
| 437 |
if(slidRow) {
|
| 438 |
let m = slidRow['MMS-LID-1024'], s = slidRow['Simba-SLID'];
|
| 439 |
let scores = [{n:'Simba-SLID', v:s}, {n:'MMS-LID-1024', v:m}].sort((a,b)=>b.v - a.v);
|
| 440 |
scores.forEach((sc, i) => {
|
| 441 |
-
let
|
| 442 |
-
h3 += `<tr><td>${
|
| 443 |
});
|
| 444 |
} else {
|
| 445 |
-
h3 += `<tr><td colspan="
|
| 446 |
}
|
| 447 |
h3 += `</tbody></table>`;
|
| 448 |
document.getElementById('lang-slid-table').innerHTML = h3;
|
|
|
|
| 13 |
|
| 14 |
<style>
|
| 15 |
:root {
|
| 16 |
+
--bg-deep: #1e1b4b;
|
| 17 |
+
--text-yellow: #fbbf24;
|
| 18 |
--text-white: #ffffff;
|
| 19 |
--simba-navy: #0f172a;
|
| 20 |
--border-gold: #dca02a;
|
|
|
|
| 36 |
a { text-decoration: none; transition: 0.2s; }
|
| 37 |
|
| 38 |
/* --- NAVBAR --- */
|
| 39 |
+
.navbar { padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; position: relative; z-index: 100; }
|
| 40 |
+
.nav-logo { color: white; font-family: 'Rubik', sans-serif; font-weight: 700; font-size: 22px; display: flex; align-items: center; gap: 12px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
.nav-logo img { height: 40px; }
|
| 42 |
.nav-text { display: flex; flex-direction: column; line-height: 1.1; }
|
| 43 |
.nav-text span:first-child { font-size: 14px; color: var(--text-yellow); }
|
|
|
|
| 69 |
/* --- MAIN BOARD --- */
|
| 70 |
.main-card { background: white; border-radius: 24px; margin: 0 40px; padding: 40px; color: #0f172a; min-height: 600px; position: relative; z-index: 10; }
|
| 71 |
|
| 72 |
+
.tabs { display: flex; gap: 10px; border-bottom: 2px solid #e2e8f0; margin-bottom: 30px; padding-bottom: 10px; overflow-x: auto; }
|
|
|
|
| 73 |
.tab-btn { background: none; border: none; font-size: 15px; font-weight: 600; color: #64748b; padding: 10px 20px; cursor: pointer; transition: 0.3s; border-radius: 8px; white-space: nowrap; }
|
| 74 |
.tab-btn:hover { background: #f1f5f9; color: var(--bg-deep); }
|
| 75 |
.tab-btn.active { background: var(--bg-deep); color: white; }
|
| 76 |
.view { display: none !important; animation: fadeIn 0.4s; }
|
| 77 |
.view.active { display: block !important; }
|
| 78 |
|
|
|
|
| 79 |
.controls { background: #f8fafc; padding: 20px; border-radius: 12px; display: flex; gap: 20px; align-items: center; margin-bottom: 20px; flex-wrap: wrap; }
|
| 80 |
select { padding: 10px; border-radius: 8px; border: 1px solid #cbd5e1; font-size: 14px; min-width: 250px; cursor:pointer; }
|
| 81 |
.rank-info { font-size: 13px; color: #64748b; margin-top: 5px; font-style: italic; }
|
|
|
|
| 86 |
th { background: #f1f5f9; color: #0f172a; font-weight: 700; padding: 16px; text-align: center; border-bottom: 2px solid #e2e8f0; white-space: nowrap; vertical-align: bottom; }
|
| 87 |
td { padding: 14px; border-bottom: 1px solid #e2e8f0; text-align: center; color: #334155; }
|
| 88 |
tr:hover td { background: #f8fafc; }
|
| 89 |
+
th:first-child, td:first-child { position: sticky; left: 0; background: white; z-index: 2; text-align: left; font-weight: 700; color: #0f172a; border-right: 2px solid #f1f5f9; min-width: 220px; }
|
| 90 |
thead th:first-child { background: #f1f5f9; z-index: 3; }
|
| 91 |
th:nth-child(2), td:nth-child(2) { text-align: left; }
|
| 92 |
|
|
|
|
| 93 |
h4 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 18px; margin: 0 0 15px 0; border-bottom: 1px solid #eee; padding-bottom: 10px; }
|
| 94 |
|
| 95 |
/* Citations */
|
|
|
|
| 258 |
populate('asr-select-mod', DATA.metadata.models);
|
| 259 |
populate('tts-select', DATA.metadata.tts_models);
|
| 260 |
|
| 261 |
+
// --- POPULATE LANGUAGES FROM ACTUAL DATA ---
|
| 262 |
const allLangs = new Set();
|
| 263 |
+
// Scan ASR by model data to find every single language present
|
| 264 |
+
Object.values(DATA.asr.by_model).forEach(rows => {
|
| 265 |
+
rows.forEach(r => allLangs.add(r.Language));
|
| 266 |
});
|
| 267 |
+
// Scan TTS as well
|
| 268 |
+
Object.values(DATA.tts).forEach(rows => {
|
| 269 |
+
rows.forEach(r => allLangs.add(r.language));
|
| 270 |
+
});
|
| 271 |
+
|
| 272 |
populate('lang-select', Array.from(allLangs).sort());
|
| 273 |
|
| 274 |
renderASR(); renderTTS(); renderSLID();
|
|
|
|
| 295 |
document.getElementById('grp-fam').style.display='none';
|
| 296 |
document.getElementById('grp-mod').style.display='none';
|
| 297 |
|
|
|
|
| 298 |
const modelStats = [];
|
| 299 |
Object.keys(DATA.asr.by_model).forEach(modName => {
|
| 300 |
const rows = DATA.asr.by_model[modName];
|
|
|
|
| 305 |
|
| 306 |
modelStats.sort((a,b) => a.wer - b.wer);
|
| 307 |
|
| 308 |
+
html = `<table><thead><tr><th>Model</th><th>Simba ASR Score (WER/CER) <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
|
| 309 |
modelStats.forEach((m, i) => {
|
| 310 |
+
let icon = (i<3) ? ['π₯','π₯','π₯'][i] + ' ' : '';
|
| 311 |
+
html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${m.name}</td><td><b>${fmt(m.wer)} / ${fmt(m.cer)}</b></td></tr>`;
|
| 312 |
});
|
| 313 |
|
| 314 |
} else if(asrMode==='family'){
|
|
|
|
| 320 |
const d = DATA.asr.by_family[val];
|
| 321 |
if(!d) return;
|
| 322 |
|
|
|
|
| 323 |
d.data.sort((a,b) => a.Avg_WER - b.Avg_WER);
|
| 324 |
|
| 325 |
+
html = `<table><thead><tr><th>Model</th><th>Simba ASR Family Score <i class="fa-solid fa-arrow-down arrow-down"></i></th>`;
|
| 326 |
d.languages.forEach(l => html += `<th>${getIso(l.name, l.iso)}</th>`);
|
| 327 |
html += `</tr></thead><tbody>`;
|
| 328 |
|
| 329 |
d.data.forEach((r, idx) => {
|
| 330 |
+
let icon = (idx<3) ? ['π₯','π₯','π₯'][idx] + ' ' : '';
|
| 331 |
+
html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.Model}</td><td style="font-weight:bold; background:#f8fafc">${fmt(r.Avg_WER)} / ${fmt(r.Avg_CER)}</td>`;
|
| 332 |
d.languages.forEach(l => {
|
| 333 |
let w=r[`WER_${l.name}`], c=r[`CER_${l.name}`];
|
| 334 |
html += `<td>${(w!=null)?fmt(w)+'/'+fmt(c):'-'}</td>`;
|
|
|
|
| 392 |
document.getElementById('slid-table').innerHTML = html;
|
| 393 |
}
|
| 394 |
|
| 395 |
+
// --- RENDER LANGUAGE VIEW ---
|
| 396 |
function renderLanguageView() {
|
| 397 |
const lang = document.getElementById('lang-select').value;
|
| 398 |
|
| 399 |
+
// 1. ASR
|
| 400 |
let asrRows = [];
|
| 401 |
Object.keys(DATA.asr.by_model).forEach(modName => {
|
| 402 |
const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
|
|
|
|
| 404 |
});
|
| 405 |
asrRows.sort((a,b) => a.wer - b.wer);
|
| 406 |
|
| 407 |
+
let h1 = `<table><thead><tr><th>Model</th><th>WER (%)</th><th>CER (%)</th></tr></thead><tbody>`;
|
| 408 |
if(asrRows.length === 0) h1 += `<tr><td colspan="4">No ASR data for this language.</td></tr>`;
|
| 409 |
else asrRows.forEach((r, i) => {
|
| 410 |
+
let icon = (i<3) ? ['π₯','π₯','π₯'][i] + ' ' : '';
|
| 411 |
+
h1 += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.model}</td><td>${fmt(r.wer)}</td><td>${fmt(r.cer)}</td></tr>`;
|
| 412 |
});
|
| 413 |
h1 += `</tbody></table>`;
|
| 414 |
document.getElementById('lang-asr-table').innerHTML = h1;
|
| 415 |
|
| 416 |
+
// 2. TTS
|
| 417 |
let h2 = `<table><thead><tr><th>Model</th><th>WER</th><th>MCD</th><th>PESQ</th></tr></thead><tbody>`;
|
| 418 |
let ttsFound = false;
|
| 419 |
Object.keys(DATA.tts).forEach(mod => {
|
| 420 |
const row = DATA.tts[mod].find(r => r.language === lang);
|
| 421 |
if(row) {
|
| 422 |
ttsFound = true;
|
| 423 |
+
h2 += `<tr><td style="font-weight:600;">${mod}</td><td>${fmt(row.wer)}</td><td>${fmt(row.mcd)}</td><td>${fmt(row.pesq)}</td></tr>`;
|
| 424 |
}
|
| 425 |
});
|
| 426 |
if(!ttsFound) h2 += `<tr><td colspan="4">No TTS data.</td></tr>`;
|
| 427 |
h2 += `</tbody></table>`;
|
| 428 |
document.getElementById('lang-tts-table').innerHTML = h2;
|
| 429 |
|
| 430 |
+
// 3. SLID
|
| 431 |
+
let h3 = `<table><thead><tr><th>Model</th><th>F1-Score</th></tr></thead><tbody>`;
|
| 432 |
const slidRow = DATA.slid.find(r => r.Language === lang);
|
| 433 |
if(slidRow) {
|
| 434 |
let m = slidRow['MMS-LID-1024'], s = slidRow['Simba-SLID'];
|
| 435 |
let scores = [{n:'Simba-SLID', v:s}, {n:'MMS-LID-1024', v:m}].sort((a,b)=>b.v - a.v);
|
| 436 |
scores.forEach((sc, i) => {
|
| 437 |
+
let icon = (i==0) ? 'π₯ ' : '';
|
| 438 |
+
h3 += `<tr><td style="font-weight:600;">${icon}${sc.n}</td><td>${fmt(sc.v)}</td></tr>`;
|
| 439 |
});
|
| 440 |
} else {
|
| 441 |
+
h3 += `<tr><td colspan="2">No SLID data.</td></tr>`;
|
| 442 |
}
|
| 443 |
h3 += `</tbody></table>`;
|
| 444 |
document.getElementById('lang-slid-table').innerHTML = h3;
|