โ† Back to Home
OMD ยท Examples

Common Use Cases

Simple Equation Display

A basic example showing how to render an equation and perform simple operations like simplification.

Open Live Preview
index.html (Structure)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple OMD Library Usage</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Simple OMD Library Example</h1>
    
    <div id="math-container"></div>
    
    <div class="controls">
        <input id="expression" type="text" value="2*x + 3 = 7" placeholder="Enter expression...">
        <button id="render">Render</button>
        <button id="simplify">Simplify Step</button>
        <button id="simplifyAll">Simplify All</button>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.11.0/math.min.js"></script>
    <script src="../jsvg/jsvg.js"></script>
    <script src="../jsvg/jsvgComponents.js"></script>
    <script type="module" src="script.js"></script>
</body>
</html>
styles.css
body {
    font-family: Arial, sans-serif;
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

#math-container {
    width: 100%;
    height: 400px;
    border: 1px solid #ccc;
    background: #f9f9f9;
    position: relative;
}

.controls {
    margin-top: 20px;
}

button {
    margin: 5px;
    padding: 8px 16px;
    cursor: pointer;
}

input {
    padding: 8px;
    width: 300px;
    margin: 5px;
}
script.js
import { omdDisplay, omdEquationSequenceNode, omdEquationNode } from '@teachinglab/omd';

let renderer;
let currentSequence;

function renderExpression(expr) {
    // Always render as a sequence for simplification functionality
    const initialNode = omdEquationNode.fromString(expr);
    currentSequence = new omdEquationSequenceNode([initialNode]);
    renderer.render(currentSequence);
    refreshDisplay();
}

function refreshDisplay() {
    if (currentSequence) {
        currentSequence.computeDimensions();
        currentSequence.updateLayout();
        renderer.centerNode();
    }
}

document.addEventListener('DOMContentLoaded', () => {
    // Create renderer (config loads automatically)
    const container = document.getElementById('math-container');
    renderer = new omdDisplay(container, {
        fontSize: 32,
        centerContent: true
    });
    
    // Expose refresh function globally for omdEquationSequenceNode to call
    window.refreshDisplayAndFilters = refreshDisplay;

    // Render initial expression
    renderExpression('2*x + 3 = 7');
    
    // Handle button clicks
    document.getElementById('render').onclick = () => {
        const expression = document.getElementById('expression').value;
        try {
            renderExpression(expression);
        } catch (error) {
            alert('Error: ' + error.message);
        }
    };
    
    document.getElementById('simplify').onclick = () => {
        if (currentSequence) {
            const result = currentSequence.simplify();
            if (!result.success) alert(result.message);
        }
    };
    
    document.getElementById('simplifyAll').onclick = () => {
        if (currentSequence) {
            const result = currentSequence.simplifyAll();
            alert(result.message);
        }
    };
});

Step-by-Step Solution

Demonstrates how to build an interactive step-by-step solver with filtering for different levels of detail.

Open Live Preview
index.html (Structure)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>OMD - Worked Solution Example</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>Worked Solution Example</h1>
        
        <div class="problem">
            <strong>Problem:</strong> Solve for x: <code>3x + 5 = 14</code>
        </div>
        
        <div class="controls">
            <button id="subtract5">Subtract 5 from both sides</button>
            <button id="divide3">Divide both sides by 3</button>
            <button id="simplifyAll">Simplify All</button>
            <button id="reset">Reset</button>
            <button id="autoSolve">Auto Solve</button>
        </div>
        
        <div id="solution-display"></div>
        
        <div class="step-filters">
            <strong>Step Filtering:</strong>
            <div class="filter-option">
                <label>
                    <input type="radio" name="filter" value="all" checked> Show All Steps
                </label>
            </div>
            <div class="filter-option">
                <label>
                    <input type="radio" name="filter" value="0"> Level 0 Only (Major Steps)
                </label>
            </div>
            <div class="filter-option">
                <label>
                    <input type="radio" name="filter" value="1"> Level 1 Only (Intermediate Steps)
                </label>
            </div>
            <div class="filter-option">
                <label>
                    <input type="radio" name="filter" value="2"> Level 2 Only (Detailed Steps)
                </label>
            </div>
        </div>
        
        <div id="explanation" class="explanation"></div>
        <div id="status" class="status"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.11.0/math.min.js"></script>
    <script src="../jsvg/jsvg.js"></script>
    <script src="../jsvg/jsvgComponents.js"></script>
    <script type="module" src="script.js"></script>
