const MOCK_TRANSLATIONS = { 'hola': { en: 'Hello', zh: '你好' }, 'buenos días': { en: 'Good morning', zh: '早上好' }, 'buenas tardes': { en: 'Good afternoon', zh: '下午好' }, 'buenas noches': { en: 'Good night', zh: '晚安' }, 'hoy': { en: 'today', zh: '今天' }, 'ayer': { en: 'yesterday', zh: '昨天' }, 'mañana': { en: 'tomorrow', zh: '明天' }, 'fui': { en: 'I went', zh: '我去了' }, 'fui a': { en: 'I went to', zh: '我去了' }, 'voy': { en: 'I go', zh: '我去' }, 'voy a': { en: 'I am going to', zh: '我要去' }, 'estoy': { en: 'I am', zh: '我是' }, 'estoy muy': { en: 'I am very', zh: '我非常' }, 'tengo': { en: 'I have', zh: '我有' }, 'quiero': { en: 'I want', zh: '我想要' }, 'me gusta': { en: 'I like', zh: '我喜欢' }, 'me gustó': { en: 'I liked', zh: '我喜欢了' }, 'aprendí': { en: 'I learned', zh: '我学了' }, 'estudié': { en: 'I studied', zh: '我学习了' }, 'comí': { en: 'I ate', zh: '我吃了' }, 'bebí': { en: 'I drank', zh: '我喝了' }, 'leí': { en: 'I read', zh: '我读了' }, 'escribí': { en: 'I wrote', zh: '我写了' }, 'trabajé': { en: 'I worked', zh: '我工作了' }, 'descansé': { en: 'I rested', zh: '我休息了' }, 'caminé': { en: 'I walked', zh: '我散步了' }, 'corrí': { en: 'I ran', zh: '我跑步了' }, 'compré': { en: 'I bought', zh: '我买了' }, 'vi': { en: 'I saw', zh: '我看了' }, 'el': { en: 'the', zh: '' }, 'la': { en: 'the', zh: '' }, 'los': { en: 'the', zh: '' }, 'las': { en: 'the', zh: '' }, 'un': { en: 'a', zh: '' }, 'una': { en: 'a', zh: '' }, 'unos': { en: 'some', zh: '一些' }, 'unas': { en: 'some', zh: '一些' }, 'al': { en: 'to the', zh: '' }, 'del': { en: 'of the', zh: '' }, 'a': { en: 'to', zh: '' }, 'de': { en: 'of', zh: '' }, 'en': { en: 'in', zh: '在' }, 'para': { en: 'for', zh: '为了' }, 'por': { en: 'for / by', zh: '' }, 'con': { en: 'with', zh: '和' }, 'sin': { en: 'without', zh: '没有' }, 'sobre': { en: 'about', zh: '关于' }, 'mi': { en: 'my', zh: '我的' }, 'tu': { en: 'your', zh: '你的' }, 'su': { en: 'his / her / their', zh: '' }, 'nuestro': { en: 'our', zh: '我们的' }, 'amigo': { en: 'friend', zh: '朋友' }, 'amiga': { en: 'friend', zh: '朋友' }, 'familia': { en: 'family', zh: '家人' }, 'casa': { en: 'home', zh: '家' }, 'trabajo': { en: 'work', zh: '工作' }, 'escuela': { en: 'school', zh: '学校' }, 'parque': { en: 'park', zh: '公园' }, 'restaurante': { en: 'restaurant', zh: '餐厅' }, 'café': { en: 'cafe', zh: '咖啡馆' }, 'libro': { en: 'book', zh: '书' }, 'película': { en: 'movie', zh: '电影' }, 'música': { en: 'music', zh: '音乐' }, 'día': { en: 'day', zh: '天' }, 'noche': { en: 'night', zh: '夜晚' }, 'comida': { en: 'food', zh: '食物' }, 'agua': { en: 'water', zh: '水' }, 'tiempo': { en: 'time / weather', zh: '时间' }, 'feliz': { en: 'happy', zh: '开心的' }, 'cansado': { en: 'tired', zh: '累的' }, 'enfermo': { en: 'sick', zh: '生病的' }, 'bien': { en: 'well', zh: '好' }, 'mal': { en: 'bad', zh: '不好' }, 'muy': { en: 'very', zh: '非常' }, 'un poco': { en: 'a little', zh: '一点' }, 'mucho': { en: 'a lot', zh: '很多' }, 'y': { en: 'and', zh: '和' }, 'pero': { en: 'but', zh: '但是' }, 'porque': { en: 'because', zh: '因为' }, 'también': { en: 'also', zh: '也' }, 'no': { en: 'not', zh: '不' }, 'sí': { en: 'yes', zh: '是的' }, 'gracias': { en: 'thank you', zh: '谢谢' }, 'por favor': { en: 'please', zh: '请' }, 'lo siento': { en: 'sorry', zh: '对不起' }, 'nuevo': { en: 'new', zh: '新的' }, 'viejo': { en: 'old', zh: '旧的' }, 'grande': { en: 'big', zh: '大' }, 'pequeño': { en: 'small', zh: '小' }, 'bueno': { en: 'good', zh: '好的' }, 'malo': { en: 'bad', zh: '坏的' }, 'bonito': { en: 'pretty', zh: '漂亮的' }, 'rápido': { en: 'fast', zh: '快的' }, 'lento': { en: 'slow', zh: '慢的' }, 'aquí': { en: 'here', zh: '这里' }, 'allí': { en: 'there', zh: '那里' }, 'ahora': { en: 'now', zh: '现在' }, 'siempre': { en: 'always', zh: '总是' }, 'nunca': { en: 'never', zh: '从不' }, 'ya': { en: 'already', zh: '已经' }, 'todavía': { en: 'still', zh: '仍然' }, 'después': { en: 'after', zh: '之后' }, 'antes': { en: 'before', zh: '之前' }, 'más': { en: 'more', zh: '更多' }, 'menos': { en: 'less', zh: '更少' }, 'tan': { en: 'so', zh: '如此' }, 'como': { en: 'as / like', zh: '像' }, 'que': { en: 'that / than', zh: '比' }, 'este': { en: 'this', zh: '这个' }, 'ese': { en: 'that', zh: '那个' }, 'qué': { en: 'what', zh: '什么' }, 'quién': { en: 'who', zh: '谁' }, 'cuándo': { en: 'when', zh: '什么时候' }, 'dónde': { en: 'where', zh: '哪里' }, 'por qué': { en: 'why', zh: '为什么' }, 'cómo': { en: 'how', zh: '如何' }, 'mucho gusto': { en: 'nice to meet you', zh: '很高兴认识你' }, 'buena suerte': { en: 'good luck', zh: '好运' }, 'tener que': { en: 'have to', zh: '必须' }, 'tener hambre': { en: 'be hungry', zh: '饿了' }, 'tener sed': { en: 'be thirsty', zh: '渴了' }, 'tener sueño': { en: 'be sleepy', zh: '困了' }, 'tener razón': { en: 'be right', zh: '是对的' }, 'hacer calor': { en: 'be hot (weather)', zh: '热' }, 'hacer frío': { en: 'be cold (weather)', zh: '冷' }, 'estar bien': { en: 'be fine', zh: '没问题' } }; var SORTED_KEYS = Object.keys(MOCK_TRANSLATIONS).sort(function(a, b) { return b.length - a.length; }); function translateText(text) { if (!text || !text.trim()) return { english: '', chinese: '' }; var lower = text.toLowerCase().trim(); var enParts = []; var zhParts = []; var i = 0; while (i < lower.length) { var matched = false; for (var k = 0; k < SORTED_KEYS.length; k++) { var key = SORTED_KEYS[k]; if (lower.indexOf(key, i) === i) { var entry = MOCK_TRANSLATIONS[key]; if (entry.en) enParts.push(entry.en); if (entry.zh) zhParts.push(entry.zh); i += key.length; matched = true; break; } } if (!matched) { var ch = lower[i]; if (/[a-zà-ÿñ]/.test(ch)) { enParts.push(ch); } i++; } } var enStr = enParts.join(' ').replace(/\s+/g, ' ').trim(); var zhStr = zhParts.join('').trim(); enStr = enStr.charAt(0).toUpperCase() + enStr.slice(1); return { english: enStr || text, chinese: zhStr || text }; } function getVocabulary(text) { if (!text || !text.trim()) return []; var lower = text.toLowerCase().trim(); var seen = {}; var result = []; var i = 0; while (i < lower.length) { for (var k = 0; k < SORTED_KEYS.length; k++) { var key = SORTED_KEYS[k]; if (lower.indexOf(key, i) === i) { var entry = MOCK_TRANSLATIONS[key]; if (!seen[key] && entry.zh && key.indexOf(' ') === -1) { seen[key] = true; result.push({ word: key, english: entry.en, chinese: entry.zh }); } i += key.length; break; } } i++; } result.sort(function(a, b) { return b.word.length - a.word.length; }); return result; } function translateSelection(text) { if (!text || !text.trim()) return { english: '', chinese: '' }; return translateText(text); } function getVocabForWord(word) { var w = word.toLowerCase().trim(); var entry = MOCK_TRANSLATIONS[w]; return entry || null; } // Chinese -> Spanish helper dictionary const ZH_TO_ES = { '你好': 'Hola', '早上好': 'Buenos días', '下午好': 'Buenas tardes', '晚上好': 'Buenas noches', '晚安': 'Buenas noches', '再见': 'Adiós', '谢谢': 'Gracias', '请': 'Por favor', '对不起': 'Lo siento', '很高兴认识你': 'Mucho gusto', '祝你好运': 'Buena suerte', '是的': 'Sí', '不是': 'No', '今天': 'Hoy', '昨天': 'Ayer', '明天': 'Mañana', '现在': 'ahora', '已经': 'ya', '总是': 'siempre', '从不': 'nunca', '我': 'yo', '你': 'tú', '他': 'él', '她': 'ella', '我们': 'nosotros', '你们': 'vosotros', '他们': 'ellos', '我的': 'mi', '你的': 'tu', '和': 'y', '或者': 'o', '但是': 'pero', '因为': 'porque', '也': 'también', '非常': 'muy', '很': 'muy', '一点': 'un poco', '很多': 'mucho', '好的': 'bien', '朋友': 'amigo', '家': 'casa', '学校': 'escuela', '工作': 'trabajo', '公园': 'parque', '餐厅': 'restaurante', '图书馆': 'biblioteca', '超市': 'supermercado', '医院': 'hospital', '书': 'libro', '篮球': 'baloncesto', '足球': 'fútbol', '羽毛球': 'bádminton', '游泳': 'nadar', '跑步': 'correr', '咖啡': 'café', '茶': 'té', '水': 'agua', '电影': 'película', '音乐': 'música', '天气': 'tiempo', '时间': 'tiempo', '星期一': 'lunes', '星期二': 'martes', '星期三': 'miércoles', '星期四': 'jueves', '星期五': 'viernes', '星期六': 'sábado', '星期日': 'domingo', '一月': 'enero', '二月': 'febrero', '三月': 'marzo', '四月': 'abril', '五月': 'mayo', '六月': 'junio', '七月': 'julio', '八月': 'agosto', '九月': 'septiembre', '十月': 'octubre', '十一月': 'noviembre', '十二月': 'diciembre', '去': 'ir', '我去了': 'fui', '我去': 'voy', '我要': 'voy a', '我想': 'quiero', '我想要': 'quiero', '我有': 'tengo', '我学习': 'estudio', '我学习了': 'estudié', '我读书': 'leo', '我读了一本书': 'leí un libro', '我吃饭': 'como', '我吃了': 'comí', '我喝水': 'bebo agua', '我喝了': 'bebí', '我喜欢': 'me gusta', '我爱': 'me encanta', '我累了': 'Estoy cansado', '我很累': 'Estoy muy cansado', '我很开心': 'Estoy muy feliz', '我生病了': 'Estoy enfermo', '我正在学习': 'Estoy estudiando', '我必须工作': 'Tengo que trabajar', '我喜欢读书': 'Me gusta leer', '我喜欢听音乐': 'Me gusta escuchar música', '我想去旅行': 'Quiero viajar', '我有一个朋友': 'Tengo un amigo', '我没有钱': 'No tengo dinero', '今天我去公园': 'Hoy fui al parque', '今天我去学校': 'Hoy fui a la escuela', '今天我去工作': 'Hoy fui al trabajo', '昨天我去了公园': 'Ayer fui al parque', '明天我要去公园': 'Mañana voy al parque', '我和朋友去了公园': 'Fui al parque con mi amigo', '今天我和朋友去了公园': 'Hoy fui al parque con mi amigo', '今天天气很好': 'Hoy hace buen tiempo', '今天天气热': 'Hoy hace calor', '今天天气冷': 'Hoy hace frío', '我学习西班牙语': 'Estudio español', '我喜欢篮球': 'Me gusta el baloncesto', '我喜欢足球': 'Me gusta el fútbol', '我喜欢游泳': 'Me gusta nadar', '我喜欢跑步': 'Me gusta correr', '我喜欢打篮球': 'Me gusta jugar al baloncesto', '我喜欢打足球': 'Me gusta jugar al fútbol', '打篮球': 'jugar al baloncesto', '打足球': 'jugar al fútbol', '我喜欢篮球今天天气真好': 'Me gusta el baloncesto. Hoy hace muy buen tiempo.', '我喜欢篮球今天天气很好': 'Me gusta el baloncesto. Hoy hace buen tiempo.', '我要去打篮球': 'Voy a jugar al baloncesto', '我要去打篮球了': 'Voy a jugar al baloncesto', '我去打篮球': 'Voy a jugar al baloncesto', '我去打篮球了': 'Fui a jugar al baloncesto', '我要去踢足球': 'Voy a jugar al fútbol', '我要去踢足球了': 'Voy a jugar al fútbol', '我要去游泳': 'Voy a nadar', '我要去游泳了': 'Voy a nadar', '我去游泳了': 'Fui a nadar', '我要去跑步': 'Voy a correr', '我要去跑步了': 'Voy a correr', '我去跑步了': 'Fui a correr', '我要去图书馆': 'Voy a la biblioteca', '我去图书馆了': 'Fui a la biblioteca', '我要去学校': 'Voy a la escuela', '我去学校了': 'Fui a la escuela', '我要去工作': 'Voy al trabajo', '我去工作了': 'Fui al trabajo', '我想去公园': 'Quiero ir al parque', '我想去学校': 'Quiero ir a la escuela', '我想去图书馆': 'Quiero ir a la biblioteca', '我想去工作': 'Quiero ir al trabajo', '去公园': 'ir al parque', '去学校': 'ir a la escuela', '去图书馆': 'ir a la biblioteca', '去工作': 'ir al trabajo', '今天天气很好': 'Hoy hace buen tiempo', '今天天气真好': 'Hoy hace muy buen tiempo', '今天天气非常好': 'Hoy hace muy buen tiempo', '天气很好': 'hace buen tiempo', '天气真好': 'hace muy buen tiempo', '真好': 'muy bien', '很好': 'muy bien', '今天我去公园和我的朋友': 'Hoy fui al parque con mi amigo', '我去了公园和我的朋友': 'Fui al parque con mi amigo', '公园和我的朋友': 'el parque con mi amigo', '公园': 'el parque', '我的朋友': 'mi amigo', '妈妈': 'mamá', '爸爸': 'papá', '爷爷': 'abuelo', '奶奶': 'abuela', '外公': 'abuelo', '外婆': 'abuela', '哥哥': 'hermano mayor', '姐姐': 'hermana mayor', '弟弟': 'hermano menor', '妹妹': 'hermana menor', '儿子': 'hijo', '女儿': 'hija', '丈夫': 'marido', '妻子': 'esposa', '男朋友': 'novio', '女朋友': 'novia', '同事': 'colega', '邻居': 'vecino', '为什么': 'por qué', '什么': 'qué', '哪里': 'dónde', '什么时候': 'cuándo', '多少': 'cuánto', '谁': 'quién', '怎么': 'cómo', '星期': 'semana', }; var ZH_SORTED_KEYS = Object.keys(ZH_TO_ES).sort(function(a, b) { return b.length - a.length; }); function translateZhSegment(segment) { if (!segment || !segment.trim()) return ''; var input = segment.replace(/[\s,。!?、,.!?;;::""''()()]/g, ''); var result = ''; var matched = false; var i = 0; while (i < input.length) { var found = false; for (var k = 0; k < ZH_SORTED_KEYS.length; k++) { var key = ZH_SORTED_KEYS[k]; if (input.indexOf(key, i) === i) { result += ZH_TO_ES[key] + ' '; i += key.length; matched = true; found = true; break; } } if (!found) i++; } return matched ? result.trim() : ''; } function translateZhToEs(text) { if (!text || !text.trim()) return ''; var clauses = []; var seps = []; var cur = ''; for (var i = 0; i < text.length; i++) { var ch = text[i]; if (ch === '。' || ch === '!' || ch === '?' || ch === '!' || ch === '?' || ch === ';' || ch === ';') { clauses.push(cur.trim()); seps.push('.'); cur = ''; } else if (ch === ',' || ch === ',') { clauses.push(cur.trim()); seps.push(','); cur = ''; } else { cur += ch; } } clauses.push(cur.trim()); seps.push(''); var parts = []; for (var j = 0; j < clauses.length; j++) { if (!clauses[j]) continue; var translated = translateZhSegment(clauses[j]); if (translated) { parts.push(translated.replace(/[.。]+$/g, '')); } } if (parts.length === 0) return ''; function capitalizeFirst(s) { return s.charAt(0).toUpperCase() + s.slice(1); } function lowercaseFirst(s) { return s.charAt(0).toLowerCase() + s.slice(1); } var out = capitalizeFirst(parts[0]); var k = 1; for (var m = 0; m < seps.length && k < parts.length; m++) { if (seps[m] && k < parts.length) { out += (seps[m] === ',' ? ', ' + lowercaseFirst(parts[k]) : '. ' + capitalizeFirst(parts[k])); k++; } } while (k < parts.length) { out += '. ' + capitalizeFirst(parts[k]); k++; } if (!/[.!?]$/.test(out)) out += '.'; return out; } // Merge B1 vocabulary into translation dictionaries if (typeof B1_VOCAB !== 'undefined') { B1_VOCAB.forEach(function(item) { var es = item[0].toLowerCase(); MOCK_TRANSLATIONS[es] = { en: item[1], zh: item[2] }; if (item[2]) ZH_TO_ES[item[2]] = item[0]; }); SORTED_KEYS = Object.keys(MOCK_TRANSLATIONS).sort(function(a, b) { return b.length - a.length; }); ZH_SORTED_KEYS = Object.keys(ZH_TO_ES).sort(function(a, b) { return b.length - a.length; }); }