Ex124OJ

Extend 124OJ!

目前为 2023-07-22 提交的版本。查看 最新版本

// ==UserScript==
// @name         Ex124OJ
// @namespace    http://tampermonkey.net/
// @version      0.10.15
// @description  Extend 124OJ!
// @author       Sukwants
// @license      MIT
// @match        http://124.221.194.184
// @match        http://124.221.194.184/*
// @icon         https://www.imageoss.com/images/2022/11/29/ex124OJba563861978a769d.png
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @grant        GM_listValues
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @connect      ex124oj.pages.dev
// ==/UserScript==


const Version = '0.10.15';

const Username = document.getElementsByClassName('uoj-username')[0] ? document.getElementsByClassName('uoj-username')[0].textContent : undefined;

const HomepageRegExp = /^http:\/\/124.221.194.184(\/){0,1}(\?.*){0,1}$/;
function isHomepage() {
    return HomepageRegExp.test(window.location.href);
}
const submissionRegExp = /^http:\/\/124.221.194.184\/submission\/\d{1,}/;
function isSubmission() {
    return submissionRegExp.test(window.location.href);
}
const ProblemRegExp = /^http:\/\/124.221.194.184.*\/problem\/(\d{1,})(\?.*){0,1}$/;
function isProblem() {
    return ProblemRegExp.test(window.location.href);
}
const UserProfileRegExp = /^http:\/\/124.221.194.184\/user\/profile\/.{1,}/;
function isUserProfile() {
    return UserProfileRegExp.test(window.location.href);
}
const BlogRegExp = /^http:\/\/124.221.194.184\/blog\/.{1,}/;
function isBlog() {
    return BlogRegExp.test(window.location.href);
}

var BackgroundImage, SiteIconImage, SiteIconSmallImage, Academic, NewYearMagical;
function resetVariables() {
    BackgroundImage = GM_getValue('BackgroundImage') != undefined ? GM_getValue('BackgroundImage') : '';
    SiteIconImage = GM_getValue('SiteIconImage') != undefined ? GM_getValue('SiteIconImage') : '';
    SiteIconSmallImage = GM_getValue('SiteIconSmallImage') != undefined ? GM_getValue('SiteIconSmallImage') : '';
    Academic = GM_getValue('Academic') != undefined ? GM_getValue('Academic') : false;
    NewYearMagical = {NameColor : GM_getValue('NewYearMagicNameColor') != undefined ? GM_getValue('NewYearMagicNameColor').split(/\s*,\s*/) : undefined,
                      CCFBadge : GM_getValue('NewYearMagicCCFBadge'),
                      TagBadge : GM_getValue('NewYearMagicTagBadge') != undefined ? GM_getValue('NewYearMagicTagBadge').split(/\s*,\s*/) : undefined};
}
resetVariables();

var NameColorList = GM_getValue('NameColorList') != undefined ? GM_getValue('NameColorList') : {};
var CCFBadgeList = GM_getValue('CCFBadgeList') != undefined ? GM_getValue('CCFBadgeList') : {};
var TagBadgeList = GM_getValue('TagBadgeList') != undefined ? GM_getValue('TagBadgeList') : {};
var NewYearMagic = GM_getValue('NewYearMagic') != undefined ? GM_getValue('NewYearMagic') : false;
GM_xmlhttpRequest({
    method: "GET",
    url: "https://ex124oj.pages.dev/public/variables.json",
    onload: function(data) {
        var variables = JSON.parse(data.responseText);
        NameColorList = variables.NameColorList;
        GM_setValue('NameColorList', NameColorList);
        CCFBadgeList = variables.CCFBadgeList;
        GM_setValue('CCFBadgeList', CCFBadgeList);
        TagBadgeList = variables.TagBadgeList;
        GM_setValue('TagBadgeList', TagBadgeList);
        NewYearMagic = variables.NewYearMagic;
        GM_setValue('NewYearMagic', NewYearMagic);
        FunctionsWithUniversalVariables();
    }
});

(function() {
    'use strict';
    FontAwesome();
    Background();
    changeIcon();
    DiscussionCard();
    CodeBlock();
    TableStyle();
    RandomProblem();
    if (isHomepage()) exAnnouncements();
    if (isSubmission()) SubmissionCard();
    if (isProblem()) downloadData();
    if (isUserProfile() || isBlog()) changeGravatarURL();
    FunctionsWithUniversalVariables();
})();

function FunctionsWithUniversalVariables() {
    Settings();
    clearNameStyle();
    if (NewYearMagic) {
        applyNewYearMagic();
    }
    NameColor();
    NameBadge();
}

