Stellar Odyssey汉化插件

Stellar Odyssey汉化插件!

目前为 2025-03-27 提交的版本。查看 最新版本

// ==UserScript==
// @name         Stellar Odyssey汉化插件
// @namespace    http://tampermonkey.net/
// @version      2025-03-28
// @description  Stellar Odyssey汉化插件!
// @author       hewilson
// @match        https://game.stellarodyssey.app/*
// @icon         https://game.stellarodyssey.app/favicon.ico
// @grant        none
// @license      MIT
// ==/UserScript==

const excludeRegs = [
    // 一个字母都不包含
    /^[^a-zA-Z]*$/,
];

const excludes = [
    "k",
    "m",
    "b",

    "Lv",
    "Lvl",
    "xp",
    "n/a",
    "x",

    "wiki",
    "discord",

    "I",
    "II",
    "III",
    "IV",
    "V",
    "VI",
    "VII",
    "VIII",
    "IX",
];

const excludeSelectors = [
    //图标
    '.q-icon',
    //排除右上角人名
    'header > div:first-child > div:nth-child(2) > div:last-child > button:first-child > span:nth-child(2) > div:first-child > span',
    //排除右上角展开的人名
    '[role="menu"] > div:first-child > div:first-child > div:nth-child(2)',
    //排除整个聊天框(临时)
    'footer *',
    //tab切换中
    '[class*="q-transition"] tbody *',
    //下拉框菜单
    '[id^="q-portal--menu"] > [role="listbox"] > [class^="q-virtual"] *',
    //星图里的星系名
    'div.Atype+div>span:first-child',
    '.custom_ship_tooltip div:has(> div > svg) *',
    //星系详情里的星系名
    '.galaxy_container > div  > div:nth-child(2) > div > div:nth-child(1) > span:nth-child(2)',
    //星系详情里的星系发现者名
    '.galaxy_container > div  > div:nth-child(2) > div > div:nth-child(2) > :nth-child(5) > span:nth-child(2)',
    //星系详情里的星系占领方
    '.galaxy_container > div  > div:nth-child(2) > div > div:nth-child(2) > :nth-child(6) > span:nth-child(2)',
    //玩家日志里的星球名
    '.q-timeline__title',
    //舰队列表里舰队名
    'div.custom_squadron_avatar + div > span',
    //舰队队长
    '.squadron_info > div:nth-child(2) > div:first-child > div:first-child > div:nth-child(2) *',
    //舰队自定义描述
    '.custom_description',
    //舰队成员列表
    '.custom_description ~ ul li',
    //舰队成员列表里人名
    'i.squadron_user_status+span',
];

const excludeHashSelectors = [
    //个人资料名字
    ['#/profile', '.q-page div > .items-start:first-child > div:nth-child(2) > div > div:first-child > span:nth-child(2)'],
    //个人资料email
    ['#/profile', '.q-page div > .items-start:first-child > div:nth-child(2) > div > div:nth-child(3) > span:nth-child(2)'],

    //SOS信号记录用户名
    ['#/galaxy', 'tbody > tr > td:nth-child(2)'],
    //SOS信号记录星系名
    ['#/galaxy', 'tbody > tr > td:nth-child(4)'],
    //排除 最常见的系统
    ['#/galaxy', '.q-dialog__inner > div > div > div:nth-child(5) > span'],

    //星系里恒星的悬浮框里的星系名
    ['#/system', '.q-tooltip:has(> div:nth-child(2)) > div:nth-child(1)'],

    //星图集里第1个table的星系名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:first-child[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(4)'],
    //星图集里第1个table的星系发现者名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:first-child[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(6)'],
    //星图集里第2个table的星系名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:nth-child(2)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(3)'],
    //星图集里第3个table的舰队名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:nth-child(3)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(1)'],
    //星图集里第3个table的空间站名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:nth-child(3)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(2)'],
    //星图集里第3个table的星系名
    ["#/atlas", '.main-card:has(.q-tabs__content>div:nth-child(3)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(3)'],

    // 存在问题,tab变化的时候无法排除
    // //舰队第1个table里的玩家名
    // ["#/squadron", '.squadron_info_layout:has(.q-tabs__content>div:first-child[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(1) *'],
    // //舰队第2个table里的玩家名和message
    // ["#/squadron", '.squadron_info_layout:has(.q-tabs__content>div:nth-child(2)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(1)'],
    // ["#/squadron", '.squadron_info_layout:has(.q-tabs__content>div:nth-child(2)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(4)'],
    // //舰队第4个table里的玩家名
    // ["#/squadron", '.squadron_info_layout:has(.q-tabs__content>div:nth-child(4)[tabindex="0"][role="tab"][aria-selected="true"]) tbody > tr > td:nth-child(1)'],
    // 临时方案,刚好能用
    ["#/squadron", '.squadron_info_layout tbody > tr > td:nth-child(1)'],
    ["#/squadron", '.squadron_info_layout tbody > tr > td:nth-child(1) *'],
    ["#/squadron", '.squadron_info_layout tbody > tr > td:nth-child(4)'],

    //社交中心里的玩家名
    ['#/socialhub', '.custom_socialhub_grid > div .user_squad > div > span:first-child']
]

