289 lines
44 KiB
JavaScript
289 lines
44 KiB
JavaScript
(function(g){"use strict";
|
||
var W={L1:{"red": {"pos": "adj", "meaning": "红色的", "unit": "S0-U0-L1", "diff": 1}, "hat": {"pos": "n", "meaning": "帽子", "unit": "S0-U0-L1", "diff": 1}, "blue": {"pos": "adj", "meaning": "蓝的", "unit": "S0-U0-L1", "diff": 1}, "bag": {"pos": "n", "meaning": "袋,包", "unit": "S0-U0-L1", "diff": 1}, "orange": {"pos": "n", "meaning": "橙子", "unit": "S1-U10-L3", "diff": 1}, "green": {"pos": "adj", "meaning": "绿色的", "unit": "S0-U0-L2", "diff": 1}, "dress": {"pos": "n", "meaning": "连衣裙", "unit": "S0-U0-L2", "diff": 1}, "there": {"pos": "adv", "meaning": "那里", "unit": "S0-U0-L3", "diff": 1}, "put": {"pos": "v", "meaning": "放", "unit": "S0-U0-L3", "diff": 1}, "purple": {"pos": "adj", "meaning": "紫色的", "unit": "S0-U0-L5", "diff": 1}, "give": {"pos": "v", "meaning": "给", "unit": "S0-U0-L3", "diff": 1}, "water": {"pos": "n", "meaning": "水", "unit": "S0-U0-L4", "diff": 1}, "here": {"pos": "adv", "meaning": "在这里", "unit": "S0-U0-L4", "diff": 1}, "dirty": {"pos": "adj", "meaning": "肮脏的", "unit": "S0-U0-L4", "diff": 1}, "clean": {"pos": "v", "meaning": "清洁", "unit": "S0-U0-L4", "diff": 1}, "pink": {"pos": "adj", "meaning": "粉红色的", "unit": "S0-U0-L2", "diff": 1}, "get": {"pos": "v", "meaning": "收到", "unit": "", "diff": 1}, "wall": {"pos": "n", "meaning": "墙", "unit": "S1-U1-L1", "diff": 1}, "table": {"pos": "n", "meaning": "桌子", "unit": "S1-U1-L1", "diff": 1}, "floor": {"pos": "n", "meaning": "地板", "unit": "S1-U1-L1", "diff": 1}, "hand": {"pos": "n", "meaning": "手", "unit": "S1-U1-L2", "diff": 1}, "foot": {"pos": "n", "meaning": "脚", "unit": "S1-U1-L2", "diff": 1}, "black": {"pos": "adj", "meaning": "黑的", "unit": "S1-U1-L2", "diff": 1}, "tomato": {"pos": "n", "meaning": "西红柿", "unit": "S1-U1-L3", "diff": 1}, "fish": {"pos": "n", "meaning": "鱼", "unit": "S1-U1-L3", "diff": 1}, "chicken": {"pos": "n", "meaning": "鸡肉", "unit": "S1-U1-L3", "diff": 1}, "nose": {"pos": "n", "meaning": "鼻子", "unit": "S1-U1-L4", "diff": 1}, "eye": {"pos": "n", "meaning": "眼睛", "unit": "S1-U1-L4", "diff": 1}, "brown": {"pos": "adj", "meaning": "棕色的", "unit": "S1-U1-L4", "diff": 1}, "yellow": {"pos": "adj", "meaning": "黄色的", "unit": "S1-U1-L5", "diff": 1}, "white": {"pos": "adj", "meaning": "白色的", "unit": "S1-U1-L5", "diff": 1}, "go": {"pos": "v", "meaning": "去,走", "unit": "S1-U2-L1", "diff": 1}, "dog": {"pos": "n", "meaning": "狗", "unit": "S1-U2-L1", "diff": 1}, "come": {"pos": "v", "meaning": "来", "unit": "S1-U2-L1", "diff": 1}, "cat": {"pos": "n", "meaning": "猫", "unit": "S1-U2-L1", "diff": 1}, "pie": {"pos": "n", "meaning": "馅饼", "unit": "S1-U2-L2", "diff": 1}, "can": {"pos": "v", "meaning": "能,会", "unit": "S1-U2-L4", "diff": 1}, "open": {"pos": "adj", "meaning": "开着的", "unit": "", "diff": 1}, "happy": {"pos": "adj", "meaning": "快乐的", "unit": "S1-U2-L5", "diff": 1}, "see": {"pos": "v", "meaning": "看见", "unit": "S1-U3-L1", "diff": 1}, "1": {"pos": "num", "meaning": "1", "unit": "S1-U3-L1", "diff": 1}, "paper": {"pos": "adj", "meaning": "纸质的", "unit": "", "diff": 1}, "book": {"pos": "n", "meaning": "书", "unit": "S1-U3-L2", "diff": 1}, "3": {"pos": "num", "meaning": "3", "unit": "S1-U3-L2", "diff": 1}, "2": {"pos": "num", "meaning": "2", "unit": "S1-U3-L2", "diff": 1}, "pen": {"pos": "n", "meaning": "钢笔", "unit": "S1-U3-L3", "diff": 1}, "box": {"pos": "n", "meaning": "盒子", "unit": "S1-U3-L3", "diff": 1}, "4": {"pos": "num", "meaning": "4", "unit": "S1-U3-L3", "diff": 1}, "6": {"pos": "num", "meaning": "6", "unit": "S1-U3-L4", "diff": 1}, "5": {"pos": "num", "meaning": "5", "unit": "S1-U3-L4", "diff": 1}, "sing": {"pos": "v", "meaning": "唱", "unit": "S1-U4-L1", "diff": 1}, "eat": {"pos": "v", "meaning": "吃", "unit": "S1-U4-L2", "diff": 1}, "7": {"pos": "num", "meaning": "7", "unit": "S1-U4-L2", "diff": 1}, "rug": {"pos": "n", "meaning": "小地毯", "unit": "S1-U4-L3", "diff": 1}, "door": {"pos": "n", "meaning": " 门", "unit": "", "diff": 1}, "bed": {"pos": "n", "meaning": "床", "unit": "S1-U4-L3", "diff": 1}, "9": {"pos": "num", "meaning": "9", "unit": "S1-U4-L4", "diff": 1}, "8": {"pos": "num", "meaning": "8", "unit": "S1-U4-L4", "diff": 1}, "10": {"pos": "num", "meaning": "10", "unit": "S1-U4-L5", "diff": 1}, "zoo": {"pos": "n", "meaning": "动物园", "unit": "", "diff": 1}, "zebra": {"pos": "n", "meaning": "斑马", "unit": "S1-U7-L2", "diff": 1}, "young": {"pos": "adj", "meaning": "年轻的", "unit": "", "diff": 1}, "year": {"pos": "n", "meaning": "年", "unit": "", "diff": 1}, "write": {"pos": "v", "meaning": "写", "unit": "", "diff": 1}, "woman": {"pos": "n", "meaning": "女人", "unit": "S1-U5-L1", "diff": 1}, "window": {"pos": "n", "meaning": "窗户", "unit": "S1-U12-L4", "diff": 1}, "warm": {"pos": "adj", "meaning": "温暖的", "unit": "", "diff": 1}, "want": {"pos": "v", "meaning": "想要", "unit": "", "diff": 1}, "walk": {"pos": "v", "meaning": "走", "unit": "S1-U7-L2", "diff": 1}, "very": {"pos": "adv", "meaning": "非常", "unit": "", "diff": 1}, "under": {"pos": "prep", "meaning": "在...下面", "unit": "S2-U14-L5", "diff": 1}, "try": {"pos": "v", "meaning": "尝试", "unit": "S1-U12-L5", "diff": 1}, "tree": {"pos": "n", "meaning": "树", "unit": "S1-U7-L1", "diff": 1}, "train": {"pos": "n", "meaning": "火车", "unit": "S1-U8-L1", "diff": 1}, "too": {"pos": "adv", "meaning": "也", "unit": "S1-U12-L2", "diff": 1}, "tomorrow": {"pos": "n", "meaning": "明天", "unit": "", "diff": 1}, "today": {"pos": "n", "meaning": "今天", "unit": "", "diff": 1}, "tiger": {"pos": "n", "meaning": "老虎", "unit": "S1-U5-L3", "diff": 1}, "those": {"pos": "pron", "meaning": "那些", "unit": "S1-U12-L1", "diff": 1}, "this": {"pos": "pron", "meaning": "这个", "unit": "S1-U12-L1", "diff": 1}, "these": {"pos": "pron", "meaning": "这些", "unit": "S1-U12-L1", "diff": 1}, "that": {"pos": "pron", "meaning": "那个", "unit": "S1-U12-L1", "diff": 1}, "tell": {"pos": "v", "meaning": "告诉", "unit": "", "diff": 1}, "teacher": {"pos": "n", "meaning": "老师", "unit": "S2-U14-L2", "diff": 1}, "talk": {"pos": "v", "meaning": "说话", "unit": "", "diff": 1}, "swim": {"pos": "v", "meaning": "游泳", "unit": "S1-U11-L5", "diff": 1}, "sun": {"pos": "n", "meaning": "太阳", "unit": "S1-U8-L2", "diff": 1}, "study": {"pos": "v", "meaning": "学习", "unit": "S2-U14-L1", "diff": 1}, "student": {"pos": "n", "meaning": "学生", "unit": "S2-U14-L1", "diff": 1}, "speak": {"pos": "v", "meaning": "说", "unit": "", "diff": 1}, "some": {"pos": "det", "meaning": "一些", "unit": "", "diff": 1}, "sofa": {"pos": "n", "meaning": "沙发", "unit": "", "diff": 1}, "sock": {"pos": "n", "meaning": "袜子", "unit": "", "diff": 1}, "small": {"pos": "adj", "meaning": "小的", "unit": "S1-U9-L1", "diff": 1}, "sleep": {"pos": "v", "meaning": "睡觉", "unit": "S1-U7-L4", "diff": 1}, "skirt": {"pos": "n", "meaning": "裙子", "unit": "S1-U9-L4", "diff": 1}, "sit": {"pos": "v", "meaning": "坐下", "unit": "S1-U8-L1", "diff": 1}, "sister": {"pos": "n", "meaning": "姐姐、妹妹", "unit": "S1-U8-L1", "diff": 1}, "short": {"pos": "adj", "meaning": "短的", "unit": "", "diff": 1}, "shoe": {"pos": "n", "meaning": "鞋", "unit": "", "diff": 1}, "shirt": {"pos": "n", "meaning": "衬衫", "unit": "S1-U9-L1", "diff": 1}, "ship": {"pos": "n", "meaning": "船", "unit": "", "diff": 1}, "sheep": {"pos": "n", "meaning": "绵羊", "unit": "S1-U5-L3", "diff": 1}, "school": {"pos": "n", "meaning": "学校", "unit": "S2-U14-L1", "diff": 1}, "say": {"pos": "v", "meaning": "说", "unit": "", "diff": 1}, "sad": {"pos": "adj", "meaning": "悲伤的", "unit": "", "diff": 1}, "run": {"pos": "v", "meaning": "跑", "unit": "", "diff": 1}, "ruler": {"pos": "n", "meaning": "尺子", "unit": "", "diff": 1}, "room": {"pos": "n", "meaning": "房间", "unit": "", "diff": 1}, "rice": {"pos": "n", "meaning": "米饭", "unit": "S1-U6-L4", "diff": 1}, "read": {"pos": "v", "meaning": "阅读", "unit": "", "diff": 1}, "radio": {"pos": "n", "meaning": "收音机", "unit": "S1-U9-L2", "diff": 1}, "potato": {"pos": "n", "meaning": "土豆", "unit": "S1-U7-L3", "diff": 1}, "play": {"pos": "v", "meaning": "玩", "unit": "S2-U14-L1", "diff": 1}, "plane": {"pos": "n", "meaning": "飞机", "unit": "S1-U8-L3", "diff": 1}, "pig": {"pos": "n", "meaning": "猪", "unit": "S1-U7-L4", "diff": 1}, "phone": {"pos": "v", "meaning": "给…...打电话", "unit": "", "diff": 1}, "people": {"pos": "n", "meaning": "人", "unit": "", "diff": 1}, "pencil": {"pos": "n", "meaning": "铅笔", "unit": "", "diff": 1}, "pea": {"pos": "n", "meaning": "豌豆", "unit": "", "diff": 1}, "pe": {"pos": "n", "meaning": "体育", "unit": "S1-U10-L4", "diff": 1}, "paint": {"pos": "v", "meaning": "(用颜料)绘画", "unit": "", "diff": 1}, "one": {"pos": "pron", "meaning": "一个人(或物)", "unit": "", "diff": 1}, "old": {"pos": "adj", "meaning": "年老的", "unit": "", "diff": 1}, "now": {"pos": "adv", "meaning": "现在", "unit": "", "diff": 1}, "night": {"pos": "n", "meaning": "夜晚", "unit": "S1-U12-L5", "diff": 1}, "nice": {"pos": "adj", "meaning": "好的", "unit": "S1-U6-L3", "diff": 1}, "new": {"pos": "adj", "meaning": "新的", "unit": "S1-U9-L2", "diff": 1}, "mum": {"pos": "n", "meaning": "妈妈", "unit": "S1-U8-L4", "diff": 1}, "mouth": {"pos": "n", "meaning": "嘴巴", "unit": "", "diff": 1}, "mother": {"pos": "n", "meaning": "母亲", "unit": "", "diff": 1}, "morning": {"pos": "n", "meaning": "早上", "unit": "S1-U12-L5", "diff": 1}, "month": {"pos": "n", "meaning": "月", "unit": "", "diff": 1}, "monkey": {"pos": "n", "meaning": "猴子", "unit": "S1-U7-L1", "diff": 1}, "minute": {"pos": "n", "meaning": "分钟", "unit": "", "diff": 1}, "mine": {"pos": "pron", "meaning": "我的", "unit": "", "diff": 1}, "milk": {"pos": "n", "meaning": "牛奶", "unit": "S1-U5-L2", "diff": 1}, "men": {"pos": "n", "meaning": "男人(man 的复数)", "unit": "", "diff": 1}, "meat": {"pos": "n", "meaning": "肉类", "unit": "S1-U10-L3", "diff": 1}, "me": {"pos": "pron", "meaning": "我", "unit": "S1-U12-L2", "diff": 1}, "mat": {"pos": "n", "meaning": "地垫", "unit": "S2-U14-L4", "diff": 1}, "many": {"pos": "det", "meaning": "许多", "unit": "", "diff": 1}, "man": {"pos": "n", "meaning": "男人", "unit": "S1-U5-L1", "diff": 1}, "make": {"pos": "v", "meaning": "制造", "unit": "S1-U6-L3", "diff": 1}, "love": {"pos": "v", "meaning": "爱", "unit": "S1-U12-L2", "diff": 1}, "lots of": {"pos": "det", "meaning": "大量的", "unit": "", "diff": 1}, "long": {"pos": "adj", "meaning": "长的", "unit": "S1-U7-L5 ", "diff": 1}},L2:{"dentist": {"pos": "n", "meaning": "牙医", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "department": {"pos": "n", "meaning": "部门", "cefr": "A2", "cambridge": "KET", "diff": 2}, "department store": {"pos": "n", "meaning": "百货商店", "cefr": "A2", "cambridge": "KET", "diff": 2}, "describe": {"pos": "v", "meaning": "描述", "cefr": "A2", "cambridge": "KET", "diff": 2}, "desert": {"pos": "v", "meaning": "遗弃", "cefr": "A2", "cambridge": "KET", "diff": 2}, "design": {"pos": "v", "meaning": "设计", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dessert": {"pos": "n", "meaning": "甜点", "cefr": "A2", "cambridge": "KET", "diff": 2}, "detailed": {"pos": "adj", "meaning": "详细的", "cefr": "A2", "cambridge": "KET", "diff": 2}, "diary": {"pos": "n", "meaning": "日记", "cefr": "A2", "cambridge": "KET/Flyers", "diff": 2}, "dictionary": {"pos": "n", "meaning": "词典", "cefr": "A2", "cambridge": "KET/Flyers", "diff": 2}, "die": {"pos": "v", "meaning": "消失;灭亡", "cefr": "A2", "cambridge": "KET", "diff": 2}, "difference": {"pos": "n", "meaning": "差别", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "different": {"pos": "adj", "meaning": "不同的", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "difficult": {"pos": "adj", "meaning": "困难的", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "digital": {"pos": "adj", "meaning": "数字的", "cefr": "A2", "cambridge": "KET", "diff": 2}, "digital camera": {"pos": "n", "meaning": "数码相机", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dinosaur": {"pos": "n", "meaning": "恐龙", "cefr": "A2", "cambridge": "KET/Flyers", "diff": 2}, "diploma": {"pos": "n", "meaning": "文凭", "cefr": "A2", "cambridge": "KET", "diff": 2}, "directions": {"pos": "n", "meaning": "方向", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dirty": {"pos": "adj", "meaning": "脏的", "cefr": "Pre-A1", "cambridge": "Starters", "diff": 2}, "disco": {"pos": "n", "meaning": "迪斯科", "cefr": "A2", "cambridge": "KET", "diff": 2}, "discount": {"pos": "n", "meaning": "折扣", "cefr": "A2", "cambridge": "KET", "diff": 2}, "discover": {"pos": "v", "meaning": "发现", "cefr": "A2", "cambridge": "KET", "diff": 2}, "discuss": {"pos": "vt", "meaning": "讨论", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dish": {"pos": "n", "meaning": "菜肴", "cefr": "A2", "cambridge": "KET", "diff": 2}, "display": {"pos": "v", "meaning": "显示", "cefr": "B1", "cambridge": "PET", "diff": 2}, "dive": {"pos": "v", "meaning": "潜水", "cefr": "A2", "cambridge": "KET", "diff": 2}, "diving": {"pos": "n", "meaning": "潜水", "cefr": "A2", "cambridge": "KET", "diff": 2}, "doctor": {"pos": "n", "meaning": "医生", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "document": {"pos": "n", "meaning": "文件", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dollar": {"pos": "n", "meaning": "美元", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dot": {"pos": "n", "meaning": "点", "cefr": "A2", "cambridge": "KET", "diff": 2}, "double": {"pos": "v", "meaning": "使加倍", "cefr": "A2", "cambridge": "KET", "diff": 2}, "double room": {"pos": "phrase", "meaning": "双人间", "cefr": "A2", "cambridge": "KET", "diff": 2}, "doubt": {"pos": "v", "meaning": "怀疑", "cefr": "B1", "cambridge": "PET", "diff": 2}, "download": {"pos": "v", "meaning": "下载", "cefr": "A2", "cambridge": "KET", "diff": 2}, "downstairs": {"pos": "adj", "meaning": "楼下的", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dozen": {"pos": "det", "meaning": "十二", "cefr": "B1", "cambridge": "PET", "diff": 2}, "draw": {"pos": "n", "meaning": "抽签", "cefr": "A2", "cambridge": "KET", "diff": 2}, "drawer": {"pos": "n", "meaning": "抽屉", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dream": {"pos": "v", "meaning": "梦想", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dress": {"pos": "v", "meaning": "穿衣服", "cefr": "A2", "cambridge": "KET", "diff": 2}, "dressed": {"pos": "adj", "meaning": "穿着衣服的", "cefr": "A2", "cambridge": "KET", "diff": 2}, "drive": {"pos": "v", "meaning": "驾车送(人)", "cefr": "A2", "cambridge": "KET", "diff": 2}, "driving licence": {"pos": "n", "meaning": "驾驶执照", "cefr": "A2", "cambridge": "KET", "diff": 2}, "drop": {"pos": "n", "meaning": "滴", "cefr": "A2", "cambridge": "KET", "diff": 2}, "drugstore": {"pos": "n", "meaning": "药店", "cefr": "A2", "cambridge": "KET", "diff": 2}, "drum": {"pos": "n", "meaning": "鼓", "cefr": "A2", "cambridge": "KET/Flyers", "diff": 2}, "dry": {"pos": "v", "meaning": "变干", "cefr": "A1", "cambridge": "Movers", "diff": 2}, "during": {"pos": "prep", "meaning": "在……期间", "cefr": "A2", "cambridge": "KET/Flyers", "diff": 2}, "duty-free": {"pos": "adj", "meaning": "免税的", "cefr": "B1", "cambridge": "PET", "diff": 2}, "dvd player": {"pos": "n", "meaning": "DVD播放机", "cefr": "A2", "cambridge": "KET", "diff": 2}}},P={L1:[{"structure": "be + adj", "module": "形容词结构", "mid": "M1", "examples": ["I am happy today.", "I am sad today."], "meaning": ["今天我很开心。", "今天我很难过。"]}, {"structure": "feel + adj", "module": "系表结构", "mid": "M1", "examples": ["I feel tired.", "I feel happy."], "meaning": ["我感到累。", "我感到开心。"]}, {"structure": "look + adj", "module": "系表结构", "mid": "M1", "examples": ["You look happy.", "He looks tired."], "meaning": ["你看起来很高兴。", "他看起来累了。"]}, {"structure": "adj and adj", "module": "并列形容词", "mid": "M1", "examples": ["The room is big and clean.", "The dog is small and cute."], "meaning": ["房间又大又干净。", "这只狗又小又可爱。"]}, {"structure": "S + V", "module": "动词与时态", "mid": "M2", "examples": ["I read books.", "We go to school."], "meaning": ["我读书。", "我们去上学。"]}, {"structure": "S + be + V-ing", "module": "动词与时态", "mid": "M2", "examples": ["I am reading now.", "She is cooking."], "meaning": ["我正在读书。", "她在做饭。"]}, {"structure": "do/does + V", "module": "动词与时态", "mid": "M2", "examples": ["Do you like apples?", "Does he like milk?"], "meaning": ["你喜欢苹果吗?", "他喜欢牛奶吗?"]}, {"structure": "can + V", "module": "动词与时态", "mid": "M2", "examples": ["I can swim.", "She can sing."], "meaning": ["我会游泳。", "她会唱歌。"]}],L2:[{"structure": "be + adj", "module": "形容词结构", "mid": "M1", "example": "I am happy today because the sun is shining.", "meaning": "今天我很开心,因为阳光灿烂。"}, {"structure": "feel/look + adj", "module": "系表结构", "mid": "M1", "example": "I feel nervous before my first day of school.", "meaning": "开学第一天前,我感到有些紧张。"}, {"structure": "look + adj", "module": "系表结构", "mid": "M1", "example": "He looks friendly, and he always says hello to everyone.", "meaning": "他看起来很友好,而且总是主动跟每个人打招呼。"}, {"structure": "adj and adj", "module": "并列形容词", "mid": "M1", "example": "She has a nice and friendly dog.", "meaning": "她有一只温顺友好的狗。"}, {"structure": "Something doesn’t feel right.", "module": "感觉异常", "mid": "M1", "example": "Something doesn’t feel right with my phone.", "meaning": "我的手机有点不太对劲。"}, {"structure": "This looks ..., but I’ll try my best.", "module": "状态对比", "mid": "M1", "example": "This looks difficult, but I’ll try my best.", "meaning": "这看起来很难,但我会尽力而为。"}, {"structure": "You look ... now.", "module": "感觉状态", "mid": "M1", "example": "You look happy now.", "meaning": "你现在看起来很开心。"}, {"structure": "The ice is too ... so we can’t ...", "module": "困难描述", "mid": "M1", "example": "The ice is too thin so we can't skate on it.", "meaning": "冰面太薄了,我们不能在上面滑冰。"}, {"structure": "How are you feeling today?", "module": "be + adj 描述", "mid": "M1", "example": "How are you feeling today? \nYou look happy!", "meaning": "你今天感觉怎么样? \n你看起来挺开心的!"}, {"structure": "I’m feeling ... today.", "module": "be + adj 描述", "mid": "M1", "example": "I'm feeling tired today.", "meaning": "今天我感觉有点累。"}, {"structure": "It’s very ... outside today.", "module": "be + adj 描述", "mid": "M1", "example": "It's very cold outside today.", "meaning": "今天外面非常冷。"}, {"structure": "You look ... in this picture.", "module": "be + adj 描述", "mid": "M1", "example": "You look happy in this picture.", "meaning": "在这张照片里,你看起来很开心。"}, {"structure": "My room is always ... and ....", "module": "be + adj 描述", "mid": "M1", "example": "My room is always warm and cozy.", "meaning": "我的房间总是温暖又舒适。"}, {"structure": "The movie was really ....", "module": "be + adj 描述", "mid": "M1", "example": "The movie was really funny.", "meaning": "这部电影真是太好笑了。"}, {"structure": "Our teacher is very ....", "module": "be + adj 描述", "mid": "M1", "example": "Our teacher is very patient.", "meaning": "我们的老师非常有耐心。"}, {"structure": "This bag is too ....", "module": "be + adj 描述", "mid": "M1", "example": "This bag is too small for all my books.", "meaning": "这个包装不下我所有的书。"}, {"structure": "Are you sure this is ....?", "module": "be + adj 描述", "mid": "M1", "example": "Are you sure this is warm enough?", "meaning": "你确定这够暖和吗?"}, {"structure": "I’m not sure if it’s ....", "module": "be + adj 描述", "mid": "M1", "example": "I’m not sure if it’s warm enough to swim today.", "meaning": "今天不太确定水温是否适合游泳。"}, {"structure": "What colour is ...?", "module": "be + adj 描述", "mid": "M1", "example": "What color is your new school uniform?", "meaning": "你的新校服是什么颜色的?"}, {"structure": "It’s ...", "module": "be + adj 描述", "mid": "M1", "example": "It's sunny today.", "meaning": "今天天气晴朗。"}, {"structure": "Are you tired?", "module": "be + adj 描述", "mid": "M1", "example": "Are you hungry after playing?", "meaning": "玩完之后你饿了吗?"}, {"structure": "Yes, I’m a bit ....", "module": "be + adj 描述", "mid": "M1", "example": "Yes, I’m a bit nervous about my first day at school.", "meaning": "是的,我对开学第一天有点紧张。"}, {"structure": "No, I’m not ....", "module": "be + adj 描述", "mid": "M1", "example": "No, I'm not tired.", "meaning": "不,我不累。"}, {"structure": "It’s so ... today!", "module": "be + adj 描述", "mid": "M1", "example": "It's so sunny today!", "meaning": "今天阳光真好啊!"}, {"structure": "This looks ....", "module": "be + adj 描述", "mid": "M1", "example": "This looks delicious.", "meaning": "这看起来很好吃。"}, {"structure": "You’re very ....", "module": "be + adj 描述", "mid": "M1", "example": "You're very kind.", "meaning": "你真是太好了。"}, {"structure": "How’s the weather today?", "module": "be + adj 描述", "mid": "M1", "example": "How’s the weather today? \nIt's sunny and warm.", "meaning": "今天天气怎么样? \n阳光很好,也很暖和。"}, {"structure": "It’s ... today.", "module": "be + adj 描述", "mid": "M1", "example": "It's sunny today.", "meaning": "今天天气晴朗。"}, {"structure": "Is it hot or cold?", "module": "be + adj 描述", "mid": "M1", "example": "Is it hot or cold?", "meaning": "是热还是冷?"}, {"structure": "It’s not very ....", "module": "be + adj 描述", "mid": "M1", "example": "It's not very expensive.", "meaning": "{中文翻译}\n这个不是很贵。"}, {"structure": "The sky is so ....", "module": "be + adj 描述", "mid": "M1", "example": "The sky is so blue today.", "meaning": "今天天空真蓝。"}, {"structure": "Everything looks....", "module": "be + adj 描述", "mid": "M1", "example": "Everything looks tidy.", "meaning": "一切看起来都井井有条。"}, {"structure": "The view is really ....", "module": "be + adj 描述", "mid": "M1", "example": "The view is really beautiful.", "meaning": "景色真是太美了。"}, {"structure": "That was very ....", "module": "be + adj 描述", "mid": "M1", "example": "That was very interesting.", "meaning": "那可真有意思。"}, {"structure": "You seem ....", "module": "be + adj 描述", "mid": "M1", "example": "You seem tired this morning.", "meaning": "今天早上你看起来有点累。"}, {"structure": "That’s really ...!", "module": "be + adj 描述", "mid": "M1", "example": "That’s really amazing!", "meaning": "这真是太棒了!"}, {"structure": "The story is very ....", "module": "be + adj 描述", "mid": "M1", "example": "The story is very exciting.", "meaning": "这个故事非常扣人心弦。"}, {"structure": "My parents are both ....", "module": "be + adj 描述", "mid": "M1", "example": "My parents are both very busy on weekdays.", "meaning": "我父母在工作日都非常忙。"}, {"structure": "I’m afraid it’s ....", "module": "be + adj 描述", "mid": "M1", "example": "I’m afraid it’s too cold.", "meaning": "恐怕天气太冷了。"}, {"structure": "It’s difficult to ....", "module": "be + adj 描述", "mid": "M1", "example": "It's difficult to find a good restaurant.", "meaning": "很难找到一家好餐馆。"}, {"structure": "It’s strange that ....", "module": "be + adj 描述", "mid": "M1", "example": "It's strange that the cat is sleeping so much today.", "meaning": "今天这只猫睡得这么多,真是奇怪。"}, {"structure": "The food smells....", "module": "be + adj 描述", "mid": "M1", "example": "The food smells wonderful.", "meaning": "这食物闻起来真香。"}, {"structure": "-er than", "module": "比较级", "mid": "M2", "example": "He is taller than me, but I run faster than him.", "meaning": "他比我高,但我跑得比他快。"}, {"structure": "What did you do yesterday?", "module": "动词与时态", "mid": "M2", "example": "What did you do yesterday? I watched a movie with my family.", "meaning": "你昨天干什么了?我和家人一起看了场电影。"}, {"structure": "I ... yesterday.", "module": "动词与时态", "mid": "M2", "example": "I called my grandmother yesterday.", "meaning": "昨天我给奶奶打了个电话。"}, {"structure": "What are you doing now?", "module": "动词与时态", "mid": "M2", "example": "What are you doing now? \nI am helping my mom cook dinner.", "meaning": "你现在在做什么? \n我正在帮我妈妈做晚饭。"}, {"structure": "I’m ... now.", "module": "动词与时态", "mid": "M2", "example": "I'm eating lunch now.", "meaning": "我正在吃午饭。"}, {"structure": "What will you do tomorrow?", "module": "动词与时态", "mid": "M2", "example": "What will you do tomorrow?", "meaning": "你明天打算做什么?"}]};
|
||
|
||
// ═══════════ BENCHMARKS ═══════════
|
||
var BM={
|
||
L1:{wordsPerSent:{ideal:5,min:3,max:7},targetsPerRound:{ideal:1,max:2},targetExposure:{ideal:3,min:1},dialogRounds:{min:2,ideal:4,max:8},questions:{min:1,ideal:2,max:5}},
|
||
L2:{wordsPerSent:{ideal:7,min:4,max:9},targetsPerRound:{ideal:1,max:2.5},targetExposure:{ideal:3,min:1},dialogRounds:{min:2,ideal:5,max:10},questions:{min:2,ideal:3,max:6}}
|
||
};
|
||
// Level-specific difficulty weights for cefr/cambridge levels
|
||
var DIFF_WEIGHT={A0:0,A1:1,A2:2,B1:4,B2:6,C1:8,C2:10,Pre_A1:0.5,Starters:0,Movers:1,Flyers:2,KET:3,PET:5};
|
||
|
||
// ── Utils ──
|
||
function ew(t){return t?t.toLowerCase().replace(/[^a-z\s'-]/g,' ').split(/\s+/).filter(function(w){return w.length>1}):[]}
|
||
function wc(t){return t?t.split(/\s+/).length:0}
|
||
function clamp(v,lo,hi){return Math.max(lo,Math.min(hi,v))}
|
||
function avg(arr){return arr.length?arr.reduce(function(a,b){return a+b},0)/arr.length:0}
|
||
|
||
// ═══════════ QUALITY SCORERS ═══════════
|
||
|
||
// 1. Vocabulary Alignment Score (0-100)
|
||
// Higher = more above-level vocabulary (worse alignment)
|
||
// Interpretation: >50 means significant over-level vocab
|
||
function scoreVocabAlignment(keyPreview,lvl){
|
||
var targets=keyPreview||[],lvl=lvl||'L1';
|
||
if(!targets.length)return{score:0,label:'无目标词',details:[],interpretation:'无法评分:缺少目标词汇数据'};
|
||
var scores=[],details=[];
|
||
targets.forEach(function(w){
|
||
var lo=(w||'').toLowerCase().trim();if(!lo)return;
|
||
var inL1=W.L1[lo],inL2=W.L2[lo];
|
||
if(lvl==='L1'){
|
||
if(inL1){scores.push(0);details.push({word:w,level:'L1',diff:inL1.diff||1,status:'in_level',msg:'"'+w+'" L1词库内 ✓'});}
|
||
else if(inL2){scores.push(70);details.push({word:w,level:'L2',cefr:inL2.cefr,cambridge:inL2.cambridge,status:'above_level',msg:'"'+w+'" 属L2词汇,超L1范围'});}
|
||
else{scores.push(90);details.push({word:w,level:'unknown',status:'out_of_scope',msg:'"'+w+'" 不在L1/L2词库,大概率超纲'});}
|
||
}else{
|
||
if(inL1){scores.push(10);details.push({word:w,level:'L1',diff:inL1.diff||1,status:'review_level',msg:'"'+w+'" L1词汇,用于L2属复习 ✓'});}
|
||
else if(inL2){scores.push(20);details.push({word:w,level:'L2',cefr:inL2.cefr,cambridge:inL2.cambridge,status:'in_level',msg:'"'+w+'" L2词库内 ✓'});}
|
||
else{scores.push(80);details.push({word:w,level:'unknown',status:'out_of_scope',msg:'"'+w+'" 不在L1/L2词库,大概率超纲'});}
|
||
}
|
||
});
|
||
var sc=avg(scores),above=details.filter(function(d){return d.status==='above_level'||d.status==='out_of_scope'}).length;
|
||
var interp=sc<15?'词汇完全在目标级别范围内':sc<40?'大部分词汇在级别内,少量超纲':sc<70?'约'+above+'/'+details.length+'词超纲,难度偏高':'多数词汇超出目标级别,难度显著偏高';
|
||
return{score:Math.round(sc),label:'词汇匹配度',details:details,overLevelCount:above,totalCount:details.length,interpretation:interp};
|
||
}
|
||
|
||
// 2. Sentence Complexity Score (0-100)
|
||
// Higher = sentences are too long/complex (worse for the level)
|
||
function scoreSentenceComplexity(dialogs,lvl){
|
||
var lines=dialogs||[],bm=BM[lvl||'L1']||BM.L1;
|
||
if(!lines.length)return{score:0,label:'无台词',details:[],interpretation:'无法评分:缺少对话台词'};
|
||
var wps=[],longCount=0;
|
||
lines.forEach(function(line){
|
||
var n=wc(line);
|
||
if(n>0){wps.push(n);if(n>bm.wordsPerSent.max+2)longCount++;}
|
||
});
|
||
var avgWPS=avg(wps),maxWPS=Math.max.apply(null,wps);
|
||
// Score: deviation from ideal. 0 = ideal, 100 = extreme deviation
|
||
var dev=avgWPS-bm.wordsPerSent.ideal;
|
||
var sc=clamp(Math.round(dev<0?Math.abs(dev)/bm.wordsPerSent.ideal*30:dev/bm.wordsPerSent.max*70+30),0,100);
|
||
var interp=sc<25?'句子简洁,适合'+lvl+'级别':sc<50?'句子长度适中':sc<75?'部分句子偏长('+longCount+'句超'+bm.wordsPerSent.max+'词),可能增加理解负担':'句子普遍偏长(均'+avgWPS.toFixed(1)+'词),显著超过'+lvl+'建议水平';
|
||
return{score:sc,label:'语句复杂度',avgWPS:Math.round(avgWPS*10)/10,maxWPS:maxWPS,longSentenceCount:longCount,totalSentences:wps.length,idealWPS:bm.wordsPerSent.ideal,bm_max:bm.wordsPerSent.max,interpretation:interp};
|
||
}
|
||
|
||
// 3. Knowledge Density Score (0-100)
|
||
// Higher = too many targets packed in (worse)
|
||
function scoreKnowledgeDensity(keyPreview,dialogRounds,lvl){
|
||
var tc=(keyPreview||[]).length,dr=Math.max(dialogRounds||1,1),bm=BM[lvl||'L1']||BM.L1;
|
||
var ratio=tc/dr;
|
||
// Ideal ratio ~1 target per 2 rounds for L1, 1 target per 1.5 rounds for L2
|
||
var idealRatio=bm.targetsPerRound.ideal;
|
||
// Score: 0 if sparse, 100 if too dense
|
||
var sc;
|
||
if(ratio<0.2)sc=10;
|
||
else if(ratio<idealRatio*0.6)sc=20;
|
||
else if(ratio<idealRatio*1.3)sc=Math.round(20+(ratio-idealRatio*0.6)/(idealRatio*1.3-idealRatio*0.6)*20);
|
||
else if(ratio<idealRatio*2.5)sc=Math.round(40+(ratio-idealRatio*1.3)/(idealRatio*2.5-idealRatio*1.3)*40);
|
||
else sc=clamp(Math.round(80+(ratio-idealRatio*2.5)/idealRatio*20),0,100);
|
||
var interp=sc<30?'知识密度偏低('+tc+'词/'+dr+'轮),学习效率可提升'
|
||
:sc<55?'知识密度适中('+tc+'词/'+dr+'轮),节奏合理 ✓'
|
||
:sc<75?'知识密度偏高('+tc+'词/'+dr+'轮),学生可能吸收不足'
|
||
:'知识密度过高('+tc+'词/'+dr+'轮),建议拆分或减少目标';
|
||
return{score:sc,label:'知识密度',targetCount:tc,dialogRounds:dr,ratio:Math.round(ratio*100)/100,idealRatio:Math.round(idealRatio*100)/100,interpretation:interp};
|
||
}
|
||
|
||
// 4. Knowledge Exposure Score (0-100)
|
||
// Higher = better exposure (positive metric)
|
||
// "How thoroughly do target words appear in the dialog?"
|
||
function scoreKnowledgeExposure(keyPreview,allDialogs,lvl){
|
||
var targets=keyPreview||[],dialogs=allDialogs||[],bm=BM[lvl||'L1']||BM.L1;
|
||
if(!targets.length||!dialogs.length)return{score:0,label:'无数据',details:[],interpretation:'无法评分:缺少目标词或台词数据'};
|
||
var dText=dialogs.join(' ').toLowerCase(),scores=[],details=[];
|
||
targets.forEach(function(w){
|
||
var lo=(w||'').toLowerCase().trim();if(!lo)return;
|
||
var re=new RegExp('\\b'+lo.replace(/[-\/\\^$*+?.()|[\]{}]/g,'\\$&')+'\\b','g');
|
||
var cnt=(dText.match(re)||[]).length;
|
||
// Score: 0 if absent, 100 if 3+ occurrences
|
||
var sc=cnt===0?0:cnt===1?30:cnt===2?70:cnt>=bm.targetExposure.ideal?100:Math.round(70+(cnt-2)/(bm.targetExposure.ideal-2)*30);
|
||
scores.push(sc);
|
||
details.push({word:w,count:cnt,score:sc,status:cnt===0?'zero':cnt===1?'low':cnt===2?'moderate':'good',msg:'"'+w+'" 出现'+cnt+'次'+(cnt===0?' ⚠️ 零暴露':cnt<bm.targetExposure.ideal?'':' ✓')});
|
||
});
|
||
var ascore=Math.round(avg(scores));
|
||
var zeroCnt=details.filter(function(d){return d.status==='zero'}).length;
|
||
var interp=ascore>=90?'全部目标词曝光充分 ✓':ascore>=60?'多数目标词曝光良好,'+zeroCnt+'个零暴露':ascore>=30?zeroCnt+'个目标词零暴露,'+details.filter(function(d){return d.status==='low'}).length+'个曝光不足':'知识点严重曝光不足,'+zeroCnt+'个目标词完全未出现';
|
||
return{score:ascore,label:'知识点曝光度',details:details,zeroExposureCount:zeroCnt,lowExposureCount:details.filter(function(d){return d.status==='low'}).length,perfectExposureCount:details.filter(function(d){return d.status==='good'}).length,idealExposure:bm.targetExposure.ideal,interpretation:interp};
|
||
}
|
||
|
||
// 5. Content Coverage Score (0-100)
|
||
// How adequate is the component's content structure?
|
||
function scoreContentCoverage(summary,lvl){
|
||
var bm=BM[lvl||'L1']||BM.L1,s=summary||{};
|
||
var scores=[],details=[];
|
||
// Dialog rounds
|
||
var dr=s.dialogRounds||0;
|
||
if(dr<=0){scores.push(0);details.push('无对话结构 ⚠️');}
|
||
else if(dr<bm.dialogRounds.min){scores.push(40);details.push('对话仅'+dr+'轮(不足'+bm.dialogRounds.min+'轮)');}
|
||
else if(dr<=bm.dialogRounds.max){scores.push(95);details.push('对话'+dr+'轮 结构合理 ✓');}
|
||
else{scores.push(70);details.push('对话'+dr+'轮 偏多,可能冗长');}
|
||
// Questions
|
||
var qc=s.questionCount||0;
|
||
if(qc<=0){scores.push(0);details.push('无练习题 ⚠️');}
|
||
else if(qc>=bm.questions.min&&qc<=bm.questions.max){scores.push(95);details.push('练习'+qc+'题 数量合理 ✓');}
|
||
else if(qc<bm.questions.min){scores.push(50);details.push('练习'+qc+'题 偏少');}
|
||
else{scores.push(70);details.push('练习'+qc+'题 偏多');}
|
||
// Learning points
|
||
var lp=s.learningItems||s.learningParts||0;
|
||
if(lp>0){scores.push(lp<=4?95:75);details.push('学习点'+lp+'个'+(lp<=4?' ✓':''));}
|
||
// Feedback
|
||
var fb=s.feedbackCount||0;
|
||
if(s.questionCount>0&&fb>0){scores.push(fb>=s.questionCount?95:60);details.push('反馈'+fb+'条'+(fb>=s.questionCount?' ✓':'(不足)'));}
|
||
var ascore=Math.round(avg(scores));
|
||
return{score:ascore,label:'内容完整度',scores:scores,details:details,interpretation:ascore>=85?'内容结构完整 ✓':ascore>=60?'内容结构基本完整,部分环节可加强':'内容结构不完整,缺少关键教学环节'};
|
||
}
|
||
|
||
// ═══════════ BEHAVIORAL CORRELATION ═══════════
|
||
|
||
// Cross-analyze quality scores with behavioral metrics
|
||
function correlateBehavioral(qualityScores,item,lvl){
|
||
var insights=[],p=Number(item&&item.perfect)||0,o=Number(item&&item.oops)||0;
|
||
// 1. Vocabulary difficulty vs Perfect rate
|
||
var vs=qualityScores.vocabAlignment;
|
||
if(vs&&vs.score>40&&p<75)insights.push({type:'vocab_difficulty_impact',confidence:vs.score>70?'high':'medium',
|
||
insight:'词汇匹配度低('+vs.score+'分):'+vs.overLevelCount+'/'+vs.totalCount+'词超纲,可能解释Perfect率'+p+'%偏低。超纲词:'+vs.details.filter(function(d){return d.status!=='in_level'}).map(function(d){return d.word}).join('、'),
|
||
action:'建议替换超纲词汇为'+lvl+'词库内等价词,或降低难度等级'});
|
||
// 2. Sentence complexity vs Oops rate
|
||
var ss=qualityScores.sentenceComplexity;
|
||
if(ss&&ss.score>50&&o>5)insights.push({type:'complexity_oops_correlation',confidence:ss.score>75?'high':'medium',
|
||
insight:'语句复杂度偏高('+ss.score+'分):均'+ss.avgWPS+'词/句(建议≤'+ss.bm_max+'词),'+ss.longSentenceCount+'/'+ss.totalSentences+'句超长。高Oops('+o+'%)可能与理解门槛有关',
|
||
action:'建议拆长句为短句(每句≤'+ss.bm_max+'词),降低单次听力/阅读负荷'});
|
||
// 3. Knowledge density vs Perfect rate
|
||
var ks=qualityScores.knowledgeDensity;
|
||
if(ks&&ks.score>60&&p<75)insights.push({type:'density_perfect_impact',confidence:ks.score>80?'high':'medium',
|
||
insight:'知识密度过高('+ks.score+'分):'+ks.targetCount+'个目标词/'+ks.dialogRounds+'轮对话,学生吸收压力大,Perfect率'+p+'%与此相关',
|
||
action:'建议减少目标词数或增加对话轮数,降低单轮知识密度'});
|
||
// 4. Knowledge exposure vs Perfect rate
|
||
var es=qualityScores.knowledgeExposure;
|
||
if(es&&es.score<50&&p<80)insights.push({type:'exposure_perfect_gap',confidence:es.score<25?'high':'medium',
|
||
insight:'知识点曝光不足('+es.score+'分):'+es.zeroExposureCount+'个目标词零暴露,学生未在语境中充分接触目标语言',
|
||
action:'建议在对话中增加目标词的自然复现,每个目标词至少出现'+es.idealExposure+'次'});
|
||
// 5. Good patterns (positive)
|
||
if(vs&&vs.score<15&&p>=80)insights.push({type:'good_alignment',confidence:'low',
|
||
insight:'词汇难度匹配良好('+vs.score+'分)+高Perfect('+p+'%):内容难度与学生水平匹配 ✓'});
|
||
if(ss&&ss.score<25&&o<=5)insights.push({type:'good_complexity',confidence:'low',
|
||
insight:'语句简洁('+ss.score+'分)+低Oops('+o+'%):语言难度控制在合理范围 ✓'});
|
||
return{insights:insights,summary:insights.length+'条诊断洞察'};
|
||
}
|
||
|
||
// ═══════════ COMPONENT COMPARISON ═══════════
|
||
function compareComponents(compA,compB,lvl){
|
||
function qs(c){return evaluate(c.summary,c.item,lvl).qualityScores;}
|
||
var qa=qs(compA),qb=qs(compB),comparisons=[];
|
||
['vocabAlignment','sentenceComplexity','knowledgeDensity','knowledgeExposure','contentCoverage'].forEach(function(k){
|
||
if(qa[k]&&qb[k]){
|
||
var da=qa[k].score-qb[k].score;
|
||
// vocabAlignment, sentenceComplexity, knowledgeDensity: lower=better. knowledgeExposure, contentCoverage: higher=better
|
||
var lowerBetter=['vocabAlignment','sentenceComplexity','knowledgeDensity'].indexOf(k)>=0;
|
||
var aBetter=lowerBetter?(da<0):(da>0);
|
||
var winner=aBetter?'A':'B',loser=aBetter?'B':'A';
|
||
if(Math.abs(da)>=10)comparisons.push({dimension:qa[k].label,diff:Math.abs(da),winner:winner,mag:Math.abs(da),msg:qa[k].label+':组件'+winner+'优于组件'+loser+'(差'+Math.abs(da)+'分)'});
|
||
}
|
||
});
|
||
return{comparisons:comparisons,summary:comparisons.length+'个维度有显著差异(≥10分)'};
|
||
}
|
||
|
||
// ═══════════ RISK FLAGS ═══════════
|
||
|
||
function analyzeRisks(qualityScores,item,lvl){
|
||
var flags=[],p=Number(item&&item.perfect)||0,o=Number(item&&item.oops)||0;
|
||
if(qualityScores.vocabAlignment&&qualityScores.vocabAlignment.score>50){
|
||
var ol=qualityScores.vocabAlignment.overLevelCount,tt=qualityScores.vocabAlignment.totalCount;
|
||
flags.push({risk:'vocab_overlevel',severity:qualityScores.vocabAlignment.score>75?'high':'medium',
|
||
detail:ol+'/'+tt+'目标词超纲',impact:'超纲词增加认知负荷 → Oops↑ Perfect↓'});
|
||
}
|
||
if(qualityScores.sentenceComplexity&&qualityScores.sentenceComplexity.score>60){
|
||
flags.push({risk:'sentence_too_long',severity:qualityScores.sentenceComplexity.score>80?'high':'medium',
|
||
detail:'均'+qualityScores.sentenceComplexity.avgWPS+'词/句(建议≤'+qualityScores.sentenceComplexity.bm_max+')',impact:'长句增加理解门槛 → Oops↑ 完成率↓'});
|
||
}
|
||
if(qualityScores.knowledgeExposure&&qualityScores.knowledgeExposure.zeroExposureCount>0){
|
||
flags.push({risk:'zero_exposure',severity:qualityScores.knowledgeExposure.zeroExposureCount>=qualityScores.knowledgeExposure.details.length/2?'high':'medium',
|
||
detail:qualityScores.knowledgeExposure.zeroExposureCount+'个目标词零暴露',impact:'学生未在语境中接触目标语言 → 学习效果差'});
|
||
}
|
||
if(qualityScores.knowledgeDensity&&qualityScores.knowledgeDensity.score>70){
|
||
flags.push({risk:'over_dense',severity:qualityScores.knowledgeDensity.score>85?'high':'medium',
|
||
detail:qualityScores.knowledgeDensity.targetCount+'词/'+qualityScores.knowledgeDensity.dialogRounds+'轮',impact:'知识密度过高 → 学生吸收困难 → Perfect↓'});
|
||
}
|
||
if(qualityScores.contentCoverage&&qualityScores.contentCoverage.score<60){
|
||
flags.push({risk:'thin_content',severity:qualityScores.contentCoverage.score<40?'high':'medium',
|
||
detail:'内容完整度仅'+qualityScores.contentCoverage.score+'分',impact:'缺少关键教学环节 → 教学效果难以保证'});
|
||
}
|
||
// Behavioral red flags
|
||
if(p<70&&o>=10)flags.push({risk:'critical_performance',severity:'high',detail:'Perfect='+p+'%/Oops='+o+'%',impact:'关键内容组件表现严重不达标,需优先排查'});
|
||
else if(p<70)flags.push({risk:'low_perfect',severity:'medium',detail:'Perfect='+p+'%',impact:'学习吸收不足,建议复核内容质量和难度'});
|
||
else if(o>=10)flags.push({risk:'high_oops',severity:'medium',detail:'Oops='+o+'%',impact:'操作或理解阻塞,建议复核交互设计和内容清晰度'});
|
||
return{flags:flags,severityCounts:{high:flags.filter(function(f){return f.severity==='high'}).length,medium:flags.filter(function(f){return f.severity==='medium'}).length},summary:flags.length+'个风险项('+flags.filter(function(f){return f.severity==='high'}).length+'高/'+flags.filter(function(f){return f.severity==='medium'}).length+'中)'};
|
||
}
|
||
|
||
// ═══════════ MAIN API ═══════════
|
||
|
||
/**
|
||
* evaluate(summary, item, level)
|
||
* summary: summarizeComponentContent() 的返回值
|
||
* item: {perfect, oops, good, cType, cId, ...} 组件的行为指标
|
||
* level: "L1" | "L2"
|
||
* Returns: {qualityScores, behavioralInsights, riskAnalysis, overallScore}
|
||
*/
|
||
function evaluate(summary,item,lvl){
|
||
var l=lvl||'L1',s=summary||{},it=item||{};
|
||
var allDialogs=(s.realContent&&s.realContent.dialogs)||[];
|
||
if(!allDialogs.length&&s.dialogLines)allDialogs=s.dialogLines.filter(function(l){return typeof l==='string'}).map(function(l){return l});
|
||
|
||
var qs={};
|
||
qs.vocabAlignment=scoreVocabAlignment(s.keyPreview,l);
|
||
qs.sentenceComplexity=scoreSentenceComplexity(allDialogs,l);
|
||
qs.knowledgeDensity=scoreKnowledgeDensity(s.keyPreview,s.dialogRounds,l);
|
||
qs.knowledgeExposure=scoreKnowledgeExposure(s.keyPreview,allDialogs,l);
|
||
qs.contentCoverage=scoreContentCoverage(s,l);
|
||
|
||
// Overall score: weighted average
|
||
// Vocab alignment and exposure are key for learning quality
|
||
var weights={vocabAlignment:0.30,sentenceComplexity:0.20,knowledgeDensity:0.10,knowledgeExposure:0.30,contentCoverage:0.10};
|
||
// Positive-direction metrics (higher=better): invert for overall problem score
|
||
var posMetrics={knowledgeExposure:true,contentCoverage:true};
|
||
var overall=0,wsum=0;
|
||
Object.keys(weights).forEach(function(k){if(qs[k]&&qs[k].score!==undefined){
|
||
var s=posMetrics[k]?(100-qs[k].score):qs[k].score;
|
||
overall+=s*weights[k];wsum+=weights[k];
|
||
}});
|
||
overall=wsum>0?Math.round(overall/wsum):null;
|
||
// Boost: if behavioral data shows critical issues, raise overall score
|
||
var p=Number(it.perfect)||0,o=Number(it.oops)||0;
|
||
if(p>0&&p<60&&overall!==null)overall=Math.round(overall*0.7+15);
|
||
if(o>15&&overall!==null)overall=Math.round(overall*0.7+15);
|
||
|
||
var bi=correlateBehavioral(qs,it,l);
|
||
var ra=analyzeRisks(qs,it,l);
|
||
|
||
return{
|
||
level:l,
|
||
componentType:it.cType||it.type||'',
|
||
componentId:it.cId||'',
|
||
qualityScores:qs,
|
||
overallQualityScore:overall,
|
||
overallLabel:overall===null?'无法计算':overall<15?'优(内容质量高)':overall<30?'良(质量较好)':overall<50?'中(有提升空间)':'差(需优化)',
|
||
behavioralInsights:bi,
|
||
riskAnalysis:ra,
|
||
timestamp:new Date().toISOString()
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Quick evaluate: just the quality scores, no behavioral correlation
|
||
*/
|
||
function score(summary,lvl){return evaluate(summary,null,lvl).qualityScores;}
|
||
|
||
/**
|
||
* Get benchmarks for reference
|
||
*/
|
||
function benchmarks(lvl){return BM[lvl||'L1']||BM.L1;}
|
||
|
||
// ── Export ──
|
||
g.PedagogyRules={VERSION:'3.0.0',
|
||
evaluate:evaluate,score:score,benchmarks:benchmarks,compare:compareComponents,
|
||
scoreVocabAlignment:scoreVocabAlignment,scoreSentenceComplexity:scoreSentenceComplexity,
|
||
scoreKnowledgeDensity:scoreKnowledgeDensity,scoreKnowledgeExposure:scoreKnowledgeExposure,
|
||
scoreContentCoverage:scoreContentCoverage,
|
||
correlateBehavioral:correlateBehavioral,analyzeRisks:analyzeRisks,
|
||
WORD_LISTS:W,PATTERNS:P,BENCHMARKS:BM
|
||
};
|
||
console.log('[PedagogyRules v3] L1 words:'+Object.keys(W.L1).length+' L2 words:'+Object.keys(W.L2).length+' L1 pat:'+P.L1.length+' L2 pat:'+P.L2.length);
|
||
})(typeof window!=='undefined'?window:this);
|