function Settings() {
    if (document.getElementsByClassName('settings-overlay').length == 0) {
        GM_addStyle('\
.settings-overlay {\
    position: fixed;\
    height: 100%;\
    width: 100%;\
    transition: visibility 0.4s, background 0.4s;\
    top: 0;\
    left: 0;\
    visibility: hidden;\
    z-index: 229;\
}\
.settings-popup-active .settings-overlay {\
    background: rgb(0,0,0,.3);\
    visibility: visible;\
}\
.settings-popup {\
    width: 60%;\
    position: relative;\
    transform: translate(-50%, -50%);\
    top: 50%;\
    left: 50%;\
    visibility: hidden;\
    border-radius: .5rem;\
    padding: 20px 20px;\
}\
.settings-popup-active .settings-overlay .settings-popup {\
    background: #ffffff;\
    visibility: visible;\
}\
.settings-popup .row {\
    padding: 0 30px 30px;\
}\
.settings-titlebar {\
    padding: 10px 20px 30px 20px !important;\
}\
.settings-titlebar h4 {\
    position: relative;\
    top: 50%;\
    left: 0;\
    transform: translate(0, -50%);\
}\
.settings-footerbar {\
    height: 60px;\
    padding: 20px 20px;\
}\
');
        var HomepageEntrance = document.createElement('li');
        document.getElementsByClassName('container')[0].children[0].children[0].children[0].before(HomepageEntrance);
        HomepageEntrance.setAttribute('class', 'nav-item');
        HomepageEntrance.innerHTML = '<span style="padding: 0.5rem 1rem; cursor:pointer"><span style="background-color: #28adca;padding:0.2em 0.6em;border-radius: 1em;color:#fff;font-size: 0.7em;font-weight:bold;display:inline-block;position: relative;top: 50%;transform: translate(0,-50%);">Ex124OJ</span></span>';
        HomepageEntrance.onclick = function() {
            document.body.setAttribute('class', 'settings-popup-active');
        }
    }
    else {
        document.getElementsByClassName('settings-overlay')[0].remove();
    }
    var SettingsOverlay = document.createElement('div');
    document.body.children[0].before(SettingsOverlay);
    SettingsOverlay.setAttribute('class', 'settings-overlay');
    var SettingsPopup = document.createElement('div');
    SettingsOverlay.appendChild(SettingsPopup);
    SettingsPopup.setAttribute('class', 'settings-popup');
    var SettingsTitlebar = document.createElement('div');
    SettingsPopup.appendChild(SettingsTitlebar);
    SettingsTitlebar.setAttribute('class', 'row settings-titlebar');
    SettingsTitlebar.innerHTML = '<h3 style="width:100%;height:3.5rem"><img src="https://ex124oj.pages.dev/images/icon.png" style="height:3.5rem;width:3.5rem;margin-right:10px"><span style="vertical-align:middle"> Ex124OJ 控制面板</span> <span style="vertical-align:middle;cursor:pointer;margin:0 10px" onclick="window.open(\'https://ex124oj.pages.dev/\');"><span style="height:1.75rem;line-height:3.5rem;vertical-align:middle;padding:0 .5rem;background-color:#28adca;border-radius:1em;color:#fff;font-size:1.2rem;font-weight:bold">Ex124OJ</span></span><span style="color:#7f7f7f;line-height:3.5rem;vertical-align:middle;font-size:1.2rem">' + Version + '</span></h3>';
    var SettingsCloseButton = document.createElement('span');
    SettingsPopup.appendChild(SettingsCloseButton);
    SettingsCloseButton.setAttribute('style', 'position: fixed;right: 20px;top:20px;cursor: pointer');
    SettingsCloseButton.setAttribute('onclick', 'document.body.setAttribute(\'class\', \'\');');
    SettingsCloseButton.innerHTML = '<h4><i class="fa fa-xmark"></i></h4>';

    var background = document.createElement('div');
    SettingsPopup.appendChild(background);
    background.setAttribute('class', 'row');
    var backgroundImageLabel = document.createElement('strong');
    background.appendChild(backgroundImageLabel);
    backgroundImageLabel.setAttribute('style', 'font-size: 1.25em');
    backgroundImageLabel.innerHTML = '背景图片&emsp;&emsp;&emsp;&emsp;';
    var backgroundImageInput = document.createElement('input');
    background.appendChild(backgroundImageInput);
    backgroundImageInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial');
    backgroundImageInput.setAttribute('class', 'form-control');

    var siteIcon = document.createElement('div');
    SettingsPopup.appendChild(siteIcon);
    siteIcon.setAttribute('class', 'row');
    var siteIconImageLabel = document.createElement('strong');
    siteIcon.appendChild(siteIconImageLabel);
    siteIconImageLabel.setAttribute('style', 'font-size: 1.25em');
    siteIconImageLabel.innerHTML = '网站图标&emsp;&emsp;&emsp;&emsp;';
    var siteIconImageInput = document.createElement('input');
    siteIcon.appendChild(siteIconImageInput);
    siteIconImageInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial');
    siteIconImageInput.setAttribute('class', 'form-control');

    var siteIconSmall = document.createElement('div');
    SettingsPopup.appendChild(siteIconSmall);
    siteIconSmall.setAttribute('class', 'row');
    var siteIconSmallImageLabel = document.createElement('strong');
    siteIconSmall.appendChild(siteIconSmallImageLabel);
    siteIconSmallImageLabel.setAttribute('style', 'font-size: 1.25em');
    siteIconSmallImageLabel.innerHTML = '网站图标(小)&emsp;';
    var siteIconSmallImageInput = document.createElement('input');
    siteIconSmall.appendChild(siteIconSmallImageInput);
    siteIconSmallImageInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial');
    siteIconSmallImageInput.setAttribute('class', 'form-control');

    var academic = document.createElement('div');
    SettingsPopup.appendChild(academic);
    academic.setAttribute('class', 'row');
    academic.setAttribute('style', 'line-height: 2.5em;vertical-align: middle');
    var academicLabel = document.createElement('strong');
    academic.appendChild(academicLabel);
    academicLabel.setAttribute('style', 'font-size: 1.25em');
    academicLabel.innerHTML = '学术模式&emsp;&emsp;&emsp;&emsp;';
    var academicOff = document.createElement('div');
    academic.appendChild(academicOff);
    academicOff.innerHTML = '<input type="radio" id="AcademicOff"> 关闭&emsp;';
    var academicOn = document.createElement('div');
    academic.appendChild(academicOn);
    academicOn.innerHTML = '<input type="radio" id="AcademicOn"> 开启&emsp;';
    document.getElementById('AcademicOff').onclick = function() {
        document.getElementById('AcademicOn').checked = false;
    }
    document.getElementById('AcademicOn').onclick = function() {
        document.getElementById('AcademicOff').checked = false;
    }

    if (NewYearMagic) {
        var newYearMagicConfig = document.createElement('div');
        SettingsPopup.appendChild(newYearMagicConfig);
        newYearMagicConfig.setAttribute('class', 'row');
        var newYearMagicConfigLabel = document.createElement('strong');
        newYearMagicConfig.appendChild(newYearMagicConfigLabel);
        newYearMagicConfigLabel.setAttribute('style', 'font-size: 1.25em');
        newYearMagicConfigLabel.innerHTML = 'New Year Magic';
        var newYearMagicConfigDiv = document.createElement('div');
        newYearMagicConfig.appendChild(newYearMagicConfigDiv);
        newYearMagicConfigDiv.setAttribute('style', 'flex-grow:1;display:flex');
        var newYearMagicNameColorInput = document.createElement('input');
        newYearMagicConfigDiv.appendChild(newYearMagicNameColorInput);
        newYearMagicNameColorInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial; margin-left:10px');
        newYearMagicNameColorInput.setAttribute('class', 'form-control');
        var newYearMagicCCFBadgeInput = document.createElement('input');
        newYearMagicConfigDiv.appendChild(newYearMagicCCFBadgeInput);
        newYearMagicCCFBadgeInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial; margin-left:10px');
        newYearMagicCCFBadgeInput.setAttribute('class', 'form-control');
        var newYearMagicTagBadgeInput = document.createElement('input');
        newYearMagicConfigDiv.appendChild(newYearMagicTagBadgeInput);
        newYearMagicTagBadgeInput.setAttribute('style', 'flex-grow: 1; height: 2em; width: initial; margin-left:10px');
        newYearMagicTagBadgeInput.setAttribute('class', 'form-control');
        var newYearMagicExplanationPage = document.createElement('i');
        newYearMagicConfigDiv.appendChild(newYearMagicExplanationPage);
        newYearMagicExplanationPage.setAttribute('class', 'far fa-circle-question');
        newYearMagicExplanationPage.setAttribute('style', 'line-height: 2em;margin-left: 10px;cursor: pointer;');
        newYearMagicExplanationPage.onclick = function() {
            window.open('https://ex124oj.pages.dev/post/explanation/new-year-magic/');
        }
    }

    function resetModified() {
        backgroundImageInput.value = BackgroundImage;
        siteIconImageInput.value = SiteIconImage;
        siteIconSmallImageInput.value = SiteIconSmallImage;
        if (Academic != true) {
            document.getElementById('AcademicOff').checked = true;
            document.getElementById('AcademicOn').checked = false;
        }
        else {
            document.getElementById('AcademicOff').checked = false;
            document.getElementById('AcademicOn').checked = true;
        }
        if (NewYearMagic) {
            newYearMagicNameColorInput.value = GM_getValue('NewYearMagicNameColor') != undefined ? GM_getValue('NewYearMagicNameColor') : '';
            newYearMagicCCFBadgeInput.value = GM_getValue('NewYearMagicCCFBadge') != undefined ? GM_getValue('NewYearMagicCCFBadge') : '';
            newYearMagicTagBadgeInput.value = GM_getValue('NewYearMagicTagBadge') != undefined ? GM_getValue('NewYearMagicTagBadge') : '';
        }
    }
    resetModified();

    var FooterRow = document.createElement('div');
    FooterRow.setAttribute('class', 'settings-footerbar');
    SettingsPopup.appendChild(FooterRow);
    var Ok = document.createElement('button');
    FooterRow.appendChild(Ok);
    Ok.setAttribute('class', 'btn btn-search btn-outline-primary float-right');
    Ok.innerHTML = '保存';
    Ok.onclick = function() {
        GM_setValue('BackgroundImage', backgroundImageInput.value);
        GM_setValue('SiteIconImage', siteIconImageInput.value);
        GM_setValue('SiteIconSmallImage', siteIconSmallImageInput.value);
        GM_setValue('Academic', document.getElementById('AcademicOn').checked);
        if (NewYearMagic) {
            GM_setValue('NewYearMagicNameColor', newYearMagicNameColorInput.value ? newYearMagicNameColorInput.value : undefined);
            GM_setValue('NewYearMagicCCFBadge', newYearMagicCCFBadgeInput.value ? newYearMagicCCFBadgeInput.value : undefined);
            GM_setValue('NewYearMagicTagBadge', newYearMagicTagBadgeInput.value ? newYearMagicTagBadgeInput.value : undefined);
        }
        resetVariables();
        window.location.href = window.location.href;
    };
    var Clear = document.createElement('button');
    FooterRow.appendChild(Clear);
    Clear.setAttribute('class', 'btn btn-search btn-outline-primary float-right');
    Clear.innerHTML = '恢复默认';
    Clear.onclick = function() {
        var values = GM_listValues();
        for (var value in values) {
            GM_deleteValue(values[value]);
        }
        resetVariables();
        resetModified();
        window.location.href = window.location.href;
    }
}