const tranDate = {
    'ms': '毫秒',
    'millisecond': '毫秒',
    'milliseconds': '毫秒',

    's': '秒',
    'sec': '秒',
    'second': '秒',
    'seconds': '秒',

    'm': '分',
    'min': '分',
    'minute': '分',
    'minutes': '分',

    'h': '时',
    'hr': '时',
    'hour': '时',
    'hours': '时',

    'd': '天',
    'day': '天',
    'days': '天',

    "Jan": "一月",
    "Feb": "二月",
    "Mar": "三月",
    "Apr": "四月",
    "May": "五月",
    "Jun": "六月",
    "Jul": "七月",
    "Aug": "八月",
    "Sep": "九月",
    "Oct": "十月",
    "Nov": "十一月",
    "Dec": "十二月"
}

const tranItem = {
    "Weapon": "武器",
    "damage": "伤害",
    "Shield": "护盾",
    "Defense": "防御",
    "Engine": "引擎",
    "Travel Boost": "航行增益",
    "Sensors": "传感器",
    "Scan Boost": "扫描增益",
    "Laser": "激光",
    "Probes": "探测器",
    "Gather Boost": "采集增益",

    "Rocky type": "岩石型",
    "Icy type": "冰型",
    "Gas type": "气态型",
    "Crystal type": "晶体型",

    "rocky": "岩石",
    "Icy": "冰",
    "gas": "气态",
    "Crystal": "晶体",

    "copper": "铜",
    "gold": "金",
    "silver": "银",
    "platinum": "铂",
    "dark matter": "暗物质",

    "water": "水",
    "nitrogen": "氮",
    "sulfur": "硫",
    "carbon": "碳",
    "silicon": "硅",

    "ammonia": "氨",
    "hydrogen": "氢",
    "helium": "氦",
    "methane": "甲烷",
    "argon": "氩",

    "diamond": "钻石",
    "ruby": "红宝石",
    "emerald": "绿宝石",
    "sapphire": "蓝宝石",
    "cobalt": "钴",

    "brute": "蛮兵",
    "spectres": "幽灵",
    "Glacial": "冰川族",
    "machiner": "机械师",
    "Scorcher": "灼烧者",
    "Toxoid": "毒蚀体",
    "Miner": "矿工",
    "Duster": "尘暴兵",

    "bones": "骨头",
    "Obtained from killing Brutes": "击杀蛮兵获得",
    "ectoplasm": "灵质",
    "Obtained from killing Spectres": "击杀幽灵获得",
    "frost shard": "霜屑",
    "Obtained from killing Glacials": "击杀冰川族获得",
    "cog": "齿轮",
    "Obtained from killing Machiners": "击杀机械师获得",
    "flame": "火焰",
    "Obtained from killing Scorchers": "击杀灼烧者获得",
    "slime": "粘液",
    "Obtained from killing Toxoids": "击杀毒蚀体获得",
    "horn": "兽角",
    "Obtained from killing Miners": "击杀矿工获得",
    "condensed sand": "压缩砂砾",
    "Obtained from killing Dusters": "击杀尘暴兵获得",

    "ingots": "金属锭",
    "Produced at the Foundry. Used for Fuel Cell Casings at the Module Assembly Plant": "在铸造厂生产,用于模块组装厂的燃料舱外壳",
    "refined crystals": "精炼晶体",
    "high end crystals": "高端晶体",
    "propulsors": "推进器",
    "Produced at the Noble Gas Processing Station. Used for Unstable Fuel at the Fuel Lab": "在惰性气体处理站生产,用于燃料实验室的不稳定燃料",
    "nanoconductors": "纳米导体",
    "microcircuits": "微电路",
    "fusion cells": "融合细胞",
    "fuel cell casing": "燃料电池外壳",
    "unstable fuel": "不稳定的燃料",
    "Warp capsule": "跃迁舱",
    "Metal Scrap": "金属碎片",
    "Obtained scrapping ship parts": "拆解飞船部件获得",
}

