{"id":1808,"date":"2024-12-12T04:16:53","date_gmt":"2024-12-12T04:16:53","guid":{"rendered":"https:\/\/phamho.com\/book\/?p=1808"},"modified":"2024-12-16T23:29:56","modified_gmt":"2024-12-16T23:29:56","slug":"basic-general-english-people","status":"publish","type":"post","link":"https:\/\/phamho.com\/book\/basic-general-english-people\/","title":{"rendered":"Basic General English &#8211; People"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Theme 1 &#8211; People<\/title>\n    <style>\n        \/* Reset and Base Styles *\/\n        * {\n            box-sizing: border-box;\n        }\n\n        body {\n            font-family: Arial, sans-serif;\n            background-color: #f4f6f8;\n            margin: 0;\n            padding: 0;\n            display: flex;\n            flex-direction: column; \/* Stack elements vertically by default *\/\n            min-height: 100vh;\n        }\n\n        \/* Menu Styles *\/\n        .menu {\n            width: 100%;\n            background-color: #17a2b8; \/* Changed color for \"People\" theme *\/\n            padding: 10px; \/* Slightly increased padding for touch *\/\n            text-align: center;\n            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\n            margin-bottom: 10px; \/* Reduced margin for better spacing *\/\n            overflow-x: auto;\n            white-space: nowrap;\n        }\n        .menu a {\n            color: #fff;\n            text-decoration: none;\n            margin: 0 10px; \/* Increased margin for better touch targets *\/\n            font-weight: bold;\n            font-size: 14px; \/* Slightly increased font for readability *\/\n            display: inline-block;\n        }\n        .menu a:hover,\n        .menu a:focus {\n            text-decoration: underline;\n            outline: 2px dashed #fff;\n            outline-offset: 4px;\n        }\n\n        \/* Container Styles *\/\n        .container {\n            display: flex;\n            flex-direction: column; \/* Stack elements vertically on mobile *\/\n            align-items: center;\n            padding: 10px; \/* Increased padding for better spacing *\/\n            box-sizing: border-box;\n            flex: 1 0 auto;\n            width: 100%;\n        }\n\n        \/* Image and Chat Containers *\/\n        .image-chat-wrapper {\n            display: flex;\n            flex-direction: column;\n            width: 100%;\n            max-width: 800px; \/* Increased max-width for landscape *\/\n            flex: 1;\n        }\n\n        \/* Image Container Styles *\/\n        .image-container {\n            flex: 1;\n            text-align: center;\n            margin-bottom: 15px; \/* Reduced margin *\/\n        }\n        .image-container img {\n            width: 100%;\n            height: auto;\n            max-height: 300px; \/* Set a maximum height *\/\n            object-fit: cover;\n            border-radius: 15px; \/* Reduced border-radius *\/\n            box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); \/* Reduced shadow *\/\n        }\n        .sentence-text {\n            margin: 10px 0; \/* Increased margin for better spacing *\/\n            font-weight: bold;\n            color: #333;\n            font-size: 16px; \/* Increased font size for readability *\/\n        }\n        .word-box {\n            margin-top: 10px; \/* Increased margin *\/\n            padding: 10px; \/* Increased padding *\/\n            background-color: #fff;\n            border: 2px solid #17a2b8; \/* Updated border color *\/\n            border-radius: 8px; \/* Reduced border-radius *\/\n            box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); \/* Reduced shadow *\/\n            font-size: 16px; \/* Maintain readability *\/\n            font-weight: bold;\n            color: #17a2b8; \/* Updated text color *\/\n            text-align: left;\n            max-height: 250px; \/* Maintain max-height *\/\n            overflow-y: auto;\n        }\n        .word-box .question {\n            color: #333;\n            font-weight: bold;\n            margin-bottom: 5px;\n        }\n        .word-box .answer {\n            color: #17a2b8;\n            margin-bottom: 10px;\n        }\n\n        \/* Chat Container Styles *\/\n        .chat-container {\n            background-color: #17a2b8; \/* Updated color *\/\n            border-radius: 15px; \/* Reduced border-radius *\/\n            box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); \/* Reduced shadow *\/\n            overflow: hidden;\n            display: flex;\n            flex-direction: column;\n            height: auto; \/* Removed fixed height *\/\n            max-height: 500px; \/* Set a reasonable max-height *\/\n            flex: 1;\n        }\n        .chat-header {\n            background-color: #117a8b; \/* Darker shade for header *\/\n            color: #fff;\n            padding: 12px; \/* Increased padding for better touch *\/\n            text-align: center;\n            border-bottom: 1px solid #0f5c67; \/* Updated border color *\/\n            position: relative;\n        }\n        .chat-header h2 {\n            margin: 0;\n            font-size: 18px; \/* Increased font size for readability *\/\n        }\n        \/* Loader Indicator *\/\n        .chat-header .loader {\n            position: absolute;\n            right: 20px;\n            top: 50%;\n            transform: translateY(-50%);\n            display: none; \/* Hidden by default *\/\n        }\n        .chat-messages {\n            padding: 12px; \/* Increased padding *\/\n            overflow-y: auto;\n            flex: 1;\n            background-color: #fff;\n            max-height: 300px; \/* Maintain max-height *\/\n        }\n        .message {\n            margin-bottom: 10px; \/* Increased margin *\/\n            padding: 10px; \/* Increased padding *\/\n            border-radius: 6px; \/* Slightly increased border-radius *\/\n            font-size: 14px; \/* Increased font size for readability *\/\n            line-height: 1.5;\n        }\n        .user-message {\n            background-color: #ffc107;\n            color: #fff;\n            text-align: right;\n        }\n        .bot-message {\n            background-color: #17a2b8;\n            color: #fff;\n            text-align: left;\n        }\n\n        \/* Chat Input Styles *\/\n        .chat-input {\n            display: flex;\n            align-items: center;\n            background-color: #b8daff;\n            padding: 10px; \/* Increased padding *\/\n            justify-content: space-between;\n            flex-wrap: wrap;\n        }\n        .send-button, .stop-button {\n            background-color: #117a8b;\n            color: #fff;\n            font-weight: bold;\n            border: none;\n            border-radius: 5px;\n            padding: 12px 16px; \/* Increased padding for touch *\/\n            cursor: pointer;\n            transition: background-color 0.3s;\n            flex: 1;\n            margin: 6px; \/* Increased margin for better spacing *\/\n            max-width: 150px; \/* Increased max-width for longer labels *\/\n            font-size: 16px; \/* Increased font size for readability *\/\n        }\n        .stop-button {\n            background-color: #dc3545;\n        }\n        .send-button:hover,\n        .stop-button:hover,\n        .send-button:focus,\n        .stop-button:focus {\n            background-color: #218838;\n            outline: none;\n        }\n\n        \/* Voice Selection Styles *\/\n        .voice-selection {\n            margin: 10px 0;\n            width: 100%;\n            max-width: 300px;\n        }\n        .voice-selection label {\n            display: block;\n            margin-bottom: 5px;\n            font-weight: bold;\n            color: #333;\n        }\n        .voice-selection select {\n            width: 100%;\n            padding: 8px;\n            border-radius: 5px;\n            border: 1px solid #ccc;\n            font-size: 14px;\n        }\n\n        \/* Loader Styles *\/\n        .loader {\n            border: 4px solid #f3f3f3;\n            border-top: 4px solid #17a2b8; \/* Updated color *\/\n            border-radius: 50%;\n            width: 20px;\n            height: 20px;\n            animation: spin 2s linear infinite;\n            display: inline-block;\n            margin-left: 10px;\n        }\n\n        @keyframes spin {\n            0% { transform: rotate(0deg); }\n            100% { transform: rotate(360deg); }\n        }\n\n        \/* Responsive Design Adjustments *\/\n\n        \/* Portrait Mode *\/\n        @media (orientation: portrait) {\n            .image-chat-wrapper {\n                flex-direction: column;\n            }\n            .image-container, .chat-container {\n                width: 100%;\n                max-width: 100%;\n            }\n        }\n\n        \/* Landscape Mode *\/\n        @media (orientation: landscape) and (min-width: 600px) {\n            .image-chat-wrapper {\n                flex-direction: row;\n                justify-content: space-between;\n            }\n            .image-container, .chat-container {\n                width: 48%;\n                max-width: 48%;\n            }\n            .word-box {\n                max-height: 200px;\n            }\n            .chat-header h2 {\n                font-size: 20px;\n            }\n            .message {\n                font-size: 15px;\n            }\n            .send-button, .stop-button {\n                font-size: 18px;\n                padding: 14px 20px;\n                max-width: 200px;\n            }\n        }\n\n        \/* General Mobile Responsiveness *\/\n        @media (max-width: 768px) {\n            .chat-header h2 {\n                font-size: 16px;\n            }\n            .message {\n                font-size: 14px;\n            }\n            .send-button, .stop-button {\n                font-size: 16px;\n                padding: 12px 16px;\n                max-width: 150px;\n            }\n            .word-box {\n                font-size: 15px;\n            }\n            .voice-selection select {\n                font-size: 14px;\n            }\n        }\n\n        \/* Samsung Android Specific Adjustments *\/\n        @media only screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) {\n            \/* Adjust font sizes and button sizes for high-density screens *\/\n            .chat-header h2 {\n                font-size: 18px; \/* Increased font size *\/\n            }\n            .send-button, .stop-button {\n                padding: 14px 18px; \/* Adjusted padding *\/\n                font-size: 16px; \/* Adjusted font size *\/\n            }\n            .message {\n                font-size: 14px; \/* Adjusted font size *\/\n            }\n            .word-box {\n                font-size: 16px; \/* Adjusted font size *\/\n            }\n            .chat-input input {\n                font-size: 16px; \/* Adjusted font size *\/\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"menu\">\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-people\/\">People<\/a>\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-possessions\/\">Possessions<\/a>\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-places\/\"> Places<\/a>\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-free-time\/\">Free Time<\/a>\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-food\/\">Food<\/a>\n      <a href=\"https:\/\/phamho.com\/book\/2024\/12\/12\/basic-general-english-past-lives\/\">Past Lives<\/a>\n    <\/div>\n\n    <div class=\"container\">\n        <div class=\"image-chat-wrapper\">\n            <div class=\"image-container\">\n                <img decoding=\"async\" src=\"https:\/\/phamho.com\/book\/wp-content\/uploads\/2024\/09\/DALL\u00b7E-2024-09-23-16.19.55-A-futuristic-classroom-setting-where-a-robot-is-teaching-an-IELTS-speaking-class.-The-robot-stands-at-the-front-of-the-room-gesturing-toward-a-digita.webp\" alt=\"Illustration representing people\"> <!-- Updated image source and alt text -->\n                <div class=\"sentence-text\">Listen to the questions and respond accordingly.<\/div>\n                <div id=\"word-box\" class=\"word-box\">\n                    <!-- Learned people-related sentences and answers will be displayed here -->\n                <\/div>\n            <\/div>\n            <div class=\"chat-container\">\n                <div class=\"chat-header\">\n                    <h2>Theme 6 &#8211; People<\/h2> <!-- Updated theme name -->\n                    <div class=\"loader\" id=\"synthesis-loader\"><\/div>\n                <\/div>\n                <div class=\"chat-messages\" id=\"chat-messages\">\n                    <!-- Messages will appear here -->\n                <\/div>\n                <div class=\"chat-input\">\n                    <!-- Voice Selection Dropdown -->\n                    <div class=\"voice-selection\">\n                        <label for=\"voice-select\">Choose Voice:<\/label>\n                        <select id=\"voice-select\" aria-label=\"Select Voice\">\n                            <option value=\"\">Loading voices&#8230;<\/option>\n                        <\/select>\n                    <\/div>\n                    <!-- Start and Stop Buttons -->\n                    <button id=\"start-btn\" class=\"send-button\" aria-label=\"Start Lesson\">Start<\/button>\n                    <button id=\"stop-btn\" class=\"stop-button\" aria-label=\"Stop Lesson\">Stop<\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    \/\/ Define the questions with expected keywords and model answers for \"People\" topic\n    const questions = [\n        { \n            english: \"Who is your best friend?\", \n            keywords: [\"best friend\", \"friend\", \"who\", \"relationship\"],\n            answer: \"My best friend is Alex. We've known each other since childhood and share many common interests, such as playing soccer and reading books. Alex is always supportive and understanding, making our friendship strong and lasting.\"\n        },\n        { \n            english: \"What does your mother or father do?\", \n            keywords: [\"mother\", \"father\", \"job\", \"profession\", \"work\"],\n            answer: \"My father is an engineer who specializes in renewable energy solutions. He works on designing and implementing solar power systems for residential and commercial buildings, contributing to a more sustainable future.\"\n        },\n        { \n            english: \"How many people are in your family?\", \n            keywords: [\"family\", \"members\", \"how many\", \"number\"],\n            answer: \"There are five people in my family: my parents, my two siblings, and me. We all get along well and enjoy spending time together, whether it's having family dinners or going on weekend trips.\"\n        },\n        { \n            english: \"Who is your favorite person in your family? Why?\", \n            keywords: [\"favorite person\", \"family\", \"why\", \"preference\"],\n            answer: \"My favorite person in my family is my younger sister, Lily. She has a vibrant personality and always brings joy and laughter to our household. Her creativity and passion for art inspire me every day.\"\n        },\n        { \n            english: \"What is your teacher\u2019s name?\", \n            keywords: [\"teacher\", \"name\", \"who\", \"educator\"],\n            answer: \"My teacher's name is Mrs. Thompson. She teaches English literature and has a remarkable ability to make complex texts engaging and accessible. Her dedication to her students' learning is truly admirable.\"\n        },\n        { \n            english: \"Do you have brothers or sisters? How old are they?\", \n            keywords: [\"brothers\", \"sisters\", \"siblings\", \"ages\", \"how old\"],\n            answer: \"Yes, I have one older brother and one younger sister. My brother is 25 years old and works as a software developer, while my sister is 18 and is currently studying graphic design at university.\"\n        },\n        { \n            english: \"What does your best friend look like?\", \n            keywords: [\"best friend\", \"appearance\", \"look like\", \"description\"],\n            answer: \"My best friend, Alex, has short brown hair and bright green eyes. He is of average height and has an athletic build from playing sports regularly. Alex often wears casual clothes, favoring comfortable jeans and t-shirts.\"\n        },\n        { \n            english: \"Who is your favorite famous person?\", \n            keywords: [\"favorite famous person\", \"celebrity\", \"inspiration\"],\n            answer: \"My favorite famous person is Malala Yousafzai. Her courage and dedication to advocating for girls' education around the world are truly inspiring. Malala's resilience in the face of adversity motivates me to make a positive impact in my community.\"\n        },\n        { \n            english: \"Do you have a neighbor? What is their name?\", \n            keywords: [\"neighbor\", \"name\", \"relationship\", \"community\"],\n            answer: \"Yes, I have a neighbor named Mr. Nguyen. He is a retired teacher who enjoys gardening and often shares fresh vegetables from his garden with the community. Mr. Nguyen is very friendly and always ready to lend a helping hand.\"\n        },\n        { \n            english: \"Who do you like to spend time with?\", \n            keywords: [\"spend time\", \"who\", \"companions\", \"enjoy\"],\n            answer: \"I like to spend time with my family and close friends. Whether we're having a movie night, going for a hike, or simply chatting over coffee, I cherish these moments of connection and relaxation.\"\n        }\n    ];\n\n    \/\/ Define positive, constructive, and pronunciation feedback arrays\n    const positiveFeedback = [\n        \"Great job!\",\n        \"Well done!\",\n        \"Excellent response!\",\n        \"Very well.\",\n        \"Your answer was clear and concise.\",\n        \"Fantastic!\",\n        \"You're doing great!\",\n        \"That's a good answer.\"\n    ];\n\n    const constructiveFeedback = [\n        \"Try to include more details related to the question.\",\n        \"Could you provide more specific information?\",\n        \"Consider mentioning related activities or reasons.\",\n        \"Adding relevant keywords can improve your answer.\",\n        \"Think about elaborating on your response.\",\n        \"Including examples would be helpful.\",\n        \"Try to relate your answer to the topic more closely.\",\n        \"Expanding your answer will make it better.\",\n        \"Providing more context can enhance your response.\",\n        \"Think about why or how to add depth to your answer.\"\n    ];\n\n    \/\/ Define pronunciation feedback messages\n    const pronunciationFeedback = [\n        \"Your pronunciation is clear, but try to emphasize key words for better clarity.\",\n        \"Good job! To improve, pay attention to the pronunciation of 'friendship' and 'community'.\",\n        \"Well spoken! Consider slowing down to ensure each word is pronounced accurately.\",\n        \"Excellent! For even better clarity, try to articulate 'celebration' and 'resilience' more distinctly.\",\n        \"Great effort! Focus on the 'th' sound in words like 'with' and 'mother'.\"\n    ];\n\n    \/\/ Define stop keywords\n    const stopKeywords = [\"goodbye\", \"good bye\", \"bye\", \"bye-bye\", \"byebye\"];\n\n    let currentQuestionIndex = 0;\n    let recognition;\n    let isLessonActive = false;\n\n    const speechSynthesisSupported = 'speechSynthesis' in window;\n    const speechRecognitionSupported = window.SpeechRecognition || window.webkitSpeechRecognition;\n\n    let voices = [];\n    let selectedVoice = null; \/\/ To store the user's selected voice\n\n    \/\/ Desired Voices: 4 Natural Native Voices\n    const desiredVoiceNames = [\n        'Google US English',            \/\/ en-US Male\n        'Google US English Female',     \/\/ en-US Female\n        'Google UK English Male',       \/\/ en-GB Male\n        'Google UK English Female'      \/\/ en-GB Female\n    ];\n\n    \/\/ Initialize the application\n    function initialize() {\n        loadVoices();\n\n        if (speechSynthesisSupported) {\n            \/\/ Delay greeting to ensure voices are loaded\n            setTimeout(() => greetUser(), 500); \n        } else {\n            appendMessage(\"Sorry, your browser does not support speech synthesis.\", \"bot\");\n        }\n\n        if (!speechRecognitionSupported) {\n            appendMessage(\"Sorry, your browser does not support speech recognition.\", \"bot\");\n        }\n\n        \/\/ Handle Start Button Click\n        document.getElementById('start-btn').onclick = function() {\n            if (isLessonActive) return; \/\/ Prevent multiple starts\n\n            if (!speechSynthesisSupported) {\n                appendMessage(\"Speech synthesis is not supported in your browser.\", \"bot\");\n                return;\n            }\n            if (!speechRecognitionSupported) {\n                appendMessage(\"Speech recognition is not supported in your browser.\", \"bot\");\n                return;\n            }\n\n            isLessonActive = true;\n            currentQuestionIndex = 0;\n            clearWordBox();\n            startLesson();\n        };\n\n        \/\/ Handle Stop Button Click\n        document.getElementById('stop-btn').onclick = function() {\n            if (recognition) {\n                recognition.stop();\n            }\n            endLesson(true);\n        };\n    }\n\n    \/\/ Load voices and populate the voice selection dropdown\n    function loadVoices() {\n        voices = window.speechSynthesis.getVoices();\n        if (voices.length === 0) {\n            \/\/ Some browsers load voices asynchronously\n            window.speechSynthesis.onvoiceschanged = () => {\n                voices = window.speechSynthesis.getVoices();\n                populateVoiceList();\n            };\n        } else {\n            populateVoiceList();\n        }\n    }\n\n    \/\/ Populate the voice selection dropdown with desired voices\n    function populateVoiceList() {\n        const voiceSelect = document.getElementById('voice-select');\n        voiceSelect.innerHTML = ''; \/\/ Clear existing options\n\n        \/\/ Filter voices to include only the desired ones\n        const filteredVoices = voices.filter(voice => desiredVoiceNames.includes(voice.name));\n\n        if (filteredVoices.length === 0) {\n            \/\/ If no desired voices are found, inform the user\n            const option = document.createElement('option');\n            option.value = \"\";\n            option.textContent = \"No desired voices available\";\n            voiceSelect.appendChild(option);\n            voiceSelect.disabled = true;\n            return;\n        }\n\n        \/\/ Populate the dropdown with the filtered voices\n        filteredVoices.forEach((voice, index) => {\n            const option = document.createElement('option');\n            option.value = index;\n            option.textContent = `${voice.name} (${voice.lang})`;\n            voiceSelect.appendChild(option);\n        });\n\n        \/\/ Set a default selected voice if available\n        if (filteredVoices.length > 0) {\n            voiceSelect.selectedIndex = 0;\n            selectedVoice = filteredVoices[0];\n        }\n\n        \/\/ Listen for voice selection changes\n        voiceSelect.onchange = () => {\n            const selectedIndex = voiceSelect.value;\n            selectedVoice = filteredVoices[selectedIndex];\n            console.log(`Selected voice: ${selectedVoice.name}`);\n        };\n    }\n\n    \/\/ Greet the user at the beginning of the lesson\n    function greetUser() {\n        const greeting = \"Hello! Welcome to the Practice Speaking about People. In this lesson, you will listen to each question carefully and provide your own answers. After each response, the correct answer will be displayed in the box. Additionally, I'll provide some tips to help improve your pronunciation. Are you ready? Click Start to begin the lesson!\";\n        appendMessage(greeting, 'bot');\n        showSynthesisLoader(true);\n        sayText(greeting, \"en-US\").then(() => {\n            showSynthesisLoader(false);\n        });\n    }\n\n    \/\/ Start the lesson by asking the first question\n    function startLesson() {\n        if (currentQuestionIndex < questions.length) {\n            const question = questions[currentQuestionIndex];\n            const questionNumber = currentQuestionIndex + 1;\n            const questionText = `Question ${questionNumber}: ${question.english}`;\n\n            appendMessage(questionText, 'bot');\n            addSentenceToBox(`Q${questionNumber}: ${question.english}`);\n            addSentenceToBox(`A${questionNumber}: ${question.answer}`); \/\/ Add model answer immediately\n            showSynthesisLoader(true);\n            sayText(questionText, \"en-US\").then(() => {\n                showSynthesisLoader(false);\n                listenUserResponse(question);\n            });\n        } else {\n            endLesson(false);\n        }\n    }\n\n    \/\/ Listen for the user's verbal response\n    function listenUserResponse(question) {\n        recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();\n        recognition.lang = 'en-US';\n        recognition.interimResults = false;\n        recognition.maxAlternatives = 1;\n\n        \/\/ Show listening indicator\n        showRecognitionLoader(true);\n        appendMessage(\"Listening...\", \"bot\");\n\n        recognition.start();\n\n        recognition.onresult = function(event) {\n            const userInput = event.results[0][0].transcript.trim();\n            const formattedInput = normalizeAndFormatUserInput(userInput);\n            appendMessage(formattedInput, 'user');\n\n            \/\/ Hide listening indicator\n            showRecognitionLoader(false);\n\n            \/\/ Check for stop keywords\n            if (checkStopKeywords(formattedInput.toLowerCase())) {\n                endLesson(true);\n                return;\n            }\n\n            \/\/ Analyze user input for feedback\n            const feedbackType = analyzeResponse(formattedInput, question.keywords);\n            let feedbackMessage = \"\";\n\n            if (feedbackType === \"positive\") {\n                feedbackMessage = positiveFeedback[Math.floor(Math.random() * positiveFeedback.length)];\n            } else if (feedbackType === \"pronunciation\") {\n                feedbackMessage = pronunciationFeedback[Math.floor(Math.random() * pronunciationFeedback.length)];\n            } else {\n                feedbackMessage = constructiveFeedback[Math.floor(Math.random() * constructiveFeedback.length)];\n            }\n\n            appendMessage(feedbackMessage, 'bot');\n            showSynthesisLoader(true);\n            sayText(feedbackMessage, \"en-US\").then(() => {\n                showSynthesisLoader(false);\n                \/\/ Optionally, you can highlight the model answer or provide additional context\n                \/\/ Proceed to next question after a delay\n                currentQuestionIndex++;\n                setTimeout(() => {\n                    startLesson();\n                }, 3000); \/\/ 3-second delay\n            });\n        };\n\n        recognition.onspeechend = function() {\n            recognition.stop();\n        };\n\n        recognition.onerror = function(event) {\n            \/\/ Hide listening indicator\n            showRecognitionLoader(false);\n            appendMessage('Error: ' + event.error, 'bot');\n            const retryMessage = \"Let's try that question again.\";\n            appendMessage(retryMessage, 'bot');\n            showSynthesisLoader(true);\n            sayText(retryMessage, \"en-US\").then(() => {\n                showSynthesisLoader(false);\n                \/\/ Retry the same question after a delay\n                setTimeout(() => {\n                    listenUserResponse(question);\n                }, 3000); \/\/ 3-second delay\n            });\n        };\n    }\n\n    \/\/ Ask the same question again in case of an error\n    function askSameQuestion(question) {\n        const questionNumber = currentQuestionIndex + 1;\n        const questionText = `Let's try again: ${question.english}`;\n\n        appendMessage(questionText, 'bot');\n        addSentenceToBox(`Q${questionNumber}: ${question.english}`);\n        addSentenceToBox(`A${questionNumber}: ${question.answer}`); \/\/ Add model answer immediately\n        showSynthesisLoader(true);\n        sayText(questionText, \"en-US\").then(() => {\n            showSynthesisLoader(false);\n            listenUserResponse(question);\n        });\n    }\n\n    \/\/ Analyze the user's response and determine feedback type\n    function analyzeResponse(userInput, keywords) {\n        const lowerCaseInput = userInput.toLowerCase();\n\n        for (let keyword of keywords) {\n            if (lowerCaseInput.includes(keyword.toLowerCase())) {\n                \/\/ Simulate pronunciation feedback for specific keywords\n                if (keyword.toLowerCase().includes(\"friend\") || keyword.toLowerCase().includes(\"neighbor\")) {\n                    return \"pronunciation\";\n                }\n                return \"positive\";\n            }\n        }\n\n        return \"constructive\";\n    }\n\n    \/\/ Check if the user's input contains any stop keywords\n    function checkStopKeywords(userInput) {\n        const pattern = new RegExp('\\\\b(' + stopKeywords.join('|') + ')\\\\b', 'i');\n        return pattern.test(userInput);\n    }\n\n    \/\/ Normalize and format the user's input\n    function normalizeAndFormatUserInput(text) {\n        let normalized = text.replace(\/\\bi\\b\/g, \"I\");\n        return formatSentence(normalized);\n    }\n\n    \/\/ Format the sentence by capitalizing and adding punctuation\n    function formatSentence(text) {\n        text = text.charAt(0).toUpperCase() + text.slice(1);\n\n        const questionWords = ['who', 'what', 'where', 'when', 'why', 'how', 'is', 'are', 'do', 'does', 'can', 'should', 'will', 'would'];\n        const firstWord = text.split(\" \")[0].toLowerCase();\n\n        if (questionWords.includes(firstWord) && !text.endsWith('?')) {\n            text += '?';\n        } else if (!text.endsWith('.') && !text.endsWith('?')) {\n            text += '.';\n        }\n\n        return text;\n    }\n\n    \/\/ Add a sentence to the word box with differentiation for questions and answers\n    function addSentenceToBox(sentence) {\n        const wordBox = document.getElementById('word-box');\n        const sentenceElement = document.createElement('div');\n\n        if (sentence.startsWith('Q')) {\n            sentenceElement.classList.add('question');\n        } else if (sentence.startsWith('A')) {\n            sentenceElement.classList.add('answer');\n        }\n\n        sentenceElement.innerText = sentence;\n        wordBox.appendChild(sentenceElement);\n        wordBox.scrollTop = wordBox.scrollHeight;\n    }\n\n    \/\/ Clear the word box\n    function clearWordBox() {\n        const wordBox = document.getElementById('word-box');\n        wordBox.innerHTML = \"\";\n    }\n\n    \/\/ End the lesson\n    function endLesson(userStopped = false) {\n        \/\/ Cancel any ongoing speech synthesis\n        if (speechSynthesisSupported) {\n            window.speechSynthesis.cancel();\n        }\n\n        if (recognition) {\n            recognition.stop();\n        }\n\n        isLessonActive = false;\n\n        let message;\n        if (userStopped) {\n            message = \"Thank you for practicing! Goodbye!\";\n        } else {\n            message = \"Well done! You've completed all the questions. Keep practicing!\";\n        }\n        appendMessage(message, \"bot\");\n        showSynthesisLoader(true);\n        sayText(message, \"en-US\").then(() => {\n            showSynthesisLoader(false);\n        });\n    }\n\n    \/\/ Speak the given text using speech synthesis and return a Promise that resolves when speaking is done\n    function sayText(text, lang) {\n        return new Promise((resolve, reject) => {\n            if (!speechSynthesisSupported) {\n                resolve();\n                return;\n            }\n            const utterance = new SpeechSynthesisUtterance(text);\n            utterance.lang = lang;\n            utterance.rate = 1.0;\n            utterance.pitch = 1.0;\n\n            \/\/ Use the selected voice if available\n            if (selectedVoice) {\n                utterance.voice = selectedVoice;\n            }\n\n            utterance.onend = function() {\n                resolve();\n            };\n\n            utterance.onerror = function(event) {\n                console.error('Speech synthesis error:', event.error);\n                resolve(); \/\/ Resolve to continue the flow even if there's an error\n            };\n\n            window.speechSynthesis.speak(utterance);\n        });\n    }\n\n    \/\/ Append a message to the chat\n    function appendMessage(text, sender) {\n        const messageContainer = document.getElementById('chat-messages');\n        const messageElement = document.createElement('div');\n        messageElement.classList.add('message');\n        messageElement.classList.add(sender === 'bot' ? 'bot-message' : 'user-message');\n        messageElement.innerText = text;\n        messageContainer.appendChild(messageElement);\n        messageContainer.scrollTop = messageContainer.scrollHeight;\n    }\n\n    \/\/ Show or hide the speech synthesis loader\n    function showSynthesisLoader(show) {\n        const loader = document.getElementById('synthesis-loader');\n        loader.style.display = show ? 'inline-block' : 'none';\n        if (show) {\n            loader.style.borderTop = '4px solid #17a2b8'; \/\/ Default speaking color\n        }\n    }\n\n    \/\/ Show or hide the speech recognition loader\n    function showRecognitionLoader(show) {\n        const loader = document.getElementById('synthesis-loader');\n        if (show) {\n            loader.style.display = 'inline-block';\n            loader.style.borderTop = '4px solid #ffc107'; \/\/ Change color to indicate listening\n        } else {\n            loader.style.display = 'none';\n        }\n    }\n\n    \/\/ Initialize the application once the DOM is fully loaded\n    window.onload = initialize;\n    <\/script>\n<\/body>\n<\/html>\n\n","protected":false},"excerpt":{"rendered":"<p>Theme 1 &#8211; People People Possessions Places Free Time Food Past Lives Listen to the questions and respond accordingly. Theme 6 &#8211; People Choose Voice: Loading voices&#8230; Start Stop<\/p>\n","protected":false},"author":1,"featured_media":538,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,34,27],"tags":[],"class_list":["post-1808","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-basic-general-english","category-robots","category-speaking"],"featured_image_src":"https:\/\/phamho.com\/book\/wp-content\/uploads\/2023\/02\/1528491290794.jpg","blog_images":{"medium":"https:\/\/phamho.com\/book\/wp-content\/uploads\/2023\/02\/1528491290794-300x159.jpg","large":"https:\/\/phamho.com\/book\/wp-content\/uploads\/2023\/02\/1528491290794.jpg"},"ams_acf":[],"_links":{"self":[{"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/posts\/1808","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/comments?post=1808"}],"version-history":[{"count":6,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/posts\/1808\/revisions"}],"predecessor-version":[{"id":1827,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/posts\/1808\/revisions\/1827"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/media\/538"}],"wp:attachment":[{"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/media?parent=1808"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/categories?post=1808"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/phamho.com\/book\/wp-json\/wp\/v2\/tags?post=1808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}