</body>
</html>
styles.css
body {
    font-family: Arial;
    max-width: 900px;
    margin: 0 auto;
    padding: 20px;
    background: #f5f5f5;
}
.container {
    background: white;
    padding: 30px;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
    color: #2196F3;
    margin-bottom: 10px;
}
.problem {
    font-size: 24px;
    color: #333;
    margin-bottom: 30px;
    padding: 20px;
    background: #e3f2fd;
    border-radius: 8px;
}
#solution-display {
    width: 100%;
    max-width: 600px;
    aspect-ratio: 1 / 1;
    border: 2px solid #e2e8f0;
    background: #fafafa;
    border-radius: 16px;
    margin: 40px auto;
    box-shadow: 0 15px 35px rgba(0,0,0,0.08);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}
button {
    padding: 12px 24px;
    background: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
    transition: background 0.3s;
}
button:hover {
    background: #45a049;
}
button:disabled {
    background: #ccc;
    cursor: not-allowed;
}
.step-filters {
    margin-top: 20px;
    padding: 15px;
    background: #f0f0f0;
    border-radius: 5px;
}
.filter-option {
    margin: 5px 0;
}
.explanation {
    margin-top: 20px;
    padding: 15px;
    background: #fff3cd;
    border-left: 4px solid #ffc107;
    border-radius: 4px;
    display: none;
}
.status {
    margin-top: 10px;
    padding: 10px;
    border-radius: 5px;
    display: none;
}
.status.success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}
.status.info {
    background: #d1ecf1;
    color: #0c5460;
    border: 1px solid #bee5eb;
}
script.js
import { omdDisplay, omdEquationSequenceNode, omdEquationNode } from '@teachinglab/omd';

let renderer;
let currentSequence;

function updateStatus(message, type = 'info') {
    const status = document.getElementById('status');
    status.textContent = message;
    status.className = `status ${type}`;
    status.style.display = 'block';
    setTimeout(() => status.style.display = 'none', 3000);
}

function refreshDisplayAndFilters() {
    if (!currentSequence) return;

    const filterValue = document.querySelector('input[name="filter"]:checked').value;
    const maxImportance = filterValue === 'all' ? 3 : parseInt(filterValue); // 3 to show all steps

    currentSequence.updateStepsVisibility(step => {
        const stepMark = step.stepMark ?? 0;
        return stepMark <= maxImportance;
    });
    
    // Ensure the sequence and display are updated after visibility changes
    currentSequence.computeDimensions();
    currentSequence.updateLayout();
    renderer.centerNode();
}

function initializeProblem() {
    const initialEquation = omdEquationNode.fromString('3x + 5 = 14');
    currentSequence = new omdEquationSequenceNode([initialEquation]);
    renderer.render(currentSequence);
    updateStatus('Problem loaded. Ready to solve!');
    refreshDisplayAndFilters();
    updateButtonStates();
}

function updateButtonStates() {
    const currentEquationStr = currentSequence.getCurrentEquation()?.toString();
    document.getElementById('subtract5').disabled = currentEquationStr !== '3x + 5 = 14';
    document.getElementById('divide3').disabled = currentEquationStr !== '3x = 9';
}

document.addEventListener('DOMContentLoaded', () => {
    renderer = new omdDisplay(document.getElementById('solution-display'), {
        fontSize: 36,
        fitToContent: false,
        centerContent: true,
        topMargin: 50
    });

    // Expose refresh function globally for omdEquationSequenceNode to call
    window.refreshDisplayAndFilters = refreshDisplayAndFilters;

    initializeProblem();
    
    document.getElementById('subtract5').onclick = () => {
        if (document.getElementById('subtract5').disabled) return;
        currentSequence.applyEquationOperation(5, 'subtract');
        currentSequence.simplify(); // Simplify the result of the operation
        updateStatus('Subtracted 5 from both sides: 3x = 9', 'success');
        updateButtonStates();
    };
    
    document.getElementById('divide3').onclick = () => {
        if (document.getElementById('divide3').disabled) return;
        currentSequence.applyEquationOperation(3, 'divide');
        currentSequence.simplify(); // Simplify the result of the operation
        updateStatus('Divided both sides by 3: x = 3', 'success');
        updateButtonStates();
    };
    
    document.getElementById('simplifyAll').onclick = () => {
        currentSequence.simplifyAll();
        updateStatus('Problem solved!', 'success');
        updateButtonStates();
    };
    
    document.getElementById('reset').onclick = () => {
        initializeProblem();
    };
    
    document.getElementById('autoSolve').onclick = () => {
        currentSequence.simplifyAll();
        updateStatus('Auto-solved!', 'success');
        updateButtonStates();
    };
    
    document.querySelectorAll('input[name="filter"]').forEach(radio => {
        radio.onchange = refreshDisplayAndFilters;
    });
});