const tranHeader = {
    "Playing": "游戏中",
    "Game Rules": "游戏规则",
    "Patch notes": "补丁说明",
    "Privacy Policy": "隐私政策",
    "Report Bug": "报告Bug",
    "Rankings": "排名",
    "Starter guide": "入门指南",

    "Connected to game server": "已连接至游戏服务器",
    "Profile": "个人资料",
    "Logout": "退出登录",
    "Average ping": "平均延迟",

    "Battling": "战斗",
    "Gathering": "采集",
    "Crafting": "制造",
    "Exploring": "探索",
}

const tranSideBar = {
    "Stellar Odyssey": "恒星奥德赛",
    "Version": "版本",
    "Player": "玩家",
    "Laboratory": "实验室",
    "Galaxy Map": "星图",
    "Atlas": "星图集",
    "Base Building": "基地建设",
    "Squadron": "舰队",
    "Social Hub": "社交中心",
    "Market": "市场",
    "Trophy Room": "荣誉室",
    "Premium store": "精品商店",
}

const tranPlayInfo = {
    "Stats": "属性",
    "Points": "点数",
    "Power": "能量",
    "Adds damage to your weapon": "提升武器伤害值",
    "Precision": "精准",
    "Increases your hit chance": "提高命中几率",
    "Evasion": "闪避",
    "Increases your evade chance": "增加闪避几率",
    "Hull": "船体",
    "Increases your health points. Additive with your shield defense": "增加生命值.与护盾防御值叠加计算",

    "Statistics": "统计",
    "Player Damage": "玩家伤害",
    "Damage Bonuses": "伤害加成",
    "Player Health": "玩家生命值",
    "Clones Health": "克隆体生命值",
    "Bonuses": "加成效果",
    "Droids dodge chance": "机器人闪避率",
    "Rare Resources Drop Chance": "稀有资源掉落率",
}

const transNotification = {
    "Actions replenished": "行动已补充",
    "Stats modified": "属性已修改",
    "Item drop logs cleared": "物品掉落记录已清空",
}

const tranCommon = {
    "Starter normal": "初级",
    "normal": "普通",
    "uncommon": "罕见",
    "rare": "稀有",
    "unique": "独特",
    "epic": "史诗",
    "legendary": "传奇",

    "chemical": "化学",
    "electromagnetic": "电磁",
    "energy": "能量",
    "explosive": "爆炸",
    "incendiary": "燃烧",
    "kinetic": "动能",

    "Category": "类别",
    "Ship parts": "飞船部件",
    "Gathering Resources": "采集资源",
    "Consumables": "消耗品",
    "Material": "材料",
    "Materials": "材料",
    "Blueprints": "蓝图",

    "Node type": "节点类型",
    "Modification": "修改",
    "Actions": "行动",
    "Reward": "奖励",
    "Fuel": "燃料",
    "System": "星系",
    "Assign": "分配",
    "Reset": "重置",
    "Save": "保存",
    "cancel": "取消",
    "Replenish": "补充",
    "Starting battle": "开始战斗",
    "Game info": "游戏信息",
    "SHIP": "飞船",
    "Filter": "筛选",
    "Rarity": "稀有度",
    "Description": "描述",
    "Quantity": "数量",
    "Slot": "插槽",
    "Normal Currency": "普通货币",
    "Rare Currency": "稀有货币",
    "Inventory": "物品栏",
    "Currencies": "货币",
    "No items yet": "暂无物品",
}