function FontAwesome() {
    var fa = document.createElement('link');
    fa.setAttribute('href', 'https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/fontawesome.css');
    fa.setAttribute('rel', 'stylesheet');
    document.head.appendChild(fa);
    var fab = document.createElement('link');
    fab.setAttribute('href', 'https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/brands.css');
    fab.setAttribute('rel', 'stylesheet');
    document.head.appendChild(fab);
    var fas = document.createElement('link');
    fas.setAttribute('href', 'https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/solid.css');
    fas.setAttribute('rel', 'stylesheet');
    document.head.appendChild(fas);
}

function Background() {
    if (BackgroundImage) {
        document.getElementsByClassName('navbar-brand')[0].innerHTML = '<img src="http://124.221.194.184/images/logo_small.png" alt="Logo" class="img-rounded" style="width:39px; height:39px;">';
        document.getElementsByClassName('container')[0].children[0].children[1].innerHTML = document.getElementsByClassName('container')[0].children[0].children[1].innerHTML.match(/(.*> ){0,1}(.*)/)[2];
        GM_addStyle('\
body {\
background: url("' + BackgroundImage + '");\
background-repeat: no-repeat;\
background-attachment: fixed;\
background-position: 50% 50%;\
background-size: cover;\
}\
.uoj-content {\
background-color: #fff;\
margin: 16px -16px;\
padding: 16px 16px;\
opacity: 0.85;\
border-radius: 8px;\
}\
.navbar {\
margin: 16px -16px;\
padding: 8px 16px;\
opacity: 0.85;\
border-radius: 8px;\
}\
.giscus {\
opacity: 0.85;\
}');
    }
}

