Files
English/kouyu_english/lib/core/seed_courses.dart
T

1318 lines
40 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'models.dart';
/// Stable A0 core identities taught by each seed lesson. Wording can vary in
/// future exercises without creating a different mastery item.
const a0TargetItemIdsByLesson = <String, List<String>>{
'a0-01': ['A0-W36', 'A0-W37', 'A0-W40', 'A0-P01', 'A0-P02', 'A0-P03'],
'a0-02': ['A0-P04'],
'a0-03': ['A0-W33', 'A0-W34', 'A0-W35', 'A0-P05', 'A0-P06'],
'a0-04': [
'A0-W01',
'A0-W02',
'A0-W03',
'A0-W04',
'A0-W05',
'A0-W06',
'A0-W07',
'A0-W08',
'A0-W09',
'A0-W10',
'A0-W11',
'A0-W20',
'A0-P07',
'A0-P08',
],
'a0-05': ['A0-W19', 'A0-W21', 'A0-W22', 'A0-W23', 'A0-P09', 'A0-P10'],
'a0-06': ['A0-P11', 'A0-P12'],
'a0-07': ['A0-W25', 'A0-W26', 'A0-W27', 'A0-W28', 'A0-P13'],
'a0-08': [
'A0-W12',
'A0-W13',
'A0-W14',
'A0-W15',
'A0-W16',
'A0-W17',
'A0-W18',
'A0-P14',
'A0-P15',
'A0-P16',
'A0-P17',
],
'a0-09': [
'A0-W29',
'A0-W30',
'A0-W31',
'A0-W32',
'A0-W38',
'A0-W39',
'A0-P18',
'A0-P19',
],
'a0-10': ['A0-W24', 'A0-P20'],
};
/// A topic may contain multiple independently resumable teaching segments.
/// Segment IDs are stable even if later wording or exercises change.
class LessonSegment {
const LessonSegment({
required this.id,
required this.targetItemIds,
required this.previewItemIds,
this.dialogueRequiredTerms = const [],
this.independentRequiredTerms = const [],
this.estimatedMinutes = 12,
});
final String id;
final List<String> targetItemIds;
final List<String> previewItemIds;
/// One accepted term group per controlled dialogue turn. A learner only
/// needs to use one term from the current group; the surrounding wording
/// may vary naturally.
final List<List<String>> dialogueRequiredTerms;
/// Terms that show the independent attempt contains the taught content.
final List<String> independentRequiredTerms;
final int estimatedMinutes;
}
const a0LessonSegments = <String, List<LessonSegment>>{
'a0-04': [
LessonSegment(
id: 'a0-04-a',
targetItemIds: [
'A0-W01',
'A0-W02',
'A0-W03',
'A0-W04',
'A0-W05',
'A0-W06',
],
previewItemIds: [
'A0-W01',
'A0-W02',
'A0-W03',
'A0-W04',
'A0-W05',
'A0-W06',
],
dialogueRequiredTerms: [
['zero', 'one', 'two'],
['three', 'four', 'five'],
],
independentRequiredTerms: ['zero', 'one', 'two', 'three', 'four', 'five'],
),
LessonSegment(
id: 'a0-04-b',
targetItemIds: [
'A0-W07',
'A0-W08',
'A0-W09',
'A0-W10',
'A0-W11',
'A0-W20',
],
previewItemIds: [
'A0-W07',
'A0-W08',
'A0-W09',
'A0-W10',
'A0-W11',
'A0-W20',
],
dialogueRequiredTerms: [
['six', 'seven', 'eight'],
['it is a phone', "it's a phone"],
],
independentRequiredTerms: ['six', 'seven', 'eight', 'nine', 'ten'],
),
LessonSegment(
id: 'a0-04-c',
targetItemIds: ['A0-P07', 'A0-P08'],
previewItemIds: ['A0-P07', 'A0-P08'],
dialogueRequiredTerms: [
[
'my number is',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'zero',
],
[
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'zero',
],
],
independentRequiredTerms: [
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'zero',
],
),
],
'a0-08': [
LessonSegment(
id: 'a0-08-a',
targetItemIds: ['A0-W12', 'A0-W13', 'A0-W14', 'A0-P14', 'A0-P15'],
previewItemIds: ['A0-W12', 'A0-W13', 'A0-W14', 'A0-P14', 'A0-P15'],
dialogueRequiredTerms: [
['what day'],
['monday', 'tuesday', 'wednesday'],
],
independentRequiredTerms: ['monday', 'tuesday', 'wednesday'],
),
LessonSegment(
id: 'a0-08-b',
targetItemIds: ['A0-W15', 'A0-W16', 'A0-W17', 'A0-W18'],
previewItemIds: ['A0-W15', 'A0-W16', 'A0-W17', 'A0-W18'],
dialogueRequiredTerms: [
['what day'],
['thursday', 'friday', 'saturday', 'sunday'],
],
independentRequiredTerms: ['thursday', 'friday', 'saturday', 'sunday'],
),
LessonSegment(
id: 'a0-08-c',
targetItemIds: ['A0-P16', 'A0-P17'],
previewItemIds: ['A0-P16', 'A0-P17'],
dialogueRequiredTerms: [
['what time'],
["o'clock", 'oclock'],
],
independentRequiredTerms: ["o'clock", 'oclock'],
),
],
};
class SeedLesson {
const SeedLesson({
required this.id,
required this.number,
required this.title,
required this.outcome,
required this.vocabulary,
this.schemaVersion = '1.0',
this.revision = 1,
this.stageVersion = 'A0-1.0',
this.source = ContentSource.builtInOriginal,
this.status = ContentStatus.approved,
this.estimatedMinutes = 12,
});
final String id;
final int number;
final String title;
final String outcome;
final List<VocabularyItem> vocabulary;
final String schemaVersion;
final int revision;
final String stageVersion;
final ContentSource source;
final ContentStatus status;
final int estimatedMinutes;
List<String> get targetItemIds =>
a0TargetItemIdsByLesson[id] ?? const <String>[];
List<String> get abilityIds => ['A0-C${number.toString().padLeft(2, '0')}'];
List<String> get prerequisiteIds => number == 1
? const []
: ['a0-${(number - 1).toString().padLeft(2, '0')}'];
List<LessonSegment> get segments =>
a0LessonSegments[id] ??
[
LessonSegment(
id: '$id-a',
targetItemIds: targetItemIds,
previewItemIds: targetItemIds,
estimatedMinutes: estimatedMinutes,
),
];
}
const a0SeedLessons = [
SeedLesson(
id: 'a0-01',
number: 1,
title: '你好,我是……',
outcome: '介绍姓名并回应问候',
vocabulary: [
VocabularyItem(
id: 'a0-01-hello',
word: 'Hello',
meaning: '你好',
example: 'Hello. Im Mia.',
exampleMeaning: '你好。我是 Mia。',
ipa: '/həˈləʊ/',
),
VocabularyItem(
id: 'a0-01-name',
word: 'name',
meaning: '名字',
example: 'My name is Shen.',
exampleMeaning: '我的名字是 Shen。',
ipa: '/neɪm/',
),
VocabularyItem(
id: 'a0-01-nice',
word: 'Nice to meet you',
meaning: '很高兴认识你',
example: 'Nice to meet you, too.',
exampleMeaning: '我也很高兴认识你。',
),
],
),
SeedLesson(
id: 'a0-02',
number: 2,
title: '拼读我的名字',
outcome: '听懂拼写,并说出名字字母',
vocabulary: [
VocabularyItem(
id: 'a0-02-spell',
word: 'spell',
meaning: '拼写',
example: 'How do you spell that?',
exampleMeaning: '那个怎么拼?',
ipa: '/spel/',
),
VocabularyItem(
id: 'a0-02-name',
word: 'name',
meaning: '名字',
example: 'My name is Shen.',
exampleMeaning: '我的名字是 Shen。',
ipa: '/neɪm/',
),
VocabularyItem(
id: 'a0-02-question',
word: 'How do you spell that?',
meaning: '那个怎么拼?',
example: 'How do you spell your name?',
exampleMeaning: '你的名字怎么拼?',
),
],
),
SeedLesson(
id: 'a0-03',
number: 3,
title: '你好吗?',
outcome: '问候并表达简单状态',
vocabulary: [
VocabularyItem(
id: 'a0-03-good',
word: 'good',
meaning: '好的',
example: 'Im good, thanks.',
exampleMeaning: '我很好,谢谢。',
ipa: '/ɡʊd/',
),
VocabularyItem(
id: 'a0-03-tired',
word: 'tired',
meaning: '累的',
example: 'Im tired today.',
exampleMeaning: '我今天有点累。',
ipa: '/ˈtaɪəd/',
),
VocabularyItem(
id: 'a0-03-how',
word: 'How are you?',
meaning: '你好吗?',
example: 'How are you today?',
exampleMeaning: '你今天怎么样?',
),
],
),
SeedLesson(
id: 'a0-04',
number: 4,
title: '数字与电话号码',
outcome: '说 010 与虚拟号码',
vocabulary: [
VocabularyItem(
id: 'a0-04-three',
word: 'three',
meaning: '三',
example: 'One, three, eight.',
exampleMeaning: '一、三、八。',
ipa: '/θriː/',
),
VocabularyItem(
id: 'a0-04-number',
word: 'number',
meaning: '号码',
example: 'My number is 1-3-8.',
exampleMeaning: '我的号码是 138。',
ipa: '/ˈnʌmbə(r)/',
),
VocabularyItem(
id: 'a0-04-phone',
word: 'phone',
meaning: '电话',
example: 'Whats your phone number?',
exampleMeaning: '你的电话号码是多少?',
),
],
),
SeedLesson(
id: 'a0-05',
number: 5,
title: '这是什么?',
outcome: '询问并说出常见物品',
vocabulary: [
VocabularyItem(
id: 'a0-05-book',
word: 'book',
meaning: '书',
example: 'Its a book.',
exampleMeaning: '这是一本书。',
ipa: '/bʊk/',
),
VocabularyItem(
id: 'a0-05-pen',
word: 'pen',
meaning: '笔',
example: 'Its a pen.',
exampleMeaning: '这是一支笔。',
ipa: '/pen/',
),
VocabularyItem(
id: 'a0-05-this',
word: 'Whats this?',
meaning: '这是什么?',
example: 'Whats this? Its a key.',
exampleMeaning: '这是什么?这是钥匙。',
),
],
),
SeedLesson(
id: 'a0-06',
number: 6,
title: '我来自哪里?',
outcome: '说明来自哪里并反问',
vocabulary: [
VocabularyItem(
id: 'a0-06-from',
word: 'from',
meaning: '来自',
example: 'Im from Hong Kong.',
exampleMeaning: '我来自香港。',
ipa: '/frəm/',
),
VocabularyItem(
id: 'a0-06-place',
word: 'place',
meaning: '地点',
example: 'Where are you from?',
exampleMeaning: '你来自哪里?',
),
],
),
SeedLesson(
id: 'a0-07',
number: 7,
title: '我的家人',
outcome: '介绍一位家人',
vocabulary: [
VocabularyItem(
id: 'a0-07-family',
word: 'family',
meaning: '家人',
example: 'This is my family.',
exampleMeaning: '这是我的家人。',
ipa: '/ˈfæməli/',
),
VocabularyItem(
id: 'a0-07-mother',
word: 'mother',
meaning: '母亲',
example: 'This is my mother.',
exampleMeaning: '这是我的妈妈。',
),
],
),
SeedLesson(
id: 'a0-08',
number: 8,
title: '星期与时间',
outcome: '说今天和整点',
vocabulary: [
VocabularyItem(
id: 'a0-08-monday',
word: 'Monday',
meaning: '星期一',
example: 'It is Monday.',
exampleMeaning: '今天是星期一。',
),
VocabularyItem(
id: 'a0-08-oclock',
word: 'oclock',
meaning: '整点',
example: 'Its three oclock.',
exampleMeaning: '现在三点整。',
),
],
),
SeedLesson(
id: 'a0-09',
number: 9,
title: '我喜欢……',
outcome: '表达喜好并回答',
vocabulary: [
VocabularyItem(
id: 'a0-09-like',
word: 'like',
meaning: '喜欢',
example: 'I like tea.',
exampleMeaning: '我喜欢茶。',
ipa: '/laɪk/',
),
VocabularyItem(
id: 'a0-09-tea',
word: 'tea',
meaning: '茶',
example: 'Do you like tea?',
exampleMeaning: '你喜欢茶吗?',
),
],
),
SeedLesson(
id: 'a0-10',
number: 10,
title: 'A0 综合任务',
outcome: '完成自我介绍、喜好和反问',
vocabulary: [
VocabularyItem(
id: 'a0-10-again',
word: 'Please say that again.',
meaning: '请再说一遍。',
example: 'Please say that again.',
exampleMeaning: '请再说一遍。',
),
VocabularyItem(
id: 'a0-10-slowly',
word: 'Please speak slowly.',
meaning: '请说慢一点。',
example: 'Please speak slowly.',
exampleMeaning: '请说慢一点。',
),
],
),
];
SeedLesson lessonById(String id) =>
a0SeedLessons.firstWhere((lesson) => lesson.id == id);
class LessonActivity {
const LessonActivity({
required this.listening,
required this.listeningQuestion,
required this.answers,
required this.speaking,
required this.reading,
required this.readingQuestion,
required this.readingAnswer,
required this.writingPrompt,
required this.writingExample,
required this.independentPrompt,
required this.independentHelp,
});
final String listening;
final String listeningQuestion;
final List<String> answers;
final String speaking;
final String reading;
final String readingQuestion;
final String readingAnswer;
final String writingPrompt;
final String writingExample;
final String independentPrompt;
final String independentHelp;
}
const a0Activities = <String, LessonActivity>{
'a0-01': LessonActivity(
listening: 'Hello. Im Mia. Nice to meet you.',
listeningQuestion: 'Mia 在做什么?',
answers: ['自我介绍', '买东西', '问时间'],
speaking: 'Hello. Im Shen. Nice to meet you.',
reading:
'Mia: Hello. Im Mia.\nShen: Hi. Im Shen.\nMia: Nice to meet you.\nShen: Nice to meet you, too.',
readingQuestion: '谁叫 Mia',
readingAnswer: '第一位说话的人',
writingPrompt: '写一句问候和姓名介绍。',
writingExample: 'Hello. Im Shen.',
independentPrompt: '不看句框,介绍你的名字并回应“Nice to meet you”。',
independentHelp: 'Hi. Im … / Nice to meet you, too.',
),
'a0-02': LessonActivity(
listening: 'How do you spell your name?',
listeningQuestion: '这句话是什么意思?',
answers: ['你的名字怎么拼?', '你的名字是什么?', '你来自哪里?'],
speaking: 'S H E N',
reading:
'Mia: Whats your name?\nShen: Shen.\nMia: How do you spell that?\nShen: S-H-E-N.',
readingQuestion: 'Shen 的名字怎么拼?',
readingAnswer: 'S-H-E-N',
writingPrompt: '把名字和拼写写完整。',
writingExample: 'My name is Shen.\nS-H-E-N.',
independentPrompt: '不看句框,用英文介绍名字并拼读它。',
independentHelp: 'My name is … / A-B-C.',
),
'a0-03': LessonActivity(
listening: 'How are you today?',
listeningQuestion: '对方在问什么?',
answers: ['你的状态', '你的号码', '你的地点'],
speaking: 'How are you? Im good, thanks.',
reading:
'Mia: Hi, Shen. How are you?\nShen: Im good, thanks. How are you?\nMia: Im okay.',
readingQuestion: 'Mia 状态如何?',
readingAnswer: 'okay',
writingPrompt: '写一句今天的状态。',
writingExample: 'Im okay today.',
independentPrompt: '不看句框,问候并说出你的状态。',
independentHelp: 'How are you? / Im …',
),
'a0-04': LessonActivity(
listening: 'One, three, eight.',
listeningQuestion: '你听到的是哪个号码?',
answers: ['138', '183', '318'],
speaking: 'My number is one-three-eight.',
reading:
'Mia: Whats your phone number?\nShen: One-three-eight.\nMia: Thank you.',
readingQuestion: 'Shen 的号码是?',
readingAnswer: '138',
writingPrompt: '把虚拟号码 139 写成英文。',
writingExample: 'one-three-nine',
independentPrompt: '不看句框,说出一个三位虚拟号码。',
independentHelp: 'My number is one-two-three.',
),
'a0-05': LessonActivity(
listening: 'Whats this? Its a key.',
listeningQuestion: '这是什么?',
answers: ['钥匙', '书', '水'],
speaking: 'Whats this? Its a pen.',
reading: 'Mia: Whats this?\nShen: Its a book.',
readingQuestion: '这是什么?',
readingAnswer: 'a book',
writingPrompt: '写一句“这是一支笔”。',
writingExample: 'Its a pen.',
independentPrompt: '不看句框,说出一个身边物品。',
independentHelp: 'Its a …',
),
'a0-06': LessonActivity(
listening: 'Where are you from?',
listeningQuestion: '对方在问什么?',
answers: ['来自哪里', '叫什么', '喜欢什么'],
speaking: 'Im from Hong Kong.',
reading: 'Mia: Where are you from?\nShen: Im from Hong Kong.',
readingQuestion: 'Shen 来自哪里?',
readingAnswer: 'Hong Kong',
writingPrompt: '写一句你来自哪里。',
writingExample: 'Im from Hong Kong.',
independentPrompt: '不看句框,说来自哪里并反问对方。',
independentHelp: 'Im from … / Where are you from?',
),
'a0-07': LessonActivity(
listening: 'Who is this? This is my mother.',
listeningQuestion: '这个人是谁?',
answers: ['妈妈', '朋友', '老师'],
speaking: 'This is my family.',
reading: 'Mia: Who is this?\nShen: This is my mother.',
readingQuestion: 'Shen 在介绍谁?',
readingAnswer: 'my mother',
writingPrompt: '介绍一位家人或朋友。',
writingExample: 'This is my mother.',
independentPrompt: '不看句框,介绍一位家人或朋友。',
independentHelp: 'This is my …',
),
'a0-08': LessonActivity(
listening: 'Its three oclock on Monday.',
listeningQuestion: '是什么时间?',
answers: ['星期一三点', '星期三一点', '星期一一点'],
speaking: 'Its three oclock.',
reading: 'Mia: What day is it?\nShen: Its Monday.',
readingQuestion: '今天星期几?',
readingAnswer: 'Monday',
writingPrompt: '写一句今天和整点。',
writingExample: 'Its Monday. Its three oclock.',
independentPrompt: '不看句框,说今天星期几或现在几点。',
independentHelp: 'Its … / Its … oclock.',
),
'a0-09': LessonActivity(
listening: 'Do you like tea? Yes, I do.',
listeningQuestion: '对方喜欢茶吗?',
answers: ['喜欢', '不喜欢', '不知道'],
speaking: 'I like tea. Do you like tea?',
reading: 'Mia: I like tea. Do you like tea?\nShen: Yes, I do.',
readingQuestion: 'Shen 的回答是什么?',
readingAnswer: 'Yes, I do.',
writingPrompt: '写一句你的喜好。',
writingExample: 'I like tea.',
independentPrompt: '不看句框,说一个喜好并反问。',
independentHelp: 'I like … / Do you like …?',
),
'a0-10': LessonActivity(
listening: 'Please say that again.',
listeningQuestion: '对方希望什么?',
answers: ['再说一遍', '说慢一点', '写下来'],
speaking: 'Please speak slowly.',
reading: 'Mia: Please say that again.\nShen: Please speak slowly.',
readingQuestion: 'Shen 希望什么?',
readingAnswer: 'speak slowly',
writingPrompt: '写姓名、地点和喜好三句。',
writingExample: 'Im Shen.\nIm from Hong Kong.\nI like tea.',
independentPrompt: '不看帮助,完成姓名、地点、喜好和反问。',
independentHelp: 'Im … / Im from … / I like …',
),
};
LessonActivity activityByLessonId(String id) => a0Activities[id]!;
/// Reviewed activities for split topics. They intentionally avoid values from
/// later segments so a segment can be completed independently.
const a0SegmentActivities = <String, LessonActivity>{
'a0-04-a': LessonActivity(
listening: 'One, two, three.',
listeningQuestion: '听到哪一组数字?',
answers: ['123', '132', '213'],
speaking: 'Zero, one, two, three.',
reading: 'Mia: One, two, three.\nShen: Four, five.',
readingQuestion: 'Shen 说了哪两个数字?',
readingAnswer: 'four, five',
writingPrompt: '把 0、1、2、3 写成英文。',
writingExample: 'zero, one, two, three',
independentPrompt: '不看帮助,说出三个 0 到 5 的数字。',
independentHelp: 'zero / one / two / three / four / five',
),
'a0-04-b': LessonActivity(
listening: 'Six, seven, eight.',
listeningQuestion: '听到哪一组数字?',
answers: ['678', '687', '768'],
speaking: 'My phone is here.',
reading: 'Mia: What is this?\nShen: It is a phone.',
readingQuestion: '这是什么?',
readingAnswer: 'a phone',
writingPrompt: '把 6、7、8 写成英文。',
writingExample: 'six, seven, eight',
independentPrompt: '不看帮助,说出三个 6 到 10 的数字。',
independentHelp: 'six / seven / eight / nine / ten',
),
'a0-04-c': LessonActivity(
listening: 'My number is one-three-eight.',
listeningQuestion: '号码是多少?',
answers: ['138', '183', '318'],
speaking: 'My number is one-three-eight.',
reading: 'Mia: Whats your phone number?\nShen: One-three-eight.',
readingQuestion: 'Shen 的号码是?',
readingAnswer: '138',
writingPrompt: '把虚拟号码 139 写成英文。',
writingExample: 'one-three-nine',
independentPrompt: '不看句框,说出一个三位虚拟号码。',
independentHelp: 'My number is one-two-three.',
),
'a0-08-a': LessonActivity(
listening: 'It is Monday.',
listeningQuestion: '今天星期几?',
answers: ['星期一', '星期二', '星期三'],
speaking: 'It is Monday.',
reading: 'Mia: What day is it?\nShen: It is Tuesday.',
readingQuestion: '今天星期几?',
readingAnswer: 'Tuesday',
writingPrompt: '写一句今天是星期一、二或三。',
writingExample: 'It is Monday.',
independentPrompt: '不看帮助,说出星期一、二或三。',
independentHelp: 'It is Monday / Tuesday / Wednesday.',
),
'a0-08-b': LessonActivity(
listening: 'It is Friday.',
listeningQuestion: '今天星期几?',
answers: ['星期五', '星期四', '星期日'],
speaking: 'It is Friday.',
reading: 'Mia: What day is it?\nShen: It is Sunday.',
readingQuestion: '今天星期几?',
readingAnswer: 'Sunday',
writingPrompt: '写一句今天是星期四到日。',
writingExample: 'It is Friday.',
independentPrompt: '不看帮助,说出星期四到日。',
independentHelp: 'It is Thursday / Friday / Saturday / Sunday.',
),
'a0-08-c': LessonActivity(
listening: 'It is three oclock.',
listeningQuestion: '是什么时间?',
answers: ['三点', '一点', '星期三'],
speaking: 'It is three oclock.',
reading: 'Mia: What time is it?\nShen: It is three oclock.',
readingQuestion: '几点?',
readingAnswer: 'three oclock',
writingPrompt: '写一句整点时间。',
writingExample: 'It is three oclock.',
independentPrompt: '不看帮助,说一个整点时间。',
independentHelp: 'It is … oclock.',
),
};
LessonActivity activityBySegmentId(String segmentId, String lessonId) =>
a0SegmentActivities[segmentId] ?? activityByLessonId(lessonId);
/// Short, reviewed entries used before each split segment. These are kept
/// separate from review prompts: a review hint is not a learner-facing
/// dictionary definition.
const a0SegmentVocabulary = <String, List<VocabularyItem>>{
'a0-04-a': [
VocabularyItem(
id: 'A0-W01',
word: 'zero',
meaning: '零',
example: 'Zero, one, two.',
exampleMeaning: '零、一、二。',
ipa: '/ˈzɪrəʊ/',
),
VocabularyItem(
id: 'A0-W02',
word: 'one',
meaning: '一',
example: 'One, two, three.',
exampleMeaning: '一、二、三。',
ipa: '/wʌn/',
),
VocabularyItem(
id: 'A0-W03',
word: 'two',
meaning: '二',
example: 'Two and three.',
exampleMeaning: '二和三。',
ipa: '/tuː/',
),
VocabularyItem(
id: 'A0-W04',
word: 'three',
meaning: '三',
example: 'Three, four, five.',
exampleMeaning: '三、四、五。',
ipa: '/θriː/',
),
VocabularyItem(
id: 'A0-W05',
word: 'four',
meaning: '四',
example: 'Four and five.',
exampleMeaning: '四和五。',
ipa: '/fɔː/',
),
VocabularyItem(
id: 'A0-W06',
word: 'five',
meaning: '五',
example: 'Five, please.',
exampleMeaning: '五,请。',
ipa: '/faɪv/',
),
],
'a0-04-b': [
VocabularyItem(
id: 'A0-W07',
word: 'six',
meaning: '六',
example: 'Six, seven, eight.',
exampleMeaning: '六、七、八。',
ipa: '/sɪks/',
),
VocabularyItem(
id: 'A0-W08',
word: 'seven',
meaning: '七',
example: 'Seven, eight, nine.',
exampleMeaning: '七、八、九。',
ipa: '/ˈsevən/',
),
VocabularyItem(
id: 'A0-W09',
word: 'eight',
meaning: '八',
example: 'Eight, nine, ten.',
exampleMeaning: '八、九、十。',
ipa: '/eɪt/',
),
VocabularyItem(
id: 'A0-W10',
word: 'nine',
meaning: '九',
example: 'Nine and ten.',
exampleMeaning: '九和十。',
ipa: '/naɪn/',
),
VocabularyItem(
id: 'A0-W11',
word: 'ten',
meaning: '十',
example: 'Ten, please.',
exampleMeaning: '十,请。',
ipa: '/ten/',
),
VocabularyItem(
id: 'A0-W20',
word: 'phone',
meaning: '电话;手机',
example: 'It is a phone.',
exampleMeaning: '它是一部手机。',
ipa: '/fəʊn/',
),
],
'a0-04-c': [
VocabularyItem(
id: 'A0-P07',
word: "What's your phone number?",
meaning: '你的电话号码是多少?',
example: "What's your phone number?",
exampleMeaning: '你的电话号码是多少?',
),
VocabularyItem(
id: 'A0-P08',
word: 'My number is one-three-eight.',
meaning: '我的号码是 138。',
example: 'My number is one-three-eight.',
exampleMeaning: '我的号码是 138。',
),
],
'a0-08-a': [
VocabularyItem(
id: 'A0-W12',
word: 'Monday',
meaning: '星期一',
example: 'It is Monday.',
exampleMeaning: '今天是星期一。',
ipa: '/ˈmʌndeɪ/',
),
VocabularyItem(
id: 'A0-W13',
word: 'Tuesday',
meaning: '星期二',
example: 'It is Tuesday.',
exampleMeaning: '今天是星期二。',
ipa: '/ˈtjuːzdeɪ/',
),
VocabularyItem(
id: 'A0-W14',
word: 'Wednesday',
meaning: '星期三',
example: 'It is Wednesday.',
exampleMeaning: '今天是星期三。',
ipa: '/ˈwenzdeɪ/',
),
VocabularyItem(
id: 'A0-P14',
word: 'What day is it today?',
meaning: '今天星期几?',
example: 'What day is it today?',
exampleMeaning: '今天星期几?',
),
VocabularyItem(
id: 'A0-P15',
word: "It's Monday.",
meaning: '今天是星期一。',
example: "It's Monday.",
exampleMeaning: '今天是星期一。',
),
],
'a0-08-b': [
VocabularyItem(
id: 'A0-W15',
word: 'Thursday',
meaning: '星期四',
example: 'It is Thursday.',
exampleMeaning: '今天是星期四。',
ipa: '/ˈθɜːzdeɪ/',
),
VocabularyItem(
id: 'A0-W16',
word: 'Friday',
meaning: '星期五',
example: 'It is Friday.',
exampleMeaning: '今天是星期五。',
ipa: '/ˈfraɪdeɪ/',
),
VocabularyItem(
id: 'A0-W17',
word: 'Saturday',
meaning: '星期六',
example: 'It is Saturday.',
exampleMeaning: '今天是星期六。',
ipa: '/ˈsætədeɪ/',
),
VocabularyItem(
id: 'A0-W18',
word: 'Sunday',
meaning: '星期日',
example: 'It is Sunday.',
exampleMeaning: '今天是星期日。',
ipa: '/ˈsʌndeɪ/',
),
],
'a0-08-c': [
VocabularyItem(
id: 'A0-P16',
word: 'What time is it?',
meaning: '现在几点?',
example: 'What time is it?',
exampleMeaning: '现在几点?',
),
VocabularyItem(
id: 'A0-P17',
word: "It's three o'clock.",
meaning: '现在三点。',
example: "It's three o'clock.",
exampleMeaning: '现在三点。',
),
],
};
List<VocabularyItem> vocabularyBySegmentId(String segmentId, String lessonId) {
if (!a0SegmentActivities.containsKey(segmentId)) {
return lessonById(lessonId).vocabulary;
}
return a0SegmentVocabulary[segmentId] ?? const <VocabularyItem>[];
}
/// One practical rule per seed lesson. These are reminders for using a sentence
/// in context, not abstract grammar lectures.
const a0GrammarNotes = <String, String>{
'a0-01': '介绍自己时,把名字放在 I’m 后面:I’m Mia. 不需要先学复杂时态。',
'a0-02': 'My name is 后面接名字;拼读时每个字母之间稍微停顿。',
'a0-03': '说状态用 Im + 状态:Im good / okay / tired。',
'a0-04': '报号码时数字一个一个说:one-three-eight,不要当成一百三十八。',
'a0-05': '问物品用 Whats this?;回答用 Its a + 物品。',
'a0-06': '说地点用 Im from + 地点:Im from Hong Kong。',
'a0-07': '介绍人用 This is my + 人:This is my mother。',
'a0-08': '星期和整点都可用 ItsIts Monday. / Its three oclock。',
'a0-09': '说喜好用 I like + 东西;一般问句用 Do you like + 东西?',
'a0-10': '礼貌请求以 Please 开头:Please say that again.',
};
String grammarNoteForLesson(String id) => a0GrammarNotes[id] ?? '';
const a0SegmentGrammarNotes = <String, String>{
'a0-04-a': '数字单独说就可以:zero, one, two。每个词之间稍微停顿。',
'a0-04-b': '认物品可以说 It is a phone. 口语里也常说 Its a phone.',
'a0-04-c': '报号码时一个数字一个数字说:one-three-eight,不把它读成一百三十八。',
'a0-08-a': '问星期用 What day is it?;回答用 It is / Its + 星期。',
'a0-08-b': '星期四到星期日也沿用 It is / It’s + 星期这个句型。',
'a0-08-c': '说整点用 It is / Its + 数字 + oclock,例如 Its three oclock。',
};
String grammarNoteForSegment(String segmentId, String lessonId) =>
a0SegmentGrammarNotes[segmentId] ?? grammarNoteForLesson(lessonId);
bool matchesSegmentDialogue(String segmentId, int stage, String response) {
final text = response.toLowerCase().replaceAll('', "'");
final segment = a0LessonSegments.values
.expand((segments) => segments)
.where((item) => item.id == segmentId)
.firstOrNull;
if (segment == null || stage >= segment.dialogueRequiredTerms.length) {
return false;
}
bool hasAny(Iterable<String> terms) =>
terms.any((term) => text.contains(term));
// A phone-number report needs both the reporting frame and at least one
// spoken digit. Other segment turns need one reviewed, task-specific term.
if (segmentId == 'a0-04-c' && stage == 0) {
return text.contains('my number is') &&
hasAny(segment.dialogueRequiredTerms[stage].skip(1));
}
return hasAny(segment.dialogueRequiredTerms[stage]);
}
bool matchesSegmentIndependent(String segmentId, String response) {
final text = response.toLowerCase().replaceAll('', "'");
final segment = a0LessonSegments.values
.expand((segments) => segments)
.where((item) => item.id == segmentId)
.firstOrNull;
if (segment == null) return true;
if (segmentId == 'a0-04-a' || segmentId == 'a0-04-b') {
final count = segment.independentRequiredTerms
.where((term) => text.contains(term))
.length;
return count >= 3;
}
if (segmentId == 'a0-04-c') {
return segment.independentRequiredTerms
.where((term) => text.contains(term))
.length >=
3;
}
return segment.independentRequiredTerms.any((term) => text.contains(term));
}
class LessonDialogue {
const LessonDialogue({
required this.goal,
required this.prompts,
required this.hints,
this.translations = const [],
});
final String goal;
final List<String> prompts;
final List<String> hints;
final List<String> translations;
}
const a0Dialogues = <String, LessonDialogue>{
'a0-01': LessonDialogue(
goal: '问候、介绍姓名并回应见面问候',
prompts: [
'Hi! Im Mia. Whats your name?',
'Nice to meet you. Say: Nice to meet you, too.',
'Great! Say hello one more time.',
'Now ask me my name!',
],
hints: [
'Im Alex.',
'Nice to meet you, too.',
'Hello!',
'Whats your name?',
],
translations: [
'嗨!我是 Mia。你叫什么名字?',
'很高兴认识你。请说:Nice to meet you, too(我也很高兴认识你)。',
'太棒了!再打一次招呼吧。',
'现在请问我的名字!',
],
),
'a0-02': LessonDialogue(
goal: '介绍姓名并完整拼读名字',
prompts: [
'Hi! Whats your name?',
'How do you spell that?',
'Thank you. Spell it one more time.',
'Now ask me my name!',
],
hints: ['My name is Alex.', 'A-L-E-X.', 'A-L-E-X.', 'Whats your name?'],
translations: [
'嗨!你叫什么名字?',
'那个怎么拼写?',
'谢谢。请再拼写一次。',
'现在请问我的名字!',
],
),
'a0-03': LessonDialogue(
goal: '询问状态、回答并反问',
prompts: [
'Hi! How are you today?',
'Good! Ask me: How are you?',
'Im okay. Say your state one more time.',
'Now say goodbye!',
],
hints: ['Im good, thanks.', 'How are you?', 'Im okay.', 'Bye!'],
translations: [
'嗨!你今天好吗?',
'很好!请问我:How are you(你好吗)?',
'我还好。请再说一次你的状态。',
'现在请说再见!',
],
),
'a0-04': LessonDialogue(
goal: '报告一个虚拟三位号码并确认',
prompts: [
'Whats your phone number? Use a fake three-digit number.',
'I heard one-three-eight. Is that right?',
'Please say the three numbers again.',
'Now ask me for my number!',
],
hints: [
'My number is one-three-eight.',
'Yes.',
'One-three-eight.',
'Whats your phone number?',
],
translations: [
'你的电话号码是多少?可以使用一个虚拟的三位数字。',
'我听到了 1-3-8。对吗?',
'请再说一遍这三个数字。',
'现在请问我的电话号码!',
],
),
'a0-05': LessonDialogue(
goal: '询问并说出一个物品',
prompts: [
'Whats this? It is a pen.',
'Now say: Its a pen.',
'Ask me: Whats this?',
'Great! Say one more object.',
],
hints: ['Its a pen.', 'Its a pen.', 'Whats this?', 'Its a book.'],
translations: [
'这是什么?这是一支笔。',
'现在请说:Its a pen(这是一支笔)。',
'请问我:Whats this(这是什么)?',
'太棒了!再说一个物品吧。',
],
),
'a0-06': LessonDialogue(
goal: '说来自哪里并反问',
prompts: [
'Where are you from?',
'Nice! Ask me: Where are you from?',
'Say where you are from one more time.',
'Say goodbye!',
],
hints: [
'Im from Hong Kong.',
'Where are you from?',
'Im from Hong Kong.',
'Bye!',
],
translations: [
'你来自哪里?',
'很好!请问我:Where are you from(你来自哪里)?',
'请再说一次你来自哪里。',
'请说再见!',
],
),
'a0-07': LessonDialogue(
goal: '介绍一位家人或朋友',
prompts: [
'Who is this?',
'Good. Say: This is my mother.',
'Ask me: Who is this?',
'Introduce one person again.',
],
hints: [
'This is my mother.',
'This is my mother.',
'Who is this?',
'This is my friend.',
],
translations: [
'这是谁?',
'很好。请说:This is my mother(这是我的妈妈)。',
'请问我:Who is this(这是谁)?',
'请再介绍一个人。',
],
),
'a0-08': LessonDialogue(
goal: '说明星期或整点',
prompts: [
'What day is it today?',
'What time is it?',
'Say one full time sentence.',
'Now ask me the day!',
],
hints: [
'Its Monday.',
'Its three oclock.',
'Its three oclock.',
'What day is it?',
],
translations: [
'今天星期几?',
'现在几点了?',
'请说一个完整的时间句子。',
'现在请问我今天是星期几!',
],
),
'a0-09': LessonDialogue(
goal: '表达喜好、回答和反问',
prompts: [
'What do you like?',
'Do you like tea?',
'Now ask me what I like.',
'Say your like one more time.',
],
hints: ['I like tea.', 'Yes, I do.', 'Do you like tea?', 'I like tea.'],
translations: [
'你喜欢什么?',
'你喜欢茶吗?',
'现在请问我喜欢什么。',
'请再说一次你的喜好。',
],
),
'a0-10': LessonDialogue(
goal: '请求重复或放慢语速,并完成基础沟通',
prompts: [
'Say: Please say that again.',
'Say: Please speak slowly.',
'Now ask me your name or where I am from.',
'Say one thing you like.',
],
hints: [
'Please say that again.',
'Please speak slowly.',
'Whats your name?',
'I like tea.',
],
translations: [
'请说:Please say that again(请再说一遍)。',
'请说:Please speak slowly(请说慢一点)。',
'现在请问我的名字或我来自哪里。',
'请说一件你喜欢的事物。',
],
),
};
const a0SegmentDialogues = <String, LessonDialogue>{
'a0-04-a': LessonDialogue(
goal: '听辨并说出 0 到 5',
prompts: ['Say zero, one, two.', 'Now say three, four, five.'],
hints: ['zero, one, two', 'three, four, five'],
translations: ['请说 zero, one, two012)。', '现在请说 three, four, five345)。'],
),
'a0-04-b': LessonDialogue(
goal: '听辨 6 到 10 并认识 phone',
prompts: ['Say six, seven, eight.', 'What is this? Say: It is a phone.'],
hints: ['six, seven, eight', 'It is a phone.'],
translations: ['请说 six, seven, eight678)。', '这是什么?请说:It is a phone(这是一部手机)。'],
),
'a0-04-c': LessonDialogue(
goal: '询问并报告三位号码',
prompts: ['What is your phone number?', 'Say a three-digit number again.'],
hints: ['My number is one-three-eight.', 'one-three-eight'],
translations: ['你的电话号码是多少?', '请再说一次三位数字。'],
),
'a0-08-a': LessonDialogue(
goal: '询问并说出星期一到三',
prompts: ['What day is it?', 'Say Monday, Tuesday, or Wednesday.'],
hints: ['What day is it?', 'It is Monday.'],
translations: ['今天星期几?', '请说 Monday, Tuesday, 或 Wednesday(周一、周二或周三)。'],
),
'a0-08-b': LessonDialogue(
goal: '说出星期四到日',
prompts: ['What day is it?', 'Say Thursday, Friday, Saturday, or Sunday.'],
hints: ['What day is it?', 'It is Friday.'],
translations: ['今天星期几?', '请说 Thursday, Friday, Saturday, 或 Sunday(周四、周五、周六或周日)。'],
),
'a0-08-c': LessonDialogue(
goal: '询问并说出整点',
prompts: ['What time is it?', 'Say one full time sentence.'],
hints: ['What time is it?', 'It is three oclock.'],
translations: ['现在几点了?', '请说一个完整的时间句子。'],
),
};
LessonDialogue dialogueByLessonId(String id) => a0Dialogues[id]!;
LessonDialogue dialogueBySegmentId(String segmentId, String lessonId) =>
a0SegmentDialogues[segmentId] ?? dialogueByLessonId(lessonId);