const tranOther = {
    "No item drops yet": "暂无物品掉落记录",
    "Ship Skins": "飞船涂装",
    "Available Ship Skins": "可用飞船涂装",
    "Starter Ship": "初始飞船",
    "Sentinel": "哨兵型",
    "Eclipse": "日蚀型",
    "Ship effects": "飞船特效",
    "Available Ship Effects": "可用飞船特效",
    "Red Glow": "红色光效",
    "Blue Glow": "蓝色光效",
    "Link in chat": "在聊天中分享链接",
    "Unequip": "卸下",
    "Buy more from the premium store": "前往精品商店购买更多",
    "Remove effect": "移除特效",
    "Equip": "装备",
    "Scrap": "拆解",
    "Wire": "定向发送",
    "Search Player": "搜索玩家",
    "Send": "发送",
    "No results": "没有结果",

    "Enemies": "敌人",
    "Weak against": "弱点",
    "Drops": "掉落",
    "Level": "等级",
    "Winrate": "胜率",
    "Start battling": "开始战斗",
    "Stop battling": "停止战斗",
    "You": "你",
    "won": "获胜",
    "after": "经过",
    "rounds": "回合",
    "Next fight in": "下一场战斗倒计时",
    "Clones": "克隆体",
    "Hit": "命中",
    "Dodge": "闪避",
    "Credits": "信用点",
    "Experience": "经验值",
    "Level up in": "升级还需",
    "Current bonuses": "当前加成",
    "Battle rounds log": "战斗回合日志",
    "Round": "回合",
    "hits": "击中",
    "Clone": "克隆体",
    "for": "造成",
    "misses hit on": "未击中",
    "died": "死亡",
    "Item drop log": "物品掉落日志",
    "Clear": "清除",
    "Buy Clone": "购买克隆体",
    "Crit. Chance": "暴击几率",
    "Crit. Damage": "暴击伤害",
    "Dual Shot": "双重射击",
    "Upgrade": "升级",
    "Records per page": "每页记录数",
    "of": "的",
    "Not Battling": "非战斗状态",
    "You are not battling right now": "当前未处于战斗中",
    "Please select an enemy from the list to start battling": "请从列表中选择敌人开始战斗",
    "No battling right now": "当前无战斗",
    "lost": "战败",
    "All clones": "全体克隆体",

    "Gathering nodes": "采集节点",
    "Nebula": "星云",
    "Quality": "品质",
    "quality": "品质",
    "Stop gathering": "停止采集",
    "Asteroid": "小行星",
    "Start gathering": "开始采集",
    "Gathering statistics": "采集统计",
    "Next action in": "下次行动倒计时",
    "Droids statistics from last gathering action": "上次采集的机器人统计",
    "Droid": "机器人",
    "Status": "状态",
    "Destroyed": "已损毁",
    "Resource": "资源",
    "Amount": "数量",
    "Taxed": "已征税",
    "Survived": "存活",
    "Currencies by node types": "节点类型对应资源",
    "Droids": "机器人",
    "Buy droid": "购买机器人",
    "Efficiency": "效率",
    "Storage": "存储量",
    "Maneuverability": "机动性",
    "none": "无",
    "Not Gathering": "未采集中",
    "No gathering right now": "当前无采集活动",

    "Available Blueprints": "可用蓝图",
    "Charges": "充能次数",
    "No blueprint selected": "未选择蓝图",
    "Choose one to start crafting": "请选择蓝图开始制作",
    "Missing some requirements": "未满足全部条件",

    "Craft": "制作",
    "Requirements": "需求材料",
    "Modifications": "改造选项",
    "You can select up to two different damage types. Having one gives 30% bonus but two gives 15% each": "最多可选择两种伤害类型。选择一种可获得30%加成,选择两种则每种获得15%加成",
    "Select bonus type": "选择加成类型",
    "Max 2 selections": "最多选择2项",
    "Current applied": "当前应用",
    "Item value range": "物品数值范围",
    "The base value applied to the formula can be modified paying with rare gathering currency": "可通过消耗稀有采集货币来调整基础数值",
    "The range goes between -30% and 30%. You can only reduce the negative range": "调整范围为-30%至30%,仅可减少负面范围",
    "Select one or leave the sliders as default. Crafting level also adds a multiplicative bonus": "选择一项或保持默认设置,制作等级还会提供额外加成",
    "Output": "成品预览",
    "Damage range": "伤害范围",
    "Craft item": "制作物品",
    "This is the last charge. The blueprint will be destroyed after this use": "这是最后一次使用,制作后蓝图将消失",
    "Defense range": "防御范围",

    "Modules": "模块",
    "Queue Status": "队列状态",
    "Buildings": "建筑设施",
    "Foundry": "铸造厂",
    "Refinery": "精炼厂",
    "Crystal Synthesis Lab": "晶体合成实验室",
    "Noble Gas Processing Station": "惰性气体处理站",
    "Nanotech Complex": "纳米科技复合体",
    "Circuit Integration Facility": "电路集成设施",
    "Build next": "建造下一个",
    "The Laboratory is a central feature in your spaceship, allowing you to build and manage up to": "实验室是您飞船的核心设施,最多可建造和管理",
    "unique structures": "独特建筑结构",
    "essential for your space journey. These buildings form a supply chain, using resources gathered from various systems to produce materials needed by others": "这些建筑构成完整的供应链,通过整合各星系采集的资源来生产其他设施所需的材料",
    "The main objective is to construct": "主要目标是制造",
    "These are used for interstellar travel, enabling exploration of new solar systems. Managing the Laboratory effectively is key to expanding your galactic reach": "用于星际旅行以探索新星系,高效管理实验室是扩展银河版图的关键",
    "Queue statistics": "生产队列统计",
    "Queue size": "队列容量",
    "No laboratory building's queues pending": "无待处理的实验室生产队列",
    "Uses": "消耗材料",
    "Produces": "产出物品",
    "Queue": "生产队列",
    "Max": "最大",
    "Timer": "计时器",
    "Queue production": "开始队列生产",
    "Upgrade building": "升级建筑",
    "Level up": "等级提升",
    "Next laboratory building": "下一实验室建筑",
    "Energetic Fusion Center": "高能聚变中心",
    "Cost": "消耗",
    "Buy building": "购买建筑",
    "Module Assembly Plant": "模块组装工厂",
    "Fuel Lab": "燃料实验室",
    "Space Capsule Complex": "太空舱综合体",

    "Enemies in your current system. Go to the Atlas or Galaxy Map to travel to other system and find more enemies": "当前星系内的敌人。前往星图或银河地图可跃迁至其他星系寻找更多敌人",
    "Not enough credits": "信用点不足",
    "Clones fight for you against enemies. Their stats depend on your ship stats, weapon and shields. They also have their own skills. Each one performs an individual action every fight": "克隆体将为你作战,其属性取决于飞船状态、武器和护盾。每个克隆体都拥有独特技能,每场战斗可执行独立行动",
    "Upgrade Clone": "克隆体升级",
    "Critical Chance": "暴击几率",
    "Purchase": "购买",
    "Critical Damage": "暴击伤害",
    "Total Upgrade Costs": "升级总消耗",
    "Confirm upgrades": "确认升级",
    "Available nodes in your current system. Go to the Atlas or Galaxy Map to travel to other system and find other nodes": "当前星系可用节点。前往星图或银河地图可跃迁至其他星系探索更多节点",
    "Droids collect resource ores you get while mining. Each one performs an individual action": "采矿机器人会自动收集矿物资源,每个机器人可执行独立采集动作",
    "Upgrade Droid": "机器人升级",

    "Engine cooldown": "引擎冷却中",
    "Fast travel": "快速跃迁",
    "SOS Signals": "求救信号",
    "Journal": "航行日志",
    "Camera controls": "镜头控制",
    "Ready": "就绪",
    "Distance": "距离",
    "ly": "光年",
    "Discovered by": "发现者",
    "Gathering Bodies": "星体数据采集中",
    "Inhabited": "已殖民",
    "yes": "是",
    "no": "否",
    "Unknown system": "未识别星系",
    "Online SOS Signals": "在线求救信号",
    "Date": "日期",
    "User": "用户",
    "No SOS Signals available": "无可用求救信号",
    "Close": "关闭",
    "Player Journal": "飞行员日志",
    "Systems visited": "已访问星系",
    "Systems discovered": "已发现星系",
    "Total distance traveled": "总航行距离",
    "Ly": "光年",
    "Most frequent system": "最常访问星系",
    "Bodies": "星体",
    "SYSTEM MAP": "星系星图",
    "System info": "星系信息",
    "Main Star": "主恒星",
    "A type": "A型恒星",
    "Claimed by": "占领方",
    "Belt": "小行星带",
    "Has gathering nodes": "含采集节点",
    "Travel": "跃迁",
    "Recharge fuel with": "燃料补充方式",
    "Mark on map": "标记星图",
    "Bookmark": "星标",
    "View system map": "查看星图",
    "Not enough fuel": "燃料不足",
    "Remove pin": "移除标记",
    "K type": "K型恒星",
    "Crystal Planet": "水晶行星",
    "Neutron Star": "中子星",
    "Comet": "彗星",
    "Icy Planet": "冰封行星",
    "type": "类型",
    "Rocky Planet": "岩质行星",
    "Gas Planet": "气态巨行星",
    "G type": "G型恒星",

    "Atlas Systems": "星系集",
    "Space Stations": "空间站",
    "This is the public list of systems discovered by players. Private systems are only shown to users who discovered it or if you travelled at least once": "本列表展示玩家发现的公开星系,私有星系仅对发现者或曾到访者可见",
    "System Name": "星系名称",
    "Coordinates": "坐标",
    "nobody": "暂无记录",
    "Highlight": "高亮标记",
    "This is a bookmark list to save your favourite systems": "此收藏夹用于保存你标记的常用星系",
    "Date added": "收藏日期",
    "List of Squadrons' space stations with public information. If the Space Station is parked in a private system, coordinates are hidden": "舰队空间站公开信息列表。若空间站位于私有星系,坐标将隐藏",
    "Station Name": "空间站名称",

    "Search": "搜索",
    "Squadron Name": "舰队名称",
    "Members": "成员",
    "Loading": "加载中",
    "Applications": "申请",
    "Donations": "捐赠",
    "Stellar Dock": "星际船坞",
    "Galaxy Power": "银河战力",
    "Squadron members list": "舰队成员列表",
    "Rank": "排名",
    "Batling": "战斗状态",
    "Current System": "当前星系",
    "Current Node": "当前节点",
    "No data available": "暂无数据",
    "Leader": "队长",
    "Created": "创建时间",
    "Reputation": "声望",
    "Squadron description": "舰队简介",
    "Member list": "成员名单",
    "Leave squadron": "退出舰队",
    "Applications activity": "申请动态",
    "Message": "消息",
    "No Applications": "暂无申请",
    "Invites registered yet": "尚未登记邀请",
    "apply": "申请",
    "accepted": "已接受",
    "invite": "邀请",
    "Your": "你的",
    "Donate": "捐赠",
    "cosmic dust": "宇宙尘埃",
    "stellar tokens": "星币",
    "Member's Donations": "成员捐赠榜",
    "Ranking of Squadron members donations, not including taxes": "舰队成员捐赠排名(不含税收)",
    "No donations registered yet": "暂无捐赠记录",
    "Donation succeeded": "捐赠成功",
    "Stellar Dock buildings": "星际船坞建筑",
    "These buildings collect resources via taxes. Each one produces one of the four parts needed to build a Space Station to be able to claim a system": "这些建筑通过税收收集资源,各自生产空间站所需的四种部件之一,用于建立星系主权",
    "Workshop": "船体工坊",
    "A mega factory where the space station structure is built": "建造空间站主体结构的巨型工厂",
    "hull parts": "船体部件",
    "Offline": "离线",
    "Tax": "税率",
    "Select tax": "选择税率",
    "Unlock Cost": "解锁成本",
    "Only the Leader can unlock it": "仅队长可解锁",
    "AI": "智能中枢",
    "The AI centre will provide all the necessary technology to operate the space station": "智能中枢提供空间站运作所需的全套技术",
    "control systems": "控制系统",
    "Bioscience": "生态科学",
    "Dedicated to life support, waste recycling and medical attendance": "负责生命维持、废物循环及医疗系统",
    "ambient systems": "环境系统",
    "Engineering": "工程中心",
    "The Engineering centre will produce engines and the internal gravity module for the space station": "工程中心制造推进器及空间站内部重力模块",
    "propulsion systems": "推进系统",
    "Squadron galaxy power management": "舰队银河势力管理",
    "Space stations management where you can build an update ever space station located on your clamed systems": "空间站管理系统 - 可建造及升级已占领星系的空间站",
    "Available Space Station parts": "可用空间站部件",
    "Space Stations available for deploy": "可部署空间站",
    "Build Space Station": "建造空间站",
    "The Squadron doesn't have claimed systems": "舰队尚未占领任何星系",
    "Build Space Stations and claim any system": "建造空间站以占领星系",

    "No Squadron": "无舰队",


    "Market listings": "市场挂牌",
    "My Listings": "我的挂牌",
    "Laboratory Materials": "实验室材料",
    "Enemy Drop Materials": "战利品材料",
    "Items": "物品",
    "Listings": "挂牌订单",
    "Select a currency from the list to show its listing orders": "选择货币类型以查看对应挂牌订单",
    "Listings history": "挂牌历史",
    "My item listings": "我的物品挂牌",
    "Item listings history": "物品挂牌历史",
    "Listing date": "挂牌日期",
    "Currency": "交易货币",
    "Operation": "操作",
    "Unit Price": "单价",
    "Qty Remaining": "剩余数量",
    "Total": "总价",
    "Price": "价格",
    "Buy orders": "收购订单",
    "New buy listing": "新建收购订单",
    "Action": "操作",
    "No listings yet": "暂无订单记录",
    "Sell orders": "出售订单",
    "New sell listing": "新建出售订单",
    "Buy": "收购",
    "My items": "我的物品",
    "Crafted": "自制",
    "Value": "估值",
    "Sell": "出售",

    "You have": "当前持有",
    "Best buy offer": "最优收购报价",
    "My offer": "我的报价",
    "Each": "单价",
    "Total listing price": "挂牌总价",
    "You pay now as listing fee": "需预付挂牌手续费",
    "Total payment": "应付总额",
    "Create listing": "创建订单",
    "Best sell offer": "最优出售报价",
    "My price": "我的定价",

    "Available Trophies": "可收集勋章",
    "Collections": "收藏系列",
    "Ringed Dwarf Runes": "环状矮星符文",
    "Binary Stars Runes": "双星系统符文",
    "Black Hole Runes": "黑洞符文",
    "Neutron Star Runes": "中子星符文",
    "No collection selected": "未选择收藏系列",
    "Choose one to learn more": "选择系列查看详情",
    "Ringed Dwarf Runes Collection": "环状矮星符文收藏集",
    "Binary Stars Runes Collection": "双星系统符文收藏集",
    "Black Hole Runes Collection": "黑洞符文收藏集",
    "Neutron Star Runes Collection": "中子星符文收藏集",
}

