{"id":7,"date":"2026-09-02T20:43:53","date_gmt":"2026-09-02T20:43:53","guid":{"rendered":"https:\/\/sunnyrockcollege.co.za\/portal\/?page_id=7"},"modified":"2026-09-03T03:22:00","modified_gmt":"2026-09-03T03:22:00","slug":"exam-solver","status":"publish","type":"page","link":"https:\/\/sunnyrockcollege.co.za\/portal\/","title":{"rendered":"SUNNYROCK College Exam Solver"},"content":{"rendered":"<link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/katex@0.16.8\/dist\/katex.min.css\">\r\n<script defer src=\"https:\/\/cdn.jsdelivr.net\/npm\/katex@0.16.8\/dist\/katex.min.js\"><\/script>\r\n<script defer src=\"https:\/\/cdn.jsdelivr.net\/npm\/katex@0.16.8\/dist\/contrib\/auto-render.min.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/marked\/marked.min.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/mermaid@10\/dist\/mermaid.min.js\"><\/script>\r\n\r\n<style>\r\n    \/* Hide theme header\/footer elements for a clean app feel *\/\r\n    header, footer, .site-header, .site-footer, .wp-block-template-part, .entry-title { \r\n        display: none !important; \r\n    }\r\n    body, #page, #content { \r\n        margin: 0 !important; \r\n        padding: 0 !important; \r\n        background-color: #f8fafc; \r\n    }\r\n    \r\n    .solver-card { \r\n        max-width: 650px; \r\n        margin: 30px auto; \r\n        padding: 25px; \r\n        background: #ffffff; \r\n        border-radius: 16px; \r\n        border: 2px solid #1e3a8a; \r\n        box-shadow: 0 8px 24px rgba(0,0,0,0.08); \r\n        font-family: system-ui, -apple-system, sans-serif; \r\n    }\r\n    .solver-header h2 { \r\n        color: #dc2626; \r\n        text-align: center; \r\n        margin-bottom: 6px; \r\n        font-weight: 800; \r\n    }\r\n    .solver-header p { \r\n        color: #1e3a8a; \r\n        text-align: center; \r\n        margin-bottom: 20px; \r\n        font-weight: 600; \r\n    }\r\n    .access-code-box { \r\n        text-align: center; \r\n        margin-bottom: 20px; \r\n    }\r\n    .access-code-box input { \r\n        width: 100%; \r\n        max-width: 380px; \r\n        padding: 12px; \r\n        border: 2px solid #cbd5e1; \r\n        border-radius: 8px; \r\n        text-align: center; \r\n        font-weight: 600; \r\n        text-transform: uppercase; \r\n        box-sizing: border-box; \r\n    }\r\n    .pricing-selector {\r\n        margin: 15px 0;\r\n        text-align: center;\r\n    }\r\n    .pricing-selector select {\r\n        padding: 10px;\r\n        border-radius: 8px;\r\n        border: 2px solid #2563eb;\r\n        font-weight: 700;\r\n        color: #1e3a8a;\r\n        background: #eff6ff;\r\n        cursor: pointer;\r\n    }\r\n    .custom-upload-btn { \r\n        display: block; \r\n        width: 100%; \r\n        padding: 16px; \r\n        background: linear-gradient(135deg, #2563eb, #1e3a8a); \r\n        color: #ffffff; \r\n        font-weight: 700; \r\n        font-size: 1.1rem; \r\n        border-radius: 10px; \r\n        cursor: pointer; \r\n        text-align: center; \r\n        border: none; \r\n        box-sizing: border-box; \r\n    }\r\n    #statusOutput { \r\n        text-align: center; \r\n        padding: 10px; \r\n        background: #eff6ff; \r\n        border-radius: 8px; \r\n        color: #1e40af; \r\n        font-weight: 600; \r\n        margin: 15px 0; \r\n        border: 1px solid #bfdbfe; \r\n    }\r\n    .solution-box { \r\n        background: #ffffff; \r\n        border: 2px solid #2563eb; \r\n        padding: 20px; \r\n        border-radius: 12px; \r\n        margin-top: 20px; \r\n    }\r\n    .solution-box h4 { \r\n        color: #dc2626; \r\n        margin-top: 0; \r\n        border-bottom: 2px solid #fecaca; \r\n        padding-bottom: 8px; \r\n        font-size: 1.1rem; \r\n    }\r\n    #solutionContent { \r\n        color: #334155; \r\n        line-height: 1.7; \r\n        overflow-x: auto; \r\n    }\r\n    \r\n    \/* Force High-Contrast Display & Responsive Scaling for SVG Diagrams *\/\r\n    #solutionContent svg {\r\n        width: 100% !important;\r\n        max-width: 100% !important;\r\n        height: auto !important;\r\n        display: block;\r\n        margin: 20px auto;\r\n        background: #ffffff !important;\r\n        border: 2px solid #cbd5e1;\r\n        border-radius: 8px;\r\n        padding: 12px;\r\n        box-shadow: 0 4px 12px rgba(0,0,0,0.05);\r\n        box-sizing: border-box;\r\n    }\r\n\r\n    \/* Fix KaTeX Vertical Clipping & Horizontal Scroll on Mobile *\/\r\n    #solutionContent .katex-display {\r\n        overflow-x: auto;\r\n        overflow-y: hidden;\r\n        padding: 8px 0;\r\n        margin: 1em 0;\r\n        line-height: 1.4;\r\n    }\r\n\r\n    #solutionContent .katex {\r\n        font-size: 1.05em;\r\n    }\r\n<\/style>\r\n\r\n<div class=\"solver-card\">\r\n    <div class=\"solver-header\">\r\n        <h2>SUNNYROCK College Exam Solver<\/h2>\r\n        <p>Business Studies & Engineering (NCV \/ NATED N1\u2013N6)<\/p>\r\n    <\/div>\r\n\r\n    <div class=\"access-code-box\">\r\n        <input type=\"text\" id=\"access_code_input\" placeholder=\"Enter Pass Key (Optional)\">\r\n    <\/div>\r\n\r\n    <div class=\"pricing-selector\">\r\n        <label for=\"passType\" style=\"font-weight:600; color:#1e3a8a;\">Select Top-Up Pass:<\/label>\r\n        <select id=\"passType\" onchange=\"updatePayfastForm()\">\r\n            <option value=\"15.00\" data-name=\"Sunnyrock Solver 10 Tries Pass Key\">R15 - 10 Tries<\/option>\r\n            <option value=\"20.00\" data-name=\"Sunnyrock Solver 24-Hour Unlimited Pass Key\">R20 - 24 Hours Unlimited<\/option>\r\n        <\/select>\r\n    <\/div>\r\n\r\n    <label for=\"imageInput\" class=\"custom-upload-btn\">\ud83d\udcf7 Take Photo or Upload Question<\/label>\r\n    <input type=\"file\" id=\"imageInput\" accept=\"image\/*\" capture=\"environment\" style=\"display:none;\">\r\n\r\n    <div id=\"statusOutput\">Ready for question photo... (2 Free Tries)<\/div>\r\n\r\n    <div id=\"imagePreviewContainer\" style=\"margin-bottom: 20px; display:none; text-align:center;\">\r\n        <img id=\"imagePreview\" alt=\"Question Preview\" style=\"max-width: 100%; max-height: 280px; border-radius: 8px; border: 2px solid #2563eb;\">\r\n    <\/div>\r\n\r\n    <div id=\"solutionContainer\" class=\"solution-box\" style=\"display:none;\">\r\n        <h4>Solution & Step-by-Step Working<\/h4>\r\n        <div id=\"solutionContent\"><\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<form id=\"payfastForm\" action=\"https:\/\/www.payfast.co.za\/eng\/process\" method=\"post\" style=\"display:none;\">\r\n    <input type=\"hidden\" name=\"merchant_id\" value=\"31120303\">\r\n    <input type=\"hidden\" name=\"merchant_key\" value=\"js8ftgs9xszpk\">\r\n    <input type=\"hidden\" name=\"return_url\" value=\"https:\/\/sunnyrockcollege.co.za\/portal\/exam-solver\">\r\n    <input type=\"hidden\" name=\"cancel_url\" value=\"https:\/\/sunnyrockcollege.co.za\/portal\/exam-solver\">\r\n    <input type=\"hidden\" id=\"payfast_amount\" name=\"amount\" value=\"15.00\">\r\n    <input type=\"hidden\" id=\"payfast_item_name\" name=\"item_name\" value=\"Sunnyrock Solver 10 Tries Pass Key\">\r\n<\/form>\r\n\r\n<script>\r\nif (window.mermaid) {\r\n    mermaid.initialize({ startOnLoad: false, theme: 'default' });\r\n}\r\n\r\nfunction updatePayfastForm() {\r\n    const select = document.getElementById('passType');\r\n    const selectedOption = select.options[select.selectedIndex];\r\n    \r\n    document.getElementById('payfast_amount').value = selectedOption.value;\r\n    document.getElementById('payfast_item_name').value = selectedOption.getAttribute('data-name');\r\n}\r\n\r\ndocument.addEventListener('change', function(event) {\r\n    if (event.target && event.target.id === 'imageInput') {\r\n        const file = event.target.files[0];\r\n        if (!file) return;\r\n\r\n        const status = document.getElementById('statusOutput');\r\n        const accessCode = document.getElementById('access_code_input').value.trim();\r\n\r\n        if (!accessCode) {\r\n            let attempts = parseInt(localStorage.getItem('sunnyrock_solver_tries') || '0');\r\n            if (attempts >= 2) {\r\n                status.innerText = \"Free limit reached (2\/2 tries). Redirecting to PayFast...\";\r\n                alert(\"You have reached your 2 free tries! Redirecting to PayFast to buy a key.\");\r\n                updatePayfastForm();\r\n                document.getElementById('payfastForm').submit();\r\n                return;\r\n            }\r\n        }\r\n\r\n        const reader = new FileReader();\r\n        reader.onload = function(e) {\r\n            document.getElementById('imagePreview').src = e.target.result;\r\n            document.getElementById('imagePreviewContainer').style.display = 'block';\r\n            \r\n            const base64Data = e.target.result.split(',')[1];\r\n            sendImageToBackend(base64Data, file.type || 'image\/jpeg', accessCode);\r\n        };\r\n        reader.readAsDataURL(file);\r\n    }\r\n});\r\n\r\nasync function sendImageToBackend(base64Image, mimeType, accessCode) {\r\n    const solContainer = document.getElementById('solutionContainer');\r\n    const solContent = document.getElementById('solutionContent');\r\n    const status = document.getElementById('statusOutput');\r\n\r\n    solContainer.style.display = 'block';\r\n    solContent.innerHTML = \"<em>Analyzing image and solving step-by-step...<\/em>\";\r\n    status.innerText = \"Processing image with AI...\";\r\n\r\n    try {\r\n        const response = await fetch('\/portal\/solver-backend.php', {\r\n            method: 'POST',\r\n            headers: { \r\n                'Content-Type': 'application\/json',\r\n                'Accept': 'application\/json'\r\n            },\r\n            body: JSON.stringify({\r\n                image: base64Image,\r\n                mimeType: mimeType,\r\n                access_code: accessCode\r\n            })\r\n        });\r\n\r\n        const data = await response.json();\r\n        if (data.answer) {\r\n            let rawText = data.answer.replace(\/\\\\n\/g, '\\n');\r\n\r\n            \/\/ 1. Remove HTML comments\r\n            rawText = rawText.replace(\/<!--[\\s\\S]*?-->\/g, '');\r\n\r\n            \/\/ 2. Extract SVG blocks and place explicit HTML element placeholders\r\n            const svgBlocks = [];\r\n            rawText = rawText.replace(\/<svg[\\s\\S]*?<\\\/svg>\/gi, function(match) {\r\n                let cleanSvg = match.replace(\/<svg\/i, '<svg style=\"background-color:#ffffff !important;\" ');\r\n                cleanSvg = cleanSvg.replace(\/<rect[^>]*fill=[\"']#(000|000000|0f172a|1e293b|111827)[\"'][^>]*\\\/>\/gi, '');\r\n                svgBlocks.push(cleanSvg);\r\n                return `<div id=\"svg-ph-${svgBlocks.length - 1}\"><\/div>`;\r\n            });\r\n\r\n            \/\/ 3. Convert Markdown text to HTML\r\n            let renderedHtml = marked.parse(rawText);\r\n\r\n            \/\/ 4. Inject HTML into container\r\n            solContent.innerHTML = renderedHtml;\r\n\r\n            \/\/ 5. Swap out placeholder <div> elements directly in the DOM\r\n            svgBlocks.forEach((svg, index) => {\r\n                const placeholder = document.getElementById(`svg-ph-${index}`);\r\n                if (placeholder) {\r\n                    placeholder.outerHTML = svg;\r\n                }\r\n            });\r\n\r\n            \/\/ 6. DOM post-processing: Guarantee high contrast against white backgrounds\r\n            const svgs = solContent.querySelectorAll('svg');\r\n            svgs.forEach(svg => {\r\n                svg.style.backgroundColor = '#ffffff';\r\n                const allElements = svg.querySelectorAll('*');\r\n                allElements.forEach(el => {\r\n                    const stroke = el.getAttribute('stroke');\r\n                    const fill = el.getAttribute('fill');\r\n\r\n                    if (stroke === '#ffffff' || stroke === '#fff' || stroke === 'white') {\r\n                        el.setAttribute('stroke', '#0f172a');\r\n                    }\r\n                    if (fill === '#ffffff' || fill === '#fff' || fill === 'white') {\r\n                        if (el.tagName.toLowerCase() !== 'rect') {\r\n                            el.setAttribute('fill', '#0f172a');\r\n                        }\r\n                    }\r\n                });\r\n            });\r\n\r\n            if (!accessCode) {\r\n                let attempts = parseInt(localStorage.getItem('sunnyrock_solver_tries') || '0');\r\n                localStorage.setItem('sunnyrock_solver_tries', (attempts + 1).toString());\r\n            }\r\n\r\n            \/\/ Render LaTeX Equations\r\n            if (window.renderMathInElement) {\r\n                renderMathInElement(solContent, {\r\n                    delimiters: [\r\n                        {left: '$$', right: '$$', display: true},\r\n                        {left: '$', right: '$', display: false}\r\n                    ],\r\n                    throwOnError: false\r\n                });\r\n            }\r\n\r\n            \/\/ Render Mermaid Diagrams\r\n            if (window.mermaid) {\r\n                mermaid.run({\r\n                    querySelector: '.language-mermaid, pre code.mermaid'\r\n                });\r\n            }\r\n\r\n            status.innerText = \"Solution Ready!\";\r\n        } else {\r\n            solContent.innerText = \"Error: \" + (data.error || data.answer || \"Could not generate a solution.\");\r\n            status.innerText = \"Process Failed.\";\r\n        }\r\n    } catch (error) {\r\n        solContent.innerText = \"Network error connecting to backend solver.\";\r\n        status.innerText = \"Connection Failed.\";\r\n        console.error(error);\r\n    }\r\n}\r\n<\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"class_list":["post-7","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/pages\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":5,"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/pages\/7\/revisions"}],"predecessor-version":[{"id":18,"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/pages\/7\/revisions\/18"}],"wp:attachment":[{"href":"https:\/\/sunnyrockcollege.co.za\/portal\/wp-json\/wp\/v2\/media?parent=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}