function getIcon() {
    if (SiteIconImage) return SiteIconImage;
    else return '/images/logo.png';
}
function getIconSmall() {
    if (SiteIconSmallImage) return SiteIconSmallImage;
    else return getIcon();
}
function changeIcon() {
    const LogoURLRegExp = /^.*\/images\/logo(_small){0,1}.png$/;
    var Links = document.getElementsByTagName('link');
    for (var link in Links) {
        if (Links[link] && Links[link].nodeType && Links[link].getAttribute('rel') == 'shortcut icon') {
            Links[link].setAttribute('href', getIconSmall());
        }
    }
    var Icons = document.getElementsByTagName('img');
    for (var icon in Icons) {
        if (Icons[icon] && Icons[icon].nodeType && LogoURLRegExp.test(Icons[icon].getAttribute('src'))) {
            if (!Icons[icon].getAttribute('style')) {
                Icons[icon].setAttribute('src', getIcon());
                Icons[icon].setAttribute('style', 'width:100%;height:auto;object-fit:cover');
            }
            else {
                Icons[icon].setAttribute('src', getIconSmall());
            }
        }
    }
}

function exAnnouncements() {
    const PostsExp = /^[\s\S]*<div id="archives">([\s\S]*)<script>([\s\S]*?)<\/script>([\s\S]*?)<\/div>\s*?<footer id="footer">[\s\S]*$/;
    const WrittenByExp = /^by (.*)$/;
    const DateTimeExp = /^(.*?) .*$/;
    if (document.getElementsByClassName('uoj-content')[0].children[0].children[0].children[0]) {
        GM_xmlhttpRequest({
            method: "GET",
            url: "https://ex124oj.pages.dev/categories/announcements/",
            onload: function(data) {
                var Announcements = document.getElementsByClassName('uoj-content')[0].children[0].children[0].children[0].children[0].children[0];
                Announcements.children[0].children[0].innerHTML = '<th style="width:30%">公告</th><th style="width:10%"></th><th style="width:10%"></th><th style="width:30%">Ex 公告</th><th style="width:10%"></th><th style="width:10%"></th>';
                var trs = Announcements.children[1].getElementsByTagName('tr');
                for (var tr = 0; tr < trs.length - 1; ++tr) {
                    if (trs[tr].innerHTML) {
                        trs[tr].innerHTML = (trs[tr].children.length > 2 ? trs[tr].innerHTML : '<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>') + '<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';
                        if (WrittenByExp.test(trs[tr].children[1] && trs[tr].children[1].innerHTML)) {
                            trs[tr].children[1].innerHTML = trs[tr].children[1].innerHTML.match(WrittenByExp)[1];
                        }
                        if (DateTimeExp.test(trs[tr].children[2] && trs[tr].children[2].innerHTML)) {
                            trs[tr].children[2].innerHTML = '<small>' + trs[tr].children[2].textContent.match(DateTimeExp)[1] + '</small>';
                        }
                    }
                }
                Announcements.children[1].children[Announcements.children[1].children.length - 1].innerHTML = '<td class="text-right" colspan="3"><a href="/announcements">所有公告……</a></td><td class="text-right" colspan="3"><a href="https://ex124oj.pages.dev/categories/announcements/">所有公告……</a></td>';
                var Posts = document.createElement('div');
                Posts.innerHTML = data.responseText.match(PostsExp)[1];
                for (var i = 0; i < Posts.children.length && i < 5; ++i) {
                    Announcements.children[1].children[i].children[3].innerHTML = '<a href="https://ex124oj.pages.dev' + Posts.children[i].children[0].children[0].children[1].getAttribute('href') + '">' + Posts.children[i].children[0].children[0].children[1].children[0].innerHTML.match(/^\s*(.*?)\s*$/)[1] + '</a>';
                    Announcements.children[1].children[i].children[4].innerHTML = '<a class="uoj-username" href="https://ex124oj.pages.dev" style="color:rgb(40,173,202)">Ex124OJ</a>';
                    var Date = Posts.children[i].children[0].children[0].children[0].innerHTML.match(/^(\d*)\/(\d*)\/(\d*)$/);
                    if (Date[2].length < 2) Date[2] = '0' + Date[2];
                    if (Date[3].length < 2) Date[3] = '0' + Date[3];
                    Announcements.children[1].children[i].children[5].innerHTML = '<small>' + Date[1] + '-' + Date[2] + '-' + Date[3] + '</small>'
                }
            }
        });
    }
}

