I ${v.v1.toLowerCase()} ${v.context}.
I ${v.v2.toLowerCase()} ${v.context}.
I have ${v.v3.toLowerCase()} ${v.context}.
`;
grid.appendChild(card);
});
isRendered = true;
}
function setupListeners() {
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.addEventListener('input', (e) => {
searchTerm = e.target.value.toLowerCase();
renderVerbs();
});
}
const filterContainer = document.getElementById('categoryFilters');
if (filterContainer) {
filterContainer.addEventListener('click', (e) => {
if (e.target.classList.contains('category-btn')) {
document.querySelectorAll('.category-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
currentCategory = e.target.dataset.category;
renderVerbs();
}
});
}
}
// Quiz Engine
let quizState = { questions: [], currentIndex: 0, score: 0 };
function startQuiz() {
quizState.score = 0;
quizState.currentIndex = 0;
const shuffled = [...verbData].sort(() => 0.5 - Math.random());
quizState.questions = shuffled.slice(0, 10).map(v => {
const targetForm = Math.random() > 0.5 ? 'v2' : 'v3';
const correct = v[targetForm];
let distractors = verbData
.filter(item => item.v1 !== v.v1)
.map(item => Math.random() > 0.5 ? item.v2 : item.v3)
.filter((val, idx, self) => self.indexOf(val) === idx && val !== correct)
.sort(() => 0.5 - Math.random())
.slice(0, 3);
const options = [correct, ...distractors].sort(() => 0.5 - Math.random());
return { verb: v.v1, bn: v.bn1, form: targetForm.toUpperCase(), correct, options };
});
document.getElementById('quizIntro').classList.add('hidden');
document.getElementById('quizResult').classList.add('hidden');
document.getElementById('quizContent').classList.remove('hidden');
showQuestion();
}
function showQuestion() {
const q = quizState.questions[quizState.currentIndex];
document.getElementById('currentQNum').innerText = quizState.currentIndex + 1;
document.getElementById('score').innerText = quizState.score;
document.getElementById('progressBar').style.width = ((quizState.currentIndex + 1) * 10) + '%';
document.getElementById('questionText').innerHTML = `What is the
${q.form} form of "
${q.verb}" (${q.bn})?`;
const optionsGrid = document.getElementById('optionsGrid');
optionsGrid.innerHTML = '';
q.options.forEach(opt => {
const btn = document.createElement('button');
btn.className = "quiz-option p-4 glass hover:bg-white text-lg font-bold rounded-xl border-2 border-transparent hover:border-purple-400 transition-all whitespace-nowrap overflow-hidden text-ellipsis";
btn.innerText = opt;
btn.onclick = () => checkAnswer(opt, btn);
optionsGrid.appendChild(btn);
});
}
function checkAnswer(selected, btn) {
const q = quizState.questions[quizState.currentIndex];
const options = document.querySelectorAll('.quiz-option');
options.forEach(o => o.disabled = true);
if (selected === q.correct) {
btn.classList.add('bg-green-500', 'text-white', 'border-green-600');
quizState.score++;
} else {
btn.classList.add('bg-red-500', 'text-white', 'border-red-600');
options.forEach(o => { if (o.innerText === q.correct) o.classList.add('bg-green-100', 'border-green-500'); });
}
setTimeout(() => {
quizState.currentIndex++;
if (quizState.currentIndex < 10) showQuestion();
else endQuiz();
}, 1200);
}
function endQuiz() {
document.getElementById('quizContent').classList.add('hidden');
document.getElementById('quizResult').classList.remove('hidden');
document.getElementById('finalScore').innerText = quizState.score;
}
function masterInit() {
if (isRendered) return;
renderVerbs();
setupListeners();
}
masterInit();
document.addEventListener('DOMContentLoaded', masterInit);
window.addEventListener('load', masterInit);
let checks = 0;
const heartbeat = setInterval(() => {
checks++;
if (isRendered || checks > 50) clearInterval(heartbeat);
else if (document.getElementById('verbGrid')) masterInit();
}, 100);