let translates = {};

for (let trans of [
    tranDate,
    tranItem,
    tranHeader,
    tranSideBar,
    tranPlayInfo,
    transNotification,
    tranCommon,
    tranOther,
]) {
    for (let key in trans) {
        translates[key.toLowerCase()] = trans[key];
    }
}

var unSet = new Set();
function baseTranslate(text) {
    if (translates[text.toLowerCase()]) {
        return translates[text.toLowerCase()];
    } else if (text.toLowerCase().endsWith("es") && translates[text.toLowerCase().slice(0, -2)]) {
        return translates[text.toLowerCase().slice(0, -2)];
    } else if (text.toLowerCase().endsWith("s") && translates[text.toLowerCase().slice(0, -1)]) {
        return translates[text.toLowerCase().slice(0, -1)];
    } else {
        unSet.add(text);
        return text;
    }
}

function cnItem(text, node) {
    if (typeof text != "string") return text;

    // 排除不需要翻译的
    for (const exclude of excludes) {
        if (exclude.toLowerCase() === text.toLowerCase()) {
            return text;
        }
    }

    // 排除不需要翻译的(使用正则)
    for (const excludeReg of excludeRegs) {
        if (excludeReg.test(text)) {
            return text;
        }
    }

    // 排除不需要翻译的(使用css选择器)
    for (const excludeSelector of excludeSelectors) {
        if ((node.nodeName !== "#text" && node.matches(excludeSelector)) || (node.parentNode && node.parentNode.matches(excludeSelector))) {
            return text;
        }
    }

    // 排除不需要翻译的(使用css选择器和hash)
    for (const [hash, excludeSelector] of excludeHashSelectors) {
        if (window.location.hash === hash && (node.nodeName !== "#text" && node.matches(excludeSelector)) || (node.parentNode && node.parentNode.matches(excludeSelector))) {
            return text;
        }
    }

    // 消除后面空格
    if (/^(.+?)(\s+)$/.test(text)) {
        let res = /^(.+?)(\s+)$/.exec(text);
        return cnItem(res[1], node) + res[2];
    }

    // 消除前面空格
    if (/^(\s+)(.+)$/.test(text)) {
        let res = /^(\s+)(.+)$/.exec(text);
        return res[1] + cnItem(res[2], node);
    }

    //星系里的发现者
    if (/^(Discovered by): (.+)$/.test(text)) {
        let res = /^(Discovered by): (.+)$/.exec(text);
        return cnItem(res[1], node) + ': ' + res[2];
    }



    //拆分所有的 some:some
    if (/^(.+)(\s*:\s*)(.+)$/.test(text)) {
        let res = /^(.+)(\s*:\s*)(.+)$/.exec(text);
        return cnItem(res[1], node) + res[2] + cnItem(res[3], node);
    }

    //拆分所有的 some/some
    if (/^(.+)(\s*\/\s*)(.+)$/.test(text)) {
        let res = /^(.+)(\s*\/\s*)(.+)$/.exec(text);
        return cnItem(res[1], node) + res[2] + cnItem(res[3], node);
    }

    //"1 days 1 hours 1 minutes 1 seconds"
    if (/^(\d+ days )?(\d+ hours )?(\d+ minutes )(\d+) seconds$/.test(text)) {
        let res = /^(\d+ days )?(\d+ hours )?(\d+ minutes )(\d+) seconds$/.exec(text);
        if (res[1]) {
            return cnItem(res[1], node) + cnItem(res[2], node) + cnItem(res[3], node) + `${res[4]} 秒`;
        } else if (res[2]) {
            return cnItem(res[2], node) + cnItem(res[3], node) + `${res[4]} 秒`;
        }
        return cnItem(res[3], node) + `${res[4]} 秒`;
    }



    //"after 7 rounds"
    if (/^(after)( \d+ )(rounds)$/.test(text)) {
        let res = /^(after)( \d+ )(rounds)$/.exec(text);
        return cnItem(res[1], node) + res[2] + cnItem(res[3], node);
    }

    //"You gained 23 battling XP and 1,230 credits"
    if (/^You gained ([0-9,]+) battling XP and ([0-9,]+) credits$/.test(text)) {
        let res = /^You gained ([0-9,]+) battling XP and ([0-9,]+) credits$/.exec(text);
        return `你中获得了 ${res[1]} 战斗经验值和 ${res[2]} 积分`;
    }

    if (/^(starter normal|normal|uncommon|rare|unique|epic|legendary) (weapon|Shield|Engine|Sensors|Laser|Probes)$/i.test(text)) {
        let res = /^(starter normal|normal|uncommon|rare|unique|epic|legendary) (weapon|Shield|Engine|Sensors|Laser|Probes)$/i.exec(text);
        return `${cnItem(res[1], node)}${cnItem(res[2], node)}`;
    }

    if (/^(.+) blueprint$/i.test(text)) {
        let res = /^(.+) blueprint$/i.exec(text);
        return `${cnItem(res[1], node)}蓝图`;
    }

    //"Uncommon Shield Lvl"
    if (/^(.+) Lvl$/.test(text)) {
        let res = /^(.+) Lvl$/.exec(text);
        return `${cnItem(res[1], node)}等级`;
    }

    if (/^([0-9\.]+k|m|b) (.+)$/i.test(text)) {
        let res = /^([0-9\.]+k|m|b) (.+)$/i.exec(text);
        return `${res[1]} ${cnItem(res[2], node)}`;
    }



    // 消除后面的非字母
    if (/^(.+?)([^a-zA-Z]+)$/.test(text)) {
        let res = /^(.+?)([^a-zA-Z]+)$/.exec(text);
        return cnItem(res[1], node) + res[2];
    }

    // 消除前面的非字母
    if (/^([^a-zA-Z]+)(.+)$/.test(text)) {
        let res = /^([^a-zA-Z]+)(.+)$/.exec(text);
        return res[1] + cnItem(res[2], node);
    }

    return baseTranslate(text);
}