function RandomProblem() {
    var SearchBox = document.getElementById('form-search-problem')
    if (SearchBox) {
        var RandomButton = document.createElement('div');
        RandomButton.setAttribute('class', 'input-group-append');
        RandomButton.innerHTML = '<button class="btn btn-search btn-outline-primary" onclick="randomProblem();">随机跳题</button>';
        var RandomScript = document.createElement('script');
        RandomScript.innerHTML = '\
var randomProblemId, randomProblemResult;\
function randomProblem() {\
    randomProblemId = Math.ceil(Math.random() * 3000);\
    randomProblemResult = ($.get(\'/problem/\' + randomProblemId));\
    turntoProblem();\
}\
function turntoProblem() {\
    if (randomProblemResult.status) {\
        if (randomProblemResult.status == 200) {\
            window.location.href = \'http://124.221.194.184/problem/\' + randomProblemId;\
        }\
        else {\
            randomProblem();\
        }\
    }\
    else {\
        setTimeout(turntoProblem, 10);\
    }\
}';
        SearchBox.after(RandomButton);
        RandomButton.after(RandomScript);
    }
}

function DiscussionCard() {
    var discrd = document.createElement('div');
    discrd.setAttribute('class', 'giscus');
    document.getElementsByClassName('uoj-footer')[0].before(discrd);
    var script = document.createElement('script');
    script.setAttribute('src', 'https://giscus.app/client.js');
    script.setAttribute('data-repo', 'Sukwants/Discuss124OJ');
    script.setAttribute('data-repo-id', 'R_kgDOImiZLA');
    script.setAttribute('data-category', 'Ideas');
    script.setAttribute('data-category-id', 'DIC_kwDOImiZLM4CTCIj');
    script.setAttribute('data-mapping', 'pathname');
    script.setAttribute('data-strict', '0');
    script.setAttribute('data-reactions-enabled', '1');
    script.setAttribute('data-emit-metadata', '0');
    script.setAttribute('data-input-position', 'top');
    script.setAttribute('data-theme', 'preferred_color_scheme');
    script.setAttribute('data-lang', 'zh-CN');
    script.setAttribute('crossorigin', 'anonymous');
    script.setAttribute('async', '');
    document.getElementsByTagName('body')[0].appendChild(script);
    GM_addStyle('\
.giscus {\
    display: ' + (Academic == true ? 'none' : 'unset') + ';\
}\
.giscus-frame {\
    margin-top: 20px;\
}');
}

