Public Access
chore: add katex, dompurify, vitest; copy sample exam files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
4f124afa6f
commit
7ad0667668
5 files changed
+349
No files matched your search
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"test": "vitest",
|
||||||
|
"test:run": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dompurify": "^3.4.1",
|
||||||
|
"katex": "^0.16.45",
|
||||||
|
"react": "^19.2.5",
|
||||||
|
"react-dom": "^19.2.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.29.0",
|
||||||
|
"@eslint/js": "^9.39.4",
|
||||||
|
"@rolldown/plugin-babel": "^0.2.3",
|
||||||
|
"@types/babel__core": "^7.20.5",
|
||||||
|
"@types/dompurify": "^3.0.5",
|
||||||
|
"@types/node": "^24.12.2",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
|
"@vitest/coverage-v8": "^4.1.5",
|
||||||
|
"babel-plugin-react-compiler": "^1.0.0",
|
||||||
|
"eslint": "^9.39.4",
|
||||||
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.5.2",
|
||||||
|
"globals": "^17.5.0",
|
||||||
|
"typescript": "~6.0.2",
|
||||||
|
"typescript-eslint": "^8.58.2",
|
||||||
|
"vite": "^8.0.9",
|
||||||
|
"vitest": "^4.1.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"title": "Calculus I — Midterm Practice",
|
||||||
|
"subtitle": "Limits, derivatives, and applications",
|
||||||
|
"author": "Dept. of Mathematics",
|
||||||
|
"timeLimitMinutes": 45,
|
||||||
|
"feedbackMode": "end",
|
||||||
|
"passingScore": 70,
|
||||||
|
"categories": ["Limits", "Derivatives", "Applications"],
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"id": "q1",
|
||||||
|
"type": "multiple-choice",
|
||||||
|
"category": "Limits",
|
||||||
|
"points": 2,
|
||||||
|
"prompt": "Evaluate $\\displaystyle\\lim_{x \\to 0} \\frac{\\sin(3x)}{x}$.",
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "$0$" },
|
||||||
|
{ "id": "b", "text": "$1$" },
|
||||||
|
{ "id": "c", "text": "$3$" },
|
||||||
|
{ "id": "d", "text": "$\\infty$" }
|
||||||
|
],
|
||||||
|
"answer": "c",
|
||||||
|
"explanation": "Using the standard limit $\\lim_{u\\to 0}\\frac{\\sin u}{u}=1$ with $u=3x$ gives $3\\cdot 1 = 3$."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q2",
|
||||||
|
"type": "multiple-select",
|
||||||
|
"category": "Derivatives",
|
||||||
|
"points": 3,
|
||||||
|
"prompt": "Which of the following functions are differentiable at $x=0$? Select all that apply.",
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "$f(x) = |x|$" },
|
||||||
|
{ "id": "b", "text": "$f(x) = x^2 \\sin(1/x)$ with $f(0)=0$" },
|
||||||
|
{ "id": "c", "text": "$f(x) = \\sqrt{x}$" },
|
||||||
|
{ "id": "d", "text": "$f(x) = e^x$" }
|
||||||
|
],
|
||||||
|
"answer": ["b", "d"],
|
||||||
|
"explanation": "$|x|$ has a corner, $\\sqrt{x}$ is not defined for $x<0$. Both $x^2\\sin(1/x)$ (extended) and $e^x$ are differentiable at 0."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q3",
|
||||||
|
"type": "math-input",
|
||||||
|
"category": "Derivatives",
|
||||||
|
"points": 3,
|
||||||
|
"prompt": "Compute $\\dfrac{d}{dx}\\left[x^2 \\ln x\\right]$. Enter your answer in LaTeX.",
|
||||||
|
"answer": "2x\\ln x + x",
|
||||||
|
"acceptedForms": ["2x\\ln(x) + x", "x(2\\ln x + 1)", "x + 2x\\ln x"],
|
||||||
|
"explanation": "By the product rule: $2x\\ln x + x^2 \\cdot \\frac{1}{x} = 2x\\ln x + x$."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q4",
|
||||||
|
"type": "short-answer",
|
||||||
|
"category": "Limits",
|
||||||
|
"points": 2,
|
||||||
|
"prompt": "What is the value of $\\displaystyle\\lim_{x \\to \\infty}\\left(1 + \\frac{1}{x}\\right)^x$? Give the standard symbol.",
|
||||||
|
"answer": "e",
|
||||||
|
"acceptedForms": ["E", "e", " e "],
|
||||||
|
"caseSensitive": false,
|
||||||
|
"explanation": "This is the definition of Euler's number, $e \\approx 2.71828$."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q5",
|
||||||
|
"type": "order",
|
||||||
|
"category": "Applications",
|
||||||
|
"points": 3,
|
||||||
|
"prompt": "Order these steps to find the absolute maximum of $f$ on $[a,b]$ (first → last):",
|
||||||
|
"items": [
|
||||||
|
{ "id": "s1", "text": "Confirm $f$ is continuous on $[a,b]$" },
|
||||||
|
{ "id": "s2", "text": "Find critical points in $(a,b)$" },
|
||||||
|
{ "id": "s3", "text": "Evaluate $f$ at critical points and endpoints" },
|
||||||
|
{ "id": "s4", "text": "Compare values; the largest is the absolute max" }
|
||||||
|
],
|
||||||
|
"answer": ["s1", "s2", "s3", "s4"],
|
||||||
|
"explanation": "The Extreme Value Theorem requires continuity on a closed interval; then candidates are critical points and endpoints."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q6",
|
||||||
|
"type": "match",
|
||||||
|
"category": "Derivatives",
|
||||||
|
"points": 4,
|
||||||
|
"prompt": "Match each function to its derivative.",
|
||||||
|
"left": [
|
||||||
|
{ "id": "l1", "text": "$\\sin x$" },
|
||||||
|
{ "id": "l2", "text": "$\\tan x$" },
|
||||||
|
{ "id": "l3", "text": "$\\ln x$" },
|
||||||
|
{ "id": "l4", "text": "$e^{2x}$" }
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
{ "id": "r1", "text": "$\\dfrac{1}{x}$" },
|
||||||
|
{ "id": "r2", "text": "$\\cos x$" },
|
||||||
|
{ "id": "r3", "text": "$2e^{2x}$" },
|
||||||
|
{ "id": "r4", "text": "$\\sec^2 x$" }
|
||||||
|
],
|
||||||
|
"answer": { "l1": "r2", "l2": "r4", "l3": "r1", "l4": "r3" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q7",
|
||||||
|
"type": "essay",
|
||||||
|
"category": "Applications",
|
||||||
|
"points": 5,
|
||||||
|
"prompt": "Explain, in your own words, the Mean Value Theorem and give a geometric interpretation.",
|
||||||
|
"rubric": [
|
||||||
|
"States hypotheses (continuous on $[a,b]$, differentiable on $(a,b)$)",
|
||||||
|
"States conclusion: $\\exists c \\in (a,b)$ with $f'(c) = \\frac{f(b)-f(a)}{b-a}$",
|
||||||
|
"Explains geometric meaning (tangent parallel to secant)",
|
||||||
|
"Gives or references an example"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"title": "Mixed Demo — Every Question Type",
|
||||||
|
"subtitle": "A tour of every renderer in the platform",
|
||||||
|
"timeLimitMinutes": null,
|
||||||
|
"feedbackMode": "end",
|
||||||
|
"categories": ["Demo"],
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"id": "q1",
|
||||||
|
"type": "multiple-choice",
|
||||||
|
"category": "Demo",
|
||||||
|
"points": 1,
|
||||||
|
"prompt": "Which of the following is the capital of Japan?",
|
||||||
|
"image": {
|
||||||
|
"src": "https://images.unsplash.com/photo-1540959733332-eab4deabeeaf?w=800",
|
||||||
|
"alt": "City skyline",
|
||||||
|
"caption": "A city skyline — can you identify it?"
|
||||||
|
},
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "Kyoto" },
|
||||||
|
{ "id": "b", "text": "Osaka" },
|
||||||
|
{ "id": "c", "text": "Tokyo" },
|
||||||
|
{ "id": "d", "text": "Hiroshima" }
|
||||||
|
],
|
||||||
|
"answer": "c",
|
||||||
|
"explanation": "Tokyo has been Japan's capital since 1868."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q2",
|
||||||
|
"type": "multiple-choice",
|
||||||
|
"category": "Demo",
|
||||||
|
"points": 2,
|
||||||
|
"prompt": "What does the following function return when called with `fib(6)`?",
|
||||||
|
"code": {
|
||||||
|
"language": "javascript",
|
||||||
|
"content": "function fib(n) {\n if (n < 2) return n;\n return fib(n - 1) + fib(n - 2);\n}"
|
||||||
|
},
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "5" },
|
||||||
|
{ "id": "b", "text": "8" },
|
||||||
|
{ "id": "c", "text": "13" },
|
||||||
|
{ "id": "d", "text": "6" }
|
||||||
|
],
|
||||||
|
"answer": "b",
|
||||||
|
"explanation": "The Fibonacci sequence is 0, 1, 1, 2, 3, 5, 8 — so fib(6) = 8."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q3",
|
||||||
|
"type": "short-answer",
|
||||||
|
"category": "Demo",
|
||||||
|
"points": 1,
|
||||||
|
"prompt": "In the data table below, which country had the highest GDP growth?",
|
||||||
|
"table": {
|
||||||
|
"headers": ["Country", "GDP Growth (%)", "Year"],
|
||||||
|
"rows": [
|
||||||
|
["Vietnam", "7.2", "2024"],
|
||||||
|
["India", "6.8", "2024"],
|
||||||
|
["Indonesia", "5.1", "2024"],
|
||||||
|
["Philippines", "5.9", "2024"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"answer": "Vietnam",
|
||||||
|
"caseSensitive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q4",
|
||||||
|
"type": "essay",
|
||||||
|
"category": "Demo",
|
||||||
|
"points": 5,
|
||||||
|
"prompt": "Describe a time you solved a difficult problem. What approach did you take?",
|
||||||
|
"minWords": 50,
|
||||||
|
"rubric": [
|
||||||
|
"Specific situation (not generic)",
|
||||||
|
"Clear problem statement",
|
||||||
|
"Described methodology",
|
||||||
|
"Outcome or reflection"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"title": "Spanish A2 — Vocabulary & Grammar",
|
||||||
|
"subtitle": "Elementary level practice set",
|
||||||
|
"timeLimitMinutes": 20,
|
||||||
|
"feedbackMode": "immediate",
|
||||||
|
"categories": ["Vocabulary", "Grammar", "Listening"],
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"id": "q1",
|
||||||
|
"type": "multiple-choice",
|
||||||
|
"category": "Grammar",
|
||||||
|
"points": 1,
|
||||||
|
"prompt": "Choose the correct form: _____ a la biblioteca todos los días.",
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "Voy" },
|
||||||
|
{ "id": "b", "text": "Va" },
|
||||||
|
{ "id": "c", "text": "Vamos" },
|
||||||
|
{ "id": "d", "text": "Van" }
|
||||||
|
],
|
||||||
|
"answer": "a",
|
||||||
|
"explanation": "First person singular of 'ir' (to go) is 'voy'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q2",
|
||||||
|
"type": "translation",
|
||||||
|
"category": "Vocabulary",
|
||||||
|
"points": 2,
|
||||||
|
"sourceLanguage": "English",
|
||||||
|
"targetLanguage": "Spanish",
|
||||||
|
"prompt": "Translate: \"I would like a coffee with milk, please.\"",
|
||||||
|
"answer": "Me gustaría un café con leche, por favor.",
|
||||||
|
"acceptedForms": [
|
||||||
|
"Quisiera un café con leche, por favor",
|
||||||
|
"Me gustaria un cafe con leche por favor",
|
||||||
|
"Quiero un café con leche, por favor"
|
||||||
|
],
|
||||||
|
"caseSensitive": false,
|
||||||
|
"ignorePunctuation": true,
|
||||||
|
"ignoreAccents": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q3",
|
||||||
|
"type": "match",
|
||||||
|
"category": "Vocabulary",
|
||||||
|
"points": 4,
|
||||||
|
"prompt": "Match each Spanish word to its English translation.",
|
||||||
|
"left": [
|
||||||
|
{ "id": "l1", "text": "perro" },
|
||||||
|
{ "id": "l2", "text": "árbol" },
|
||||||
|
{ "id": "l3", "text": "lluvia" },
|
||||||
|
{ "id": "l4", "text": "manzana" }
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
{ "id": "r1", "text": "rain" },
|
||||||
|
{ "id": "r2", "text": "apple" },
|
||||||
|
{ "id": "r3", "text": "dog" },
|
||||||
|
{ "id": "r4", "text": "tree" }
|
||||||
|
],
|
||||||
|
"answer": { "l1": "r3", "l2": "r4", "l3": "r1", "l4": "r2" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q4",
|
||||||
|
"type": "short-answer",
|
||||||
|
"category": "Grammar",
|
||||||
|
"points": 2,
|
||||||
|
"prompt": "Conjugate 'comer' in the first person plural, present tense.",
|
||||||
|
"answer": "comemos",
|
||||||
|
"caseSensitive": false,
|
||||||
|
"explanation": "Regular -er verb: com + emos = comemos ('we eat')."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q5",
|
||||||
|
"type": "multiple-select",
|
||||||
|
"category": "Grammar",
|
||||||
|
"points": 2,
|
||||||
|
"prompt": "Which of the following are feminine nouns? Select all that apply.",
|
||||||
|
"choices": [
|
||||||
|
{ "id": "a", "text": "la mesa" },
|
||||||
|
{ "id": "b", "text": "el libro" },
|
||||||
|
{ "id": "c", "text": "la casa" },
|
||||||
|
{ "id": "d", "text": "el perro" },
|
||||||
|
{ "id": "e", "text": "la ciudad" }
|
||||||
|
],
|
||||||
|
"answer": ["a", "c", "e"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "q6",
|
||||||
|
"type": "order",
|
||||||
|
"category": "Grammar",
|
||||||
|
"points": 3,
|
||||||
|
"prompt": "Arrange these words to form a grammatically correct sentence:",
|
||||||
|
"items": [
|
||||||
|
{ "id": "w1", "text": "Mi" },
|
||||||
|
{ "id": "w2", "text": "hermana" },
|
||||||
|
{ "id": "w3", "text": "estudia" },
|
||||||
|
{ "id": "w4", "text": "en" },
|
||||||
|
{ "id": "w5", "text": "la universidad" }
|
||||||
|
],
|
||||||
|
"answer": ["w1", "w2", "w3", "w4", "w5"],
|
||||||
|
"explanation": "Subject + verb + prepositional phrase: 'My sister studies at the university.'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/// <reference types="vitest" />
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
|
||||||
|
import babel from '@rolldown/plugin-babel'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
babel({ presets: [reactCompilerPreset()] })
|
||||||
|
],
|
||||||
|
test: {
|
||||||
|
environment: 'node',
|
||||||
|
globals: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in new issue
Block a user