Interactive Learning App

A complete mini-application for kids to solve math problems, featuring hints, feedback, and progress tracking.

Open Live Preview
index.html (Structure)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Math Problem Solver for Kids</title>
    <link href="https://fonts.googleapis.com/css2?family=Albert+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="kids-interactive.css">
</head>
<body>
    <div class="container">
        <h1>Math Problem Solver for Kids</h1>
        
        <div class="problem-selector">
            <!-- Problem cards will be dynamically inserted here -->
        </div>
        
        <div class="progress">
            <div class="progress-bar"></div>
        </div>
        
        <div id="math-display"></div>
        
        <div class="hint-area" id="hint-area"></div>
        
        <div class="answer-input">
            <label style="font-size: 20px; font-weight: bold;">What is x equal to?</label><br>
            <input type="number" id="answer" placeholder="?">
        </div>
        
        <div class="controls">
            <button class="btn btn-hint" id="hint-btn">๐Ÿ’ก Show Next Step</button>
            <button class="btn btn-check" id="check-btn">โœ“ Check Answer</button>
            <button class="btn btn-next" id="next-btn" style="display: none;">Next Problem โ†’</button>
        </div>
        
        <div class="feedback" id="feedback"></div>
        
        <div class="stars" id="stars"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.11.0/math.min.js"></script>
    <script src="../jsvg/jsvg.js"></script>
    <script src="../jsvg/jsvgComponents.js"></script>
    <script type="module" src="script.js"></script>