function CodeBlock() {
    const ManageStatementExp = /^.*\/manage\/statement(\?.*){0,1}$/
    GM_addStyle('\
@import url(https://cdn.jsdelivr.net/npm/[email protected]/distr/fira_code.css);\
code {\
    font-family: "Fira Code";\
}\
code.sh_cpp>span {\
    font-style: normal !important;\
    font-weight: 400 !important;\
}\
code.sh_cpp>span.sh_preproc,\
code.sh_cpp>span.sh_keyword,\
code.sh_cpp>span.sh_type {\
    color: #8959a8;\
}\
code.sh_cpp>span.sh_string {\
    color: #718c00;\
}\
code.sh_cpp>span.sh_cbracket {\
    color: #4d4d4c;\
}\
code.sh_cpp>span.sh_symbol {\
    color: #3e999f;\
}\
code.sh_cpp>span.sh_number {\
    color: #f5871f;\
}\
code.sh_cpp>span.sh_function {\
    color: #4271ae;\
}\
code.sh_cpp>span.sh_comment {\
    color: #8e908c;\
}\
.copybutton {\
    float: right;\
    background-color: rgb(0,0,0,.1);\
    padding: .25em .625em;\
    border: 0 solid transparent;\
    border-radius: .28571429rem;\
}\
.copybutton:hover {\
    background-color: rgb(0,0,0,.2);\
}\
.copybutton:focus {\
    background-color: rgb(0,0,0,.2);\
    outline: none;\
}');
    if (!ManageStatementExp.test(window.location.href)) {
        setTimeout(function(){
            var CodeBlocks = document.getElementsByTagName('pre');
            for (var cb in CodeBlocks) {
                if (CodeBlocks[cb] && CodeBlocks[cb].nodeType) {
                    var Content = CodeBlocks[cb].textContent;
                    var InputId = Math.round(Math.random() * 998244353);
                    var ButtonId = Math.round(Math.random() * 998244353);
                    CodeBlocks[cb].innerHTML = '<button class="copybutton" id = "' + ButtonId + '" onclick="\
var ib = document.getElementById(\'' + InputId + '\');\
ib.setAttribute(\'style\', \'display:initial\');\
ib.value = \'' + Content.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, '\\&#39;').replace(/"/g, '&#34;') + '\';\
ib.select();\
document.execCommand(\'copy\');\
ib.setAttribute(\'style\', \'display:none\');\
var ic = document.getElementById(\'' + ButtonId + '\');\
ic.innerHTML = \'已复制\';\
setTimeout(function() { ic.innerHTML = \'复制\'; }, 500);">复制</button>' + CodeBlocks[cb].innerHTML;
                    var InputBox = document.createElement('textarea');
                    InputBox.setAttribute('id', InputId);
                    InputBox.setAttribute('style', 'display:none');
                    CodeBlocks[cb].appendChild(InputBox);
                }
            }

        }, 30);
    }
}

function TableStyle() {
    var Tables = document.getElementsByTagName('table');
    for (var table in Tables) {
        if (Tables[table].nodeType && Tables[table].parentNode.getAttribute('class') != 'legend' && !Tables[table].classList.length) {
            Tables[table].classList.add('table', 'table-bordered');
        }
    }
    var ths = document.getElementsByTagName('th');
    for (var th in ths) {
        if (ths[th].nodeType && ths[th].getAttribute('align')) {
            ths[th].setAttribute('style', 'text-align:' + ths[th].getAttribute('align'));
        }
    }
}

