Add NCE modules integration and enhanced wizard effects
- Add 3 NCE content modules (NCE1-Lesson63-64, NCE2-Lesson3, NCE2-Lesson30) - Integrate NCE modules in content-scanner, game-loader, navigation - Add sentences extracted from stories for better game compatibility - Add meteor spells to NCE1 (15+ word sentences for wizard game) - Enhanced wizard spell effects with particles and casting animations - Update games-config.json with NCE module configurations Note: Architecture needs refactoring - too many interdependencies Current state has issues that need systematic cleanup 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
30fb6cd46c
commit
79a2cd3778
@ -214,6 +214,33 @@
|
|||||||
"difficulty": "intermediate",
|
"difficulty": "intermediate",
|
||||||
"vocabulary_count": 10,
|
"vocabulary_count": 10,
|
||||||
"topics": ["adventure", "story", "reading", "sentence_chunking", "word_translation"]
|
"topics": ["adventure", "story", "reading", "sentence_chunking", "word_translation"]
|
||||||
|
},
|
||||||
|
"nce1-lesson63-64": {
|
||||||
|
"enabled": true,
|
||||||
|
"name": "NCE1-Lesson63-64",
|
||||||
|
"icon": "👨⚕️",
|
||||||
|
"description": "Medical dialogue and prohibition commands with modal verbs",
|
||||||
|
"difficulty": "intermediate",
|
||||||
|
"vocabulary_count": 120,
|
||||||
|
"topics": ["medical", "modal_verbs", "imperatives", "safety_rules"]
|
||||||
|
},
|
||||||
|
"nce2-lesson3": {
|
||||||
|
"enabled": true,
|
||||||
|
"name": "NCE2-Lesson3",
|
||||||
|
"icon": "✉️",
|
||||||
|
"description": "Please Send Me a Card - Past tense and travel vocabulary",
|
||||||
|
"difficulty": "intermediate",
|
||||||
|
"vocabulary_count": 150,
|
||||||
|
"topics": ["past_tense", "travel", "postcards", "holidays", "grammar"]
|
||||||
|
},
|
||||||
|
"nce2-lesson30": {
|
||||||
|
"enabled": true,
|
||||||
|
"name": "NCE2-Lesson30",
|
||||||
|
"icon": "⚽",
|
||||||
|
"description": "Football or Polo? - Articles and quantifiers",
|
||||||
|
"difficulty": "intermediate",
|
||||||
|
"vocabulary_count": 180,
|
||||||
|
"topics": ["articles", "quantifiers", "sports", "past_continuous", "grammar"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
|||||||
850
js/content/NCE1-Lesson63-64.js
Normal file
850
js/content/NCE1-Lesson63-64.js
Normal file
@ -0,0 +1,850 @@
|
|||||||
|
// === ENGLISH MEDICAL AND SAFETY LESSONS ===
|
||||||
|
// Lessons 63-64: Doctor visit and prohibition commands with Chinese translation
|
||||||
|
|
||||||
|
window.ContentModules = window.ContentModules || {};
|
||||||
|
|
||||||
|
window.ContentModules.NCE1Lesson6364 = {
|
||||||
|
id: "nce1-lesson63-64",
|
||||||
|
name: "NCE1-Lesson63-64",
|
||||||
|
description: "English medical dialogue and prohibition commands with modal verbs",
|
||||||
|
difficulty: "intermediate",
|
||||||
|
language: "en-US",
|
||||||
|
userLanguage: "zh-CN",
|
||||||
|
totalWords: 120,
|
||||||
|
|
||||||
|
// === GRAMMAR LESSONS SYSTEM ===
|
||||||
|
grammar: {
|
||||||
|
"modal-must-mustnot": {
|
||||||
|
title: "Modal Verbs: Must and Mustn't - 情态动词must和mustn't",
|
||||||
|
explanation: "English uses 'must' for strong obligation and 'mustn't' for prohibition.",
|
||||||
|
rules: [
|
||||||
|
"must + verb - for strong necessity: You must stay in bed",
|
||||||
|
"mustn't + verb - for prohibition: You mustn't get up yet",
|
||||||
|
"Must + subject + verb? - for questions: Must he stay in bed?",
|
||||||
|
"No contraction for positive must, but mustn't = must not"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "You must stay in bed.",
|
||||||
|
chinese: "你必须卧床休息。",
|
||||||
|
explanation: "Use 'must' for strong obligation or medical advice",
|
||||||
|
pronunciation: "ju mʌst steɪ ɪn bed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "You mustn't get up yet.",
|
||||||
|
chinese: "你还不能起床。",
|
||||||
|
explanation: "Use 'mustn't' for prohibition or things not allowed",
|
||||||
|
pronunciation: "ju mʌsnt get ʌp jet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Must he stay in bed?",
|
||||||
|
chinese: "他必须卧床吗?",
|
||||||
|
explanation: "Use 'Must' at the start for yes/no questions",
|
||||||
|
pronunciation: "mʌst hi steɪ ɪn bed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "He mustn't eat rich food.",
|
||||||
|
chinese: "他不能吃油腻食物。",
|
||||||
|
explanation: "Use 'mustn't' for medical restrictions",
|
||||||
|
pronunciation: "hi mʌsnt it rɪtʃ fud"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "You must keep the room warm.",
|
||||||
|
chinese: "你必须保持房间温暖。",
|
||||||
|
explanation: "Use 'must' for important instructions",
|
||||||
|
pronunciation: "ju mʌst kip ðə rum wɔrm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "The boy mustn't go to school yet.",
|
||||||
|
chinese: "这个男孩还不能去上学。",
|
||||||
|
explanation: "Use 'mustn't' for temporary restrictions",
|
||||||
|
pronunciation: "ðə bɔɪ mʌsnt gəʊ tu skul jet"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "You _____ stay in bed for two days.",
|
||||||
|
options: ["must", "mustn't", "can", "can't"],
|
||||||
|
correct: "must",
|
||||||
|
explanation: "Use 'must' for medical necessity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "He _____ eat rich food when he's sick.",
|
||||||
|
options: ["must", "mustn't", "should", "can"],
|
||||||
|
correct: "mustn't",
|
||||||
|
explanation: "Use 'mustn't' for medical restrictions"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"imperatives-commands": {
|
||||||
|
title: "Imperative Commands - 祈使句",
|
||||||
|
explanation: "English uses imperatives to give commands, instructions, or make requests.",
|
||||||
|
rules: [
|
||||||
|
"Positive commands: Verb + object: Come upstairs",
|
||||||
|
"Negative commands: Don't + verb: Don't take medicine",
|
||||||
|
"No subject pronoun needed in commands",
|
||||||
|
"Use for instructions, warnings, and advice"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "Come upstairs.",
|
||||||
|
chinese: "上楼来。",
|
||||||
|
explanation: "Positive command - just use the base verb",
|
||||||
|
pronunciation: "kʌm ʌpstɛrz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't take any aspirins.",
|
||||||
|
chinese: "不要吃任何阿司匹林。",
|
||||||
|
explanation: "Negative command - Don't + base verb",
|
||||||
|
pronunciation: "dəʊnt teɪk eni æspɪrɪnz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't play with matches.",
|
||||||
|
chinese: "不要玩火柴。",
|
||||||
|
explanation: "Safety warning using negative command",
|
||||||
|
pronunciation: "dəʊnt pleɪ wɪð mætʃɪz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't make a noise.",
|
||||||
|
chinese: "不要制造噪音。",
|
||||||
|
explanation: "Polite request using negative command",
|
||||||
|
pronunciation: "dəʊnt meɪk ə nɔɪz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't drive so quickly.",
|
||||||
|
chinese: "不要开得这么快。",
|
||||||
|
explanation: "Safety advice using negative command",
|
||||||
|
pronunciation: "dəʊnt draɪv səʊ kwɪkli"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't break that vase.",
|
||||||
|
chinese: "不要打破那个花瓶。",
|
||||||
|
explanation: "Warning using negative command",
|
||||||
|
pronunciation: "dəʊnt breɪk ðæt vɑːz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "transformation",
|
||||||
|
instruction: "Make this a negative command:",
|
||||||
|
original: "Take this medicine.",
|
||||||
|
correct: "Don't take this medicine.",
|
||||||
|
explanation: "Add 'Don't' before the verb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"present-simple-questions": {
|
||||||
|
title: "Present Simple Questions - 一般现在时疑问句",
|
||||||
|
explanation: "English forms questions differently for 'be' verbs and other verbs.",
|
||||||
|
rules: [
|
||||||
|
"With 'be': Be + subject: How's Jimmy? Where's Mr. Williams?",
|
||||||
|
"With other verbs: Do/Does + subject + verb: Does he have a temperature?",
|
||||||
|
"Question words come first: How, What, Where, When"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "How's Jimmy today?",
|
||||||
|
chinese: "吉米今天怎么样?",
|
||||||
|
explanation: "Question with 'be' verb - How + is contracted",
|
||||||
|
pronunciation: "haʊz dʒɪmi tədeɪ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Where's Mr. Williams?",
|
||||||
|
chinese: "威廉姆斯先生在哪里?",
|
||||||
|
explanation: "Question with 'be' verb - Where + is contracted",
|
||||||
|
pronunciation: "wɛrz mɪstər wɪljəmz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Does he have a temperature?",
|
||||||
|
chinese: "他发烧吗?",
|
||||||
|
explanation: "Question with regular verb - Does + subject + verb",
|
||||||
|
pronunciation: "dʌz hi hæv ə tempərətʃər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Can I see him please?",
|
||||||
|
chinese: "我可以看看他吗?",
|
||||||
|
explanation: "Question with modal verb - Modal + subject + verb",
|
||||||
|
pronunciation: "kæn aɪ si hɪm pliz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "question_formation",
|
||||||
|
statement: "He has a cold.",
|
||||||
|
correct: "Does he have a cold?",
|
||||||
|
explanation: "Use 'Does' + subject + base verb for questions"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
vocabulary: {
|
||||||
|
"doctor": {
|
||||||
|
"user_language": "医生",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "dɔktər"
|
||||||
|
},
|
||||||
|
"better": {
|
||||||
|
"user_language": "更好的",
|
||||||
|
"type": "adjective",
|
||||||
|
"pronunciation": "betər"
|
||||||
|
},
|
||||||
|
"certainly": {
|
||||||
|
"user_language": "当然",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "sɜrtənli"
|
||||||
|
},
|
||||||
|
"upstairs": {
|
||||||
|
"user_language": "楼上",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "ʌpstɛrz"
|
||||||
|
},
|
||||||
|
"bed": {
|
||||||
|
"user_language": "床",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "bed"
|
||||||
|
},
|
||||||
|
"yet": {
|
||||||
|
"user_language": "还,仍",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "jet"
|
||||||
|
},
|
||||||
|
"stay": {
|
||||||
|
"user_language": "停留",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "steɪ"
|
||||||
|
},
|
||||||
|
"school": {
|
||||||
|
"user_language": "学校",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "skul"
|
||||||
|
},
|
||||||
|
"rich": {
|
||||||
|
"user_language": "油腻的",
|
||||||
|
"type": "adjective",
|
||||||
|
"pronunciation": "rɪtʃ"
|
||||||
|
},
|
||||||
|
"food": {
|
||||||
|
"user_language": "食物",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "fud"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"user_language": "体温,发烧",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "tempərətʃər"
|
||||||
|
},
|
||||||
|
"remain": {
|
||||||
|
"user_language": "保持,继续",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "rɪmeɪn"
|
||||||
|
},
|
||||||
|
"warm": {
|
||||||
|
"user_language": "温暖的",
|
||||||
|
"type": "adjective",
|
||||||
|
"pronunciation": "wɔrm"
|
||||||
|
},
|
||||||
|
"cold": {
|
||||||
|
"user_language": "感冒",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "kəʊld"
|
||||||
|
},
|
||||||
|
"aspirins": {
|
||||||
|
"user_language": "阿司匹林",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "æspɪrɪnz"
|
||||||
|
},
|
||||||
|
"medicine": {
|
||||||
|
"user_language": "药",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "medɪsən"
|
||||||
|
},
|
||||||
|
"play": {
|
||||||
|
"user_language": "玩",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "pleɪ"
|
||||||
|
},
|
||||||
|
"matches": {
|
||||||
|
"user_language": "火柴",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "mætʃɪz"
|
||||||
|
},
|
||||||
|
"talk": {
|
||||||
|
"user_language": "谈话",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "tɔk"
|
||||||
|
},
|
||||||
|
"library": {
|
||||||
|
"user_language": "图书馆",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "laɪbrəri"
|
||||||
|
},
|
||||||
|
"noise": {
|
||||||
|
"user_language": "噪音",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "nɔɪz"
|
||||||
|
},
|
||||||
|
"drive": {
|
||||||
|
"user_language": "开车",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "draɪv"
|
||||||
|
},
|
||||||
|
"quickly": {
|
||||||
|
"user_language": "快地",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "kwɪkli"
|
||||||
|
},
|
||||||
|
"lean": {
|
||||||
|
"user_language": "探身",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "lin"
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"user_language": "窗户",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "wɪndəʊ"
|
||||||
|
},
|
||||||
|
"break": {
|
||||||
|
"user_language": "打破",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "breɪk"
|
||||||
|
},
|
||||||
|
"vase": {
|
||||||
|
"user_language": "花瓶",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "vɑz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === SENTENCES FOR GAMES (extracted from stories) ===
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
english: "How's Jimmy today?",
|
||||||
|
chinese: "吉米今天怎么样?",
|
||||||
|
prononciation: "haʊz dʒɪmi tədeɪ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Better. Thank you, doctor.",
|
||||||
|
chinese: "好一些了。谢谢你,医生。",
|
||||||
|
prononciation: "betər θæŋk ju dɔktər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Can I see him please?",
|
||||||
|
chinese: "我可以看看他吗?",
|
||||||
|
prononciation: "kæn aɪ si hɪm pliz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "You must stay in bed.",
|
||||||
|
chinese: "你必须卧床休息。",
|
||||||
|
prononciation: "ju mʌst steɪ ɪn bed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "You mustn't get up yet.",
|
||||||
|
chinese: "你还不能起床。",
|
||||||
|
prononciation: "ju mʌsnt get ʌp jet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't take any aspirins.",
|
||||||
|
chinese: "不要吃任何阿司匹林。",
|
||||||
|
prononciation: "dəʊnt teɪk eni æspɪrɪnz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Don't play with matches.",
|
||||||
|
chinese: "不要玩火柴。",
|
||||||
|
prononciation: "dəʊnt pleɪ wɪð mætʃɪz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "The doctor says Jimmy must rest.",
|
||||||
|
chinese: "医生说吉米必须休息。",
|
||||||
|
prononciation: "ðə dɔktər sez dʒɪmi mʌst rest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "He mustn't go outside yet.",
|
||||||
|
chinese: "他还不能出门。",
|
||||||
|
prononciation: "hi mʌsnt gəʊ aʊtsaɪd jet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Mrs. Williams must keep him warm.",
|
||||||
|
chinese: "威廉姆斯太太必须让他保暖。",
|
||||||
|
prononciation: "mɪsɪz wɪljəmz mʌst kip hɪm wɔrm"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
story: {
|
||||||
|
title: "At the Doctor's Visit - 看医生",
|
||||||
|
totalSentences: 23,
|
||||||
|
chapters: [
|
||||||
|
{
|
||||||
|
title: "Chapter 1: Jimmy is Sick - 第一章:吉米生病了",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
original: "How's Jimmy today?",
|
||||||
|
translation: "吉米今天怎么样?",
|
||||||
|
words: [
|
||||||
|
{word: "How's", translation: "怎么样", type: "question", pronunciation: "haʊz"},
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"},
|
||||||
|
{word: "today", translation: "今天", type: "adverb", pronunciation: "tədeɪ"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
original: "Better. Thank you, doctor.",
|
||||||
|
translation: "好一些了。谢谢你,医生。",
|
||||||
|
words: [
|
||||||
|
{word: "Better", translation: "好一些", type: "adjective", pronunciation: "betər"},
|
||||||
|
{word: "Thank", translation: "谢谢", type: "verb", pronunciation: "θæŋk"},
|
||||||
|
{word: "you", translation: "你", type: "pronoun", pronunciation: "ju"},
|
||||||
|
{word: "doctor", translation: "医生", type: "noun", pronunciation: "dɔktər"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
original: "Can I see him please?",
|
||||||
|
translation: "我可以看看他吗?",
|
||||||
|
words: [
|
||||||
|
{word: "Can", translation: "可以", type: "modal", pronunciation: "kæn"},
|
||||||
|
{word: "I", translation: "我", type: "pronoun", pronunciation: "aɪ"},
|
||||||
|
{word: "see", translation: "看", type: "verb", pronunciation: "si"},
|
||||||
|
{word: "him", translation: "他", type: "pronoun", pronunciation: "hɪm"},
|
||||||
|
{word: "please", translation: "请", type: "adverb", pronunciation: "pliz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
original: "Certainly, doctor. Come upstairs.",
|
||||||
|
translation: "当然可以,医生。上楼来。",
|
||||||
|
words: [
|
||||||
|
{word: "Certainly", translation: "当然", type: "adverb", pronunciation: "sɜrtənli"},
|
||||||
|
{word: "doctor", translation: "医生", type: "noun", pronunciation: "dɔktər"},
|
||||||
|
{word: "Come", translation: "来", type: "verb", pronunciation: "kʌm"},
|
||||||
|
{word: "upstairs", translation: "楼上", type: "adverb", pronunciation: "ʌpstɛrz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
original: "You look very well, Jimmy.",
|
||||||
|
translation: "你看起来很好,吉米。",
|
||||||
|
words: [
|
||||||
|
{word: "You", translation: "你", type: "pronoun", pronunciation: "ju"},
|
||||||
|
{word: "look", translation: "看起来", type: "verb", pronunciation: "lʊk"},
|
||||||
|
{word: "very", translation: "很", type: "adverb", pronunciation: "vɛri"},
|
||||||
|
{word: "well", translation: "好", type: "adverb", pronunciation: "wɛl"},
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
original: "You are better now.",
|
||||||
|
translation: "你现在好多了。",
|
||||||
|
words: [
|
||||||
|
{word: "You", translation: "你", type: "pronoun", pronunciation: "ju"},
|
||||||
|
{word: "are", translation: "是", type: "verb", pronunciation: "ɑr"},
|
||||||
|
{word: "better", translation: "更好", type: "adjective", pronunciation: "betər"},
|
||||||
|
{word: "now", translation: "现在", type: "adverb", pronunciation: "naʊ"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
original: "You mustn't get up yet.",
|
||||||
|
translation: "你还不能起床。",
|
||||||
|
words: [
|
||||||
|
{word: "You", translation: "你", type: "pronoun", pronunciation: "ju"},
|
||||||
|
{word: "mustn't", translation: "不能", type: "modal", pronunciation: "mʌsnt"},
|
||||||
|
{word: "get", translation: "起", type: "verb", pronunciation: "get"},
|
||||||
|
{word: "up", translation: "床", type: "adverb", pronunciation: "ʌp"},
|
||||||
|
{word: "yet", translation: "还", type: "adverb", pronunciation: "jet"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
original: "You must stay in bed.",
|
||||||
|
translation: "你必须卧床休息。",
|
||||||
|
words: [
|
||||||
|
{word: "You", translation: "你", type: "pronoun", pronunciation: "ju"},
|
||||||
|
{word: "must", translation: "必须", type: "modal", pronunciation: "mʌst"},
|
||||||
|
{word: "stay", translation: "停留", type: "verb", pronunciation: "steɪ"},
|
||||||
|
{word: "in", translation: "在", type: "preposition", pronunciation: "ɪn"},
|
||||||
|
{word: "bed", translation: "床", type: "noun", pronunciation: "bed"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
original: "He mustn't go to school yet.",
|
||||||
|
translation: "他还不能去上学。",
|
||||||
|
words: [
|
||||||
|
{word: "He", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "mustn't", translation: "不能", type: "modal", pronunciation: "mʌsnt"},
|
||||||
|
{word: "go", translation: "去", type: "verb", pronunciation: "gəʊ"},
|
||||||
|
{word: "to", translation: "到", type: "preposition", pronunciation: "tu"},
|
||||||
|
{word: "school", translation: "学校", type: "noun", pronunciation: "skul"},
|
||||||
|
{word: "yet", translation: "还", type: "adverb", pronunciation: "jet"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
original: "He mustn't eat rich food.",
|
||||||
|
translation: "他不能吃油腻食物。",
|
||||||
|
words: [
|
||||||
|
{word: "He", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "mustn't", translation: "不能", type: "modal", pronunciation: "mʌsnt"},
|
||||||
|
{word: "eat", translation: "吃", type: "verb", pronunciation: "it"},
|
||||||
|
{word: "rich", translation: "油腻的", type: "adjective", pronunciation: "rɪtʃ"},
|
||||||
|
{word: "food", translation: "食物", type: "noun", pronunciation: "fud"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Chapter 2: Safety Rules - 第二章:安全规则",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 11,
|
||||||
|
original: "Don't take any aspirins.",
|
||||||
|
translation: "不要吃任何阿司匹林。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "take", translation: "吃", type: "verb", pronunciation: "teɪk"},
|
||||||
|
{word: "any", translation: "任何", type: "determiner", pronunciation: "eni"},
|
||||||
|
{word: "aspirins", translation: "阿司匹林", type: "noun", pronunciation: "æspɪrɪnz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 12,
|
||||||
|
original: "Don't take this medicine.",
|
||||||
|
translation: "不要吃这个药。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "take", translation: "吃", type: "verb", pronunciation: "teɪk"},
|
||||||
|
{word: "this", translation: "这个", type: "determiner", pronunciation: "ðɪs"},
|
||||||
|
{word: "medicine", translation: "药", type: "noun", pronunciation: "medɪsən"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 13,
|
||||||
|
original: "Don't play with matches.",
|
||||||
|
translation: "不要玩火柴。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "play", translation: "玩", type: "verb", pronunciation: "pleɪ"},
|
||||||
|
{word: "with", translation: "和", type: "preposition", pronunciation: "wɪð"},
|
||||||
|
{word: "matches", translation: "火柴", type: "noun", pronunciation: "mætʃɪz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 14,
|
||||||
|
original: "Don't talk in the library.",
|
||||||
|
translation: "不要在图书馆说话。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "talk", translation: "说话", type: "verb", pronunciation: "tɔk"},
|
||||||
|
{word: "in", translation: "在", type: "preposition", pronunciation: "ɪn"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "library", translation: "图书馆", type: "noun", pronunciation: "laɪbrəri"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 15,
|
||||||
|
original: "Don't make a noise.",
|
||||||
|
translation: "不要制造噪音。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "make", translation: "制造", type: "verb", pronunciation: "meɪk"},
|
||||||
|
{word: "a", translation: "一个", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "noise", translation: "噪音", type: "noun", pronunciation: "nɔɪz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 16,
|
||||||
|
original: "Don't drive so quickly.",
|
||||||
|
translation: "不要开得这么快。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "drive", translation: "开车", type: "verb", pronunciation: "draɪv"},
|
||||||
|
{word: "so", translation: "如此", type: "adverb", pronunciation: "səʊ"},
|
||||||
|
{word: "quickly", translation: "快地", type: "adverb", pronunciation: "kwɪkli"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 17,
|
||||||
|
original: "Don't lean out of the window.",
|
||||||
|
translation: "不要从窗户探出身子。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "lean", translation: "探身", type: "verb", pronunciation: "lin"},
|
||||||
|
{word: "out", translation: "出", type: "adverb", pronunciation: "aʊt"},
|
||||||
|
{word: "of", translation: "从", type: "preposition", pronunciation: "ʌv"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "window", translation: "窗户", type: "noun", pronunciation: "wɪndəʊ"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 18,
|
||||||
|
original: "Don't break that vase.",
|
||||||
|
translation: "不要打破那个花瓶。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "break", translation: "打破", type: "verb", pronunciation: "breɪk"},
|
||||||
|
{word: "that", translation: "那个", type: "determiner", pronunciation: "ðæt"},
|
||||||
|
{word: "vase", translation: "花瓶", type: "noun", pronunciation: "vɑz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 19,
|
||||||
|
original: "Does he have a temperature?",
|
||||||
|
translation: "他发烧吗?",
|
||||||
|
words: [
|
||||||
|
{word: "Does", translation: "吗", type: "auxiliary", pronunciation: "dʌz"},
|
||||||
|
{word: "he", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "have", translation: "有", type: "verb", pronunciation: "hæv"},
|
||||||
|
{word: "a", translation: "一个", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "temperature", translation: "体温", type: "noun", pronunciation: "tempərətʃər"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 20,
|
||||||
|
original: "He has a bad cold too.",
|
||||||
|
translation: "他也得了重感冒。",
|
||||||
|
words: [
|
||||||
|
{word: "He", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "has", translation: "有", type: "verb", pronunciation: "hæz"},
|
||||||
|
{word: "a", translation: "一个", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "bad", translation: "严重的", type: "adjective", pronunciation: "bæd"},
|
||||||
|
{word: "cold", translation: "感冒", type: "noun", pronunciation: "kəʊld"},
|
||||||
|
{word: "too", translation: "也", type: "adverb", pronunciation: "tu"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 21,
|
||||||
|
original: "The doctor told Mrs. Williams to keep Jimmy warm and give him plenty of rest.",
|
||||||
|
translation: "医生告诉威廉姆斯太太要让吉米保暖并让他多休息。",
|
||||||
|
words: [
|
||||||
|
{word: "The", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "doctor", translation: "医生", type: "noun", pronunciation: "dɔktər"},
|
||||||
|
{word: "told", translation: "告诉", type: "verb", pronunciation: "toʊld"},
|
||||||
|
{word: "Mrs.", translation: "太太", type: "title", pronunciation: "mɪsɪz"},
|
||||||
|
{word: "Williams", translation: "威廉姆斯", type: "noun", pronunciation: "wɪljəmz"},
|
||||||
|
{word: "to", translation: "要", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "keep", translation: "保持", type: "verb", pronunciation: "kiːp"},
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"},
|
||||||
|
{word: "warm", translation: "温暖", type: "adjective", pronunciation: "wɔːrm"},
|
||||||
|
{word: "and", translation: "并且", type: "conjunction", pronunciation: "ænd"},
|
||||||
|
{word: "give", translation: "给", type: "verb", pronunciation: "gɪv"},
|
||||||
|
{word: "him", translation: "他", type: "pronoun", pronunciation: "hɪm"},
|
||||||
|
{word: "plenty", translation: "大量", type: "noun", pronunciation: "plenti"},
|
||||||
|
{word: "of", translation: "的", type: "preposition", pronunciation: "ʌv"},
|
||||||
|
{word: "rest", translation: "休息", type: "noun", pronunciation: "rest"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 22,
|
||||||
|
original: "Jimmy must stay in bed until the doctor says he can go back to school.",
|
||||||
|
translation: "吉米必须卧床直到医生说他可以回学校。",
|
||||||
|
words: [
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"},
|
||||||
|
{word: "must", translation: "必须", type: "modal", pronunciation: "mʌst"},
|
||||||
|
{word: "stay", translation: "停留", type: "verb", pronunciation: "steɪ"},
|
||||||
|
{word: "in", translation: "在", type: "preposition", pronunciation: "ɪn"},
|
||||||
|
{word: "bed", translation: "床", type: "noun", pronunciation: "bed"},
|
||||||
|
{word: "until", translation: "直到", type: "conjunction", pronunciation: "ənˈtɪl"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "doctor", translation: "医生", type: "noun", pronunciation: "dɔktər"},
|
||||||
|
{word: "says", translation: "说", type: "verb", pronunciation: "sez"},
|
||||||
|
{word: "he", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "can", translation: "可以", type: "modal", pronunciation: "kæn"},
|
||||||
|
{word: "go", translation: "去", type: "verb", pronunciation: "goʊ"},
|
||||||
|
{word: "back", translation: "回", type: "adverb", pronunciation: "bæk"},
|
||||||
|
{word: "to", translation: "到", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "school", translation: "学校", type: "noun", pronunciation: "skuːl"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 23,
|
||||||
|
original: "Mrs. Williams promised to follow all the doctor's instructions very carefully until Jimmy feels completely better.",
|
||||||
|
translation: "威廉姆斯太太承诺会非常仔细地遵循医生的所有指示直到吉米完全康复。",
|
||||||
|
words: [
|
||||||
|
{word: "Mrs.", translation: "太太", type: "title", pronunciation: "mɪsɪz"},
|
||||||
|
{word: "Williams", translation: "威廉姆斯", type: "noun", pronunciation: "wɪljəmz"},
|
||||||
|
{word: "promised", translation: "承诺", type: "verb", pronunciation: "prɑːmɪst"},
|
||||||
|
{word: "to", translation: "要", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "follow", translation: "遵循", type: "verb", pronunciation: "fɑːloʊ"},
|
||||||
|
{word: "all", translation: "所有", type: "determiner", pronunciation: "ɔːl"},
|
||||||
|
{word: "the", translation: "这些", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "doctor's", translation: "医生的", type: "noun", pronunciation: "dɔktərz"},
|
||||||
|
{word: "instructions", translation: "指示", type: "noun", pronunciation: "ɪnˈstrʌkʃənz"},
|
||||||
|
{word: "very", translation: "非常", type: "adverb", pronunciation: "veri"},
|
||||||
|
{word: "carefully", translation: "仔细地", type: "adverb", pronunciation: "kɛrfəli"},
|
||||||
|
{word: "until", translation: "直到", type: "conjunction", pronunciation: "ənˈtɪl"},
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"},
|
||||||
|
{word: "feels", translation: "感觉", type: "verb", pronunciation: "fiːlz"},
|
||||||
|
{word: "completely", translation: "完全", type: "adverb", pronunciation: "kəmˈpliːtli"},
|
||||||
|
{word: "better", translation: "更好", type: "adjective", pronunciation: "betər"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// === GRAMMAR-BASED FILL IN THE BLANKS ===
|
||||||
|
fillInBlanks: [
|
||||||
|
{
|
||||||
|
sentence: "You _____ stay in bed for two days.",
|
||||||
|
options: ["must", "mustn't", "can", "don't"],
|
||||||
|
correctAnswer: "must",
|
||||||
|
explanation: "Use 'must' for strong medical advice",
|
||||||
|
grammarFocus: "modal-must-mustnot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "He _____ eat rich food when sick.",
|
||||||
|
options: ["must", "mustn't", "should", "can"],
|
||||||
|
correctAnswer: "mustn't",
|
||||||
|
explanation: "Use 'mustn't' for medical restrictions",
|
||||||
|
grammarFocus: "modal-must-mustnot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "_____ take this medicine!",
|
||||||
|
options: ["Don't", "Not", "No", "Doesn't"],
|
||||||
|
correctAnswer: "Don't",
|
||||||
|
explanation: "Use 'Don't' for negative commands",
|
||||||
|
grammarFocus: "imperatives-commands"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "_____ he have a temperature?",
|
||||||
|
options: ["Do", "Does", "Is", "Has"],
|
||||||
|
correctAnswer: "Does",
|
||||||
|
explanation: "Use 'Does' for questions with third person singular",
|
||||||
|
grammarFocus: "present-simple-questions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "_____ play with matches!",
|
||||||
|
options: ["Not", "Don't", "No", "Mustn't"],
|
||||||
|
correctAnswer: "Don't",
|
||||||
|
explanation: "Use 'Don't' for safety warnings",
|
||||||
|
grammarFocus: "imperatives-commands"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "_____ Mr. Williams this evening?",
|
||||||
|
options: ["Where", "Where's", "Where are", "Where is"],
|
||||||
|
correctAnswer: "Where's",
|
||||||
|
explanation: "Use 'Where's' (Where is) for location questions",
|
||||||
|
grammarFocus: "present-simple-questions"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// === GRAMMAR CORRECTION EXERCISES ===
|
||||||
|
corrections: [
|
||||||
|
{
|
||||||
|
incorrect: "You don't must get up yet.",
|
||||||
|
correct: "You mustn't get up yet.",
|
||||||
|
explanation: "Use 'mustn't' not 'don't must' for prohibition",
|
||||||
|
grammarFocus: "modal-must-mustnot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "Not take this medicine!",
|
||||||
|
correct: "Don't take this medicine!",
|
||||||
|
explanation: "Use 'Don't' + verb for negative commands",
|
||||||
|
grammarFocus: "imperatives-commands"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "He must not to eat rich food.",
|
||||||
|
correct: "He mustn't eat rich food.",
|
||||||
|
explanation: "Don't use 'to' after modal verbs",
|
||||||
|
grammarFocus: "modal-must-mustnot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "Do he have a temperature?",
|
||||||
|
correct: "Does he have a temperature?",
|
||||||
|
explanation: "Use 'Does' with third person singular subjects",
|
||||||
|
grammarFocus: "present-simple-questions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "You must to stay in bed.",
|
||||||
|
correct: "You must stay in bed.",
|
||||||
|
explanation: "Don't use 'to' after 'must'",
|
||||||
|
grammarFocus: "modal-must-mustnot"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// === ADDITIONAL READING STORIES ===
|
||||||
|
additionalStories: [
|
||||||
|
{
|
||||||
|
title: "Doctor's Advice - 医生的建议",
|
||||||
|
totalSentences: 12,
|
||||||
|
chapters: [
|
||||||
|
{
|
||||||
|
title: "Chapter 1: Following Medical Instructions - 遵循医嘱",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
original: "The doctor says Jimmy must rest.",
|
||||||
|
translation: "医生说吉米必须休息。",
|
||||||
|
words: [
|
||||||
|
{word: "The", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "doctor", translation: "医生", type: "noun", pronunciation: "dɔktər"},
|
||||||
|
{word: "says", translation: "说", type: "verb", pronunciation: "sez"},
|
||||||
|
{word: "Jimmy", translation: "吉米", type: "noun", pronunciation: "dʒɪmi"},
|
||||||
|
{word: "must", translation: "必须", type: "modal", pronunciation: "mʌst"},
|
||||||
|
{word: "rest", translation: "休息", type: "verb", pronunciation: "rest"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
original: "He mustn't go outside yet.",
|
||||||
|
translation: "他还不能出门。",
|
||||||
|
words: [
|
||||||
|
{word: "He", translation: "他", type: "pronoun", pronunciation: "hi"},
|
||||||
|
{word: "mustn't", translation: "不能", type: "modal", pronunciation: "mʌsnt"},
|
||||||
|
{word: "go", translation: "去", type: "verb", pronunciation: "gəʊ"},
|
||||||
|
{word: "outside", translation: "外面", type: "adverb", pronunciation: "aʊtsaɪd"},
|
||||||
|
{word: "yet", translation: "还", type: "adverb", pronunciation: "jet"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
original: "Mrs. Williams must keep him warm.",
|
||||||
|
translation: "威廉姆斯太太必须让他保暖。",
|
||||||
|
words: [
|
||||||
|
{word: "Mrs.", translation: "太太", type: "title", pronunciation: "mɪsɪz"},
|
||||||
|
{word: "Williams", translation: "威廉姆斯", type: "noun", pronunciation: "wɪljəmz"},
|
||||||
|
{word: "must", translation: "必须", type: "modal", pronunciation: "mʌst"},
|
||||||
|
{word: "keep", translation: "保持", type: "verb", pronunciation: "kip"},
|
||||||
|
{word: "him", translation: "他", type: "pronoun", pronunciation: "hɪm"},
|
||||||
|
{word: "warm", translation: "温暖", type: "adjective", pronunciation: "wɔrm"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
original: "Don't give him cold drinks.",
|
||||||
|
translation: "不要给他冷饮。",
|
||||||
|
words: [
|
||||||
|
{word: "Don't", translation: "不要", type: "auxiliary", pronunciation: "dəʊnt"},
|
||||||
|
{word: "give", translation: "给", type: "verb", pronunciation: "gɪv"},
|
||||||
|
{word: "him", translation: "他", type: "pronoun", pronunciation: "hɪm"},
|
||||||
|
{word: "cold", translation: "冷的", type: "adjective", pronunciation: "kəʊld"},
|
||||||
|
{word: "drinks", translation: "饮料", type: "noun", pronunciation: "drɪŋks"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONTENT STRUCTURE SUMMARY - FOR AI REFERENCE
|
||||||
|
// ============================================================================
|
||||||
|
// This module contains:
|
||||||
|
// - Medical dialogue vocabulary and situations
|
||||||
|
// - Modal verbs (must/mustn't) for obligations and prohibitions
|
||||||
|
// - Imperative commands for instructions and warnings
|
||||||
|
// - Present simple questions for medical inquiries
|
||||||
|
// - Safety-focused vocabulary and scenarios
|
||||||
|
// - Chinese translations for all content
|
||||||
|
// - Comprehensive grammar explanations and examples
|
||||||
|
// ============================================================================
|
||||||
1134
js/content/NCE2-Lesson3.js
Normal file
1134
js/content/NCE2-Lesson3.js
Normal file
File diff suppressed because it is too large
Load Diff
785
js/content/NCE2-Lesson30.js
Normal file
785
js/content/NCE2-Lesson30.js
Normal file
@ -0,0 +1,785 @@
|
|||||||
|
// === LESSON 30: FOOTBALL OR POLO? ===
|
||||||
|
// English learning story with Chinese translation - Intermediate Level
|
||||||
|
|
||||||
|
window.ContentModules = window.ContentModules || {};
|
||||||
|
|
||||||
|
window.ContentModules.NCE2Lesson30 = {
|
||||||
|
id: "nce2-lesson30",
|
||||||
|
name: "NCE2-Lesson30",
|
||||||
|
description: "Football or polo? - A story about the Wayle river with grammar focus on articles and quantifiers",
|
||||||
|
difficulty: "intermediate",
|
||||||
|
language: "en-US",
|
||||||
|
userLanguage: "zh-CN",
|
||||||
|
totalWords: 200,
|
||||||
|
|
||||||
|
// === GRAMMAR LESSONS SYSTEM ===
|
||||||
|
grammar: {
|
||||||
|
"articles-usage": {
|
||||||
|
title: "Articles Usage - 冠词使用",
|
||||||
|
explanation: "English uses 'a', 'an', and 'the' in specific ways, especially with names and places.",
|
||||||
|
rules: [
|
||||||
|
"the - use with rivers, seas, oceans, mountain ranges: the Thames, the Pacific",
|
||||||
|
"no article - use with most personal names and countries: John, England",
|
||||||
|
"the - use with certain countries: the United States, the United Kingdom",
|
||||||
|
"the - use with superlatives and unique things: the best, the sun"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "The Wayle is a small river.",
|
||||||
|
chinese: "威尔河是一条小河。",
|
||||||
|
explanation: "Use 'the' with river names",
|
||||||
|
pronunciation: "ðə weɪl ɪz ə smɔːl ˈrɪvər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Paris is on the Seine.",
|
||||||
|
chinese: "巴黎在塞纳河上。",
|
||||||
|
explanation: "Use 'the' with famous rivers",
|
||||||
|
pronunciation: "ˈpærɪs ɪz ɒn ðə seɪn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "London is on the Thames.",
|
||||||
|
chinese: "伦敦在泰晤士河上。",
|
||||||
|
explanation: "River names always take 'the'",
|
||||||
|
pronunciation: "ˈlʌndən ɪz ɒn ðə temz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "He lives in England.",
|
||||||
|
chinese: "他住在英国。",
|
||||||
|
explanation: "Most country names don't use 'the'",
|
||||||
|
pronunciation: "hiː lɪvz ɪn ˈɪŋɡlənd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "I went to the United States.",
|
||||||
|
chinese: "我去了美国。",
|
||||||
|
explanation: "Some countries use 'the'",
|
||||||
|
pronunciation: "aɪ went tuː ðə juˈnaɪtɪd steɪts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "_____ Thames flows through London.",
|
||||||
|
options: ["The", "A", "An", "No article"],
|
||||||
|
correct: "The",
|
||||||
|
explanation: "River names always use 'the'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "John lives in _____ England.",
|
||||||
|
options: ["the", "a", "an", "no article"],
|
||||||
|
correct: "no article",
|
||||||
|
explanation: "Most country names don't use articles"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"some-any-usage": {
|
||||||
|
title: "Some and Any Usage - Some和Any的使用",
|
||||||
|
explanation: "English uses 'some' and 'any' differently depending on sentence type and meaning.",
|
||||||
|
rules: [
|
||||||
|
"some - use in positive statements: There are some people",
|
||||||
|
"any - use in questions: Are there any people?",
|
||||||
|
"any - use in negative statements: There aren't any people",
|
||||||
|
"some - use in offers and requests: Would you like some tea?"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "Some children were playing games.",
|
||||||
|
chinese: "一些孩子在玩游戏。",
|
||||||
|
explanation: "Use 'some' in positive statements",
|
||||||
|
pronunciation: "sʌm ˈtʃɪldrən wər ˈpleɪɪŋ ɡeɪmz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "There were some people rowing.",
|
||||||
|
chinese: "有一些人在划船。",
|
||||||
|
explanation: "Use 'some' to describe what exists",
|
||||||
|
pronunciation: "ðər wər sʌm ˈpiːpəl ˈroʊɪŋ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "There weren't any children in sight.",
|
||||||
|
chinese: "看不见任何孩子。",
|
||||||
|
explanation: "Use 'any' in negative statements",
|
||||||
|
pronunciation: "ðər wərnt ˈeni ˈtʃɪldrən ɪn saɪt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Are there any boats on the river?",
|
||||||
|
chinese: "河上有船吗?",
|
||||||
|
explanation: "Use 'any' in questions",
|
||||||
|
pronunciation: "ər ðər ˈeni boʊts ɒn ðə ˈrɪvər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Would you like some water?",
|
||||||
|
chinese: "你想要一些水吗?",
|
||||||
|
explanation: "Use 'some' in offers",
|
||||||
|
pronunciation: "wʊd juː laɪk sʌm ˈwɔːtər"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "There are _____ people on the bank.",
|
||||||
|
options: ["some", "any", "a", "the"],
|
||||||
|
correct: "some",
|
||||||
|
explanation: "Use 'some' in positive statements"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "There weren't _____ children in sight.",
|
||||||
|
options: ["some", "any", "a", "the"],
|
||||||
|
correct: "any",
|
||||||
|
explanation: "Use 'any' in negative statements"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"past-continuous": {
|
||||||
|
title: "Past Continuous Tense - 过去进行时",
|
||||||
|
explanation: "Use past continuous for actions that were in progress at a specific time in the past.",
|
||||||
|
rules: [
|
||||||
|
"Form: was/were + verb-ing",
|
||||||
|
"Use for ongoing past actions: I was sitting by the river",
|
||||||
|
"Use for background actions in stories: Children were playing while I sat",
|
||||||
|
"Use with time expressions: at 3pm yesterday, last Sunday"
|
||||||
|
],
|
||||||
|
examples: [
|
||||||
|
{
|
||||||
|
english: "Some children were playing games.",
|
||||||
|
chinese: "一些孩子在玩游戏。",
|
||||||
|
explanation: "Action in progress in the past",
|
||||||
|
pronunciation: "sʌm ˈtʃɪldrən wər ˈpleɪɪŋ ɡeɪmz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "People were rowing on the river.",
|
||||||
|
chinese: "人们在河上划船。",
|
||||||
|
explanation: "Ongoing action in the past",
|
||||||
|
pronunciation: "ˈpiːpəl wər ˈroʊɪŋ ɒn ðə ˈrɪvər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "I was sitting by the river.",
|
||||||
|
chinese: "我坐在河边。",
|
||||||
|
explanation: "Past continuous shows duration",
|
||||||
|
pronunciation: "aɪ wəz ˈsɪtɪŋ baɪ ðə ˈrɪvər"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exercises: [
|
||||||
|
{
|
||||||
|
type: "fill_blank",
|
||||||
|
sentence: "The children _____ playing when it happened.",
|
||||||
|
options: ["were", "was", "are", "is"],
|
||||||
|
correct: "were",
|
||||||
|
explanation: "Use 'were' with plural subjects in past continuous"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
vocabulary: {
|
||||||
|
"polo": {
|
||||||
|
"user_language": "水球",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˈpoʊloʊ"
|
||||||
|
},
|
||||||
|
"river": {
|
||||||
|
"user_language": "河流",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˈrɪvər"
|
||||||
|
},
|
||||||
|
"cut": {
|
||||||
|
"user_language": "穿过",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "kʌt"
|
||||||
|
},
|
||||||
|
"park": {
|
||||||
|
"user_language": "公园",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "pɑːrk"
|
||||||
|
},
|
||||||
|
"afternoon": {
|
||||||
|
"user_language": "下午",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˌæftərˈnuːn"
|
||||||
|
},
|
||||||
|
"bank": {
|
||||||
|
"user_language": "河岸",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "bæŋk"
|
||||||
|
},
|
||||||
|
"usual": {
|
||||||
|
"user_language": "平常的",
|
||||||
|
"type": "adjective",
|
||||||
|
"pronunciation": "ˈjuːʒuəl"
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"user_language": "孩子们",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˈtʃɪldrən"
|
||||||
|
},
|
||||||
|
"games": {
|
||||||
|
"user_language": "游戏",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ɡeɪmz"
|
||||||
|
},
|
||||||
|
"people": {
|
||||||
|
"user_language": "人们",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˈpiːpəl"
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"user_language": "划船",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "roʊ"
|
||||||
|
},
|
||||||
|
"suddenly": {
|
||||||
|
"user_language": "突然",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "ˈsʌdənli"
|
||||||
|
},
|
||||||
|
"kick": {
|
||||||
|
"user_language": "踢",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "kɪk"
|
||||||
|
},
|
||||||
|
"ball": {
|
||||||
|
"user_language": "球",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "bɔːl"
|
||||||
|
},
|
||||||
|
"hard": {
|
||||||
|
"user_language": "用力地",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "hɑːrd"
|
||||||
|
},
|
||||||
|
"towards": {
|
||||||
|
"user_language": "朝向",
|
||||||
|
"type": "preposition",
|
||||||
|
"pronunciation": "təˈwɔːrdz"
|
||||||
|
},
|
||||||
|
"passing": {
|
||||||
|
"user_language": "经过的",
|
||||||
|
"type": "adjective",
|
||||||
|
"pronunciation": "ˈpæsɪŋ"
|
||||||
|
},
|
||||||
|
"boat": {
|
||||||
|
"user_language": "船",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "boʊt"
|
||||||
|
},
|
||||||
|
"called": {
|
||||||
|
"user_language": "叫喊",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "kɔːld"
|
||||||
|
},
|
||||||
|
"hear": {
|
||||||
|
"user_language": "听见",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "hɪr"
|
||||||
|
},
|
||||||
|
"struck": {
|
||||||
|
"user_language": "击打",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "strʌk"
|
||||||
|
},
|
||||||
|
"nearly": {
|
||||||
|
"user_language": "几乎",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "ˈnɪrli"
|
||||||
|
},
|
||||||
|
"fell": {
|
||||||
|
"user_language": "落下",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "fel"
|
||||||
|
},
|
||||||
|
"water": {
|
||||||
|
"user_language": "水",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "ˈwɔːtər"
|
||||||
|
},
|
||||||
|
"turned": {
|
||||||
|
"user_language": "转身",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "tɜːrnd"
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"user_language": "视线",
|
||||||
|
"type": "noun",
|
||||||
|
"pronunciation": "saɪt"
|
||||||
|
},
|
||||||
|
"run away": {
|
||||||
|
"user_language": "跑开",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "rʌn əˈweɪ"
|
||||||
|
},
|
||||||
|
"laughed": {
|
||||||
|
"user_language": "笑",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "læft"
|
||||||
|
},
|
||||||
|
"realized": {
|
||||||
|
"user_language": "意识到",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "ˈriəlaɪzd"
|
||||||
|
},
|
||||||
|
"happened": {
|
||||||
|
"user_language": "发生",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "ˈhæpənd"
|
||||||
|
},
|
||||||
|
"threw": {
|
||||||
|
"user_language": "扔",
|
||||||
|
"type": "verb",
|
||||||
|
"pronunciation": "θruː"
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"user_language": "回来",
|
||||||
|
"type": "adverb",
|
||||||
|
"pronunciation": "bæk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === SENTENCES FOR GAMES (extracted from stories) ===
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
english: "The Wayle is a small river.",
|
||||||
|
chinese: "威尔河是一条小河。",
|
||||||
|
prononciation: "ðə weɪl ɪz ə smɔːl ˈrɪvər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "It cuts across the park near my home.",
|
||||||
|
chinese: "它横穿我家附近的公园。",
|
||||||
|
prononciation: "ɪt kʌts əˈkrɔːs ðə pɑːrk nɪr maɪ hoʊm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "I like sitting by the Wayle on fine afternoons.",
|
||||||
|
chinese: "我喜欢在晴朗的下午坐在威尔河边。",
|
||||||
|
prononciation: "aɪ laɪk ˈsɪtɪŋ baɪ ðə weɪl ɑːn faɪn ˌæftərˈnuːnz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "Some children were playing games on the bank.",
|
||||||
|
chinese: "一些孩子在河岸上玩游戏。",
|
||||||
|
prononciation: "sʌm ˈtʃɪldrən wər ˈpleɪɪŋ geɪmz ɑːn ðə bæŋk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "There were some people rowing on the river.",
|
||||||
|
chinese: "河上有一些人在划船。",
|
||||||
|
prononciation: "ðɛr wər sʌm ˈpiːpəl ˈroʊɪŋ ɑːn ðə ˈrɪvər"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "The ball struck him so hard.",
|
||||||
|
chinese: "球重重地打在他身上。",
|
||||||
|
prononciation: "ðə bɔːl strʌk hɪm soʊ hɑːrd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "This is a pleasant surprise!",
|
||||||
|
chinese: "这真是个意外的惊喜!",
|
||||||
|
prononciation: "ðɪs ɪz ə ˈplɛzənt sərˈpraɪz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "I turned to look at the children.",
|
||||||
|
chinese: "我转身看向孩子们。",
|
||||||
|
prononciation: "aɪ tɜːrnd tuː lʊk æt ðə ˈtʃɪldrən"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
english: "They were playing football, not polo!",
|
||||||
|
chinese: "他们在踢足球,不是水球!",
|
||||||
|
prononciation: "ðeɪ wər ˈpleɪɪŋ ˈfʊtbɔːl nɑːt ˈpoʊloʊ"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
story: {
|
||||||
|
title: "Football or polo? - 足球还是水球?",
|
||||||
|
totalSentences: 12,
|
||||||
|
chapters: [
|
||||||
|
{
|
||||||
|
title: "Chapter 1: A Day by the River - 河边的一天",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
original: "The Wayle is a small river that cuts across the park near my home.",
|
||||||
|
translation: "威尔河是横穿我家附近公园的一条小河。",
|
||||||
|
words: [
|
||||||
|
{word: "The", translation: "这条", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "Wayle", translation: "威尔河", type: "noun", pronunciation: "weɪl"},
|
||||||
|
{word: "is", translation: "是", type: "verb", pronunciation: "ɪz"},
|
||||||
|
{word: "a", translation: "一条", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "small", translation: "小的", type: "adjective", pronunciation: "smɔːl"},
|
||||||
|
{word: "river", translation: "河流", type: "noun", pronunciation: "ˈrɪvər"},
|
||||||
|
{word: "that", translation: "那", type: "pronoun", pronunciation: "ðæt"},
|
||||||
|
{word: "cuts", translation: "穿过", type: "verb", pronunciation: "kʌts"},
|
||||||
|
{word: "across", translation: "横穿", type: "preposition", pronunciation: "əˈkrɔːs"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "park", translation: "公园", type: "noun", pronunciation: "pɑːrk"},
|
||||||
|
{word: "near", translation: "靠近", type: "preposition", pronunciation: "nɪr"},
|
||||||
|
{word: "my", translation: "我的", type: "pronoun", pronunciation: "maɪ"},
|
||||||
|
{word: "home", translation: "家", type: "noun", pronunciation: "hoʊm"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
original: "I like sitting by the Wayle on fine afternoons.",
|
||||||
|
translation: "我喜欢在天气晴朗的下午坐在威尔河边。",
|
||||||
|
words: [
|
||||||
|
{word: "I", translation: "我", type: "pronoun", pronunciation: "aɪ"},
|
||||||
|
{word: "like", translation: "喜欢", type: "verb", pronunciation: "laɪk"},
|
||||||
|
{word: "sitting", translation: "坐", type: "verb", pronunciation: "ˈsɪtɪŋ"},
|
||||||
|
{word: "by", translation: "在...旁边", type: "preposition", pronunciation: "baɪ"},
|
||||||
|
{word: "the", translation: "这条", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "Wayle", translation: "威尔河", type: "noun", pronunciation: "weɪl"},
|
||||||
|
{word: "on", translation: "在", type: "preposition", pronunciation: "ɒn"},
|
||||||
|
{word: "fine", translation: "晴朗的", type: "adjective", pronunciation: "faɪn"},
|
||||||
|
{word: "afternoons", translation: "下午", type: "noun", pronunciation: "ˌæftərˈnuːnz"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
original: "It was warm last Sunday, so I went and sat on the river bank as usual.",
|
||||||
|
translation: "上星期日天气很暖和,于是我像往常一样又去河边坐坐。",
|
||||||
|
words: [
|
||||||
|
{word: "It", translation: "天气", type: "pronoun", pronunciation: "ɪt"},
|
||||||
|
{word: "was", translation: "是", type: "verb", pronunciation: "wəz"},
|
||||||
|
{word: "warm", translation: "暖和的", type: "adjective", pronunciation: "wɔːrm"},
|
||||||
|
{word: "last", translation: "上", type: "adjective", pronunciation: "læst"},
|
||||||
|
{word: "Sunday", translation: "星期日", type: "noun", pronunciation: "ˈsʌndeɪ"},
|
||||||
|
{word: "so", translation: "所以", type: "conjunction", pronunciation: "soʊ"},
|
||||||
|
{word: "I", translation: "我", type: "pronoun", pronunciation: "aɪ"},
|
||||||
|
{word: "went", translation: "去了", type: "verb", pronunciation: "went"},
|
||||||
|
{word: "and", translation: "和", type: "conjunction", pronunciation: "ænd"},
|
||||||
|
{word: "sat", translation: "坐", type: "verb", pronunciation: "sæt"},
|
||||||
|
{word: "on", translation: "在", type: "preposition", pronunciation: "ɒn"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "river", translation: "河", type: "noun", pronunciation: "ˈrɪvər"},
|
||||||
|
{word: "bank", translation: "岸边", type: "noun", pronunciation: "bæŋk"},
|
||||||
|
{word: "as", translation: "像", type: "adverb", pronunciation: "æz"},
|
||||||
|
{word: "usual", translation: "往常一样", type: "adjective", pronunciation: "ˈjuːʒuəl"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
original: "Some children were playing games on the bank and there were some people rowing on the river.",
|
||||||
|
translation: "河岸上有些孩子在玩耍,河面上有些人在划船。",
|
||||||
|
words: [
|
||||||
|
{word: "Some", translation: "一些", type: "determiner", pronunciation: "sʌm"},
|
||||||
|
{word: "children", translation: "孩子们", type: "noun", pronunciation: "ˈtʃɪldrən"},
|
||||||
|
{word: "were", translation: "正在", type: "verb", pronunciation: "wər"},
|
||||||
|
{word: "playing", translation: "玩", type: "verb", pronunciation: "ˈpleɪɪŋ"},
|
||||||
|
{word: "games", translation: "游戏", type: "noun", pronunciation: "ɡeɪmz"},
|
||||||
|
{word: "on", translation: "在", type: "preposition", pronunciation: "ɒn"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "bank", translation: "岸边", type: "noun", pronunciation: "bæŋk"},
|
||||||
|
{word: "and", translation: "和", type: "conjunction", pronunciation: "ænd"},
|
||||||
|
{word: "there", translation: "那里", type: "adverb", pronunciation: "ðer"},
|
||||||
|
{word: "were", translation: "有", type: "verb", pronunciation: "wər"},
|
||||||
|
{word: "some", translation: "一些", type: "determiner", pronunciation: "sʌm"},
|
||||||
|
{word: "people", translation: "人们", type: "noun", pronunciation: "ˈpiːpəl"},
|
||||||
|
{word: "rowing", translation: "划船", type: "verb", pronunciation: "ˈroʊɪŋ"},
|
||||||
|
{word: "on", translation: "在", type: "preposition", pronunciation: "ɒn"},
|
||||||
|
{word: "the", translation: "这条", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "river", translation: "河", type: "noun", pronunciation: "ˈrɪvər"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Chapter 2: The Ball Incident - 球的事件",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
original: "Suddenly, one of the children kicked a ball very hard and it went towards a passing boat.",
|
||||||
|
translation: "突然,一个孩子狠狠地踢了一脚球,球便向一条经过的小船飞去。",
|
||||||
|
words: [
|
||||||
|
{word: "Suddenly", translation: "突然", type: "adverb", pronunciation: "ˈsʌdənli"},
|
||||||
|
{word: "one", translation: "一个", type: "number", pronunciation: "wʌn"},
|
||||||
|
{word: "of", translation: "的", type: "preposition", pronunciation: "ʌv"},
|
||||||
|
{word: "the", translation: "这些", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "children", translation: "孩子们", type: "noun", pronunciation: "ˈtʃɪldrən"},
|
||||||
|
{word: "kicked", translation: "踢了", type: "verb", pronunciation: "kɪkt"},
|
||||||
|
{word: "a", translation: "一个", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "ball", translation: "球", type: "noun", pronunciation: "bɔːl"},
|
||||||
|
{word: "very", translation: "非常", type: "adverb", pronunciation: "ˈveri"},
|
||||||
|
{word: "hard", translation: "用力地", type: "adverb", pronunciation: "hɑːrd"},
|
||||||
|
{word: "and", translation: "并且", type: "conjunction", pronunciation: "ænd"},
|
||||||
|
{word: "it", translation: "它", type: "pronoun", pronunciation: "ɪt"},
|
||||||
|
{word: "went", translation: "飞去", type: "verb", pronunciation: "went"},
|
||||||
|
{word: "towards", translation: "朝向", type: "preposition", pronunciation: "təˈwɔːrdz"},
|
||||||
|
{word: "a", translation: "一条", type: "article", pronunciation: "ə"},
|
||||||
|
{word: "passing", translation: "经过的", type: "adjective", pronunciation: "ˈpæsɪŋ"},
|
||||||
|
{word: "boat", translation: "船", type: "noun", pronunciation: "boʊt"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
original: "Some people on the bank called out to the man in the boat, but he did not hear them.",
|
||||||
|
translation: "岸上的一些人对船上的人高喊,但他没有听见。",
|
||||||
|
words: [
|
||||||
|
{word: "Some", translation: "一些", type: "determiner", pronunciation: "sʌm"},
|
||||||
|
{word: "people", translation: "人们", type: "noun", pronunciation: "ˈpiːpəl"},
|
||||||
|
{word: "on", translation: "在", type: "preposition", pronunciation: "ɒn"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "bank", translation: "岸上", type: "noun", pronunciation: "bæŋk"},
|
||||||
|
{word: "called", translation: "叫喊", type: "verb", pronunciation: "kɔːld"},
|
||||||
|
{word: "out", translation: "出来", type: "adverb", pronunciation: "aʊt"},
|
||||||
|
{word: "to", translation: "对", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "man", translation: "人", type: "noun", pronunciation: "mæn"},
|
||||||
|
{word: "in", translation: "在", type: "preposition", pronunciation: "ɪn"},
|
||||||
|
{word: "the", translation: "这条", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "boat", translation: "船上", type: "noun", pronunciation: "boʊt"},
|
||||||
|
{word: "but", translation: "但是", type: "conjunction", pronunciation: "bʌt"},
|
||||||
|
{word: "he", translation: "他", type: "pronoun", pronunciation: "hiː"},
|
||||||
|
{word: "did", translation: "助动词", type: "auxiliary", pronunciation: "dɪd"},
|
||||||
|
{word: "not", translation: "不", type: "adverb", pronunciation: "nɑːt"},
|
||||||
|
{word: "hear", translation: "听见", type: "verb", pronunciation: "hɪr"},
|
||||||
|
{word: "them", translation: "他们", type: "pronoun", pronunciation: "ðem"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
original: "The ball struck him so hard that he nearly fell into the water.",
|
||||||
|
translation: "球重重地打在他身上,使他差点儿落入水中。",
|
||||||
|
words: [
|
||||||
|
{word: "The", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "ball", translation: "球", type: "noun", pronunciation: "bɔːl"},
|
||||||
|
{word: "struck", translation: "击打", type: "verb", pronunciation: "strʌk"},
|
||||||
|
{word: "him", translation: "他", type: "pronoun", pronunciation: "hɪm"},
|
||||||
|
{word: "so", translation: "如此", type: "adverb", pronunciation: "soʊ"},
|
||||||
|
{word: "hard", translation: "用力", type: "adverb", pronunciation: "hɑːrd"},
|
||||||
|
{word: "that", translation: "以至于", type: "conjunction", pronunciation: "ðæt"},
|
||||||
|
{word: "he", translation: "他", type: "pronoun", pronunciation: "hiː"},
|
||||||
|
{word: "nearly", translation: "几乎", type: "adverb", pronunciation: "ˈnɪrli"},
|
||||||
|
{word: "fell", translation: "落下", type: "verb", pronunciation: "fel"},
|
||||||
|
{word: "into", translation: "进入", type: "preposition", pronunciation: "ˈɪntuː"},
|
||||||
|
{word: "the", translation: "这", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "water", translation: "水中", type: "noun", pronunciation: "ˈwɔːtər"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
original: "I turned to look at the children, but there weren't any in sight: they had all run away!",
|
||||||
|
translation: "我转过头去看那些孩子,但一个也不见,全都跑了!",
|
||||||
|
words: [
|
||||||
|
{word: "I", translation: "我", type: "pronoun", pronunciation: "aɪ"},
|
||||||
|
{word: "turned", translation: "转身", type: "verb", pronunciation: "tɜːrnd"},
|
||||||
|
{word: "to", translation: "去", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "look", translation: "看", type: "verb", pronunciation: "lʊk"},
|
||||||
|
{word: "at", translation: "看", type: "preposition", pronunciation: "æt"},
|
||||||
|
{word: "the", translation: "这些", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "children", translation: "孩子们", type: "noun", pronunciation: "ˈtʃɪldrən"},
|
||||||
|
{word: "but", translation: "但是", type: "conjunction", pronunciation: "bʌt"},
|
||||||
|
{word: "there", translation: "那里", type: "adverb", pronunciation: "ðer"},
|
||||||
|
{word: "weren't", translation: "没有", type: "verb", pronunciation: "wərnt"},
|
||||||
|
{word: "any", translation: "任何", type: "determiner", pronunciation: "ˈeni"},
|
||||||
|
{word: "in", translation: "在", type: "preposition", pronunciation: "ɪn"},
|
||||||
|
{word: "sight", translation: "视线中", type: "noun", pronunciation: "saɪt"},
|
||||||
|
{word: "they", translation: "他们", type: "pronoun", pronunciation: "ðeɪ"},
|
||||||
|
{word: "had", translation: "已经", type: "auxiliary", pronunciation: "hæd"},
|
||||||
|
{word: "all", translation: "全部", type: "adverb", pronunciation: "ɔːl"},
|
||||||
|
{word: "run", translation: "跑", type: "verb", pronunciation: "rʌn"},
|
||||||
|
{word: "away", translation: "走了", type: "adverb", pronunciation: "əˈweɪ"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Chapter 3: The Happy Ending - 愉快的结局",
|
||||||
|
sentences: [
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
original: "The man laughed when he realized what had happened.",
|
||||||
|
translation: "当那个人明白了发生的事情时,笑了。",
|
||||||
|
words: [
|
||||||
|
{word: "The", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "man", translation: "人", type: "noun", pronunciation: "mæn"},
|
||||||
|
{word: "laughed", translation: "笑了", type: "verb", pronunciation: "læft"},
|
||||||
|
{word: "when", translation: "当", type: "conjunction", pronunciation: "wen"},
|
||||||
|
{word: "he", translation: "他", type: "pronoun", pronunciation: "hiː"},
|
||||||
|
{word: "realized", translation: "意识到", type: "verb", pronunciation: "ˈriəlaɪzd"},
|
||||||
|
{word: "what", translation: "什么", type: "pronoun", pronunciation: "wʌt"},
|
||||||
|
{word: "had", translation: "已经", type: "auxiliary", pronunciation: "hæd"},
|
||||||
|
{word: "happened", translation: "发生了", type: "verb", pronunciation: "ˈhæpənd"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
original: "He called out to the children and threw the ball back to the bank.",
|
||||||
|
translation: "他大声叫那些孩子,把球扔回到岸上。",
|
||||||
|
words: [
|
||||||
|
{word: "He", translation: "他", type: "pronoun", pronunciation: "hiː"},
|
||||||
|
{word: "called", translation: "叫", type: "verb", pronunciation: "kɔːld"},
|
||||||
|
{word: "out", translation: "出来", type: "adverb", pronunciation: "aʊt"},
|
||||||
|
{word: "to", translation: "对", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "the", translation: "这些", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "children", translation: "孩子们", type: "noun", pronunciation: "ˈtʃɪldrən"},
|
||||||
|
{word: "and", translation: "并且", type: "conjunction", pronunciation: "ænd"},
|
||||||
|
{word: "threw", translation: "扔", type: "verb", pronunciation: "θruː"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "ball", translation: "球", type: "noun", pronunciation: "bɔːl"},
|
||||||
|
{word: "back", translation: "回", type: "adverb", pronunciation: "bæk"},
|
||||||
|
{word: "to", translation: "到", type: "preposition", pronunciation: "tuː"},
|
||||||
|
{word: "the", translation: "这个", type: "article", pronunciation: "ðə"},
|
||||||
|
{word: "bank", translation: "岸上", type: "noun", pronunciation: "bæŋk"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// === GRAMMAR-BASED FILL IN THE BLANKS ===
|
||||||
|
fillInBlanks: [
|
||||||
|
{
|
||||||
|
sentence: "_____ Wayle is a small river.",
|
||||||
|
options: ["The", "A", "An", "No article"],
|
||||||
|
correctAnswer: "The",
|
||||||
|
explanation: "River names always use 'the'",
|
||||||
|
grammarFocus: "articles-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "There were _____ people rowing on the river.",
|
||||||
|
options: ["some", "any", "a", "the"],
|
||||||
|
correctAnswer: "some",
|
||||||
|
explanation: "Use 'some' in positive statements",
|
||||||
|
grammarFocus: "some-any-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "There weren't _____ children in sight.",
|
||||||
|
options: ["some", "any", "a", "the"],
|
||||||
|
correctAnswer: "any",
|
||||||
|
explanation: "Use 'any' in negative statements",
|
||||||
|
grammarFocus: "some-any-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "The children _____ playing games on the bank.",
|
||||||
|
options: ["were", "was", "are", "is"],
|
||||||
|
correctAnswer: "were",
|
||||||
|
explanation: "Use 'were' with plural subjects in past continuous",
|
||||||
|
grammarFocus: "past-continuous"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "He lives in _____ England.",
|
||||||
|
options: ["the", "a", "an", "no article"],
|
||||||
|
correctAnswer: "no article",
|
||||||
|
explanation: "Most country names don't use articles",
|
||||||
|
grammarFocus: "articles-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sentence: "Are there _____ boats on the river?",
|
||||||
|
options: ["some", "any", "a", "the"],
|
||||||
|
correctAnswer: "any",
|
||||||
|
explanation: "Use 'any' in questions",
|
||||||
|
grammarFocus: "some-any-usage"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// === GRAMMAR CORRECTION EXERCISES ===
|
||||||
|
corrections: [
|
||||||
|
{
|
||||||
|
incorrect: "Wayle is small river.",
|
||||||
|
correct: "The Wayle is a small river.",
|
||||||
|
explanation: "River names need 'the' and countable nouns need 'a'",
|
||||||
|
grammarFocus: "articles-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "There were any children playing.",
|
||||||
|
correct: "There were some children playing.",
|
||||||
|
explanation: "Use 'some' in positive statements, not 'any'",
|
||||||
|
grammarFocus: "some-any-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "There wasn't some people in sight.",
|
||||||
|
correct: "There weren't any people in sight.",
|
||||||
|
explanation: "Use 'any' in negative statements, not 'some'",
|
||||||
|
grammarFocus: "some-any-usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
incorrect: "He goes to United States.",
|
||||||
|
correct: "He goes to the United States.",
|
||||||
|
explanation: "Some countries like 'the United States' require 'the'",
|
||||||
|
grammarFocus: "articles-usage"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// === COMPREHENSION QUESTIONS ===
|
||||||
|
comprehension: [
|
||||||
|
{
|
||||||
|
question: "Where does the writer like to sit?",
|
||||||
|
options: [
|
||||||
|
"In the park",
|
||||||
|
"By the Wayle river",
|
||||||
|
"On the boat",
|
||||||
|
"In his garden"
|
||||||
|
],
|
||||||
|
correct: "By the Wayle river",
|
||||||
|
explanation: "The writer says 'I like sitting by the Wayle on fine afternoons'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "What were the children doing?",
|
||||||
|
options: [
|
||||||
|
"Swimming in the river",
|
||||||
|
"Playing games on the bank",
|
||||||
|
"Rowing on the river",
|
||||||
|
"Sitting by the water"
|
||||||
|
],
|
||||||
|
correct: "Playing games on the bank",
|
||||||
|
explanation: "The text states 'Some children were playing games on the bank'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "Why didn't the man in the boat hear the people calling?",
|
||||||
|
options: [
|
||||||
|
"He was deaf",
|
||||||
|
"The text doesn't say why",
|
||||||
|
"He was sleeping",
|
||||||
|
"The water was too loud"
|
||||||
|
],
|
||||||
|
correct: "The text doesn't say why",
|
||||||
|
explanation: "The text only says 'he did not hear them' but doesn't give a reason"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "What happened after the ball hit the man?",
|
||||||
|
options: [
|
||||||
|
"He fell into the water",
|
||||||
|
"He got angry with the children",
|
||||||
|
"The children ran away",
|
||||||
|
"He threw the ball at the children"
|
||||||
|
],
|
||||||
|
correct: "The children ran away",
|
||||||
|
explanation: "The text says 'there weren't any in sight: they had all run away!'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "How did the story end?",
|
||||||
|
options: [
|
||||||
|
"The man was angry",
|
||||||
|
"The man called police",
|
||||||
|
"The man laughed and threw the ball back",
|
||||||
|
"The children came back"
|
||||||
|
],
|
||||||
|
correct: "The man laughed and threw the ball back",
|
||||||
|
explanation: "The text ends with 'The man laughed... threw the ball back to the bank'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONTENT STRUCTURE SUMMARY - FOR AI REFERENCE
|
||||||
|
// ============================================================================
|
||||||
|
//
|
||||||
|
// This module represents INTERMEDIATE level English learning content for Chinese speakers:
|
||||||
|
// - Focus on past tense narrative and descriptive language
|
||||||
|
// - Grammar emphasis on articles (the/a/an) and quantifiers (some/any)
|
||||||
|
// - Rich vocabulary around outdoor activities and everyday situations
|
||||||
|
// - Complex sentence structures with subordinate clauses
|
||||||
|
// - Cultural context of British/Western recreational activities
|
||||||
|
//
|
||||||
|
// LEARNING OBJECTIVES:
|
||||||
|
// - Master use of definite/indefinite articles with different noun types
|
||||||
|
// - Understand some/any usage in different sentence types
|
||||||
|
// - Practice past continuous vs simple past tense
|
||||||
|
// - Build vocabulary around outdoor activities and emotions
|
||||||
|
// - Develop reading comprehension of narrative texts
|
||||||
|
//
|
||||||
|
// DIFFICULTY INDICATORS:
|
||||||
|
// - Longer sentences with multiple clauses
|
||||||
|
// - Past perfect and continuous tenses
|
||||||
|
// - Abstract concepts (realization, consequences)
|
||||||
|
// - Cultural references (British countryside, recreational activities)
|
||||||
|
// - Advanced vocabulary (struck, realized, rowing, etc.)
|
||||||
|
//
|
||||||
|
// ============================================================================
|
||||||
@ -247,8 +247,8 @@ window.ContentModules.SBSLevel1 = {
|
|||||||
sentences: [
|
sentences: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
original: "Learn the alphabet: Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz",
|
original: "Learn the alphabet Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz",
|
||||||
translation: "学习字母表:Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz",
|
translation: "学习字母表 Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz",
|
||||||
words: [
|
words: [
|
||||||
{word: "Learn", translation: "学习", type: "verb", pronunciation: "/lɜrn/"},
|
{word: "Learn", translation: "学习", type: "verb", pronunciation: "/lɜrn/"},
|
||||||
{word: "alphabet", translation: "字母表", type: "noun", pronunciation: "/ˈælfəbet/"}
|
{word: "alphabet", translation: "字母表", type: "noun", pronunciation: "/ˈælfəbet/"}
|
||||||
@ -256,8 +256,8 @@ window.ContentModules.SBSLevel1 = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
original: "Practice numbers: 0 1 2 3 4 5 6 7 8 9 10",
|
original: "Practice numbers 0 1 2 3 4 5 6 7 8 9 10",
|
||||||
translation: "练习数字:0 1 2 3 4 5 6 7 8 9 10",
|
translation: "练习数字 0 1 2 3 4 5 6 7 8 9 10",
|
||||||
words: [
|
words: [
|
||||||
{word: "Practice", translation: "练习", type: "verb", pronunciation: "/ˈpræktɪs/"},
|
{word: "Practice", translation: "练习", type: "verb", pronunciation: "/ˈpræktɪs/"},
|
||||||
{word: "numbers", translation: "数字", type: "noun", pronunciation: "/ˈnʌmbərz/"}
|
{word: "numbers", translation: "数字", type: "noun", pronunciation: "/ˈnʌmbərz/"}
|
||||||
|
|||||||
1252
js/content/WTA1B1-documented.js
Normal file
1252
js/content/WTA1B1-documented.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,626 +0,0 @@
|
|||||||
// === VÉRIFICATEUR DE COMPATIBILITÉ CONTENU-JEU ===
|
|
||||||
|
|
||||||
class ContentGameCompatibility {
|
|
||||||
constructor() {
|
|
||||||
this.compatibilityCache = new Map();
|
|
||||||
this.minimumScores = {
|
|
||||||
'whack-a-mole': 40,
|
|
||||||
'whack-a-mole-hard': 45,
|
|
||||||
'memory-match': 50,
|
|
||||||
'quiz-game': 30,
|
|
||||||
'fill-the-blank': 30,
|
|
||||||
'adventure-reader': 50,
|
|
||||||
'chinese-study': 35,
|
|
||||||
'story-builder': 35,
|
|
||||||
'story-reader': 40,
|
|
||||||
'word-storm': 15,
|
|
||||||
'letter-discovery': 60
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vérifie si un contenu est compatible avec un jeu
|
|
||||||
* @param {Object} content - Le contenu à vérifier
|
|
||||||
* @param {string} gameType - Le type de jeu
|
|
||||||
* @returns {Object} - { compatible: boolean, score: number, reason: string, requirements: string[] }
|
|
||||||
*/
|
|
||||||
checkCompatibility(content, gameType) {
|
|
||||||
// Utiliser le cache si disponible
|
|
||||||
const cacheKey = `${content.id || content.name}_${gameType}`;
|
|
||||||
if (this.compatibilityCache.has(cacheKey)) {
|
|
||||||
return this.compatibilityCache.get(cacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
let result;
|
|
||||||
|
|
||||||
// Si le contenu a déjà une analyse de compatibilité (depuis ContentScanner)
|
|
||||||
if (content.gameCompatibility && content.gameCompatibility[gameType]) {
|
|
||||||
result = this.enrichCompatibilityInfo(content.gameCompatibility[gameType], gameType);
|
|
||||||
} else {
|
|
||||||
// Analyser manuellement
|
|
||||||
result = this.analyzeCompatibility(content, gameType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mettre en cache
|
|
||||||
this.compatibilityCache.set(cacheKey, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enrichit les informations de compatibilité existantes
|
|
||||||
*/
|
|
||||||
enrichCompatibilityInfo(existingCompat, gameType) {
|
|
||||||
const minScore = this.minimumScores[gameType] || 30;
|
|
||||||
return {
|
|
||||||
compatible: existingCompat.score >= minScore,
|
|
||||||
score: existingCompat.score,
|
|
||||||
reason: existingCompat.reason || this.getDefaultReason(gameType),
|
|
||||||
requirements: this.getGameRequirements(gameType),
|
|
||||||
details: this.getDetailedAnalysis(existingCompat, gameType)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyse manuelle de compatibilité si pas déjà calculée
|
|
||||||
*/
|
|
||||||
analyzeCompatibility(content, gameType) {
|
|
||||||
const capabilities = this.analyzeContentCapabilities(content);
|
|
||||||
const compatResult = this.calculateGameCompatibilityForType(capabilities, gameType);
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: compatResult.compatible,
|
|
||||||
score: compatResult.score,
|
|
||||||
reason: compatResult.reason,
|
|
||||||
requirements: this.getGameRequirements(gameType),
|
|
||||||
details: this.getDetailedAnalysis(compatResult, gameType),
|
|
||||||
capabilities: capabilities
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyse les capacités d'un contenu
|
|
||||||
*/
|
|
||||||
analyzeContentCapabilities(content) {
|
|
||||||
return {
|
|
||||||
hasVocabulary: this.hasContent(content, 'vocabulary'),
|
|
||||||
hasSentences: this.hasContent(content, 'sentences'),
|
|
||||||
hasGrammar: this.hasContent(content, 'grammar'),
|
|
||||||
hasAudio: this.hasContent(content, 'audio'),
|
|
||||||
hasDialogues: this.hasContent(content, 'dialogues'),
|
|
||||||
hasExercises: this.hasExercises(content),
|
|
||||||
hasFillInBlanks: this.hasContent(content, 'fillInBlanks'),
|
|
||||||
hasCorrections: this.hasContent(content, 'corrections'),
|
|
||||||
hasComprehension: this.hasContent(content, 'comprehension'),
|
|
||||||
hasMatching: this.hasContent(content, 'matching'),
|
|
||||||
hasLetters: this.hasContent(content, 'letters'),
|
|
||||||
|
|
||||||
// Compteurs
|
|
||||||
vocabularyCount: this.countItems(content, 'vocabulary'),
|
|
||||||
sentenceCount: this.countItems(content, 'sentences'),
|
|
||||||
dialogueCount: this.countItems(content, 'dialogues'),
|
|
||||||
grammarCount: this.countItems(content, 'grammar'),
|
|
||||||
letterCount: this.countItems(content, 'letters'),
|
|
||||||
letterWordsCount: this.calculateAverageWordsPerLetter(content)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calcule la compatibilité pour un type de jeu spécifique
|
|
||||||
*/
|
|
||||||
calculateGameCompatibilityForType(capabilities, gameType) {
|
|
||||||
switch (gameType) {
|
|
||||||
case 'whack-a-mole':
|
|
||||||
case 'whack-a-mole-hard':
|
|
||||||
return this.calculateWhackAMoleCompat(capabilities, gameType === 'whack-a-mole-hard');
|
|
||||||
|
|
||||||
case 'memory-match':
|
|
||||||
return this.calculateMemoryMatchCompat(capabilities);
|
|
||||||
|
|
||||||
case 'quiz-game':
|
|
||||||
return this.calculateQuizGameCompat(capabilities);
|
|
||||||
|
|
||||||
case 'fill-the-blank':
|
|
||||||
return this.calculateFillBlankCompat(capabilities);
|
|
||||||
|
|
||||||
case 'story-reader':
|
|
||||||
return this.calculateTextReaderCompat(capabilities);
|
|
||||||
|
|
||||||
case 'adventure-reader':
|
|
||||||
return this.calculateAdventureCompat(capabilities);
|
|
||||||
|
|
||||||
case 'chinese-study':
|
|
||||||
return this.calculateChineseStudyCompat(capabilities);
|
|
||||||
|
|
||||||
case 'story-builder':
|
|
||||||
return this.calculateStoryBuilderCompat(capabilities);
|
|
||||||
|
|
||||||
case 'word-storm':
|
|
||||||
return this.calculateWordStormCompat(capabilities);
|
|
||||||
|
|
||||||
case 'letter-discovery':
|
|
||||||
return this.calculateLetterDiscoveryCompat(capabilities);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return { compatible: true, score: 50, reason: 'Jeu non spécifiquement analysé' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// === CALCULS DE COMPATIBILITÉ SPÉCIFIQUES PAR JEU ===
|
|
||||||
|
|
||||||
calculateWhackAMoleCompat(capabilities, isHard = false) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasVocabulary && capabilities.vocabularyCount >= 5) {
|
|
||||||
score += 40;
|
|
||||||
reasons.push(`${capabilities.vocabularyCount} mots de vocabulaire`);
|
|
||||||
} else if (capabilities.vocabularyCount > 0) {
|
|
||||||
score += 20;
|
|
||||||
reasons.push(`${capabilities.vocabularyCount} mots (minimum recommandé: 5)`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capabilities.hasSentences && capabilities.sentenceCount >= 3) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push(`${capabilities.sentenceCount} phrases`);
|
|
||||||
} else if (capabilities.sentenceCount > 0) {
|
|
||||||
score += 15;
|
|
||||||
reasons.push(`${capabilities.sentenceCount} phrases (minimum recommandé: 3)`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capabilities.hasAudio) {
|
|
||||||
score += 20;
|
|
||||||
reasons.push('Fichiers audio disponibles');
|
|
||||||
}
|
|
||||||
|
|
||||||
const minScore = isHard ? 45 : 40;
|
|
||||||
const compatible = score >= minScore;
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible,
|
|
||||||
score,
|
|
||||||
reason: compatible ?
|
|
||||||
`Compatible: ${reasons.join(', ')}` :
|
|
||||||
`Incompatible (score: ${score}/${minScore}): Nécessite plus de vocabulaire ou phrases`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateMemoryMatchCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasVocabulary && capabilities.vocabularyCount >= 4) {
|
|
||||||
score += 50;
|
|
||||||
reasons.push(`${capabilities.vocabularyCount} paires de vocabulaire`);
|
|
||||||
} else {
|
|
||||||
return { compatible: false, score: 0, reason: 'Nécessite au moins 4 mots de vocabulaire' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capabilities.hasAudio) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push('Audio pour pronunciation');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 50,
|
|
||||||
score,
|
|
||||||
reason: `Compatible: ${reasons.join(', ')}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateQuizGameCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
// Quiz est très flexible
|
|
||||||
if (capabilities.hasVocabulary) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push('Questions de vocabulaire');
|
|
||||||
}
|
|
||||||
if (capabilities.hasGrammar) {
|
|
||||||
score += 25;
|
|
||||||
reasons.push('Questions de grammaire');
|
|
||||||
}
|
|
||||||
if (capabilities.hasSentences) {
|
|
||||||
score += 20;
|
|
||||||
reasons.push('Questions sur les phrases');
|
|
||||||
}
|
|
||||||
if (capabilities.hasExercises) {
|
|
||||||
score += 45;
|
|
||||||
reasons.push('Exercices intégrés');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz fonctionne avec presque tout
|
|
||||||
if (score === 0 && (capabilities.vocabularyCount > 0 || capabilities.sentenceCount > 0)) {
|
|
||||||
score = 30;
|
|
||||||
reasons.push('Contenu de base disponible');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 30,
|
|
||||||
score,
|
|
||||||
reason: `Compatible: ${reasons.join(', ')}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateFillBlankCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasFillInBlanks) {
|
|
||||||
score += 70;
|
|
||||||
reasons.push('Exercices à trous intégrés');
|
|
||||||
} else if (capabilities.hasSentences && capabilities.sentenceCount >= 3) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push('Phrases pouvant être adaptées en exercices à trous');
|
|
||||||
} else {
|
|
||||||
return { compatible: false, score: 0, reason: 'Nécessite des phrases ou exercices à trous' };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 30,
|
|
||||||
score,
|
|
||||||
reason: `Compatible: ${reasons.join(', ')}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateTextReaderCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasSentences && capabilities.sentenceCount >= 3) {
|
|
||||||
score += 40;
|
|
||||||
reasons.push(`${capabilities.sentenceCount} phrases à lire`);
|
|
||||||
}
|
|
||||||
if (capabilities.hasDialogues && capabilities.dialogueCount > 0) {
|
|
||||||
score += 50;
|
|
||||||
reasons.push(`${capabilities.dialogueCount} dialogues`);
|
|
||||||
}
|
|
||||||
if (capabilities.hasAudio) {
|
|
||||||
score += 10;
|
|
||||||
reasons.push('Audio disponible');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 40,
|
|
||||||
score,
|
|
||||||
reason: score >= 40 ? `Compatible: ${reasons.join(', ')}` : 'Nécessite des phrases ou dialogues à lire'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateAdventureCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasDialogues && capabilities.dialogueCount > 0) {
|
|
||||||
score += 60;
|
|
||||||
reasons.push('Dialogues pour narration');
|
|
||||||
}
|
|
||||||
if (capabilities.hasSentences && capabilities.sentenceCount >= 5) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push('Contenu narratif suffisant');
|
|
||||||
}
|
|
||||||
if (capabilities.hasVocabulary && capabilities.vocabularyCount >= 10) {
|
|
||||||
score += 10;
|
|
||||||
reasons.push('Vocabulaire riche');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 50,
|
|
||||||
score,
|
|
||||||
reason: score >= 50 ? `Compatible: ${reasons.join(', ')}` : 'Nécessite plus de dialogues et contenu narratif'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateChineseStudyCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasVocabulary) {
|
|
||||||
score += 35;
|
|
||||||
reasons.push('Vocabulaire chinois');
|
|
||||||
}
|
|
||||||
if (capabilities.hasSentences) {
|
|
||||||
score += 25;
|
|
||||||
reasons.push('Phrases chinoises');
|
|
||||||
}
|
|
||||||
if (capabilities.hasAudio) {
|
|
||||||
score += 40;
|
|
||||||
reasons.push('Prononciation audio');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 35,
|
|
||||||
score,
|
|
||||||
reason: score >= 35 ? `Compatible: ${reasons.join(', ')}` : 'Optimisé pour contenu chinois'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateStoryBuilderCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
if (capabilities.hasDialogues) {
|
|
||||||
score += 40;
|
|
||||||
reasons.push('Dialogues pour construction');
|
|
||||||
}
|
|
||||||
if (capabilities.hasSentences && capabilities.sentenceCount >= 5) {
|
|
||||||
score += 35;
|
|
||||||
reasons.push('Phrases pour séquences');
|
|
||||||
}
|
|
||||||
if (capabilities.hasVocabulary && capabilities.vocabularyCount >= 8) {
|
|
||||||
score += 25;
|
|
||||||
reasons.push('Vocabulaire varié');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 35,
|
|
||||||
score,
|
|
||||||
reason: score >= 35 ? `Compatible: ${reasons.join(', ')}` : 'Nécessite contenu pour construction narrative'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateWordStormCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
// Word Storm nécessite principalement du vocabulaire
|
|
||||||
if (capabilities.hasVocabulary && capabilities.vocabularyCount >= 5) {
|
|
||||||
score += 60;
|
|
||||||
reasons.push(`${capabilities.vocabularyCount} mots de vocabulaire`);
|
|
||||||
} else if (capabilities.vocabularyCount > 0) {
|
|
||||||
score += 30;
|
|
||||||
reasons.push(`${capabilities.vocabularyCount} mots (peu mais suffisant)`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bonus pour plus de vocabulaire
|
|
||||||
if (capabilities.vocabularyCount >= 20) {
|
|
||||||
score += 15;
|
|
||||||
reasons.push('Vocabulaire riche');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bonus si les mots ont des prononciations
|
|
||||||
if (capabilities.hasPronunciation) {
|
|
||||||
score += 10;
|
|
||||||
reasons.push('Prononciations disponibles');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Word Storm peut fonctionner même avec peu de contenu
|
|
||||||
if (score === 0 && (capabilities.hasSentences || capabilities.hasDialogues)) {
|
|
||||||
score = 25;
|
|
||||||
reasons.push('Peut extraire vocabulaire des phrases/dialogues');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 15,
|
|
||||||
score,
|
|
||||||
reason: score >= 15 ? `Compatible: ${reasons.join(', ')}` : 'Nécessite au moins quelques mots de vocabulaire'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateLetterDiscoveryCompat(capabilities) {
|
|
||||||
let score = 0;
|
|
||||||
const reasons = [];
|
|
||||||
|
|
||||||
// Letter Discovery requires predefined letters structure
|
|
||||||
if (capabilities.hasLetters) {
|
|
||||||
score += 80;
|
|
||||||
const letterCount = capabilities.letterCount || 'unknown';
|
|
||||||
reasons.push(`Structure de lettres prédéfinie (${letterCount} lettres)`);
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
compatible: false,
|
|
||||||
score: 0,
|
|
||||||
reason: 'Nécessite une structure de lettres prédéfinie (content.letters)'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bonus for well-structured letter content
|
|
||||||
if (capabilities.letterWordsCount && capabilities.letterWordsCount >= 3) {
|
|
||||||
score += 20;
|
|
||||||
reasons.push(`${capabilities.letterWordsCount} mots par lettre en moyenne`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
compatible: score >= 60,
|
|
||||||
score,
|
|
||||||
reason: score >= 60 ? `Compatible: ${reasons.join(', ')}` : 'Structure de lettres insuffisante'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// === UTILITAIRES ===
|
|
||||||
|
|
||||||
hasContent(content, type) {
|
|
||||||
// Vérification standard
|
|
||||||
const data = content[type] || content.rawContent?.[type] || content.adaptedContent?.[type];
|
|
||||||
if (data) {
|
|
||||||
if (Array.isArray(data)) return data.length > 0;
|
|
||||||
if (typeof data === 'object') return Object.keys(data).length > 0;
|
|
||||||
return !!data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support pour formats spéciaux
|
|
||||||
if (type === 'sentences' && content.story?.chapters) {
|
|
||||||
// Format story avec chapitres (comme Dragon's Pearl)
|
|
||||||
return content.story.chapters.some(chapter =>
|
|
||||||
chapter.sentences && chapter.sentences.length > 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'dialogues' && content.story?.chapters) {
|
|
||||||
// Vérifier s'il y a du contenu narratif riche dans les stories
|
|
||||||
return content.story.chapters.length > 1; // Multiple chapitres = contenu narratif
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasExercises(content) {
|
|
||||||
return this.hasContent(content, 'exercises') ||
|
|
||||||
this.hasContent(content, 'fillInBlanks') ||
|
|
||||||
this.hasContent(content, 'corrections') ||
|
|
||||||
this.hasContent(content, 'comprehension') ||
|
|
||||||
this.hasContent(content, 'matching');
|
|
||||||
}
|
|
||||||
|
|
||||||
countItems(content, type) {
|
|
||||||
// Vérification standard
|
|
||||||
const data = content[type] || content.rawContent?.[type] || content.adaptedContent?.[type];
|
|
||||||
if (data) {
|
|
||||||
if (Array.isArray(data)) return data.length;
|
|
||||||
if (typeof data === 'object') return Object.keys(data).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support pour formats spéciaux
|
|
||||||
if (type === 'sentences' && content.story?.chapters) {
|
|
||||||
// Compter toutes les phrases dans tous les chapitres
|
|
||||||
return content.story.chapters.reduce((total, chapter) =>
|
|
||||||
total + (chapter.sentences ? chapter.sentences.length : 0), 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'dialogues' && content.story?.chapters) {
|
|
||||||
// Considérer chaque chapitre comme un "dialogue" narratif
|
|
||||||
return content.story.chapters.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'vocabulary') {
|
|
||||||
// Vérifier d'abord le format standard
|
|
||||||
const vocab = content.vocabulary || content.rawContent?.vocabulary || content.adaptedContent?.vocabulary;
|
|
||||||
if (vocab) {
|
|
||||||
if (Array.isArray(vocab)) return vocab.length;
|
|
||||||
if (typeof vocab === 'object') return Object.keys(vocab).length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateAverageWordsPerLetter(content) {
|
|
||||||
const letters = content.letters || content.rawContent?.letters || content.adaptedContent?.letters;
|
|
||||||
if (!letters || typeof letters !== 'object') return 0;
|
|
||||||
|
|
||||||
let totalWords = 0;
|
|
||||||
let letterCount = 0;
|
|
||||||
|
|
||||||
Object.values(letters).forEach(letterWords => {
|
|
||||||
if (Array.isArray(letterWords)) {
|
|
||||||
totalWords += letterWords.length;
|
|
||||||
letterCount++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return letterCount > 0 ? Math.round(totalWords / letterCount) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getGameRequirements(gameType) {
|
|
||||||
const requirements = {
|
|
||||||
'whack-a-mole': ['5+ mots de vocabulaire OU 3+ phrases', 'Contenu simple et répétitif'],
|
|
||||||
'whack-a-mole-hard': ['5+ mots de vocabulaire ET 3+ phrases', 'Contenu varié'],
|
|
||||||
'memory-match': ['4+ paires de vocabulaire', 'Idéalement avec images/audio'],
|
|
||||||
'quiz-game': ['Vocabulaire OU phrases OU exercices', 'Très flexible'],
|
|
||||||
'fill-the-blank': ['Phrases avec exercices à trous OU phrases simples', 'Contenu éducatif'],
|
|
||||||
'adventure-reader': ['Dialogues + contenu narratif riche', 'Histoire cohérente'],
|
|
||||||
'chinese-study': ['Vocabulaire et phrases chinoises', 'Audio recommandé'],
|
|
||||||
'story-builder': ['Dialogues OU 5+ phrases', 'Vocabulaire varié'],
|
|
||||||
'story-reader': ['Textes à lire, dialogues recommandés', 'Contenu narratif'],
|
|
||||||
'word-storm': ['3+ mots de vocabulaire', 'Prononciations recommandées'],
|
|
||||||
'letter-discovery': ['Structure de lettres prédéfinie (content.letters)', 'Lettres avec mots associés']
|
|
||||||
};
|
|
||||||
|
|
||||||
return requirements[gameType] || ['Contenu de base'];
|
|
||||||
}
|
|
||||||
|
|
||||||
getDefaultReason(gameType) {
|
|
||||||
const reasons = {
|
|
||||||
'whack-a-mole': 'Jeu de rapidité nécessitant vocabulaire ou phrases',
|
|
||||||
'memory-match': 'Jeu de mémoire optimisé pour paires vocabulaire-traduction',
|
|
||||||
'quiz-game': 'Jeu polyvalent compatible avec la plupart des contenus',
|
|
||||||
'fill-the-blank': 'Exercices à trous nécessitant phrases structurées',
|
|
||||||
'adventure-reader': 'Aventure narrative nécessitant contenu riche',
|
|
||||||
'chinese-study': 'Optimisé pour apprentissage du chinois',
|
|
||||||
'story-builder': 'Construction narrative nécessitant éléments variés',
|
|
||||||
'story-reader': 'Lecture d\'histoires nécessitant contenu narratif',
|
|
||||||
'letter-discovery': 'Apprentissage par lettres nécessitant structure prédéfinie'
|
|
||||||
};
|
|
||||||
|
|
||||||
return reasons[gameType] || 'Compatibilité non évaluée spécifiquement';
|
|
||||||
}
|
|
||||||
|
|
||||||
getDetailedAnalysis(compatResult, gameType) {
|
|
||||||
return {
|
|
||||||
minimumScore: this.minimumScores[gameType] || 30,
|
|
||||||
actualScore: compatResult.score,
|
|
||||||
recommendation: compatResult.score >= (this.minimumScores[gameType] || 30) ?
|
|
||||||
'Fortement recommandé' :
|
|
||||||
compatResult.score >= (this.minimumScores[gameType] || 30) * 0.7 ?
|
|
||||||
'Compatible avec limitations' :
|
|
||||||
'Non recommandé'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filtre une liste de contenus pour un jeu spécifique
|
|
||||||
* @param {Array} contentList - Liste des contenus
|
|
||||||
* @param {string} gameType - Type de jeu
|
|
||||||
* @returns {Array} - Contenus compatibles triés par score
|
|
||||||
*/
|
|
||||||
filterCompatibleContent(contentList, gameType) {
|
|
||||||
return contentList
|
|
||||||
.map(content => ({
|
|
||||||
...content,
|
|
||||||
compatibility: this.checkCompatibility(content, gameType)
|
|
||||||
}))
|
|
||||||
.filter(content => content.compatibility.compatible)
|
|
||||||
.sort((a, b) => b.compatibility.score - a.compatibility.score);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtient des suggestions d'amélioration pour rendre un contenu compatible
|
|
||||||
* @param {Object} content - Le contenu à analyser
|
|
||||||
* @param {string} gameType - Le type de jeu
|
|
||||||
* @returns {Array} - Liste de suggestions
|
|
||||||
*/
|
|
||||||
getImprovementSuggestions(content, gameType) {
|
|
||||||
const compatibility = this.checkCompatibility(content, gameType);
|
|
||||||
if (compatibility.compatible) return [];
|
|
||||||
|
|
||||||
const suggestions = [];
|
|
||||||
const capabilities = compatibility.capabilities || this.analyzeContentCapabilities(content);
|
|
||||||
|
|
||||||
switch (gameType) {
|
|
||||||
case 'whack-a-mole':
|
|
||||||
case 'whack-a-mole-hard':
|
|
||||||
if (capabilities.vocabularyCount < 5) {
|
|
||||||
suggestions.push(`Ajouter ${5 - capabilities.vocabularyCount} mots de vocabulaire supplémentaires`);
|
|
||||||
}
|
|
||||||
if (capabilities.sentenceCount < 3) {
|
|
||||||
suggestions.push(`Ajouter ${3 - capabilities.sentenceCount} phrases supplémentaires`);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'memory-match':
|
|
||||||
if (capabilities.vocabularyCount < 4) {
|
|
||||||
suggestions.push(`Ajouter ${4 - capabilities.vocabularyCount} paires de vocabulaire supplémentaires`);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Autres cas...
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suggestions.length === 0) {
|
|
||||||
suggestions.push('Enrichir le contenu général du module');
|
|
||||||
}
|
|
||||||
|
|
||||||
return suggestions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vide le cache de compatibilité
|
|
||||||
*/
|
|
||||||
clearCache() {
|
|
||||||
this.compatibilityCache.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export global
|
|
||||||
window.ContentGameCompatibility = ContentGameCompatibility;
|
|
||||||
@ -26,13 +26,17 @@ class ContentScanner {
|
|||||||
|
|
||||||
for (const filename of contentFiles) {
|
for (const filename of contentFiles) {
|
||||||
try {
|
try {
|
||||||
|
logSh(`🔍 Scanning content file: ${filename}`, 'DEBUG');
|
||||||
const contentInfo = await this.scanContentFile(filename);
|
const contentInfo = await this.scanContentFile(filename);
|
||||||
if (contentInfo) {
|
if (contentInfo) {
|
||||||
|
logSh(`✅ Successfully scanned: ${contentInfo.id} (${contentInfo.name})`, 'INFO');
|
||||||
this.discoveredContent.set(contentInfo.id, contentInfo);
|
this.discoveredContent.set(contentInfo.id, contentInfo);
|
||||||
results.found.push(contentInfo);
|
results.found.push(contentInfo);
|
||||||
|
} else {
|
||||||
|
logSh(`⚠️ scanContentFile returned null for ${filename}`, 'WARN');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logSh(`⚠️ Erreur scan ${filename}:`, error.message, 'WARN');
|
logSh(`⚠️ Erreur scan ${filename}: ${error.message}`, 'WARN');
|
||||||
results.errors.push({ filename, error: error.message });
|
results.errors.push({ filename, error: error.message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +114,10 @@ class ContentScanner {
|
|||||||
'story-prototype-optimized.js', // Optimized story with centralized vocabulary
|
'story-prototype-optimized.js', // Optimized story with centralized vocabulary
|
||||||
'test-compatibility.js', // Test content for compatibility system
|
'test-compatibility.js', // Test content for compatibility system
|
||||||
'test-minimal.js', // Minimal test content
|
'test-minimal.js', // Minimal test content
|
||||||
'test-rich.js' // Rich test content
|
'test-rich.js', // Rich test content
|
||||||
|
'NCE1-Lesson63-64.js', // New Concept English Book 1 - Lessons 63-64
|
||||||
|
'NCE2-Lesson3.js', // New Concept English Book 2 - Lesson 3
|
||||||
|
'NCE2-Lesson30.js' // New Concept English Book 2 - Lesson 30
|
||||||
];
|
];
|
||||||
|
|
||||||
logSh('📂 Préchargement des fichiers connus...', 'INFO');
|
logSh('📂 Préchargement des fichiers connus...', 'INFO');
|
||||||
@ -259,14 +266,26 @@ class ContentScanner {
|
|||||||
const loadedFiles = [];
|
const loadedFiles = [];
|
||||||
|
|
||||||
if (window.ContentModules) {
|
if (window.ContentModules) {
|
||||||
|
logSh(`📂 Modules already loaded in window.ContentModules:`, 'DEBUG');
|
||||||
for (const moduleName in window.ContentModules) {
|
for (const moduleName in window.ContentModules) {
|
||||||
// Convertir le nom du module en nom de fichier probable
|
// Convertir le nom du module en nom de fichier probable
|
||||||
const filename = this.moduleNameToFilename(moduleName);
|
const filename = this.moduleNameToFilename(moduleName);
|
||||||
loadedFiles.push(filename);
|
loadedFiles.push(filename);
|
||||||
logSh(`✓ Module découvert: ${moduleName} → ${filename}`, 'INFO');
|
logSh(`✓ Module découvert: ${moduleName} → ${filename}`, 'INFO');
|
||||||
|
|
||||||
|
// Debug : vérifier si le module a un id
|
||||||
|
const module = window.ContentModules[moduleName];
|
||||||
|
if (module.id) {
|
||||||
|
logSh(` Module ID: ${module.id}`, 'DEBUG');
|
||||||
|
} else {
|
||||||
|
logSh(` ⚠️ Module ${moduleName} has no ID!`, 'WARN');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logSh(`⚠️ window.ContentModules is undefined!`, 'WARN');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logSh(`📂 Total loaded files from modules: ${loadedFiles.length}`, 'INFO');
|
||||||
return loadedFiles;
|
return loadedFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +314,11 @@ class ContentScanner {
|
|||||||
// AJOUT: Test compatibility modules
|
// AJOUT: Test compatibility modules
|
||||||
'TestMinimalContent': 'test-compatibility.js',
|
'TestMinimalContent': 'test-compatibility.js',
|
||||||
'TestRichContent': 'test-compatibility.js',
|
'TestRichContent': 'test-compatibility.js',
|
||||||
'TestSentenceOnly': 'test-compatibility.js'
|
'TestSentenceOnly': 'test-compatibility.js',
|
||||||
|
// AJOUT: NCE modules
|
||||||
|
'NCE1Lesson6364': 'NCE1-Lesson63-64.js',
|
||||||
|
'NCE2Lesson3': 'NCE2-Lesson3.js',
|
||||||
|
'NCE2Lesson30': 'NCE2-Lesson30.js'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mapping[moduleName]) {
|
if (mapping[moduleName]) {
|
||||||
@ -339,7 +362,11 @@ class ContentScanner {
|
|||||||
'example-with-images.js', // Local JS with image support for Word Discovery
|
'example-with-images.js', // Local JS with image support for Word Discovery
|
||||||
// AJOUT: Fichiers générés par le système de conversion
|
// AJOUT: Fichiers générés par le système de conversion
|
||||||
'sbs-level-7-8-GENERATED-from-js.json',
|
'sbs-level-7-8-GENERATED-from-js.json',
|
||||||
'english-exemple-commented-GENERATED.json'
|
'english-exemple-commented-GENERATED.json',
|
||||||
|
// AJOUT: Fichiers NCE (New Concept English)
|
||||||
|
'NCE1-Lesson63-64.js', // New Concept English Book 1 - Lessons 63-64
|
||||||
|
'NCE2-Lesson3.js', // New Concept English Book 2 - Lesson 3
|
||||||
|
'NCE2-Lesson30.js' // New Concept English Book 2 - Lesson 30
|
||||||
];
|
];
|
||||||
|
|
||||||
const existingFiles = [];
|
const existingFiles = [];
|
||||||
@ -405,18 +432,24 @@ class ContentScanner {
|
|||||||
const moduleName = this.getModuleName(contentId);
|
const moduleName = this.getModuleName(contentId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Détecter le type de fichier et charger en conséquence
|
// Vérifier d'abord si le module est déjà chargé
|
||||||
if (filename.endsWith('.json')) {
|
|
||||||
// Fichier JSON - essayer de le charger via proxy ou local
|
|
||||||
await this.loadJsonContent(filename);
|
|
||||||
} else {
|
|
||||||
// Fichier JS - charger le script classique
|
|
||||||
await this.loadScript(`js/content/${filename}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifier si le module existe
|
|
||||||
if (!window.ContentModules || !window.ContentModules[moduleName]) {
|
if (!window.ContentModules || !window.ContentModules[moduleName]) {
|
||||||
throw new Error(`Module ${moduleName} non trouvé après chargement`);
|
// Le module n'est pas encore chargé, on doit le charger
|
||||||
|
// Détecter le type de fichier et charger en conséquence
|
||||||
|
if (filename.endsWith('.json')) {
|
||||||
|
// Fichier JSON - essayer de le charger via proxy ou local
|
||||||
|
await this.loadJsonContent(filename);
|
||||||
|
} else {
|
||||||
|
// Fichier JS - charger le script classique
|
||||||
|
await this.loadScript(`js/content/${filename}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier si le module existe après chargement
|
||||||
|
if (!window.ContentModules || !window.ContentModules[moduleName]) {
|
||||||
|
throw new Error(`Module ${moduleName} non trouvé après chargement`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logSh(`✓ Module ${moduleName} déjà chargé, pas besoin de recharger`, 'INFO');
|
||||||
}
|
}
|
||||||
|
|
||||||
const module = window.ContentModules[moduleName];
|
const module = window.ContentModules[moduleName];
|
||||||
@ -434,7 +467,19 @@ class ContentScanner {
|
|||||||
|
|
||||||
extractContentInfo(module, contentId, filename) {
|
extractContentInfo(module, contentId, filename) {
|
||||||
// Analyser les capacités du contenu ultra-modulaire
|
// Analyser les capacités du contenu ultra-modulaire
|
||||||
const capabilities = this.analyzeContentCapabilities(module);
|
let capabilities;
|
||||||
|
try {
|
||||||
|
capabilities = this.analyzeContentCapabilities(module);
|
||||||
|
} catch (error) {
|
||||||
|
logSh(`⚠️ Erreur dans analyzeContentCapabilities pour ${contentId}: ${error.message}`, 'WARN');
|
||||||
|
// Fallback avec capacités basiques
|
||||||
|
capabilities = {
|
||||||
|
hasVocabulary: !!module.vocabulary,
|
||||||
|
hasSentences: !!module.sentences,
|
||||||
|
hasGrammar: !!module.grammar,
|
||||||
|
hasBasicContent: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: module.id || contentId,
|
id: module.id || contentId,
|
||||||
@ -453,8 +498,8 @@ class ContentScanner {
|
|||||||
|
|
||||||
// Content capabilities analysis
|
// Content capabilities analysis
|
||||||
capabilities: capabilities,
|
capabilities: capabilities,
|
||||||
compatibility: this.calculateGameCompatibility(capabilities),
|
compatibility: this.safeCalculateGameCompatibility(capabilities),
|
||||||
icon: this.getContentIcon(module, contentId),
|
icon: this.safeGetContentIcon(module, contentId),
|
||||||
difficulty: module.difficulty || 'medium',
|
difficulty: module.difficulty || 'medium',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|
||||||
@ -478,10 +523,37 @@ class ContentScanner {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Configuration pour les jeux
|
// Configuration pour les jeux
|
||||||
gameCompatibility: this.analyzeGameCompatibility(module)
|
gameCompatibility: this.safeAnalyzeGameCompatibility(module)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safeCalculateGameCompatibility(capabilities) {
|
||||||
|
try {
|
||||||
|
return this.calculateGameCompatibility(capabilities);
|
||||||
|
} catch (error) {
|
||||||
|
logSh(`⚠️ Erreur dans calculateGameCompatibility: ${error.message}`, 'WARN');
|
||||||
|
return {}; // Retourner un objet vide en cas d'erreur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safeGetContentIcon(module, contentId) {
|
||||||
|
try {
|
||||||
|
return this.getContentIcon(module, contentId);
|
||||||
|
} catch (error) {
|
||||||
|
logSh(`⚠️ Erreur dans getContentIcon: ${error.message}`, 'WARN');
|
||||||
|
return '📚'; // Icône par défaut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safeAnalyzeGameCompatibility(module) {
|
||||||
|
try {
|
||||||
|
return this.analyzeGameCompatibility(module);
|
||||||
|
} catch (error) {
|
||||||
|
logSh(`⚠️ Erreur dans analyzeGameCompatibility: ${error.message}`, 'WARN');
|
||||||
|
return {}; // Retourner un objet vide en cas d'erreur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extractContentId(filename) {
|
extractContentId(filename) {
|
||||||
return filename.replace('.js', '').toLowerCase();
|
return filename.replace('.js', '').toLowerCase();
|
||||||
}
|
}
|
||||||
@ -496,7 +568,11 @@ class ContentScanner {
|
|||||||
'story-prototype-optimized': 'StoryPrototypeOptimized',
|
'story-prototype-optimized': 'StoryPrototypeOptimized',
|
||||||
'test-compatibility': 'TestMinimalContent',
|
'test-compatibility': 'TestMinimalContent',
|
||||||
'test-minimal': 'TestMinimal',
|
'test-minimal': 'TestMinimal',
|
||||||
'test-rich': 'TestRich'
|
'test-rich': 'TestRich',
|
||||||
|
// Ajout des modules NCE
|
||||||
|
'nce1-lesson63-64': 'NCE1Lesson6364',
|
||||||
|
'nce2-lesson3': 'NCE2Lesson3',
|
||||||
|
'nce2-lesson30': 'NCE2Lesson30'
|
||||||
};
|
};
|
||||||
return mapping[contentId] || this.toPascalCase(contentId);
|
return mapping[contentId] || this.toPascalCase(contentId);
|
||||||
}
|
}
|
||||||
@ -742,7 +818,11 @@ class ContentScanner {
|
|||||||
'chinese-long-story': 'ChineseLongStory',
|
'chinese-long-story': 'ChineseLongStory',
|
||||||
'french-beginner-story': 'FrenchBeginnerStory',
|
'french-beginner-story': 'FrenchBeginnerStory',
|
||||||
'wta1b1': 'WTA1B1',
|
'wta1b1': 'WTA1B1',
|
||||||
'story-prototype-optimized': 'StoryPrototypeOptimized'
|
'story-prototype-optimized': 'StoryPrototypeOptimized',
|
||||||
|
// Ajout des modules NCE
|
||||||
|
'nce1-lesson63-64': 'NCE1Lesson6364',
|
||||||
|
'nce2-lesson3': 'NCE2Lesson3',
|
||||||
|
'nce2-lesson30': 'NCE2Lesson30'
|
||||||
};
|
};
|
||||||
|
|
||||||
return specialMappings[filename] || this.toPascalCase(filename);
|
return specialMappings[filename] || this.toPascalCase(filename);
|
||||||
|
|||||||
@ -325,7 +325,8 @@ const GameLoader = {
|
|||||||
'word-storm': 'WordStorm',
|
'word-storm': 'WordStorm',
|
||||||
'word-discovery': 'WordDiscovery',
|
'word-discovery': 'WordDiscovery',
|
||||||
'letter-discovery': 'LetterDiscovery',
|
'letter-discovery': 'LetterDiscovery',
|
||||||
'river-run': 'RiverRun'
|
'river-run': 'RiverRun',
|
||||||
|
'wizard-spell-caster': 'WizardSpellCaster'
|
||||||
};
|
};
|
||||||
return names[gameType] || gameType;
|
return names[gameType] || gameType;
|
||||||
},
|
},
|
||||||
@ -345,7 +346,10 @@ const GameLoader = {
|
|||||||
'test-rich-content': 'TestRichContent',
|
'test-rich-content': 'TestRichContent',
|
||||||
'test-sentence-only': 'TestSentenceOnly',
|
'test-sentence-only': 'TestSentenceOnly',
|
||||||
'test-minimal': 'TestMinimal',
|
'test-minimal': 'TestMinimal',
|
||||||
'test-rich': 'TestRich'
|
'test-rich': 'TestRich',
|
||||||
|
'nce1-lesson63-64': 'NCE1Lesson6364',
|
||||||
|
'nce2-lesson3': 'NCE2Lesson3',
|
||||||
|
'nce2-lesson30': 'NCE2Lesson30'
|
||||||
};
|
};
|
||||||
return mapping[contentType] || this.toPascalCase(contentType);
|
return mapping[contentType] || this.toPascalCase(contentType);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -6,12 +6,10 @@ const AppNavigation = {
|
|||||||
gamesConfig: null,
|
gamesConfig: null,
|
||||||
contentScanner: new ContentScanner(),
|
contentScanner: new ContentScanner(),
|
||||||
scannedContent: null,
|
scannedContent: null,
|
||||||
compatibilityChecker: null,
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.loadGamesConfig();
|
this.loadGamesConfig();
|
||||||
this.initContentScanner();
|
this.initContentScanner();
|
||||||
this.initCompatibilityChecker();
|
|
||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
this.handleInitialRoute();
|
this.handleInitialRoute();
|
||||||
},
|
},
|
||||||
@ -32,14 +30,6 @@ const AppNavigation = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initCompatibilityChecker() {
|
|
||||||
if (window.ContentGameCompatibility) {
|
|
||||||
this.compatibilityChecker = new ContentGameCompatibility();
|
|
||||||
logSh('🎯 Content-Game compatibility checker initialized', 'INFO');
|
|
||||||
} else {
|
|
||||||
logSh('⚠️ ContentGameCompatibility not found, compatibility checks disabled', 'WARN');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultConfig() {
|
getDefaultConfig() {
|
||||||
return {
|
return {
|
||||||
@ -98,6 +88,12 @@ const AppNavigation = {
|
|||||||
icon: '🔍',
|
icon: '🔍',
|
||||||
description: 'Learn new words with images and interactive practice!'
|
description: 'Learn new words with images and interactive practice!'
|
||||||
},
|
},
|
||||||
|
'wizard-spell-caster': {
|
||||||
|
enabled: true,
|
||||||
|
name: 'Wizard Spell Caster',
|
||||||
|
icon: '🧙♂️',
|
||||||
|
description: 'Cast spells by forming correct sentences! (Advanced - 11+ years)'
|
||||||
|
},
|
||||||
'letter-discovery': {
|
'letter-discovery': {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
name: 'Letter Discovery',
|
name: 'Letter Discovery',
|
||||||
@ -171,6 +167,24 @@ const AppNavigation = {
|
|||||||
name: 'The Magical Library (Optimized)',
|
name: 'The Magical Library (Optimized)',
|
||||||
icon: '⚡',
|
icon: '⚡',
|
||||||
description: 'Story with smart vocabulary matching and game compatibility'
|
description: 'Story with smart vocabulary matching and game compatibility'
|
||||||
|
},
|
||||||
|
'nce1-lesson63-64': {
|
||||||
|
enabled: true,
|
||||||
|
name: 'NCE1-Lesson63-64',
|
||||||
|
icon: '👨⚕️',
|
||||||
|
description: 'Medical dialogue and prohibition commands with modal verbs'
|
||||||
|
},
|
||||||
|
'nce2-lesson3': {
|
||||||
|
enabled: true,
|
||||||
|
name: 'NCE2-Lesson3',
|
||||||
|
icon: '✉️',
|
||||||
|
description: 'Please Send Me a Card - Past tense and travel vocabulary'
|
||||||
|
},
|
||||||
|
'nce2-lesson30': {
|
||||||
|
enabled: true,
|
||||||
|
name: 'NCE2-Lesson30',
|
||||||
|
icon: '⚽',
|
||||||
|
description: 'Football or Polo? - Articles and quantifiers'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
1881
js/games/wizard-spell-caster.js
Normal file
1881
js/games/wizard-spell-caster.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user