Atcoder 中文版

翻译

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Atcoder 中文版
// @namespace    http://tampermonkey.net/
// @version      2024-08-15
// @description  翻译
// @author       You
// @match        https://atcoder.jp/*
// @run-at       document-start
// @grant        none
// @license      GNU GPL v3
// ==/UserScript==
(function () {
    const TEXT = {
        "(local time)": "(本地时间)",
        "Active Users": "活跃用户",
        "Affiliation": "工作单位",
        "Algorithm": "算法竞赛",
        "All": "全部",
        "All Submissions": "所有提交",
        "All Users": "所有用户",
        "Auto Refresh": "自动刷新",
        "Back to Home": "返回主页",
        "Birth Year": "出生年份",
        "Category": "类别",
        "Change Password": "更换密码",
        "Change Photo": "更换头像",
        "Change/Verify Email address": "更改/验证电子邮件地址",
        "Clarifications": "提问",
        "Company": "公司信息",
        "Competition History": "历史比赛",
        "Contact": "联系方式",
        "Contest": "比赛",
        "Contest Archive": "比赛记录",
        "Contest Name": "比赛名字",
        "Contest Status": "比赛记录",
        "Country/Region": "国家/地区",
        "Custom Test": "自定义测试",
        "Customize": "自定义",
        "Duration": "持续时间",
        "Editorial": "题解",
        "Email Notifications": "邮箱提醒",
        "FAQ": "常见问题",
        "General Settings": "基本设置",
        "Glossary": "术语",
        "Heuristic": "启发式竞赛",
        "Heuristic Contest": "启发式比赛",
        "Highest Rating": "最高等级分",
        "Home": "首页",
        "Information": "公告",
        "Information Protection Policy": "信息保护政策",
        "Last Contest Result": "上次比赛结果",
        "Manage Fav": " 管理收藏",
        "More...": "更多...",
        "My Profile": "我的主页",
        "My Score": "我的分数",
        "My Submissions": "我的提交",
        "Nickname": "昵称",
        "Other": "其他",
        "Page Top": "页首",
        "Past Contests": "往届比赛",
        "Permanent Contests": "永久性比赛",
        "Present Contests": "当前比赛",
        "Privacy Policy": "隐私政策",
        "Profile": "简介",
        "Rank": "排名",
        "Ranking": "排名",
        "Rated Range": "等级范围",
        "Rating": "等级分",
        "Rating Distribution": "评级分布",
        "Recent Contests": "最近的比赛",
        "Refresh": "刷新",
        "Register": "报名",
        "Reset": "重置",
        "Restructuring of contests": "比赛调整",
        "Results": "结果",
        "Rule": "规则",
        "Search": "搜索",
        "Search in Archive": "在存档中搜索",
        "Settings": "设置",
        "Sign In": "登录",
        "Sign Out": "退出登录",
        "Sign Up": "注册",
        "Sponsored ABC": "赞助入门赛(ABC)",
        "Sponsored ARC": "赞助常规赛(ARC)",
        "Sponsored Heuristic Contest": "赞助启发式比赛",
        "Sponsored Parallel(rated)": "赞助平行赛(评级)",
        "Sponsored Parallel(unrated)": "赞助平行赛(未评级)",
        "Sponsored Tournament": "赞助锦标赛",
        "Standings": "排名",
        "Start Time": "开始时间",
        "Submit": "提交",
        "Tasks": "题目",
        "Terms of service": "服务条款",
        "The file size must be at most 1MB.": "文件大小不得超过1MB。",
        "The width and height must be at most 512px.": "宽度和高度不得超过512px。",
        "There is no clarifications yet.": "目前还没有提示。",
        "This user has not competed in a rated contest yet.": "该用户没有参加过有评级的比赛。",
        "This user has not competed yet.": "该用户没有参加过比赛。",
        "Top": "首页",
        "Unofficial(unrated)": "非官方(未评级)",
        "Upcoming Contests": "即将到来的比赛",
        "Update": "更新",
        "Upload": "上传",
        "User": "用户",
        "View all": "查看全部",
        "Virtual Participation": "虚拟参与",
        "Virtual Standings": "虚拟排名",
        "You can use only jpg/png files.": "您只能使用jpg/png文件。",
        "last update": "上次更新",
        "【Important Notice】 Please beware of fake sites impersonating AtCoder": "【重要提示】请注意假冒AtCoder的虚假网站"
    }
    function ObjSort(arys) {
        var newkey = Object.keys(arys).sort();
        var newObj = {};
        for (var i = 0; i < newkey.length; i++) newObj[newkey[i]] = arys[newkey[i]];
        return newObj; //返回排好序的新对象
    }
    console.log("词汇表:");
    console.log(ObjSort(TEXT));
    let cnt = 0, id, flag = sessionStorage["translate"], bflag = 0;
    if (flag == undefined) {
        flag = 1;
        sessionStorage["translate"] = 1;
    }
    function translate(x) {
        if (x.nodeType == 3) {
            let str = x.nodeValue, l = 0, ls = "", r = 0, rs = "";
            while (" \n\t".includes(str[l])) ls += str[l], l++;
            while (" \n\t".includes(str[str.length - 1 - r]) && str.length - 1 - r >= l) rs += str[str.length - 1 - r], r++;
            if (str[str.length - 1 - r] == ":") rs += ":", r++;
            if (TEXT[str.substring(l, str.length - r)] != undefined) {
                str = TEXT[str.substring(l, str.length - r)];
                x.old = x.nodeValue;
                x.nodeValue = ls + str + rs;
            }
            return;
        }
        let c = Array.from(x.childNodes)
        for (let i of c) translate(i);
    }
    function back(x) {
        if (x.nodeType == 3) {
            if (x.old != undefined) {
                x.nodeValue = x.old
                x.old = undefined;
            }
            return;
        }
        let c = Array.from(x.childNodes)
        for (let i of c) back(i);
    }
    function main() {
        if (bflag == 0) {
            let a = document.getElementsByClassName("nav navbar-nav navbar-right")[0];
            if (a != undefined) {
                bflag = 1;
                let bu = document.createElement("button");
                bu.innerText = (flag == 1) ? "关闭翻译" : "开启翻译";
                bu.onclick = function () {
                    if (bu.innerText == "关闭翻译") {
                        bu.innerText = "开启翻译";
                        back(document.body);
                        flag = 0;
                    } else {
                        bu.innerText = "关闭翻译";
                        flag = 1;
                    }
                    sessionStorage["translate"] = flag;
                }
                a.appendChild(bu);
            }
        }
        if (flag != 0) translate(document.body);
        cnt++;
        if (cnt == 1000) {
            // 网页启动时高频刷新,启动后 1 秒降低刷新频率,降低压力
            clearInterval(id);
            setInterval(main, 100);
        }
    }
    id = setInterval(main, 1);
})();