const transTaskMgr = {
    tasks: [],
    addTask: function (node, attr, text) {
        this.tasks.push({
            node,
            attr,
            text,
        });
    },
    doTask: async function () {
        let task = null;
        while ((task = this.tasks.pop())) {
            task.node.parentNode.setAttribute("script_translatedfrom", task.node[task.attr]);
            task.node[task.attr] = task.text;
        }
    },
};

function TransSubTextNode(node) {
    if (node.childNodes.length > 0) {
        for (let subnode of node.childNodes) {
            if (subnode.placeholder) {
                let text = subnode.placeholder;
                let cnText = cnItem(text, subnode);
                cnText !== text && transTaskMgr.addTask(subnode, "placeholder", cnText);
            }
            if (subnode.nodeName === "#text") {
                let text = subnode.textContent;
                let cnText = cnItem(text, subnode);
                cnText !== text && transTaskMgr.addTask(subnode, "textContent", cnText);
            } else if (subnode.nodeName !== "SCRIPT" && subnode.nodeName !== "STYLE" && subnode.nodeName !== "TEXTAREA") {
                if (!subnode.childNodes || subnode.childNodes.length == 0) {
                    let text = subnode.innerText;
                    let cnText = cnItem(text, subnode);
                    cnText !== text && transTaskMgr.addTask(subnode, "innerText", cnText);
                } else {
                    TransSubTextNode(subnode);
                }
            }
        }
    }
}

