{"id":5671,"date":"2025-06-16T13:23:13","date_gmt":"2025-06-16T06:23:13","guid":{"rendered":"https:\/\/tubtimsiam04.ac.th\/?page_id=5671"},"modified":"2025-06-16T13:23:37","modified_gmt":"2025-06-16T06:23:37","slug":"%e0%b9%81%e0%b8%9a%e0%b8%9a%e0%b8%97%e0%b8%94%e0%b8%aa%e0%b8%ad%e0%b8%9a-%e0%b8%a7%e0%b8%b1%e0%b8%aa%e0%b8%94%e0%b8%b8-2-2-2-4","status":"publish","type":"page","link":"https:\/\/tubtimsiam04.ac.th\/?page_id=5671","title":{"rendered":"\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a &#8211; \u0e41\u0e1b\u0e49\u0e19\u0e40\u0e2b\u0e22\u0e49\u0e32"},"content":{"rendered":"\n<script>\n\n        const SHEET_RANGE = '\u0e04\u0e2d\u0e21\u0e1e\u0e34\u0e27\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e15\u0e49\u0e19!A11:G21';\n        const TEST_SET = 'keyboard';\n\n<\/script>\n\n<!DOCTYPE html>\n<html lang=\"th\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c<\/title>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Sarabun:wght@400;700&#038;display=swap\" rel=\"stylesheet\">\n\n    <link href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.29.0\/themes\/prism-tomorrow.min.css\" rel=\"stylesheet\">\n\t<link href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.29.0\/plugins\/normalize-whitespace\/prism-normalize-whitespace.min.css\" rel=\"stylesheet\">\n    <style>\n        body {\n            font-family: 'Sarabun', sans-serif;\n            margin: 20px;\n            background-color: #f9f9f9;\n            color: #333;\n        }\n\n        h1 {\n            text-align: center;\n            color: #4CAF50;\n            font-weight: 700;\n        }\n\n        .quiz-container {\n            max-width: 800px;\n            margin: 0 auto;\n            padding: 20px;\n            background-color: #fff;\n            border-radius: 8px;\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n        }\n\n        input[type=\"text\"] {\n            width: 98%;\n            padding: 8px;\n            margin: 10px 0;\n            border: 1px solid #ddd;\n            border-radius: 4px;\n            font-family: 'Sarabun', sans-serif;\n            font-size: 16px;\n        }\n\n        .question {\n            margin-bottom: 20px;\n            padding: 15px;\n            background-color: #f1f1f1;\n            border-radius: 4px;\n        }\n\n        .question p {\n            font-weight: bold;\n            margin-bottom: 10px;\n        }\n\n        .options {\n            margin-left: 20px;\n        }\n\n        .options label {\n            display: block;\n            margin: 5px 0;\n            font-size: 16px;\n        }\n\n        button {\n            background-color: #4CAF50;\n            color: white;\n            padding: 10px 20px;\n            border: none;\n            border-radius: 4px;\n            cursor: pointer;\n            font-size: 16px;\n            font-family: 'Sarabun', sans-serif;\n            display: block;\n            margin: 20px auto;\n        }\n\n        button:disabled {\n            background-color: #cccccc;\n            cursor: not-allowed;\n\t\t\topacity: 0.7;\n        }\n        .error {\n            color: red;\n            font-weight: bold;\n        }\n\n        .error-message {\n            color: red;\n            text-align: center;\n            margin-bottom: 10px;\n        }\n        .progress {\n            text-align: center;\n            margin: 20px 0;\n            font-weight: bold;\n            color: #4CAF50;\n        }\n        \n      .options label:hover {\n          background-color: #f0f0f0;\n      }\n\n      .options input[type=\"radio\"]:checked + label {\n          background-color: #e3f2fd;\n          border-color: #2196F3;\n      }        \n\t\n\t\/* \u0e1b\u0e23\u0e31\u0e1a\u0e2a\u0e35\u0e1e\u0e37\u0e49\u0e19\u0e2b\u0e25\u0e31\u0e07\u0e41\u0e25\u0e30\u0e02\u0e2d\u0e1a\u0e02\u0e2d\u0e07 code block *\/\n\tpre[class*=\"language-\"] {\n\t\tbackground: #2d2d2d;\n\t\tborder-radius: 4px;\n\t\tmargin: 1em 0;\n\t\tpadding: 1em; \/* \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e19\u0e35\u0e49 *\/\n                max-width: 500px;\n\t}\n\n\t\/* \u0e1b\u0e23\u0e31\u0e1a\u0e02\u0e19\u0e32\u0e14\u0e15\u0e31\u0e27\u0e2d\u0e31\u0e01\u0e29\u0e23\u0e02\u0e2d\u0e07 code *\/\n\tcode[class*=\"language-\"] {\n\t\tfont-size: 14px;\n\t\tfont-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n\t}\n\n    <\/style>\n<\/head>\n<body>\n\n<script>\n        \/\/ \u0e2a\u0e23\u0e49\u0e32\u0e07\u0e2b\u0e19\u0e49\u0e32\u0e41\u0e2a\u0e14\u0e07\u0e2a\u0e16\u0e32\u0e19\u0e30\u0e01\u0e32\u0e23\u0e42\u0e2b\u0e25\u0e14\n\t\t\/\/ Add these lines at the end of style section\n        const additionalStyles = `\n\t\t\t.loading {\n\t\t\t\tposition: fixed;\n\t\t\t\ttop: 50%;\n\t\t\t\tleft: 50%;\n\t\t\t\twidth: 350px;\n\t\t\t\ttransform: translate(-50%, -50%);\n\t\t\t\tbackground: rgba(0, 0, 139, 0.9); \/* \u0e2a\u0e35\u0e19\u0e49\u0e33\u0e40\u0e07\u0e34\u0e19\u0e40\u0e02\u0e49\u0e21 *\/\n\t\t\t\tcolor: #ffffff; \/* \u0e2a\u0e35\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e1b\u0e47\u0e19\u0e2a\u0e35\u0e02\u0e32\u0e27 *\/\n\t\t\t\tpadding: 20px;\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tbox-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n\t\t\t\tz-index: 1000;\n\t\t\t}\n\t\t\t .fa-spin {\n\t\t\t\t\tmargin-right: 8px;\n\t\t\t }\n        `;\n\n\t\t\/\/ \u0e2a\u0e23\u0e49\u0e32\u0e07 element style \u0e43\u0e2b\u0e21\u0e48\n\t\tconst styleElement = document.createElement('style');\n\n\t\t\/\/ \u0e01\u0e33\u0e2b\u0e19\u0e14 CSS \u0e08\u0e32\u0e01\u0e15\u0e31\u0e27\u0e41\u0e1b\u0e23 additionalStyles \u0e43\u0e2b\u0e49\u0e01\u0e31\u0e1a styleElement\n\t\tstyleElement.textContent = additionalStyles;\n\n\t\t\/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21 styleElement \u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\u0e43\u0e19 <head> \u0e02\u0e2d\u0e07\u0e40\u0e2d\u0e01\u0e2a\u0e32\u0e23\n\t\tdocument.head.appendChild(styleElement);\n\t\t\n        \/\/ Show loading indicator\n        function showLoading(show = true) {\n            const loadingDiv = document.createElement('div');\n            loadingDiv.id = 'loadingIndicator';\n            loadingDiv.className = 'loading';\n            loadingDiv.innerHTML = '<i class=\"fas fa-spinner fa-spin\"><\/i>  \u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14... ';\n            \n            if (show) {\n                document.body.appendChild(loadingDiv);\n            } else {\n                const existingLoader = document.getElementById('loadingIndicator');\n                if (existingLoader) {\n                    existingLoader.remove();\n                }\n            }\n        }\n        \n        \/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e2b\u0e19\u0e48\u0e27\u0e07\u0e40\u0e27\u0e25\u0e32\n        function delay(ms) {\n            return new Promise(resolve => setTimeout(resolve, ms));\n        }\n        \n\t\t\n\t\tshowLoading(true);\t\t\n<\/script>\n\n\n    <div class=\"quiz-container\">\n        <h1>\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c<\/h1>\n        <form id=\"quizForm\">\n            <label for=\"name\">\u0e0a\u0e37\u0e48\u0e2d\u0e1c\u0e39\u0e49\u0e17\u0e33\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a:<\/label>\n            <input type=\"text\" id=\"name\" name=\"name\" required placeholder=\"\u0e01\u0e23\u0e38\u0e13\u0e32\u0e01\u0e23\u0e2d\u0e01\u0e40\u0e25\u0e02\u0e17\u0e35\u0e48-\u0e0a\u0e37\u0e48\u0e2d\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13 \u0e40\u0e0a\u0e48\u0e19 05-\u0e40\u0e21\u0e18\u0e32\u0e27\u0e14\u0e35 \u0e01\u0e30\u0e01\u0e32\u0e23\u0e14\u0e35 \"><br><br>\n\n            <div id=\"questions\"><\/div>\n\n            <div id=\"errorMessage\" class=\"error-message\"><\/div>\n            <div id=\"successMessage\" class=\"success-message\"><\/div>\n            <div id=\"progress\" class=\"progress\"><\/div>\n\n            <button type=\"button\" id=\"submitButton\" onclick=\"submitQuiz()\">\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a<\/button>\n        <\/form>\n    <\/div>\n\n    <script>\n        \/\/ \u0e42\u0e04\u0e49\u0e14\u0e01\u0e32\u0e23\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e04\u0e48\u0e32 Normalize Whitespace \u0e17\u0e35\u0e48\u0e41\u0e2a\u0e14\u0e07\u0e02\u0e49\u0e32\u0e07\u0e15\u0e49\u0e19\n\t\t\/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e01\u0e32\u0e23\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e04\u0e48\u0e32 Normalize Whitespace\n\t\tPrism.plugins.NormalizeWhitespace.setDefaults({\n\t\t\t'remove-trailing': true,        \/\/ \u0e25\u0e1a whitespace \u0e17\u0e35\u0e48\u0e17\u0e49\u0e32\u0e22\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\n\t\t\t'remove-indent': true,          \/\/ \u0e25\u0e1a\u0e01\u0e32\u0e23\u0e40\u0e22\u0e37\u0e49\u0e2d\u0e07\u0e17\u0e35\u0e48\u0e44\u0e21\u0e48\u0e08\u0e33\u0e40\u0e1b\u0e47\u0e19\n\t\t\t'left-trim': true,              \/\/ \u0e25\u0e1a whitespace \u0e14\u0e49\u0e32\u0e19\u0e0b\u0e49\u0e32\u0e22\n\t\t\t'right-trim': true,             \/\/ \u0e25\u0e1a whitespace \u0e14\u0e49\u0e32\u0e19\u0e02\u0e27\u0e32\n\t\t\t'break-lines': 80,              \/\/ \u0e15\u0e31\u0e14\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e17\u0e35\u0e48\u0e04\u0e27\u0e32\u0e21\u0e22\u0e32\u0e27 80 \u0e15\u0e31\u0e27\u0e2d\u0e31\u0e01\u0e29\u0e23\n\t\t\t'indent': 0,                    \/\/ \u0e23\u0e30\u0e14\u0e31\u0e1a\u0e01\u0e32\u0e23\u0e40\u0e22\u0e37\u0e49\u0e2d\u0e07\n\t\t\t'remove-initial-line-feed': false, \/\/ \u0e44\u0e21\u0e48\u0e25\u0e1a\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e27\u0e48\u0e32\u0e07\u0e41\u0e23\u0e01\n\t\t\t'tabs-to-spaces': 4,            \/\/ \u0e41\u0e1b\u0e25\u0e07 tab \u0e40\u0e1b\u0e47\u0e19 space 4 \u0e15\u0e31\u0e27\n\t\t\t'spaces-to-tabs': 4             \/\/ \u0e41\u0e1b\u0e25\u0e07 space 4 \u0e15\u0e31\u0e27\u0e40\u0e1b\u0e47\u0e19 tab\n\t\t});\n    <\/script>\n\n    <script>\n\t\n        const SHEET_ID = '1q1m67I3EkHYI8e25SRLW_eaog4JXhVyXTWChdArmFbo';\n        \/\/const SHEET_RANGE = 'word!A41:G51';\n        \/\/const TEST_SET = 'word-\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c';\n        const API_KEY = 'AIzaSyDESM8XwBxuDqRj-yW-2cHHBEyf8NJ5CUo';\n        const SCRIPT_URL = 'https:\/\/script.google.com\/macros\/s\/AKfycbzbbazjVePnleRdMVXXVaP4W2xtF2LeFoOH9MQAzMiG-wTNr4YUuO6katxdHVFZdoUX\/exec';\n\n\n        let questions = [];\n\n        \/\/ \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheet\n        async function fetchQuestions() {\n            try {\n                const url = `https:\/\/sheets.googleapis.com\/v4\/spreadsheets\/${SHEET_ID}\/values\/${SHEET_RANGE}?key=${API_KEY}`;\n                const response = await fetch(url);\n                const data = await response.json();\n                questions = data.values.slice(1);\n                renderQuestions();\n\t\t\t\tshowLoading(false);\t\n            } catch (error) {\n                showError('\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e42\u0e2b\u0e25\u0e14\u0e04\u0e33\u0e16\u0e32\u0e21\u0e44\u0e14\u0e49 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07');\n                console.error('Error fetching questions:', error);\n            }\n        }\n\n\t\t \/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e2a\u0e38\u0e48\u0e21\u0e25\u0e33\u0e14\u0e31\u0e1a array\n\t\tfunction shuffleArray(array) {\n\t\t\tfor (let i = array.length - 1; i > 0; i--) {\n\t\t\t\tconst j = Math.floor(Math.random() * (i + 1));\n\t\t\t\t[array[i], array[j]] = [array[j], array[i]];\n\t\t\t}\n\t\t\treturn array;\n\t\t}\n\n\n\t\tfunction renderQuestions() {\n\t\t\tconst container = document.getElementById('questions');\n\t\t\tcontainer.innerHTML = '';\n\t\t\t\n\t\t\tquestions.forEach((row, index) => {\n\t\t\t\tconst choices = [\n\t\t\t\t\t{ text: row[1], value: '1' },\n\t\t\t\t\t{ text: row[2], value: '2' },\n\t\t\t\t\t{ text: row[3], value: '3' },\n\t\t\t\t\t{ text: row[4], value: '4' }\n\t\t\t\t];\n\t\t\t\t\n\t\t\t\tconst shuffledChoices = shuffleArray([...choices]);\n\t\t\t\t\n\t\t\t\tconst questionDiv = document.createElement('div');\n\t\t\t\tquestionDiv.className = 'question';\n\t\t\t\t\n\t\t\t\t\/\/ \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e48\u0e32\u0e04\u0e33\u0e16\u0e32\u0e21\u0e21\u0e35 code python \u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48\n\t\t\t\tlet questionText = row[0];\n\t\t\t\tif (questionText.includes('```python')) {\n\t\t\t\t\t\/\/ \u0e41\u0e22\u0e01 code python \u0e2d\u0e2d\u0e01\u0e08\u0e32\u0e01\u0e04\u0e33\u0e16\u0e32\u0e21\n\t\t\t\t\tconst parts = questionText.split('```python');\n\t\t\t\t\tconst beforeCode = parts[0];\n\t\t\t\t\tconst codeAndRest = parts[1].split('```');\n\t\t\t\t\tlet code = codeAndRest[0];\n\t\t\t\t\tconst afterCode = codeAndRest[1] || '';\n\t\t\t\t\t\n\t\t\t\t\t\/\/ \u0e17\u0e33\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e30\u0e2d\u0e32\u0e14 whitespace \u0e02\u0e2d\u0e07\u0e42\u0e04\u0e49\u0e14\n\t\t\t\t\tif (Prism.plugins.NormalizeWhitespace) {\n\t\t\t\t\t\tconst nw = Prism.plugins.NormalizeWhitespace;\n\t\t\t\t\t\tcode = nw.normalize(code, {\n\t\t\t\t\t\t\t'remove-trailing': true,\n\t\t\t\t\t\t\t'remove-indent': true,\n\t\t\t\t\t\t\t'left-trim': true,\n\t\t\t\t\t\t\t'right-trim': true\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t\/*\n\t\t\t\t\t\/\/ \u0e2a\u0e23\u0e49\u0e32\u0e07 HTML \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e41\u0e2a\u0e14\u0e07 code \u0e1e\u0e23\u0e49\u0e2d\u0e21 line numbers\n\t\t\t\t\tquestionText = `\n\t\t\t\t\t\t${beforeCode}\n\t\t\t\t\t\t<pre class=\"line-numbers\"><code class=\"language-python\">${code}<\/code><\/pre>\n\t\t\t\t\t\t${afterCode}\n\t\t\t\t\t`;\n\t\t\t\t\t*\/\n\t\t\t\t\tquestionText = `\n\t\t\t\t\t\t${beforeCode}\n\t\t\t\t\t\t<pre><code class=\"language-python\">${code}<\/code><\/pre>\n\t\t\t\t\t\t${afterCode}\n\t\t\t\t\t`;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tlet choicesHTML = '';\n\t\t\t\tconst thaiLetters = ['\u0e01', '\u0e02', '\u0e04', '\u0e07'];\n\t\t\t\tshuffledChoices.forEach((choice, choiceIndex) => {\n\t\t\t\t\tchoicesHTML += `\n\t\t\t\t\t\t<label>\n\t\t\t\t\t\t\t<input type=\"radio\" name=\"q${index}\" value=\"${choice.value}\"> \n\t\t\t\t\t\t\t${thaiLetters[choiceIndex]}. ${choice.text}\n\t\t\t\t\t\t<\/label>\n\t\t\t\t\t`;\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tquestionDiv.innerHTML = `\n\t\t\t\t\t<p>${index + 1}. ${questionText}<\/p>\n\t\t\t\t\t<div class=\"options\">\n\t\t\t\t\t\t${choicesHTML}\n\t\t\t\t\t<\/div>\n\t\t\t\t`;\n\t\t\t\tcontainer.appendChild(questionDiv);\n\t\t\t});\n\t\t\t\n\t\t\t\/\/ \u0e40\u0e23\u0e35\u0e22\u0e01 Prism.highlightAll() \u0e2b\u0e25\u0e31\u0e07\u0e08\u0e32\u0e01\u0e40\u0e1e\u0e34\u0e48\u0e21 code \u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\u0e43\u0e19 DOM\n\t\t\tPrism.highlightAll();\n\t\t}\n\n\t\t\/\/ \u0e1b\u0e23\u0e31\u0e1a\u0e1b\u0e23\u0e38\u0e07\u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19 getChoiceLetter \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49\u0e15\u0e23\u0e07\u0e01\u0e31\u0e1a\u0e15\u0e31\u0e27\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e17\u0e35\u0e48\u0e41\u0e2a\u0e14\u0e07\n\t\tfunction getChoiceLetter(number) {\n\t\t\tconst letters = ['', '\u0e01', '\u0e02', '\u0e04', '\u0e07'];\n\t\t\treturn letters[number] || '';\n\t\t}\n\n        \/\/ \u0e41\u0e01\u0e49\u0e44\u0e02\u0e2a\u0e48\u0e27\u0e19\u0e02\u0e2d\u0e07 submitQuiz()\n\t\tasync function submitQuiz() {\n\t\t\tclearMessages();\n\n\t\t\t\/\/ \u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e1b\u0e38\u0e48\u0e21\u0e17\u0e31\u0e19\u0e17\u0e35\u0e17\u0e35\u0e48\u0e01\u0e14\u0e2a\u0e48\u0e07\n\t\t\tconst submitButton = document.getElementById('submitButton');\n\t\t\tsubmitButton.disabled = true;\n\t\t\tsubmitButton.textContent = '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a...';\n\t\n\t\t\t\n\t\t\tconst nameInput = document.getElementById('name');\n\t\t\tconst name = nameInput.value.trim();\n\t\t\t\n\t\t\tif (!name) {\n\t\t\t\tshowError('\u0e01\u0e23\u0e38\u0e13\u0e32\u0e01\u0e23\u0e2d\u0e01\u0e0a\u0e37\u0e48\u0e2d\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e1a');\n\t\t\t\tnameInput.focus();\n\n\t\t\t\t\/\/ \u0e40\u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e1b\u0e38\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e01\u0e23\u0e2d\u0e01\u0e0a\u0e37\u0e48\u0e2d\n\t\t\t\tsubmitButton.disabled = false;\n\t\t\t\tsubmitButton.textContent = '\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a';\t\t\t\t\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet allAnswered = true;\n\t\t\tanswers = []; \/\/ \u0e40\u0e01\u0e47\u0e1a\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e44\u0e27\u0e49\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e41\u0e2a\u0e14\u0e07\u0e40\u0e09\u0e25\u0e22\n\t\t\tquestions.forEach((row, index) => {\n\t\t\t\tconst selected = document.querySelector(`input[name=\"q${index}\"]:checked`);\n\t\t\t\tif (!selected) {\n\t\t\t\t\tallAnswered = false;\n\t\t\t\t\tdocument.querySelector(`.question:nth-child(${index + 1})`).classList.add('error');\n\t\t\t\t} else {\n\t\t\t\t\tanswers.push(selected.value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!allAnswered) {\n\t\t\t\tshowError('\u0e01\u0e23\u0e38\u0e13\u0e32\u0e15\u0e2d\u0e1a\u0e04\u0e33\u0e16\u0e32\u0e21\u0e17\u0e38\u0e01\u0e02\u0e49\u0e2d');\n\t\t\t\t\n\t\t\t\t\/\/ \u0e40\u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e1b\u0e38\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e01\u0e23\u0e2d\u0e01\u0e0a\u0e37\u0e48\u0e2d\n\t\t\t\tsubmitButton.disabled = false;\n\t\t\t\tsubmitButton.textContent = '\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a';\t\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdocument.getElementById('progress').textContent = '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e1b\u0e23\u0e30\u0e21\u0e27\u0e25\u0e1c\u0e25...';\n\n\t\t\ttry {\n\t\t\t\tconst result = calculateScore(answers);\n\t\t\t\tshowSuccess(`\u0e04\u0e30\u0e41\u0e19\u0e19\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e04\u0e37\u0e2d ${result.score} \/ ${questions.length}`);\n\t\t\t\t\n\t\t\t\tawait saveResult(name, result.score);\n\t\t\t\tdocument.getElementById('progress').textContent = '\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08';\n\t\t\t\t\/\/ \u0e1b\u0e38\u0e48\u0e21\u0e08\u0e30\u0e22\u0e31\u0e07\u0e04\u0e07\u0e16\u0e39\u0e01\u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e2b\u0e25\u0e31\u0e07\u0e08\u0e32\u0e01\u0e2a\u0e48\u0e07\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\n\t\t\t\tsubmitButton.textContent = '\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e41\u0e25\u0e49\u0e27';\n\t\t\t\t\n\t\t\t} catch (error) {\n\t\t\t\tshowError('\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e1c\u0e25 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07');\n\t\t\t\tconsole.error('Error saving result:', error);\n\t\t\t\tdocument.getElementById('progress').textContent = '';\n\t\t\t\t\n\t\t\t\t\/\/ \u0e40\u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e1b\u0e38\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\n\t\t\t\tsubmitButton.disabled = false;\n\t\t\t\tsubmitButton.textContent = '\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e15\u0e2d\u0e1a';\t\t\t\t\n\n\t\t\t}\n\t\t}\n\n\t\t\/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e04\u0e33\u0e19\u0e27\u0e13\u0e04\u0e30\u0e41\u0e19\u0e19\u0e41\u0e25\u0e30\u0e23\u0e27\u0e1a\u0e23\u0e27\u0e21\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e09\u0e25\u0e22\n\t\tfunction calculateScore(answers) {\n\t\t\tlet score = 0;\n\t\t\tlet details = [];\n\t\t\t\n\t\t\tanswers.forEach((answer, index) => {\n\t\t\t\tconst isCorrect = answer == questions[index][5];\n\t\t\t\tif (isCorrect) {\n\t\t\t\t\tscore++;\n\t\t\t\t}\n\t\t\t\t\/\/ \u0e40\u0e01\u0e47\u0e1a\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e16\u0e39\u0e01\/\u0e1c\u0e34\u0e14 \u0e41\u0e25\u0e30\u0e40\u0e09\u0e25\u0e22\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\n\t\t\t\tdetails.push({\n\t\t\t\t\tquestionNo: index + 1,\n\t\t\t\t\tuserAnswer: getChoiceLetter(answer),\n\t\t\t\t\tcorrectAnswer: getChoiceLetter(questions[index][5]),\n\t\t\t\t\tisCorrect: isCorrect\n\t\t\t\t});\n\t\t\t});\n\t\t\t\n\t\t\treturn { score, details };\n\t\t}\n\n        \/\/ \u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e1c\u0e25\u0e25\u0e31\u0e1e\u0e18\u0e4c\u0e25\u0e07 Google Sheet\n        \/*\n\t\tasync function saveResult(name, score) {\n            const formData = new FormData();\n            formData.append('name', name);\n            formData.append('score', score);\n            formData.append('group_set', TEST_SET);\n\n            const response = await fetch(SCRIPT_URL, {\n                method: 'POST',\n                body: formData\n            });\n\n            if (!response.ok) {\n                throw new Error('Failed to save result');\n            }\n        }\n\t\t*\/\n\n\/*\nasync function saveResult(name, score) {\n    \/\/ \u0e2a\u0e23\u0e49\u0e32\u0e07 array \u0e40\u0e01\u0e47\u0e1a\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n    let allAnswers = [];\n    \n    \/\/ \u0e27\u0e19\u0e25\u0e39\u0e1b\u0e40\u0e01\u0e47\u0e1a\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e38\u0e01\u0e02\u0e49\u0e2d\n    questions.forEach((question, index) => {\n        const selectedRadio = document.querySelector(`input[name=\"q${index}\"]:checked`);\n        if (selectedRadio) {\n            \/\/ \u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e02\u0e2d\u0e07\u0e15\u0e31\u0e27\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e17\u0e35\u0e48\u0e19\u0e31\u0e01\u0e40\u0e23\u0e35\u0e22\u0e19\u0e40\u0e25\u0e37\u0e2d\u0e01\n            const selectedValue = selectedRadio.value;\n            const selectedText = question[selectedValue]; \/\/ \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e02\u0e2d\u0e07\u0e15\u0e31\u0e27\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e17\u0e35\u0e48\u0e40\u0e25\u0e37\u0e2d\u0e01\n            allAnswers.push(selectedText);\n        } else {\n            allAnswers.push('\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e15\u0e2d\u0e1a');\n        }\n    });\n\n    const formData = new FormData();\n    \n    \/\/ \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1e\u0e37\u0e49\u0e19\u0e10\u0e32\u0e19\n    formData.append('name', name);\n    formData.append('score', score);\n    formData.append('group_set', TEST_SET);\n    formData.append('timestamp', new Date().toISOString());\n    \n    \/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e41\u0e15\u0e48\u0e25\u0e30\u0e02\u0e49\u0e2d\n    allAnswers.forEach((answer, index) => {\n        formData.append(`answer_${index + 1}`, answer);\n    });\n    \n    \/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e04\u0e27\u0e32\u0e21\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\n    const results = calculateScore(answers);\n    results.details.forEach((detail, index) => {\n        formData.append(`is_correct_${index + 1}`, detail.isCorrect ? '1' : '0');\n        formData.append(`correct_answer_${index + 1}`, questions[index][questions[index][5]]); \/\/ \u0e40\u0e01\u0e47\u0e1a\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\n    });\n\n    const response = await fetch(SCRIPT_URL, {\n        method: 'POST',\n        body: formData\n    });\n\n    if (!response.ok) {\n        throw new Error('Failed to save result');\n    }\n}\n*\/\nasync function saveResult(name, score) {\n    const formData = new FormData();\n    \n    \/\/ \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1e\u0e37\u0e49\u0e19\u0e10\u0e32\u0e19\n    formData.append('name', name);\n    formData.append('score', score);\n    formData.append('group_set', TEST_SET);\n\t\n    \/\/ \u0e40\u0e01\u0e47\u0e1a\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e04\u0e27\u0e32\u0e21\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\n    questions.forEach((question, index) => {\n        const selectedRadio = document.querySelector(`input[name=\"q${index}\"]:checked`);\n        \/\/ \u0e40\u0e01\u0e47\u0e1a\u0e1c\u0e25\u0e27\u0e48\u0e32\u0e16\u0e39\u0e01\u0e2b\u0e23\u0e37\u0e2d\u0e1c\u0e34\u0e14\n        const isCorrect = selectedRadio && (selectedRadio.value === question[5]);\n        formData.append(`is_correct_${index + 1}`, isCorrect ? '1' : '0');\n    });\n\n    const response = await fetch(SCRIPT_URL, {\n        method: 'POST',\n        body: formData\n    });\n\n    if (!response.ok) {\n        throw new Error('Failed to save result');\n    }\n}\n        \/\/ \u0e41\u0e2a\u0e14\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\n        function showError(message) {\n            const errorMessage = document.getElementById('errorMessage');\n            errorMessage.textContent = message;\n            errorMessage.scrollIntoView({ behavior: 'smooth' });\n        }\n\n\n\t\t\/\/ Update the showSuccess function to include explanations\n\t\tfunction showSuccess(message) {\n\t\t\tconst successMessage = document.getElementById('successMessage');\n\t\t\tlet html = `<h3>${message}<\/h3><br>\u0e40\u0e09\u0e25\u0e22\u0e04\u0e33\u0e15\u0e2d\u0e1a:<br><br>`;\n\t\t\t\n\t\t\tconst results = calculateScore(answers);\n\t\t\tresults.details.forEach(detail => {\n\t\t\t\tconst symbol = detail.isCorrect ? '\u2713' : '\u2717';\n\t\t\t\tconst color = detail.isCorrect ? 'green' : 'red';\n\t\t\t\tconst question = questions[detail.questionNo - 1];\n\t\t\t\tconst correctAnswerText = question[question[5]]; \/\/ \u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\n\t\t\t\tconst explanation = question[6] || ''; \/\/ \u0e04\u0e33\u0e2d\u0e18\u0e34\u0e1a\u0e32\u0e22\u0e08\u0e32\u0e01\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c G\n\t\t\t\t\n\t\t\t\thtml += `<div style=\"color: ${color}\">\n\t\t\t\t\t\u0e02\u0e49\u0e2d ${detail.questionNo}: ${symbol} \n\t\t\t\t\t${!detail.isCorrect ? `<br>\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07: ${correctAnswerText}` : ''}\n\t\t\t\t\t${explanation ? `<br><span style=\"color: #666; font-style: italic\">\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25: ${explanation}<\/span>` : ''}\n\t\t\t\t<\/div><br>`;\n\t\t\t});\n\t\t\t\n\t\t\tsuccessMessage.innerHTML = html;\n\t\t\tsuccessMessage.scrollIntoView({ behavior: 'smooth' });\n\t\t}\n\t\t\n        \/\/ \u0e40\u0e04\u0e25\u0e35\u0e22\u0e23\u0e4c\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n        function clearMessages() {\n            document.getElementById('errorMessage').textContent = '';\n            document.getElementById('successMessage').textContent = '';\n            document.querySelectorAll('.question').forEach(q => q.classList.remove('error'));\n        }\n\n        \/\/ \u0e42\u0e2b\u0e25\u0e14\u0e04\u0e33\u0e16\u0e32\u0e21\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e2b\u0e19\u0e49\u0e32\u0e40\u0e27\u0e47\u0e1a\u0e42\u0e2b\u0e25\u0e14\u0e40\u0e2a\u0e23\u0e47\u0e08\n        window.onload = fetchQuestions;\n    <\/script>\n\t\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.29.0\/prism.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.29.0\/components\/prism-python.min.js\"><\/script>\n\t<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.29.0\/plugins\/normalize-whitespace\/prism-normalize-whitespace.min.js\"><\/script>\n<\/body>\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c \u0e41\u0e1a\u0e1a\u0e17<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"colormag_page_container_layout":"no_sidebar_full_width","colormag_page_sidebar_layout":"no_sidebar","footnotes":""},"class_list":["post-5671","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/5671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5671"}],"version-history":[{"count":2,"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/5671\/revisions"}],"predecessor-version":[{"id":5673,"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/5671\/revisions\/5673"}],"wp:attachment":[{"href":"https:\/\/tubtimsiam04.ac.th\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}