function SubmissionCard() {
    setTimeout(function() {
        var Content = document.getElementsByClassName('uoj-content')[0];
        if (Content.childElementCount == 3) {
            var Table = Content.children[0];
            var TabList = document.createElement('ul');
            TabList.setAttribute('class', 'nav nav-tabs');
            TabList.setAttribute('role', 'tablist');
            TabList.innerHTML = '<li class="nav-item"><a class="nav-link active" href="#test-cases" role="tab" data-toggle="tab" aria-selected="true"><span class="glyphicon glyphicon-check"></span> 测试点信息</a></li><li class="nav-item"><a class="nav-link" href="#source" role="tab" data-toggle="tab" aria-selected="false"><span class="glyphicon glyphicon-file"></span> 源代码</a></li>';
            var TabContent = document.createElement('div');
            TabContent.setAttribute('class', 'tab-content');
            TabContent.innerHTML = '<div class="tab-pane card active" id="test-cases"><div class="card-body">' + Content.children[2].children[1].innerHTML + '</div></div><div class="tab-pane card" id="source"><div class="card-body">' + Content.children[1].children[1].innerHTML + '</div></div>';
            Content.innerHTML = "";
            Content.appendChild(Table);
            Content.appendChild(TabList);
            Content.appendChild(TabContent);
        }
    }, 50);
}

function downloadData() {
    var DownloadTag = document.createElement('a');
    document.getElementsByClassName("btn btn-info float-right")[0].after(DownloadTag);
    DownloadTag.setAttribute('role', 'button');
    DownloadTag.setAttribute('class', 'btn btn-primary float-right');
    DownloadTag.setAttribute('href', '/download.php?type=problem&id=' + window.location.href.match(ProblemRegExp)[1]);
    DownloadTag.setAttribute('target', '_blank');
    DownloadTag.innerHTML = '<span class="glyphicon glyphicon-download-alt"></span> 下载数据';

    var TJTag = document.createElement('li');
    document.getElementsByClassName('nav nav-tabs')[0].children[2].after(TJTag);
    TJTag.setAttribute('class', 'nav-item');
    var TJInnerTag = document.createElement('a');
    TJTag.appendChild(TJInnerTag);
    TJInnerTag.setAttribute('role', 'tab');
    TJInnerTag.setAttribute('class', 'nav-link');
    TJInnerTag.setAttribute('href', '/download.php?type=tj&id=' + window.location.href.match(ProblemRegExp)[1]);
    TJInnerTag.innerHTML = '<span class="glyphicon glyphicon-book"></span> 题解';
}

function changeGravatarURL() {
    const GravatarURLRegExp = /\/\/cn.gravatar.com\/avatar\/(.*)$/;
    var Gravatar = document.getElementsByClassName('img-thumbnail')[0];
    if (Gravatar && Gravatar.nodeType){
        Gravatar.setAttribute('src', '//cravatar.cn/avatar/' + Gravatar.getAttribute('src').match(GravatarURLRegExp)[1]);
    }
    var Gravatars = document.getElementsByClassName('img-rounded');
    for (var gravatar in Gravatars) {
        if (Gravatars[gravatar] && Gravatars[gravatar].nodeType && GravatarURLRegExp.test(Gravatars[gravatar].getAttribute('src'))) {
            Gravatars[gravatar].setAttribute('src', '//gravatar.loli.net/avatar/' + Gravatars[gravatar].getAttribute('src').match(GravatarURLRegExp)[1]);
        }
    }
}

function clearNameStyle() {
    const NameExp = /^(.{1,}?)( .*)*$/;
    var Names = document.getElementsByClassName('uoj-username');
    for (var i in Names) {
        if (!Names[i].innerHTML) continue;
        Names[i].innerHTML = Names[i].textContent.match(NameExp)[1];
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (!Honors[j].innerHTML) continue;
        Honors[j].innerHTML = Honors[j].textContent.match(NameExp)[1];
    }
}

function applyNewYearMagic() {
    if (NewYearMagical.NameColor) {
        NameColorList[Username] = NewYearMagical.NameColor;
    }
    if (NewYearMagical.CCFBadge) {
        CCFBadgeList[Username] = NewYearMagical.CCFBadge;
    }
    if (NewYearMagical.TagBadge) {
        TagBadgeList[Username] = NewYearMagical.TagBadge;
    }
}