(function () {
    'use strict';
    //汉化静态页面内容
    TransSubTextNode(document.body);
    transTaskMgr.doTask();
    //监听页面变化并汉化动态内容
    const observer_config = {
        attributes: false,
        characterData: true,
        childList: true,
        subtree: true,
    };
    const observer = new MutationObserver(function (e) {
        observer.disconnect();
        for (let mutation of e) {
            if (mutation.target.nodeName === "SCRIPT" || mutation.target.nodeName === "STYLE" || mutation.target.nodeName === "TEXTAREA") continue;
            if (mutation.target.nodeName === "#text") {
                mutation.target.textContent = cnItem(mutation.target.textContent, mutation.target);
            } else if (!mutation.target.childNodes || mutation.target.childNodes.length == 0) {
                mutation.target.innerText = cnItem(mutation.target.innerText, mutation.target);
                if (mutation.target.placeholder) {
                    mutation.target.placeholder = cnItem(mutation.target.placeholder, mutation.target);
                }
            } else if (mutation.addedNodes.length > 0) {
                for (let node of mutation.addedNodes) {
                    if (node.placeholder) {
                        node.placeholder = cnItem(node.placeholder, node);
                    }
                    if (node.nodeName === "#text") {
                        node.textContent = cnItem(node.textContent, node);
                    } else if (node.nodeName !== "SCRIPT" && node.nodeName !== "STYLE" && node.nodeName !== "TEXTAREA") {
                        if (!node.childNodes || node.childNodes.length == 0) {
                            if (node.innerText) node.innerText = cnItem(node.innerText, node);
                        } else {
                            TransSubTextNode(node);
                            transTaskMgr.doTask();
                            const unMap = new Map(Array.from(unSet).map(item => [item, item]));
                            const unObj = Array.from(unSet).reduce((obj, item) => {
                                obj[item] = item;
                                return obj;
                            }, {});
                            console.log(JSON.stringify(unObj))
                        }
                    }
                }
            }
        }
        observer.observe(document.body, observer_config);
    });
    observer.observe(document.body, observer_config);
})();