Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Live WebApp Viewer</title> | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap'); | |
:root { | |
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
--secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
--accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
--dark-bg: #0a0a0a; | |
--card-bg: #ffffff; | |
--text-primary: #1a1a1a; | |
--text-secondary: #666666; | |
--text-muted: #888888; | |
--border-color: #e5e7eb; | |
--shadow-sm: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); | |
--shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 1px 3px rgba(0,0,0,0.06); | |
--shadow-lg: 0 10px 25px rgba(0,0,0,0.1), 0 4px 10px rgba(0,0,0,0.06); | |
--shadow-xl: 0 20px 40px rgba(0,0,0,0.1), 0 8px 20px rgba(0,0,0,0.08); | |
--border-radius: 16px; | |
--border-radius-sm: 12px; | |
--border-radius-lg: 24px; | |
} | |
* { | |
box-sizing: border-box; | |
} | |
body { | |
margin: 0; | |
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
color: var(--text-primary); | |
line-height: 1.6; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
} | |
.container { | |
width: 100vw; | |
padding: 20px; | |
box-sizing: border-box; | |
max-width: 1400px; | |
margin: 0 auto; | |
} | |
.loading { | |
text-align: center; | |
padding: 80px 20px; | |
font-size: 18px; | |
color: var(--text-secondary); | |
font-weight: 500; | |
} | |
/* Main Title Section */ | |
.main-title { | |
text-align: center; | |
margin-bottom: 40px; | |
padding: 0 20px; | |
} | |
.main-title h1 { | |
font-size: clamp(36px, 8vw, 64px); | |
font-weight: 900; | |
margin: 0 0 16px 0; | |
letter-spacing: -2px; | |
background: var(--primary-gradient); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
position: relative; | |
} | |
.main-title h1::after { | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 50%; | |
transform: translateX(-50%); | |
width: 60px; | |
height: 4px; | |
background: var(--accent-gradient); | |
border-radius: 2px; | |
} | |
.main-title p { | |
font-size: clamp(16px, 4vw, 22px); | |
margin: 0 0 20px 0; | |
color: var(--text-secondary); | |
font-weight: 400; | |
line-height: 1.5; | |
max-width: 600px; | |
margin-left: auto; | |
margin-right: auto; | |
} | |
.aisheets-credit { | |
font-size: 14px; | |
color: var(--text-muted); | |
margin-top: 16px; | |
font-weight: 500; | |
} | |
.aisheets-credit a { | |
color: #667eea; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
padding: 4px 8px; | |
border-radius: 6px; | |
background: rgba(102, 126, 234, 0.1); | |
} | |
.aisheets-credit a:hover { | |
color: #764ba2; | |
background: rgba(118, 75, 162, 0.1); | |
transform: translateY(-1px); | |
} | |
/* Stats Header */ | |
.stats-header { | |
background: var(--card-bg); | |
color: var(--text-primary); | |
padding: 40px 30px; | |
text-align: center; | |
margin-bottom: 40px; | |
border-radius: var(--border-radius-lg); | |
box-shadow: var(--shadow-xl); | |
border: 1px solid rgba(255,255,255,0.8); | |
backdrop-filter: blur(20px); | |
} | |
.stats-header p { | |
font-size: 16px; | |
margin: 0 0 30px 0; | |
color: var(--text-secondary); | |
font-weight: 500; | |
line-height: 1.6; | |
} | |
.win-stats { | |
display: flex; | |
justify-content: center; | |
gap: 30px; | |
margin-top: 30px; | |
flex-wrap: wrap; | |
} | |
.stat { | |
font-size: 16px; | |
background: var(--primary-gradient); | |
padding: 20px 30px; | |
border-radius: var(--border-radius-sm); | |
color: white; | |
box-shadow: var(--shadow-md); | |
transition: all 0.3s ease; | |
border: 1px solid rgba(255,255,255,0.2); | |
} | |
.stat:hover { | |
transform: translateY(-2px); | |
box-shadow: var(--shadow-lg); | |
} | |
.stat .model { | |
font-weight: 600; | |
display: block; | |
margin-bottom: 8px; | |
font-size: 14px; | |
opacity: 0.9; | |
} | |
.stat .wins { | |
color: #4ade80; | |
font-weight: 800; | |
font-size: 24px; | |
text-shadow: 0 1px 2px rgba(0,0,0,0.1); | |
} | |
/* TOC Section */ | |
.toc-container { | |
background: var(--card-bg); | |
border-radius: var(--border-radius-lg); | |
box-shadow: var(--shadow-xl); | |
margin-bottom: 40px; | |
padding: 30px; | |
border: 1px solid rgba(255,255,255,0.8); | |
backdrop-filter: blur(20px); | |
} | |
.toc-title { | |
font-size: 20px; | |
font-weight: 700; | |
margin-bottom: 20px; | |
color: var(--text-primary); | |
text-align: center; | |
cursor: pointer; | |
user-select: none; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
gap: 12px; | |
padding: 12px; | |
border-radius: var(--border-radius-sm); | |
transition: all 0.3s ease; | |
} | |
.toc-title:hover { | |
background: rgba(102, 126, 234, 0.1); | |
color: #667eea; | |
transform: translateY(-1px); | |
} | |
.toc-content { | |
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
overflow: hidden; | |
} | |
.toc-content.collapsed { | |
max-height: 0; | |
margin-bottom: 0; | |
} | |
.toc-content.expanded { | |
max-height: none; | |
margin-bottom: 20px; | |
} | |
.toc-grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); | |
gap: 16px; | |
} | |
.toc-item { | |
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); | |
border: 1px solid var(--border-color); | |
border-radius: var(--border-radius-sm); | |
padding: 20px; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
text-decoration: none; | |
color: inherit; | |
position: relative; | |
overflow: hidden; | |
} | |
.toc-item::before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
height: 3px; | |
background: var(--accent-gradient); | |
transform: scaleX(0); | |
transition: transform 0.3s ease; | |
} | |
.toc-item:hover { | |
background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%); | |
border-color: #667eea; | |
transform: translateY(-4px); | |
box-shadow: var(--shadow-lg); | |
} | |
.toc-item:hover::before { | |
transform: scaleX(1); | |
} | |
.toc-number { | |
font-weight: 700; | |
color: #667eea; | |
margin-right: 12px; | |
font-size: 16px; | |
} | |
.toc-description { | |
font-size: 15px; | |
line-height: 1.5; | |
display: -webkit-box; | |
-webkit-line-clamp: 2; | |
-webkit-box-orient: vertical; | |
overflow: hidden; | |
font-weight: 500; | |
} | |
/* App Sections */ | |
.app-section { | |
margin-bottom: 40px; | |
background: var(--card-bg); | |
border-radius: var(--border-radius-lg); | |
box-shadow: var(--shadow-xl); | |
overflow: hidden; | |
border: 1px solid rgba(255,255,255,0.8); | |
backdrop-filter: blur(20px); | |
transition: all 0.3s ease; | |
} | |
.app-section:hover { | |
transform: translateY(-2px); | |
box-shadow: 0 25px 50px rgba(0,0,0,0.15), 0 10px 25px rgba(0,0,0,0.1); | |
} | |
.description-header { | |
background: var(--primary-gradient); | |
color: white; | |
padding: 25px 20px; | |
text-align: center; | |
font-size: 18px; | |
font-weight: 700; | |
letter-spacing: -0.3px; | |
position: relative; | |
} | |
.description-header::after { | |
content: ''; | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
height: 1px; | |
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
} | |
/* Evaluation Section */ | |
.evaluation-section { | |
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); | |
border-bottom: 1px solid var(--border-color); | |
padding: 20px; | |
} | |
.evaluation-result { | |
background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%); | |
border: 1px solid #86efac; | |
border-radius: var(--border-radius-sm); | |
padding: 20px; | |
margin-bottom: 15px; | |
box-shadow: var(--shadow-sm); | |
} | |
.eval-label { | |
font-size: 12px; | |
color: var(--text-muted); | |
margin-bottom: 8px; | |
font-weight: 600; | |
text-transform: uppercase; | |
letter-spacing: 0.5px; | |
} | |
.winner { | |
color: #166534; | |
font-weight: 800; | |
margin-bottom: 8px; | |
font-size: 16px; | |
} | |
.reason { | |
color: #166534; | |
font-weight: 500; | |
} | |
.view-eval-btn { | |
background: var(--primary-gradient); | |
color: white; | |
border: none; | |
padding: 8px 16px; | |
border-radius: var(--border-radius-sm); | |
cursor: pointer; | |
margin-top: 12px; | |
font-size: 13px; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
} | |
.view-eval-btn:hover { | |
transform: translateY(-1px); | |
box-shadow: var(--shadow-md); | |
} | |
.full-evaluation { | |
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
border: 1px solid #fbbf24; | |
border-radius: var(--border-radius-sm); | |
padding: 20px; | |
margin-top: 15px; | |
display: none; | |
box-shadow: var(--shadow-sm); | |
} | |
.thinking-content { | |
max-height: 300px; | |
overflow-y: auto; | |
font-size: 14px; | |
line-height: 1.6; | |
white-space: pre-wrap; | |
text-align: left; | |
color: #92400e; | |
font-weight: 500; | |
} | |
/* Implementation Panels */ | |
.implementations { | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
gap: 0; | |
} | |
.impl-panel { | |
border-right: 1px solid var(--border-color); | |
position: relative; | |
} | |
.impl-panel:last-child { | |
border-right: none; | |
} | |
.impl-header { | |
background: var(--secondary-gradient); | |
color: white; | |
padding: 16px 20px; | |
font-weight: 700; | |
text-align: center; | |
font-size: 16px; | |
letter-spacing: -0.2px; | |
position: relative; | |
} | |
.impl-header::after { | |
content: ''; | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
height: 1px; | |
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
} | |
.iframe-container { | |
height: 600px; | |
background: #f8fafc; | |
position: relative; | |
} | |
.iframe-container::before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
height: 1px; | |
background: linear-gradient(90deg, transparent, var(--border-color), transparent); | |
} | |
iframe { | |
width: 100%; | |
height: 100%; | |
border: none; | |
transform: scale(1); | |
transform-origin: top left; | |
} | |
.error { | |
color: #ef4444; | |
text-align: center; | |
padding: 40px 20px; | |
font-weight: 600; | |
} | |
/* Responsive Design */ | |
@media (min-width: 1400px) { | |
.iframe-container { height: 700px; } | |
.container { padding: 30px; } | |
} | |
@media (max-width: 1200px) { | |
.iframe-container { height: 500px; } | |
.win-stats { gap: 20px; } | |
.stat { padding: 16px 24px; } | |
} | |
@media (max-width: 768px) { | |
.implementations { grid-template-columns: 1fr; } | |
.impl-panel { border-right: none; border-bottom: 1px solid var(--border-color); } | |
.impl-panel:last-child { border-bottom: none; } | |
.iframe-container { height: 400px; } | |
.container { padding: 15px; } | |
.description-header { padding: 20px 15px; font-size: 16px; } | |
.toc-grid { grid-template-columns: 1fr; } | |
.win-stats { gap: 15px; } | |
.stat { padding: 15px 20px; } | |
.main-title h1 { font-size: 48px; } | |
.main-title p { font-size: 18px; } | |
} | |
/* Scrollbar Styling */ | |
::-webkit-scrollbar { | |
width: 8px; | |
} | |
::-webkit-scrollbar-track { | |
background: #f1f5f9; | |
border-radius: 4px; | |
} | |
::-webkit-scrollbar-thumb { | |
background: var(--primary-gradient); | |
border-radius: 4px; | |
} | |
::-webkit-scrollbar-thumb:hover { | |
background: var(--secondary-gradient); | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<div id="apps-container" class="loading">Loading apps from Hugging Face...</div> | |
</div> | |
<script> | |
function parseEvaluation(evalText) { | |
if (!evalText) return null; | |
try { | |
// Look for "chosen:" and "reason:" patterns | |
const chosenMatch = evalText.match(/chosen:\s*(.+?)(?:\n|$)/i); | |
const reasonMatch = evalText.match(/reason:\s*(.+?)(?:\n|$)/is); | |
if (chosenMatch) { | |
return { | |
winner: chosenMatch[1].trim(), | |
reason: reasonMatch ? reasonMatch[1].trim() : '', | |
fullEval: evalText | |
}; | |
} | |
return null; | |
} catch (e) { | |
console.error('Error parsing evaluation:', e); | |
return null; | |
} | |
} | |
function createEvaluationSection(evaluation, index) { | |
const winner = evaluation.winner.toLowerCase().includes('kimi') ? 'Kimi-K2' : | |
evaluation.winner.toLowerCase().includes('qwen') ? 'Qwen3-Coder' : | |
evaluation.winner; | |
return ` | |
<div class="evaluation-section"> | |
<div class="eval-label">(Kimi-K2 judge)</div> | |
<div class="evaluation-result"> | |
<div class="winner">🏆 Winner: ${winner}</div> | |
<button class="view-eval-btn" onclick="toggleFullEval(${index})">View Reason</button> | |
</div> | |
<div class="full-evaluation" id="full-eval-${index}"> | |
<div class="thinking-content">${evaluation.reason}</div> | |
</div> | |
</div> | |
`; | |
} | |
function calculateWinRates(rows) { | |
let kimiWins = 0; | |
let qwenWins = 0; | |
let ties = 0; | |
let totalEvaluated = 0; | |
rows.forEach(row => { | |
const evaluation = parseEvaluation(row.row['r1-evaluation'] || ''); | |
if (evaluation) { | |
totalEvaluated++; | |
const winner = evaluation.winner.toLowerCase(); | |
if (winner.includes('kimi')) { | |
kimiWins++; | |
} else if (winner.includes('qwen')) { | |
qwenWins++; | |
} else { | |
ties++; | |
} | |
} | |
}); | |
const kimiRate = totalEvaluated > 0 ? Math.round((kimiWins / totalEvaluated) * 100) : 0; | |
const qwenRate = totalEvaluated > 0 ? Math.round((qwenWins / totalEvaluated) * 100) : 0; | |
return { | |
kimi: kimiWins, | |
qwen: qwenWins, | |
ties: ties, | |
kimiRate: kimiRate, | |
qwenRate: qwenRate, | |
total: totalEvaluated | |
}; | |
} | |
function toggleFullEval(index) { | |
const fullEval = document.getElementById(`full-eval-${index}`); | |
if (fullEval.style.display === 'block') { | |
fullEval.style.display = 'none'; | |
} else { | |
fullEval.style.display = 'block'; | |
} | |
} | |
function scrollToApp(index) { | |
const appSection = document.getElementById(`app-${index}`); | |
if (appSection) { | |
appSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); | |
} | |
} | |
function toggleTOC() { | |
const tocContent = document.getElementById('toc-content'); | |
const tocTitle = document.getElementById('toc-title'); | |
const isCollapsed = tocContent.classList.contains('collapsed'); | |
if (isCollapsed) { | |
tocContent.classList.remove('collapsed'); | |
tocContent.classList.add('expanded'); | |
tocTitle.innerHTML = '📋 List of Apps ▼'; | |
} else { | |
tocContent.classList.remove('expanded'); | |
tocContent.classList.add('collapsed'); | |
tocTitle.innerHTML = '📋 List of Apps ▶'; | |
} | |
} | |
async function loadAppsFromHuggingFace() { | |
const container = document.getElementById('apps-container'); | |
const response = await fetch('https://datasets-server.huggingface.co/rows?dataset=dvilasuero/JSVibes&config=default&split=train&offset=0&length=50'); | |
const data = await response.json(); | |
// Calculate win rates | |
const winStats = calculateWinRates(data.rows); | |
container.innerHTML = ` | |
<div class="main-title"> | |
<h1>JSVibes</h1> | |
<p>Vibe testing open models for simple but useful (web) code tasks</p> | |
<div class="aisheets-credit"> | |
Built with <a href="https://huggingface.co/spaces/aisheets/sheets" target="_blank">AISheets</a> | |
</div> | |
</div> | |
<div class="stats-header"> | |
<p style="font-size: 14px; opacity: 0.8;">Automatically evaluated by Kimi K2 as a judge. Judgments are imperfect, test them yourself!</p> | |
<div class="win-stats"> | |
<div class="stat"> | |
<span class="model">Kimi-K2</span> | |
<span class="wins">${winStats.kimi} wins</span> | |
<div style="font-size: 14px; opacity: 0.8;">${winStats.kimiRate}%</div> | |
</div> | |
<div class="stat"> | |
<span class="model">Qwen3-Coder</span> | |
<span class="wins">${winStats.qwen} wins</span> | |
<div style="font-size: 14px; opacity: 0.8;">${winStats.qwenRate}%</div> | |
</div> | |
<div class="stat"> | |
<span class="model">Ties</span> | |
<span class="wins">${winStats.ties}</span> | |
</div> | |
</div> | |
</div> | |
<div class="toc-container"> | |
<div class="toc-title" id="toc-title" onclick="toggleTOC()">📋 List of Apps ▶</div> | |
<div class="toc-content collapsed" id="toc-content"> | |
<div class="toc-grid" id="toc-grid"> | |
<!-- TOC items will be populated here --> | |
</div> | |
</div> | |
</div> | |
`; | |
// Build TOC first | |
const tocGrid = document.getElementById('toc-grid'); | |
data.rows.forEach((row, index) => { | |
const app = row.row; | |
const tocItem = document.createElement('div'); | |
tocItem.className = 'toc-item'; | |
tocItem.onclick = () => scrollToApp(index); | |
tocItem.innerHTML = ` | |
<div> | |
<span class="toc-number">#${index + 1}</span> | |
<span class="toc-description">${app.description || 'No description available'}</span> | |
</div> | |
`; | |
tocGrid.appendChild(tocItem); | |
}); | |
data.rows.forEach((row, index) => { | |
const app = row.row; | |
// Clean HTML content by removing markdown code blocks | |
let kimiHtml = app['kimi-k2'] || ''; | |
let qwenHtml = app['qwen3-coder'] || ''; | |
if (kimiHtml.startsWith('```html')) { | |
kimiHtml = kimiHtml.replace(/```html\n?/, '').replace(/```$/, ''); | |
} | |
if (qwenHtml.startsWith('```html')) { | |
qwenHtml = qwenHtml.replace(/```html\n?/, '').replace(/```$/, ''); | |
} | |
// Parse evaluation data | |
const evaluation = parseEvaluation(app['r1-evaluation'] || ''); | |
if (!evaluation && app['r1-evaluation']) { | |
console.log(`Failed to parse evaluation for app ${index}:`, app['r1-evaluation']); | |
} | |
const section = document.createElement('div'); | |
section.className = 'app-section'; | |
section.id = `app-${index}`; | |
section.innerHTML = ` | |
<div class="description-header"> | |
${index + 1}. ${app.description || 'No description available'} | |
</div> | |
${evaluation ? createEvaluationSection(evaluation, index) : ''} | |
<div class="implementations"> | |
<div class="impl-panel"> | |
<div class="impl-header">Kimi-K2</div> | |
<div class="iframe-container"> | |
<iframe srcdoc="${kimiHtml.replace(/"/g, '"')}"></iframe> | |
</div> | |
</div> | |
<div class="impl-panel"> | |
<div class="impl-header">Qwen3-Coder</div> | |
<div class="iframe-container"> | |
<iframe srcdoc="${qwenHtml.replace(/"/g, '"')}"></iframe> | |
</div> | |
</div> | |
</div> | |
`; | |
container.appendChild(section); | |
}); | |
} | |
// Load apps when page loads | |
loadAppsFromHuggingFace(); | |
</script> | |
</body> | |
</html> |