Files
fitness-coach/backend/scripts/translate-exercises.mjs
wm 70ff806042 feat: 小程序连接服务器IP + 同步未提交开发
- miniprogram/config.js: BASE_URL 指向 http://192.227.237.8:3001
- 动作标题中文化(nameZh),搜索匹配 name/nameZh/nameEn
- 新增计划/收藏/我的 等页面与组件
- 后端 Docker 化(Dockerfile/.dockerignore)与翻译脚本
- .gitignore 补充 .DS_Store
2026-07-22 14:05:30 +08:00

339 lines
28 KiB
JavaScript
Raw Permalink 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.

// 动作标题中文化引擎 v2
// 策略:短语词典(习语优先)→ 词元词典(大幅扩充)→ 词干归并 → 未知英文做音译兜底
// 保证 100% 中文化且无生硬英文残留只保留数字与少数专有器械缩写EZ/SZ/TRX/BOSU
import fs from 'fs';
const DATA = '/Users/wm/WorkBuddy/健身/fitness-coach/backend/src/exercises/data/exercises.json';
const PHRASES = [
['push up', '俯卧撑'], ['pull up', '引体向上'], ['chin up', '下巴引体'],
['sit-up', '仰卧起坐'], ['pull-up', '引体向上'], ['push-up', '俯卧撑'], ['chin-up', '下巴引体'],
['bench press', '卧推'], ['incline bench', '上斜凳'], ['decline bench', '下斜凳'],
['flat bench', '平板凳'], ['chest press', '胸推'], ['shoulder press', '肩上推举'],
['overhead press', '过顶推举'], ['military press', '军用推举'], ['arnold press', '阿诺德推举'],
['landmine press', '地雷推举'], ['leg press', '腿举'], ['leg curl', '腿弯举'],
['leg extension', '腿屈伸'], ['calf raise', '提踵'], ['sit up', '仰卧起坐'],
['side bend', '侧屈'], ['v up', 'V字挺身'], ['good morning', '早安式'],
['romanian deadlift', '罗马尼亚硬拉'], ['stiff leg deadlift', '直腿硬拉'],
['sumo deadlift', '相扑硬拉'], ['hip thrust', '髋推'], ['glute bridge', '臀桥'],
['hip bridge', '臀桥'], ['wall sit', '靠墙静蹲'], ['wall ball', '墙球'],
['battle rope', '战绳'], ['mountain climber', '登山跑'], ['russian twist', '俄罗斯转体'],
['bicycle crunch', '蹬车卷腹'], ['reverse crunch', '反向卷腹'], ['cable crossover', '绳索夹胸'],
['pec deck', '夹胸器'], ['lat pulldown', '高位下拉'], ['pulldown', '下拉'],
['preacher curl', '传教士弯举'], ['hammer curl', '锤式弯举'], ['bicep curl', '二头弯举'],
['tricep extension', '三头下压'], ['triceps pushdown', '三头下压'], ['skull crusher', '仰卧臂屈伸'],
['lateral raise', '侧平举'], ['front raise', '前平举'], ['rear delt raise', '后束平举'],
['rear delt fly', '后束飞鸟'], ['face pull', '面拉'], ['kettlebell swing', '壶铃摆荡'],
['dumbbell swing', '哑铃摆荡'], ['jump squat', '深蹲跳'], ['jump lunge', '箭步蹲跳'],
['split squat', '分腿蹲'], ['bulgarian split squat', '保加利亚分腿蹲'], ['goblet squat', '高脚杯深蹲'],
['front squat', '前蹲'], ['back squat', '背蹲'], ['overhead squat', '过顶深蹲'],
['box jump', '跳箱'], ['burpee', '波比跳'], ['jumping jack', '开合跳'],
['bear crawl', '熊爬'], ['crab walk', '蟹行'], ['bird dog', '鸟狗式'],
['dead bug', '死虫式'], ['plank', '平板支撑'], ['side plank', '侧平板'],
['hollow hold', ' hollow支撑'], ['superman', '超人式'], ['resistance band', '阻力带'],
['mini band', '迷你弹力带'], ['loop band', '环形弹力带'], ['exercise ball', '健身球'],
['medicine ball', '药球'], ['stability ball', '瑞士球'], ['swiss ball', '瑞士球'],
['bosu ball', '博苏球'], ['foam roller', '泡沫轴'], ['foam roll', '泡沫轴'],
['ab wheel', '健腹轮'], ['wheel roller', '健腹轮'], ['smith machine', '史密斯机'],
['cable machine', '绳索器械'], ['ez bar', '曲杠'], ['ez barbell', '曲杠铃'], ['ez-bar', '曲杠'], ['ez-barbell', '曲杠铃'],
['pull up bar', '单杠'], ['pullup bar', '单杠'], ['parallel bars', '双杠'],
['body weight', '自重'], ['bodyweight', '自重'], ['overhand grip', '正握'],
['underhand grip', '反握'], ['neutral grip', '对握'], ['close grip', '窄握'],
['wide grip', '宽握'], ['reverse grip', '反握'], ['hammer grip', '锤式握'],
['mixed grip', '混握'], ['single leg', '单腿'], ['single arm', '单臂'],
['double leg', '双腿'], ['both legs', '双腿'], ['both arms', '双臂'],
['one leg', '单腿'], ['one arm', '单臂'], ['t bar', 'T杆'], ['t-bar', 'T杆'],
['dumbbell row', '哑铃划船'], ['barbell row', '杠铃划船'], ['incline row', '上斜划船'],
['seated row', '坐姿划船'], ['cable row', '绳索划船'], ['upright row', '直立划船'],
['inverted row', '反向划船'], ['bent over', '俯身'], ['bent-over', '俯身'], ['lying', '仰卧'],
['pullover', '过顶臂屈伸'], ['clean and press', '抓举推举'], ['clean', '抓举'],
['snatch', '挺举'], ['jerk', '上挺'], ['thruster', '推举蹲'], ['zercher squat', '泽彻深蹲'], ['pin presses', '销钉推'],
['hack squat', '哈克深蹲'], ['jefferson squat', '杰弗逊深蹲'], ['pendlay row', '彭德雷划船'],
['guillotine bench press', '断头台卧推'], ['jm bench press', '杰姆卧推'], ['rack pull', '架上拉'],
['skullcrusher', '碎颅者'], ['skull crusher', '碎颅者'], ['pin presses', '销钉推'],
['cuban press', '古巴推举'], ['scott press', '斯科特推举'], ['tate press', '泰特推举'],
['w-press', 'W推举'], ['waiter biceps curl', '侍者弯举'], ['zottman preacher curl', '佐特曼传教士弯举'],
['figure 8', '8字'], ['turkish get up', '土耳其起立'], ['pike push up', '派克俯卧撑'],
['diamond push-up', '钻石俯卧撑'], ['clap push up', '击掌俯卧撑'], ['clock push-up', '时钟俯卧撑'],
['spider curl', '蜘蛛弯举'], ['french press', '法式推举'], ['sumo pull through', '相扑穿插'],
['sissy squat', '少女深蹲'], ['cossack squats', '哥萨克深蹲'], ['pistol squat', '手枪深蹲'],
['potty squat', '幼儿深蹲'], ['frog crunch', '蛙式卷腹'], ['windmill', '风车'],
['renegade row', '叛徒划船'], ['see-saw press', '跷跷板推举'], ['gironda sternum chin', '吉龙达下胸引体'],
['world greatest stretch', '世界最佳拉伸'], ['butterfly yoga pose', '蝴蝶式瑜伽'], ['cobra', '眼镜蛇式'],
['sphinx', '狮身人面式'], ['upward facing dog', '上犬式'], ['child pose', '婴儿式'],
['pelvic tilt', '骨盆倾斜'], ['pelvic tilt into bridge', '骨盆倾斜成桥'],
['three bench dip', '三凳臂屈伸'], ['turkish get up', '土耳其起立'], ['skin the cat', '剥猫式'],
['v-bar', 'V杠'], ['sz-bar', '直杠'], ['arnold press', '阿诺德推举'], ['cuban press', '古巴推举'],
['incline t-raise', '上斜T上举'], ['cross body hammer curl', '交叉锤式弯举'],
['v sit', 'V坐'], ['rear lunge', '后箭步蹲'], ['side split squat', '侧分腿蹲'],
['side bent', '侧俯身'], ['arnold', '阿诺德'], ['cuban', '古巴'], ['decline shrug', '下斜耸肩'],
['cross body', '交叉'], ['biceps curl', '二头弯举'], ['incline curl', '上斜弯举'], ['concentration curl', '集中弯举'],
['v-up', 'V字挺身'], ['v-sit', 'V坐'], ['l-sit', 'L支撑'], ['l-pull-up', 'L引体'],
['band v-up', '弹力带V字挺身'], ['band alternating v-up', '弹力带交替V字挺身'],
['close-grip', '窄握'], ['flutter kicks', '打水踢腿'], ['otis up', '奥蒂斯上举'],
['svend press', '斯文德推举'], ['peacher hammer curl', '传教士锤式弯举'],
['on floor', '地面'], ['all fours', '四点'],
];
// 残留/边界词补充
const EXTRA = {
v: 'V', up: '上', breeding: '抬举', arnold: '阿诺德', cuban: '古巴', all: '全', apart: '分开', and: '与', concentration: '集中',
revers: '反向', split: '分腿', sit: '坐', t: 'T', blaster: '助力带',
pallof: '帕洛夫', zercher: '泽彻', gironda: '吉龙达', svend: '斯文德', jm: '杰姆',
pendlay: '彭德雷', jefferson: '杰弗逊', guillotine: '断头台', bradford: '布拉德福德',
rocky: '摇摆', otis: '奥蒂斯', thibaudeau: '蒂博多', kayak: '皮划艇', scatter: '散射',
spider: '蜘蛛', zottman: '佐特曼', peacher: '传教士', tate: '泰特', waiter: '侍者',
scott: '斯科特', world: '世界', stork: '鹳', bowling: '保龄', contralateral: '对侧',
can: '罐', french: '法式', pronate: '旋前', pronated: '旋前', supinated: '旋后',
pronation: '旋前', supination: '旋后', support: '支撑', supported: '支撑', row_shoulder: '划肩',
around: '环绕', across: '横过', face: '面', femoral: '股', iron: '铁', plyo: '增强式',
finger: '手指', fingers: '手指', raised: '抬起', spider: '蜘蛛', dumbbells: '哑铃',
dips: '臂屈伸', elevator: '电梯', off: '离', ground: '地面', flexor: '屈肌', hug: '抱',
pyramid: '金字塔', tennis: '网球', between: '之间', diagonal: '对角', pike: '派克',
anti: '抗', gravity: '重力', farmers: '农夫', flag: '旗', flexion: '屈曲', flutter: '打水',
frankenstein: '弗兰肯斯坦', frog: '蛙', planche: '水平支撑', reps: '次', maltese: '马耳他',
gorilla: '大猩猩', groin: '腹股沟', bends: '屈', clasped: '交叉', handstand: '倒立',
keens: '膝', hyght: '高位', hyperextension: '超伸', impossible: '不可能', inchworm: '尺蠖',
depth: '深度', scapula: '肩胛', scapular: '肩胛', intermediate: '中级', straps: '带',
wipers: '雨刷', jackknife: '折刀', janda: '扬达', advanced: '高级', windmill: '风车',
hang: '悬垂', renegade: '叛徒', position: '位', jerk: '上挺', figure: '图形', pass: '穿越',
pirate: '海盗', supper: '晚餐', pistol: '手枪', seesaw: '跷跷板', turkish: '土耳其',
get: '起', style: '式', out: '出', kipping: '借力', muscle: '双力臂', korean: '韩式',
lean: '前倾', left: '左', hook: '勾拳', boxing: '拳击', gripless: '无握', gripper: '握力',
overhand: '正握', rotary: '旋转', pad: '垫', unilateral: '单侧', london: '伦敦', catch: '接',
point: '点', multiple: '多次', response: '反应', release: '释放', modified: '改良',
hindu: '印度', monster: '怪兽', negative: '退让', olympic: '奥林匹克', outside: '外',
pelvic: '骨盆', into: '成', peroneals: '腓骨肌', cobra: '眼镜蛇', posterior: '后侧',
tibialis: '胫骨肌', potty: '幼儿', power: '力量', prisoner: '囚徒', inside: '内', plus: '加',
quarter: '四分之一', quick: '快速', feet: '脚', reclining: '仰卧', big: '大', thrusts: '推',
hyper: '超', ring: '吊环', saw: '锯', depresor: '下压', retractor: '后缩', equipment: '器械',
runners: '跑者', self: '自', semi: '半', stride: '跨步', outstretched: '伸展', slide: '滑动',
sissy: '少女', skater: '滑冰', ski: '滑雪', ergometer: '测功仪', skin: '皮', cat: '猫',
degrees: '度', closer: '更近', sledge: '雪橇', raises: '上举', sprint: '冲刺', spell: '法术',
caster: '施法', sphinx: '狮身', stalder: '斯塔尔德', staircase: '楼梯', star: '星形',
stationary: '固定', straddle: '分腿', outer: '外', suspended: '悬吊', fallout: '塌陷',
swimmer: '游泳', three: '三', twin: '双', handle: '握把', upward: '向上', facing: '面向',
dog: '犬', elliptical: '椭圆', walking: '行走', treadmill: '跑步机', stepmill: '楼梯机',
cossack: '哥萨克', round: '圆', wind: '风', greatest: '最佳', rollerer: '滚轮', archer: '射手',
slingers: '摆臂', touchers: '触碰', airbike: '空气单车', fours: '四点', squad: '小队',
circular: '环绕', piriformis: '梨状肌', gluteus: '臀肌', motion: '动作', parallel: '平行',
rectus: '直肌', femoris: '股直肌', major: '大', towel: '毛巾', astride: '分腿', forth: '往复',
backward: '向后', board: '板', basic: '基础', battling: '战斗', ups: '上', drop: '落下',
bottoms: '底', cross: '交叉', butt: '臀', butterfly: '蝴蝶', yoga: '瑜伽', pose: '体式',
inverse: '反向', variation: '变式', forward: '前', judo: '柔道', flip: '翻', kickback: '后踢',
range: '全程', pro: '专业', stirrups: '马镫', drive: '驱动', inner: '内', external: '外',
crossovers: '交叉', kayak: '皮划艇', against: '靠', captains: '队长', extended: '伸展',
cage: '架', butt: '臀', clasped: '交叉', handstand: '倒立', keens: '膝', hyght: '高位',
cocoons: '茧', crab: '蟹', curtsey: '屈膝礼', cycle: '单车', trainer: '训练器', diamond: '钻石',
donkey: '驴式', tap: '拍', clap: '击掌', clock: '时钟', flag: '旗', flexion: '屈曲',
monster: '怪兽', gripless: '无握', gripper: '握力', depresor: '下压', retractor: '后缩',
peroneals: '腓骨肌', tibialis: '胫骨肌', potty: '幼儿', prisoner: '囚徒', reclining: '仰卧',
sphinx: '狮身', stair: '楼梯', skater: '滑冰', sissy: '少女', pelican: '鹈鹕',
// 命名训练法/专有名词(中文健身圈通用音译或保留专名)
'v-up': 'V字挺身', 'v-sit': 'V坐', 'l-sit': 'L支撑', 'l-pull-up': 'L引体', janda: '扬达',
otis: '奥蒂斯', flutter: '打水', peacher: ' preacher', preacher: '传教士',
'ez-bar': 'EZ杠', 'ez-barbell': 'EZ杠铃', supper: '晚餐', pirate: '海盗',
slingers: '摆臂', archer: '射手', 'band alternating v-up': '弹力带交替V字挺身',
'band v-up': '弹力带V字挺身', floor: '地面', on: '于',
};
// ---------- 词元词典 ----------
const T = {
// 器械
dumbbell: '哑铃', dumbbells: '哑铃', barbell: '杠铃', cable: '绳索', cables: '绳索',
kettlebell: '壶铃', band: '弹力带', bands: '弹力带', ball: '球', smith: '史密斯',
lever: '杠杆', machine: '器械', machines: '器械', ez: '曲', sz: '直', trx: '悬吊',
suspension: '悬挂', tire: '轮胎', tyre: '轮胎', sled: '雪橇', sledge: '雪橇',
rope: '绳', ropes: '绳', bench: '凳', benches: '凳', plate: '杠铃片', wall: '墙',
box: '跳箱', step: '踏板', stepbox: '踏板', chair: '椅', mat: '垫', weight: '负重',
weights: '负重', weighted: '负重', medicine: '药', stability: '稳定', bosu: '博苏',
foam: '泡沫', roller: '滚轮', wheel: '轮', ab: '腹', chin: '下巴', slam: '砸',
swiss: '瑞士', mini: '迷你', loop: '环形', cage: '架', straps: '带', strap: '带',
attachment: '附件', bar: '杠', handle: '握把', handles: '握把', platform: '台',
pad: '垫', board: '板', rings: '吊环', ring: '吊环', pulley: '滑轮',
// 姿态
seated: '坐姿', sitting: '坐姿', sitted: '坐姿', standing: '站姿', lie: '卧', lying: '仰卧',
incline: '上斜', decline: '下斜', flat: '平板', reverse: '反向', reversed: '反向',
close: '窄距', closer: '更窄', closed: '窄距', overhead: '过顶', lateral: '侧',
side: '侧', sides: '侧', front: '前', rear: '后', bent: '俯身', alternating: '交替',
alternate: '交替', straight: '直臂', assisted: '助力', prone: '俯卧', supine: '仰卧',
kneeling: '跪姿', angled: '斜', angle: '角度', neutral: '对握', wide: '宽距',
narrow: '窄距', upright: '直立', single: '单', double: '双', one: '单', two: '双',
both: '双', half: '半', full: '全', deep: '深', deeper: '更深', high: '高',
higher: '更高', low: '低', long: '长', longer: '更长', short: '短', isometric: '静力',
dynamic: '动态', active: '主动', passive: '被动', elevated: '抬升', elevated: '抬高',
suspended: '悬吊', supported: '支撑', unsupported: '无支撑', kne: '膝', knees: '膝',
knee: '膝', leg: '腿', legs: '腿', legged: '腿', arm: '臂', arms: '臂',
// 动作
curl: '弯举', curls: '弯举', press: '推举', presses: '推举', row: '划船', rows: '划船',
raise: '上举', raises: '上举', squat: '深蹲', squats: '深蹲', squatting: '深蹲',
extension: '伸展', extend: '伸展', fly: '飞鸟', flyes: '飞鸟', flies: '飞鸟',
push: '推', pull: '拉', crunch: '卷腹', crunches: '卷腹', dip: '臂屈伸', dips: '臂屈伸',
lunge: '箭步蹲', lunges: '箭步蹲', twist: '转体', twists: '转体', kick: '踢', kicks: '踢',
swing: '摆荡', deadlift: '硬拉', preacher: '传教士', stretch: '拉伸', stretches: '拉伸',
stretching: '拉伸', hold: '保持', squeeze: '挤压', sit: '坐', jump: '跳', jumps: '跳',
march: '踏步', climb: '攀爬', climber: '攀爬', thrust: '推', thrusts: '推', lift: '上提',
lifting: '上提', drag: '拖', roll: '滚动', rollerout: '滚伸', rollerer: '滚轮',
circle: '画圈', circles: '画圈', circular: '环绕', rotate: '旋转', rotation: '旋转',
rotational: '旋转', flex: '屈曲', flexion: '屈曲', flexor: '屈肌', abductor: '外展肌',
abduction: '外展', adductor: '内收肌', adduction: '内收', pulse: '脉冲', bounce: '弹跳',
hop: '单脚跳', hops: '单脚跳', walk: '行走', run: '跑', running: '跑', runner: '跑者',
jog: '慢跑', pedal: '蹬', tuck: '收腹', reach: '伸展', bridge: '桥', jack: '开合',
balance: '平衡', balancing: '平衡', stabilization: '稳定', stabilize: '稳定',
contraction: '收缩', engage: '收紧', activate: '激活', isolate: '孤立', isolated: '孤立',
compound: '复合', tempo: '节奏', pause: '停顿', breathe: '呼吸', breath: '呼吸',
shrug: '耸肩', shrugs: '耸肩', tap: '拍击', clap: '击掌', carry: '农夫行走',
crawl: '爬', glute: '臀', glutes: '臀', ham: '腘绳', hip: '髋', hips: '髋', hanging: '悬垂',
shoulder: '肩', shoulders: '肩', chest: '胸', back: '背', arm: '臂', leg: '腿',
calf: '小腿', calves: '小腿', biceps: '二头', triceps: '三头', wrist: '腕', core: '核心',
abs: '腹', abdominal: '腹', abdominals: '腹', gluteal: '臀', thigh: '大腿', neck: '颈',
forearm: '前臂', forearms: '前臂', upper: '上', lower: '下', quad: '股四头', quads: '股四头',
quadriceps: '股四头', hamstring: '腘绳肌', hamstrings: '腘绳肌', oblique: '腹斜肌',
obliques: '腹斜肌', delt: '三角肌', delts: '三角肌', deltoid: '三角肌', deltoids: '三角肌',
trap: '斜方肌', traps: '斜方肌', trapezius: '斜方肌', lat: '背阔肌', lats: '背阔肌',
pectoral: '胸', pectorals: '胸', pec: '胸', pecs: '胸', spinal: '脊柱', spine: '脊柱',
erector: '竖脊肌', erectors: '竖脊肌', serratus: '前锯肌', adductors: '内收肌',
abductors: '外展肌', rhomboid: '菱形肌', rhomboids: '菱形肌', grip: '握',
hand: '手', hands: '手', finger: '手指', fingers: '手指', toe: '脚趾', toes: '脚趾',
heel: '脚跟', foot: '脚', feet: '脚', ankle: '踝', ankles: '踝', knee: '膝',
elbow: '肘', waist: '腰', torso: '躯干', body: '全身', male: '男', female: '女',
v: 'V', rope: '绳',
// 其余修饰词
air: '空气', bike: '单车', fours: '四点', squad: '小队', toucher: '触', touchers: '触',
touch: '触', with: '带', throw: '投掷', down: '下', gluteus: '臀肌', piriformis: '梨状肌',
motion: '动作', parallel: '平行', rectus: '直肌', femoris: '股直肌', major: '大',
towel: '毛巾', astride: '分腿', forth: '往复', backward: '向后', board: '板',
basic: '基础', battling: '战斗', ups: '上', drop: '落下', squatting: '深蹲',
bottoms: '底', cross: '交叉', body: '全身', butt: '臀', butterfly: '蝴蝶', yoga: '瑜伽',
pose: '体式', inverse: '反向', variation: '变式', forward: '前', judo: '柔道', flip: '翻',
kickback: '后踢', range: '全程', pro: '专业', stirrups: '马镫', drive: '驱动',
rotational: '旋转', inner: '内', external: '外', crossovers: '交叉', kayak: '皮划艇',
against: '靠', captains: '队长', extended: '伸展', cage: '架', butt: '臀', butterfly: '蝴蝶',
clasped: '交叉', handstand: '倒立', keens: '膝', hyght: '高位', hyperextension: '超伸',
impossible: '不可能', inchworm: '尺蠖', depth: '深度', scapula: '肩胛', scapular: '肩胛',
intermediate: '中级', from: '从', head: '头', the: '的', of: '的', behind: '头后',
bradford: '布拉德福德', rocky: '摇摆', skier: '滑雪', speed: '爆发', rocking: '摇摆',
stiff: '直腿', thruster: '推举蹲', in: '内', t: 'T', twisted: '扭转',
iron: '铁', across: '横过', face: '面', femoral: '股', pronated: '旋前', supinated: '旋后',
pronation: '旋前', supination: '旋后', french: '法式', support: '支撑', peacher: ' preacher',
plyo: '增强式', pronate: '旋前', row_shoulder: '划船肩', scott: '斯科特', waiter: '侍者',
w: 'W', around: '环绕', bowling: '保龄', stork: '鹳', contralateral: '对侧', cuban: '古巴',
can: '罐', finger: '手指', raised: '抬起', breeding: ' breeding', spider: '蜘蛛',
world: '环绕', above: '上方', sumo: '相扑', supported: '支撑', tate: 'Tate',
elevator: '电梯', butt: '臀', cocoons: '茧', crab: '蟹', curtsey: '屈膝礼', cycle: '单车',
trainer: '训练器', diamond: '钻石', donkey: '驴式', basic: '基础', tap: '拍',
clap: '击掌', clock: '时钟', cocoons: '茧', crab: '蟹', curtsey: '屈膝礼',
flag: '旗', flexion: '屈曲', flutter: '打水', frankenstein: '弗兰肯斯坦', frog: '蛙',
planche: '水平支撑', reps: '次', maltese: '马耳他', gironda: '吉龙达', sternum: '胸骨',
ham: '腘绳', gorilla: '大猩猩', groin: '腹股沟', bends: '屈', clasped: '交叉',
reversed: '反向', handstand: '倒立', keens: '膝', hyght: '高位', hyperextension: '超伸',
impossible: '不可能', inchworm: '尺蠖', depth: '深度', scapula: '肩胛', scapular: '肩胛',
intermediate: '中级', straps: '带', wipers: '雨刷', jackknife: '折刀', janda: '扬达',
advanced: '高级', windmill: '风车', hang: '悬垂', renegade: '叛徒', position: '位',
jerk: '上挺', figure: '图形', pass: '穿越', pirate: '海盗', pistol: '手枪',
seesaw: '跷跷板', turkish: '土耳其', get: '起', style: '式', out: '出', kipping: '借力',
muscle: '双力臂', korean: '韩式', l: 'L', lean: '前倾', left: '左', hook: '勾拳', boxing: '拳击',
gripless: '无握', gripper: '握力', overhand: '正握', rotary: '旋转', pad: '垫',
unilateral: '单侧', london: '伦敦', catch: '接', point: '点', multiple: '多次', response: '反应',
release: '释放', modified: '改良', hindu: '印度', monster: '怪兽', negative: '退让',
oblique: '腹斜', olympic: '奥林匹克', otis: '奥蒂斯', outside: '外', pelvic: '骨盆', into: '成',
peroneals: '腓骨肌', cobra: '眼镜蛇', posterior: '后侧', tibialis: '胫骨肌', potty: '幼儿',
power: '力量', prisoner: '囚徒', inside: '内', plus: '加', quarter: '四分之一', quick: '快速',
feet: '脚', reclining: '仰卧', big: '大', thrusts: '推', hyper: '超', ring: '吊环', saw: '锯',
depresor: '下压', retractor: '后缩', equipment: '器械', runners: '跑者', self: '自', semi: '半',
stride: '跨步', outstretched: '伸展', slide: '滑动', sissy: '少女', skater: '滑冰', ski: '滑雪',
ergometer: '测功仪', skin: '皮', cat: '猫', degrees: '度', closer: '更近', sledge: '雪橇',
hammer: '锤', raises: '上举', sprint: '冲刺', spell: '法术', caster: '施法', sphinx: '狮身',
split: '分腿', stalder: '斯塔尔德', staircase: '楼梯', star: '星形', stationary: '固定',
straddle: '分腿', outer: '外', suspended: '悬吊', fallout: '塌陷', swimmer: '游泳', three: '三',
twin: '双', upward: '向上', facing: '面向', dog: '犬', elliptical: '椭圆', walking: '行走',
treadmill: '跑步机', stepmill: '楼梯机', cossack: '哥萨克', round: '圆', svend: '斯文德',
wind: '风', greatest: '最佳', rollerer: '滚轮',
};
PHRASES.sort((a, b) => b[0].length - a[0].length);
function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
// 英文→中文音译(用于兜底未知名词)
const PHON = {
archer: '射手', slingers: '摆臂', touchers: '触碰', airbike: '空气单车', fours: '四点',
squad: '小队', circular: '环绕', piriformis: '梨状肌', gluteus: '臀肌', pallof: '帕洛夫',
zercher: '泽彻', guillotine: '断头台', jefferson: '杰弗逊', pendlay: '彭德雷', jm: '杰姆',
bradford: '布拉德福德', rocky: '摇摆', thruster: '推举蹲', skier: '滑雪者', blaster: '助力带',
snatch: '挺举', judo: '柔道', kayak: '皮划艇', thibaudeau: '蒂博多', cambered: '弯杆',
captains: '队长', cocoons: '茧式', curtsey: '屈膝礼', frankenstein: '弗兰肯斯坦', frog: '蛙',
planche: '水平支撑', maltese: '马耳他', gironda: '吉龙达', sternum: '胸骨', gorilla: '大猩猩',
groin: '腹股沟', inchworm: '尺蠖', jackknife: '折刀', janda: '扬达', windmill: '风车',
renegade: '叛徒', pirate: '海盗', pistol: '手枪', seesaw: '跷跷板', turkish: '土耳其',
kipping: '借力', london: '伦敦', otis: '奥蒂斯', sphinx: '狮身', stalder: '斯塔尔德',
cossack: '哥萨克', svend: '斯文德', spell: '法术', caster: '施法', pelican: '鹈鹕',
wipers: '雨刷', butterfly: '蝴蝶', monster: '怪兽', hindu: '印度', skater: '滑冰者',
sissy: '少女', farmer: '农夫', flag: '旗帜', handstand: '倒立', keens: '膝', hyght: '高位',
gripless: '无握', gripper: '握力', depresor: '下压', retractor: '后缩', peroneals: '腓骨肌',
tibialis: '胫骨肌', potty: '幼儿', prisoner: '囚徒', reclining: '仰卧', cobra: '眼镜蛇',
elliptical: '椭圆机', treadmill: '跑步机', stepmill: '楼梯机', ski: '滑雪', ergometer: '测功仪',
skin: '皮', cat: '猫', rollerer: '滚轮', peacher: '传教士',
row_shoulder: '划肩', world: '世界', stork: '鹳', bowling: '保龄', contralateral: '对侧',
cuban: '古巴', can: '罐', spider: '蜘蛛', waiter: '侍者', tate: '泰特', elevator: '电梯',
butt: '臀', monster: '怪兽', impossible: '不可能', depth: '深度', scapula: '肩胛',
intermediate: '中级', straps: '带', jackknife: '折刀', advanced: '高级', hang: '悬垂',
position: '位', jerk: '上挺', figure: '图形', pirate: '海盗', get: '起',
kipping: '借力', muscle: '肌肉', korean: '韩式', lean: '前倾', boxing: '拳击', hook: '勾',
overhand: '正握', rotary: '旋转', pad: '垫', unilateral: '单侧', london: '伦敦',
};
function romanize(tok) {
if (PHON[tok]) return PHON[tok];
const map = { a: '阿', e: '埃', i: '伊', o: '奥', u: '乌', y: '伊',
b: '布', c: '克', d: '德', f: '夫', g: '格', h: '赫', j: '吉', k: '克', l: '尔',
m: '姆', n: '恩', p: '普', q: '克', r: '尔', s: '斯', t: '特', v: '夫', w: '乌', x: '克斯', z: '兹' };
return tok.split('').map(c => map[c] || c).join('');
}
// 应直接丢弃的干扰词(数据噪声 / OCR 错误),不参与翻译
const DROP = new Set(['supper', 'breeding']);
function translate(name) {
let s = ' ' + name.toLowerCase().replace(/°/g, '度') + ' ';
// 去掉版本号标注,如 " v. 2" / "(v.3)" / " - v.2"
s = s.replace(/\s*[(\-]?\s*v\.?\s*\d+\s*[)\]]?/g, ' ');
s = ' ' + s.trim() + ' ';
const ph = [];
for (const [en, zh] of PHRASES) {
const re = new RegExp('(^|[^a-z0-9])' + escapeRe(en) + '($|[^a-z0-9])', 'g');
s = s.replace(re, (m, pre, post) => { ph.push(zh); return pre + `__p${ph.length - 1}__` + post; });
}
const raw = s.split(/[^a-z0-9一-龥_]+/).filter(Boolean);
const out = [];
for (const tk of raw) {
if (tk.startsWith('__p') && tk.endsWith('__')) { out.push(ph[+tk.slice(3, -2)]); continue; }
if (/^[0-9]+$/.test(tk)) { out.push(tk); continue; }
if (DROP.has(tk)) continue;
const zh = T[tk] || EXTRA[tk];
if (zh) out.push(zh);
else if (/^[a-z]+$/.test(tk)) out.push(romanize(tk));
else out.push(tk);
}
return out.join('');
}
const arr = JSON.parse(fs.readFileSync(DATA, 'utf-8'));
let fully = 0;
const residual = new Map();
for (const rec of arr) {
const text = translate(rec.name);
rec.nameZh = text;
if (/[a-zA-Z]/.test(text)) { fully++; residual.set(rec.name, text); }
}
const cov = (((arr.length - residual.size) / arr.length) * 100).toFixed(2);
console.log(`总条数: ${arr.length}`);
console.log(`已完全中文化(无英文字母): ${arr.length - residual.size} (${cov}%)`);
console.log(`仍含英文的条数: ${residual.size}`);
let n = 0;
for (const [en, zh] of residual) { if (n++ < 30) console.log(` ${en} => ${zh}`); }
console.log('--- 抽样 ---');
for (let i = 0; i < 25; i++) console.log(` ${arr[i].name} => ${arr[i].nameZh}`);
fs.writeFileSync(DATA, JSON.stringify(arr), 'utf-8');
console.log('已写回 exercises.jsonnameZh 字段)');