function NameColor() {
    var Names = document.getElementsByClassName('uoj-username');
    var NeedsRepeat = false;
    for (var i in Names) {
        if (Names[i].innerHTML && NameColorList[Names[i].innerHTML]) {
            Names[i].style = 'color:' + NameColorList[Names[i].innerHTML][0];
            var resN = '';
            for (var charN = 1; charN < NameColorList[Names[i].innerHTML].length; ++charN) {
                resN = resN + '<font style="color:' + NameColorList[Names[i].innerHTML][charN] + '">' + Names[i].innerHTML.substring(charN - 1, charN) + '</font>';
            }
            Names[i].innerHTML = resN + Names[i].innerHTML.substring(NameColorList[Names[i].innerHTML].length - 1);
            if (Names[i].parentElement.getAttribute('class') == 'legendLabel') {
                NeedsRepeat = true;
            }
        }
    }
    if (NeedsRepeat) {
        setInterval(function(){
            var Names = document.getElementsByClassName('uoj-username');
            for (var i in Names) {
                if (Names[i].innerHTML && Names[i].parentElement.getAttribute('class') == 'legendLabel' && NameColorList[Names[i].innerHTML]) {
                    Names[i].style = 'color:' + NameColorList[Names[i].innerHTML][0];
                    var resN = '';
                    for (var charN = 1; charN < NameColorList[Names[i].innerHTML].length; ++charN) {
                        resN = resN + '<font style="color:' + NameColorList[Names[i].innerHTML][charN] + '">' + Names[i].innerHTML.substring(charN - 1, charN) + '</font>';
                    }
                    Names[i].innerHTML = resN + Names[i].innerHTML.substring(NameColorList[Names[i].innerHTML].length - 1);
                }
            }
        }, 200);
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (Honors[j].innerHTML && NameColorList[Honors[j].innerHTML]) {
            Honors[j].style = 'color:' + NameColorList[Honors[j].innerHTML][0];
            var resH = '';
            for (var charH = 1; charH < NameColorList[Honors[j].innerHTML].length; ++charH) {
                resH = resH + '<font style="color:' + NameColorList[Honors[j].innerHTML][charH] + '">' + Honors[j].innerHTML.substring(charH - 1, charH) + '</font>';
            }
            Honors[j].innerHTML = resH + Honors[j].innerHTML.substring(NameColorList[Honors[j].innerHTML].length - 1);
        }
    }
}

function NameBadge() {
    var Names = document.getElementsByClassName('uoj-username');
    for (var i in Names) {
        if (!Names[i].innerHTML) continue;
        var name = Names[i].textContent;
        if (CCFBadgeList[name] && Names[i].parentElement.getAttribute('class') != 'legendLabel') {
            Names[i].innerHTML = Names[i].innerHTML + ' <svg width="1em" height="1em" data-v-303bbf52="" aria-hidden="true" focusable="false" data-prefix="fad" data-icon="badge-check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="margin-bottom:.25em!important;bottom:10px;--fa-primary-color:#fff;--fa-secondary-color:' + CCFBadgeList[name] + ';--fa-secondary-opacity:1;"><g data-v-303bbf52="" class="fa-group"><path data-v-303bbf52="" fill="var(--fa-secondary-color)" d="M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z" class="fa-secondary"></path></g></svg>';
        }
        if (TagBadgeList[name] && Names[i].parentElement.getAttribute('class') != 'legendLabel') {
            Names[i].innerHTML = Names[i].innerHTML + ' <span style="background-color:' + TagBadgeList[name][0] + ';padding:0.2em 0.6em;border-radius:.2em;color:#fff;font-size:0.7em;font-weight:bold;display:inline-block">' + TagBadgeList[name][1] + '</span>';
        }
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (!Honors[j].innerHTML) continue;
        var honor = Honors[j].textContent;
        if (CCFBadgeList[honor]) {
            Honors[j].innerHTML = Honors[j].innerHTML + ' <svg width="1em" height="1em" data-v-303bbf52="" aria-hidden="true" focusable="false" data-prefix="fad" data-icon="badge-check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="margin-bottom:.25em!important;bottom:10px;--fa-primary-color:#fff;--fa-secondary-color:' + CCFBadgeList[honor] + ';--fa-secondary-opacity:1;"><g data-v-303bbf52="" class="fa-group"><path data-v-303bbf52="" fill="var(--fa-secondary-color)" d="M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z" class="fa-secondary"></path></g></svg>';
        }
        if (TagBadgeList[honor]) {
            Honors[j].innerHTML = Honors[j].innerHTML + ' <span style="background-color:' + TagBadgeList[honor][0] + ';padding:0.2em 0.6em;border-radius:.2em;color:#fff;font-size:0.7em;font-weight:bold;display:inline-block">' + TagBadgeList[honor][1] + '</span>';
        }
    }
}