</body>
</html>
kids-interactive.css
/* Only one #math-display block, with all properties */
#math-display {
    width: 100%;
    max-width: 600px;
    aspect-ratio: 1 / 1; /* Force square */
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    border: 3px solid #e2e8f0;
    background: #f7fafc;
    border-radius: 25px;
    margin: 20px auto;
    position: relative;
    padding: 20px;
    box-sizing: border-box;
    box-shadow: 0 15px 35px rgba(0,0,0,0.1);
}
#math-display > svg {
    max-height: 100%;
    width: auto;
    height: auto;
    display: block;
}
body {
    font-family: 'Albert Sans', 'Arial', sans-serif;
    margin: 0;
    padding: 20px;
    background: #5a67d8;
    min-height: 100vh;
}
.container {
    max-width: 1000px;
    margin: 0 auto;
    background: white;
    padding: 30px;
    border-radius: 20px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
h1 {
    color: #5a67d8;
    text-align: center;
    font-size: 2.5em;
    margin-bottom: 30px;
    text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.problem-selector {
    display: flex;
    gap: 15px;
    margin-bottom: 30px;
    flex-wrap: wrap;
    justify-content: center;
}
.problem-card {
    background: #f7fafc;
    border: 3px solid #e2e8f0;
    padding: 15px 25px;
    border-radius: 15px;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 20px;
    font-weight: bold;
}
.problem-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
    border-color: #5a67d8;
    background: #edf2f7;
}
.problem-card.selected {
    background: #5a67d8;
    color: white;
    border-color: #5a67d8;
}
.hint-area {
    background: #c6f6d5;
    border: 2px solid #9ae6b4;
    padding: 20px;
    border-radius: 10px;
    margin: 20px 0;
    font-size: 18px;
    display: none;
    animation: slideIn 0.5s ease-out;
}
@keyframes slideIn {
    from {
        transform: translateX(-20px);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}
.controls {
    display: flex;
    gap: 15px;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 20px;
}
.btn {
    padding: 15px 30px;
    font-size: 18px;
    border: none;
    border-radius: 30px;
    cursor: pointer;
    transition: all 0.3s;
    font-weight: bold;
    text-transform: uppercase;
}
.btn-hint {
    background: #f6e05e;
    color: #744210;
}
.btn-hint:hover {
    background: #f6d743;
    transform: scale(1.05);
}
.btn-hint:disabled {
    background: #e2e8f0;
    color: #a0aec0;
    cursor: not-allowed;
    transform: none;
}
.btn-check {
    background: #48bb78;
    color: white;
}
.btn-check:hover {
    background: #38a169;
    transform: scale(1.05);
}
.btn-next {
    background: #667eea;
    color: white;
}
.btn-next:hover {
    background: #5a67d8;
    transform: scale(1.05);
}
.answer-input {
    text-align: center;
    margin: 20px 0;
}
.answer-input input {
    padding: 15px;
    font-size: 24px;
    width: 150px;
    text-align: center;
    border: 3px solid #e2e8f0;
    border-radius: 10px;
    font-weight: bold;
}
.answer-input input:focus {
    outline: none;
    border-color: #5a67d8;
}
.feedback {
    text-align: center;
    font-size: 24px;
    margin: 20px 0;
    padding: 20px;
    border-radius: 10px;
    display: none;
    font-weight: bold;
}
.feedback.correct {
    background: #c6f6d5;
    color: #22543d;
    animation: bounce 0.5s ease-out;
}
.feedback.incorrect {
    background: #feb2b2;
    color: #742a2a;
    animation: shake 0.5s ease-out;
}
@keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
}
@keyframes shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-10px); }
    75% { transform: translateX(10px); }
}
.stars {
    text-align: center;
    font-size: 40px;
    margin: 20px 0;
}
.star {
    color: #f6e05e;
    display: inline-block;
    margin: 0 5px;
    animation: starPop 0.5s ease-out;
}
@keyframes starPop {
    0% { transform: scale(0); }
    50% { transform: scale(1.2); }
    100% { transform: scale(1); }
}
.progress {
    background: #e2e8f0;
    height: 20px;
    border-radius: 10px;
    overflow: hidden;
    margin: 20px 0;
}
.progress-bar {
    background: linear-gradient(90deg, #48bb78, #38a169);
    height: 100%;
    width: 0%;
    transition: width 0.5s ease-out;
}
script.js
import { omdDisplay, omdEquationNode, omdEquationStack } from '@teachinglab/omd';

class KidsMathSolver {
    constructor() {
        this.display = new omdDisplay(document.getElementById('math-display'), {
            backgroundColor: '#f7fafc',
            fitToContent: false,
            centerContent: true,
            fontSize: 48 
        });
        
        this.problems = {
            'x + 3 = 7': { 
                answer: 4, 
                hint: 'Subtract 3 from both sides to find x',
                operations: [
                    { type: 'subtract', value: 3, description: 'Subtract 3 from both sides' },
                ]
            },
            '2x + 4 = 10': { 
                answer: 3, 
                hint: 'First subtract 4, then divide by 2',
                operations: [
                    { type: 'subtract', value: 4, description: 'Subtract 4 from both sides' },
                    { type: 'divide', value: 2, description: 'Divide both sides by 2' }
                ]
            },
            '3x - 6 = 9': { 
                answer: 5, 
                hint: 'First add 6, then divide by 3',
                operations: [
                    { type: 'add', value: 6, description: 'Add 6 to both sides' },
                    { type: 'divide', value: 3, description: 'Divide both sides by 3' }
                ]
            },
            '2x+4=3x+2': { 
                answer: 2, 
                hint: 'First subtract 2x from both sides, then subtract 2 from both sides',
                operations: [
                    { type: 'subtract', value: '2x', description: 'Subtract 2x from both sides' },
                    { type: 'subtract', value: 2, description: 'Subtract 2 from both sides' }
                ]
            },
            'x + 5 = 12': {
                answer: 7,
                hint: 'Subtract 5 from both sides to find x',
                operations: [
                    { type: 'subtract', value: 5, description: 'Subtract 5 from both sides' }
                ]
            },
            '4x - 8 = 0': {
                answer: 2,
                hint: 'Add 8 to both sides, then divide by 4',
                operations: [
                    { type: 'add', value: 8, description: 'Add 8 to both sides' },
                    { type: 'divide', value: 4, description: 'Divide both sides by 4' }
                ]
            },  
            'x/3 + 2 = 5': {
                answer: 9,
                hint: 'First subtract 2 from both sides, then multiply by 3',
                operations: [
                    { type: 'subtract', value: 2, description: 'Subtract 2 from both sides' },
                    { type: 'multiply', value: 3, description: 'Multiply both sides by 3' }
                ]
            },
            '6x - 3 = 15': {
                answer: 3, 
                hint: 'First add 3 to both sides, then divide by 6',
                operations: [
                    { type: 'add', value: 3, description: 'Add 3 to both sides' },
                    { type: 'divide', value: 6, description: 'Divide both sides by 6' }
                ]
            }, 
            '2x+3=4': {
                answer: 0.5,
                hint: 'First subtract 3 from both sides, then divide by 2',
                operations: [
                    { type: 'subtract', value: 3, description: 'Subtract 3 from both sides' },
                    { type: 'divide', value: 2, description: 'Divide both sides by 2' }
                ]
            }
            
        };
        
        this.problemKeys = Object.keys(this.problems);
        this.currentProblemIndex = -1;
        this.score = 0;
        this.currentEquationStack = null;
        this.currentOperationIndex = 0;
        
        this.elements = {
            problemSelector: document.querySelector('.problem-selector'),
            answerInput: document.getElementById('answer'),
            hintArea: document.getElementById('hint-area'),
            feedback: document.getElementById('feedback'),
            nextBtn: document.getElementById('next-btn'),
            hintBtn: document.getElementById('hint-btn'),
            checkBtn: document.getElementById('check-btn'),
            stars: document.getElementById('stars'),
            progressBar: document.querySelector('.progress-bar')
        };

        this.createProblemSelector();
        this.initializeEventHandlers();
        this.loadNextProblem(); // Load the first problem
        // Set up the automatic filtering like in equation-stack-test
        window.refreshDisplayAndFilters = () => {
            if (this.currentEquationStack) {
                const seq = this.currentEquationStack.getSequence();
                seq.simplifyAll();
                seq.updateStepsVisibility(step => (step.stepMark ?? 0) === 0); // Show step 0, filter out 1 and 2
                this.currentEquationStack.updateLayout();
                this.display.centerNode();
            }
        };
    }

    createProblemSelector() {
        this.elements.problemSelector.innerHTML = ''; // Clear existing cards
        this.problemKeys.forEach(problemString => {
            const card = document.createElement('div');
            card.className = 'problem-card';
            card.dataset.problem = problemString;
            card.textContent = problemString;
            this.elements.problemSelector.appendChild(card);
        });
    }
    
    initializeEventHandlers() {
        this.elements.problemSelector.addEventListener('click', (e) => {
            if (e.target.classList.contains('problem-card')) {
                this.loadProblem(e.target.dataset.problem);
            }
        });
        
        this.elements.hintBtn.addEventListener('click', () => this.showHint());
        this.elements.checkBtn.addEventListener('click', () => this.checkAnswer());
        this.elements.nextBtn.addEventListener('click', () => this.loadNextProblem());
        this.elements.answerInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') this.checkAnswer();
        });
    }

    loadProblem(problemString) {
        // Ensure previous problem is completely cleared (handles residual SVG/viewBox)
        this.clearCurrentProblem();
        document.querySelectorAll('.problem-card').forEach(c => c.classList.remove('selected'));
        const selectedCard = document.querySelector(`.problem-card[data-problem="${problemString}"]`);
        if (selectedCard) selectedCard.classList.add('selected');

        this.currentProblem = problemString;
        this.currentOperationIndex = 0;
        // (clearCurrentProblem already recreated display)
        
        // Create equation stack like in equation-stack-test
        const initialEquation = omdEquationNode.fromString(problemString);
        this.currentEquationStack = new omdEquationStack([initialEquation], {
            stepVisualizer: true,
            toolbar: false
        });
        

        this.display.render(this.currentEquationStack);
        this.display.centerNode();

        this.resetUI();
    }

    clearCurrentProblem() {
        // Fully clear current visual + state
        try {
            const md = document.getElementById('math-display');
            if (this.display) {
                try { this.display.destroy(); } catch(_) {}
            }
            if (md) {
                // Hard reset container
                md.innerHTML = '';
                // Recreate display fresh so no lingering references remain
                this.display = new omdDisplay(md, {
                    backgroundColor: '#f7fafc',
                    fitToContent: false,
                    centerContent: true,
                    fontSize: 48 
                });
            }
        } catch(_) {}
        this.currentEquationStack = null;
        this.currentOperationIndex = 0;
        // UI cleanup
        this.elements.hintArea.style.display = 'none';
        this.elements.feedback.style.display = 'none';
        this.elements.nextBtn.style.display = 'none';
    }

    loadNextProblem() {
        // Ensure previous problem visuals are cleared before proceeding
        this.clearCurrentProblem();
        this.currentProblemIndex++;
        if (this.currentProblemIndex >= this.problemKeys.length) {
            this.showCompletionMessage();
            this.currentProblemIndex = 0; // Loop back to start
            this.score = 0;
        }
        this.loadProblem(this.problemKeys[this.currentProblemIndex]);
        this.updateScoreDisplay();
    }
    
    showCompletionMessage() {
        this.elements.feedback.textContent = '๐ŸŽŠ Amazing! You completed all problems! Starting over...';
        this.elements.feedback.className = 'feedback correct';
        this.elements.feedback.style.display = 'block';
        setTimeout(() => {
            this.elements.feedback.style.display = 'none';
        }, 3000);
    }

    resetUI() {
        this.elements.answerInput.value = '';
        this.elements.feedback.style.display = 'none';
        this.elements.hintArea.style.display = 'none';
        this.elements.nextBtn.style.display = 'none';
        this.elements.hintBtn.style.display = 'inline-block';
        this.elements.checkBtn.style.display = 'inline-block';
        
        this.currentOperationIndex = 0;
    }

    showHint() {
        if (!this.currentProblem || !this.currentEquationStack) return;
        
        const problemData = this.problems[this.currentProblem];
        
        // Check if we have more operations to apply
        if (this.currentOperationIndex < problemData.operations.length) {
            const operation = problemData.operations[this.currentOperationIndex];
            const sequence = this.currentEquationStack.getSequence();
            const currentEquation = sequence.getCurrentEquation();
            
            if (!currentEquation) return;
            
            // Apply the operation using the sequence's built-in methods
            let result;
            switch (operation.type) {
                case 'add':
                    result = sequence.applyEquationOperation(operation.value, 'add');
                    break;
                case 'subtract':
                    result = sequence.applyEquationOperation(operation.value, 'subtract');
                    break;
                case 'multiply':
                    result = sequence.applyEquationOperation(operation.value, 'multiply');
                    break;
                case 'divide':
                    result = sequence.applyEquationOperation(operation.value, 'divide');
                    break;
                default:
                    console.error('Unknown operation type:', operation.type);
                    return;
            }
            
            this.currentOperationIndex++;
            
            // Show hint text
            this.elements.hintArea.textContent = `๐Ÿ’ก ${operation.description}!`;
            this.elements.hintArea.style.display = 'block';
            
            // Check if we've applied all operations
            if (this.currentOperationIndex >= problemData.operations.length) {
                this.elements.hintBtn.style.display = 'none';
                this.elements.hintArea.textContent += ' Now you can see the answer!';
            }
        } else {
            this.elements.hintBtn.style.display = 'none';
        }
    }

    checkAnswer() {
        if (!this.currentProblem) return;
        
        const userAnswer = parseInt(this.elements.answerInput.value);
        const correctAnswer = this.problems[this.currentProblem].answer;
        
        if (userAnswer === correctAnswer) {
            this.elements.feedback.textContent = '๐ŸŽ‰ Correct! Great job!';
            this.elements.feedback.className = 'feedback correct';
            this.elements.nextBtn.style.display = 'inline-block';
            this.score++;
            this.elements.hintBtn.style.display = 'none';
            this.elements.checkBtn.style.display = 'none';
            
            // Show the complete solution if not already shown
            const problemData = this.problems[this.currentProblem];
            while (this.currentOperationIndex < problemData.operations.length) {
                this.showHint();
            }
        } else {
            this.elements.feedback.textContent = 'โŒ Try again! Use the hint to see the next step.';
            this.elements.feedback.className = 'feedback incorrect';
        }
        this.elements.feedback.style.display = 'block';
        this.updateScoreDisplay();
    }

    updateScoreDisplay() {
        this.elements.stars.innerHTML = 'โญ'.repeat(this.score);
        this.elements.progressBar.style.width = `${(this.score / this.problemKeys.length) * 100}%`;
    }
}

document.addEventListener('DOMContentLoaded', () => {
    window.math = math; // Make math.js globally available for OMD
    new KidsMathSolver();
});