Greasy Fork

来自缓存

Greasy Fork is available in English.

luogu 插件集合

非常好的 luogu 插件集合

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         luogu 插件集合
// @namespace    http://tampermonkey.net/
// @version      1.3.0
// @description  非常好的 luogu 插件集合
// @author       konyakest
// @license      MIT
// @match        https://www.luogu.com.cn/*
// @match        https://www.luogu.com/*
// @match        https://api.loj.ac/
// @icon         https://fecdn.luogu.com.cn/luogu/logo.png
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';
    var url = window.location.href;
    async function user_detail(){
        var button = document.createElement('button');
        button.textContent = '复制Md';
        button.style.position = "absolute";
        button.style.top = "100px";button.style.right = "100px";
        window.addEventListener('scroll', function() {
            var scrollY = window.scrollY;
            button.style.top = (100 + scrollY) + 'px';
        });
        button.classList.add('button-lgcm');
        button.addEventListener('click', async function() {
            var introduction = _feInstance.currentData.user.introduction;
            await navigator.clipboard.writeText(introduction);
            alert('复制成功');
        });
        document.body.appendChild(button);
    }
    async function blog(){
            var button = document.createElement('button');
            button.textContent = '复制Md';
            button.style.position = "absolute";
            button.style.top = "100px";button.style.right = "100px";
            window.addEventListener('scroll', function() {
                var scrollY = window.scrollY;
                button.style.top = (100 + scrollY) + 'px';
            });
            button.classList.add('button-lgcm');
            button.addEventListener('click', async function() {
                fetch('/api/blog/detail/' + BlogGlobals.blogID).then(res => res.json()).then(res => navigator.clipboard.writeText(res.data.Content));
                alert('复制成功');
            });
            document.body.appendChild(button);
        };
    async function contest_detail(){
        var button = document.createElement('button');
        button.textContent = '复制Md';
        button.style.position = "absolute";
        button.style.top = "100px";button.style.right = "100px";
        window.addEventListener('scroll', function() {
            var scrollY = window.scrollY;
            button.style.top = (100 + scrollY) + 'px';
        });
        button.classList.add('button-lgcm');
        button.addEventListener('click', async function() {
            var introduction = _feInstance.currentData.contest.description;
            await navigator.clipboard.writeText(introduction);
            alert('复制成功');
        });
        document.body.appendChild(button);
    };
    async function training_detail(){
        var button = document.createElement('button');
        button.textContent = '复制Md';
        button.style.position = "absolute";
        button.style.top = "100px";button.style.right = "100px";
        window.addEventListener('scroll', function() {
            var scrollY = window.scrollY;
            button.style.top = (100 + scrollY) + 'px';
        });
        button.classList.add('button-lgcm');
        button.addEventListener('click', async function() {
            var introduction = _feInstance.currentData.training.description;
            await navigator.clipboard.writeText(introduction);
            alert('复制成功');
        });
        document.body.appendChild(button);
    };
    var style = document.createElement('style');
    style.textContent = `
        .button-lgcm {
            outline:none !important;
            cursor: pointer;
            line-height: 1.25;
            position: relative;
            display: block;
            margin-left: -.0625rem;
            padding: .5rem .75rem;
            color: #fff !important;
            border: .0625rem solid #dee2e6;
            font-size: 15px;
            font-weight: unset;
            display: flex;
            min-width: 36px;
            height: 36px;
            margin: 0 3px;
            border-radius: 100px!important;
            align-items: center;
            justify-content: center;
            transition:all .3s;
            background-color: #5e72e4;
        }
        .button-lgcm:hover {
            box-shadow: 0 7px 14px rgba(50,50,93,.1), 0 3px 6px rgba(0,0,0,.08);
            transform: translateY(-1px);
        }
        `;
    document.head.appendChild(style);
    if (url.includes('blog') && !url.includes('Admin') && !url.includes('admin')) {
        var parsedUrl = new URL(url);
        if (url.includes('org')) {
            var path = parsedUrl.pathname.split('/');
            if (path.length >= 2 && path[1] != '') {
                window.addEventListener('load', blog);
            }
        } else {
            var path = parsedUrl.pathname.split('/');
            if (path.length >= 4) {
                console.log('a');
                window.addEventListener('load', blog);
            }
        }
    }
    if (url.includes('user') && !url.includes('notification')) {
        window.addEventListener('load', user_detail);
    }
    if (url.includes('contest') && !url.includes('list') && !url.includes('edit') && !url.includes('contestId')) {
        window.addEventListener('load', contest_detail);
    }
    if (url.includes('training') && !url.includes('edit') && !url.includes('list')) {
        window.addEventListener('load', training_detail);
    }
})();

(function () {
  'use strict';
  const url = window.location.href;
  async function clickBotton_blog() {
    var x = document.querySelector("#lentille-context").text
    var y = JSON.parse(x)
    var z = y.data.article.content
    navigator.clipboard.writeText(z);
  };
  if (url.includes("article")) {
    document.onkeydown = function (e) {
      if (e.keyCode == 67 && e.ctrlKey && e.altKey) {
        clickBotton_blog();
        alert("复制成功!");
      }
    }
  }
  // Your code here...
})();

(function() {
    'use strict';

    function remove(){
        var xpath = "/html/body/div/div[2]/main/div/section[1]/div[1]/a[2]";

        var iterator = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);

        var element;
        while (element = iterator.iterateNext()) {
            if (element) {
                element.parentNode.removeChild(element);
            }
        }
    }

    window.addEventListener("load", () => {
        remove();
    });
})();

/*
- 浏览记录
- 显示代码长度
- 简要题面
- 首页暂存内容
- 卷题情况
- 测试用例
- 显示今日AC
*/

const PASTEID = "1vvwrtao"/*请自行设置,如"eyb488k7"*/;
const TRAINING_ID = 551473/*请自行设置,如100,**必须是团队作业题单,且您必须有题单的编辑权限***/;

function URLmatch(pat){
    return Boolean(window.location.href.match(pat));
}

async function 显示代码长度(){
    const ENABLE_CACHE = true;
    /*
    ENABLE_CACHE:是否使用缓存(缓存即将获取的结果存下来,下一次直接使用)
    根据代码长度判定颜色的方案可以自行修改 makeColoredTextBySize 中的内容,我相信这部分是可以直接看懂的(*´▽`)ノノ
    */

    function getMid(lst){
        // console.log(lst);
        return (function(x){
            if(x<1024){
                return x+" B";
            }
            return (x/1024).toFixed(2)+" K";
        })(lst[Math.floor(lst.length/2)]);
    }

    function makeColoredText(color,text){
        return `
        <a data-v-0640126c="" data-v-beeebc6e=""
            colorscheme="default" class="color-default" data-v-b5709dda="">
                <span data-v-71731098="" data-v-beeebc6e="" class="lfe-caption"
                    style="background: ${color}; color: rgb(255, 255, 255);" data-v-0640126c="">${text}
                </span>
        </a>
        `
    }

    let colors = {
        red:     "rgb(254,76,97)",
        orange:  "rgb(243,156,17)",
        yellow:  "rgb(255,193,22)",
        green:   "rgb(82,196,26)",
        blue:    "rgb(52,152,219)",
        purple:  "rgb(157,61,207)",
        black:   "rgb(14,29,105)"
    };

    function makeColoredTextBySize(size,text){
        size = size.split(' ');
        size = Number(size[1]==="K"?size[0]*1024:size[0]);
        const K = 1024;
        if(size <= 1*K) return makeColoredText(colors.yellow,text);
        if(size <= 2*K) return makeColoredText(colors.green,text);
        if(size <= 3*K) return makeColoredText(colors.blue,text);
        if(size <= 4*K) return makeColoredText(colors.purple,text);
        return makeColoredText(colors.black,text);
    }

    async function sampleRecord(pid){
        if(ENABLE_CACHE){
            if(GM_getValue(pid)&&(GM_getValue(pid)!=="NaN K")){
                return GM_getValue(pid);
            }
        }
        let lst = [];
        try{
            let promiselst = [];
            for(let i=1;i<=5;i++){
                promiselst.push(
                    fetch(
                        `https://www.luogu.com.cn/record/list?pid=${pid}&status=12&_contentOnly=1&page=${i}`
                    )
                    .then(x=>x.json())
                    .then(x=>x.currentData.records.result)
                );
            }
            await Promise.all(promiselst).then(function(x){
                x.forEach(x=>x.forEach(x=>lst.push(x.sourceCodeLength)));
                lst.sort((a,b)=>a-b);
            });
        }catch(e){};
        // console.log(lst);
        lst.sort((a,b)=>a-b);
        let res = getMid(lst);
        if(ENABLE_CACHE){
            GM_setValue(pid,res);
        }
        return res;
    }

    if(window.location.href.split('/')[3] === "problem"){
        let field = document.querySelector(".color-inverse > div:nth-child(1)");
        let clone = field.cloneNode(true);
        field.parentNode.appendChild(clone);
        clone.children[0].innerHTML = "平均码长";
        clone.children[1].innerHTML = "正在获取中";
        let size = await sampleRecord(window.location.href.split('/')[4],clone.children[1]);
        clone.children[1].innerHTML = makeColoredTextBySize(size,size);
    }
    else if(window.location.href.match('#').length){
        let all = document.querySelector(".row-wrap");
        //all.childNodes.forEach(async function(x){
        for(let i=0;i<all.childNodes.length;i++){
            let x = all.childNodes[i];
            if(!x.innerHTML){
                continue;
            }
            let element = x.children[1];
            let a = document.createElement('a');
            let size = await sampleRecord(element.title);
            a.innerHTML = makeColoredTextBySize(size,size);
            element.appendChild(a);
         };
    }
}

async function 浏览记录(){
    const MAX_COUNT = 20;
    const DELAY = 20;//停留超过 20s 会被记录

    var has_built;

    function mySetTimeOut(func,tim){
        let a;
        a = setInterval(()=>{func();clearInterval(a);},tim);
    }

    function store(problem,title,link){
        let all = (GM_getValue("all") || []).slice(-MAX_COUNT);
        if(!all.some(x=>x.problem === problem)){
            all.push({problem:problem,title:title,link:link});
        }
        GM_setValue("all",all);
    }

    async function inPaste(){
        let value = GM_getValue("doit");
        if(!value){
            return;
        }
        GM_deleteValue("doit");
        let data = "";
        GM_getValue("all").forEach(x => {
            data += `- [${x.title}](${x.link})`
            data += "\n\n"
        });
        await fetch(`https://www.luogu.com.cn/paste/edit/${PASTEID}`, {
            "credentials": "include",
            "headers": {
                "Accept": "application/json, text/plain, */*",
                "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
                "X-Requested-With": "XMLHttpRequest",
                "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content,
                "Content-Type": "application/json",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-origin"
            },
            "body": JSON.stringify({"data":data}),
            "method": "POST",
            "mode": "cors"
        });
        window.location.reload();
    }

    function buildstatisticsbutton() {
        if (has_built) return;
        let tmp = document.querySelector(".operation > span:nth-child(3)");
        let tmp2 = tmp.cloneNode(true);
        tmp2.childNodes[0].childNodes[0].innerText = "历史记录";
        tmp2.onclick = async function() {
            GM_setValue("doit",true);
            window.open(`https://www.luogu.com.cn/paste/${PASTEID}`);
        };
        tmp.parentNode.appendChild(tmp2);
        has_built = true;
    }

    window.addEventListener('load',function(){
        if(window.location.href.split('/')[3] === "paste"){
            inPaste();
            return;
        }
        let title = document.querySelector(".lfe-h1 > span:nth-child(1)")?
            document.querySelector(".lfe-h1 > span:nth-child(1)").title :
            document.querySelector(".lfe-h1").innerText;
        let problem = window.location.href.split('/')[4];
        mySetTimeOut(function(){store(problem,title,window.location.href);console.log("store!");},1000*DELAY);
    })

    window.addEventListener('load', buildstatisticsbutton);
    setTimeout(buildstatisticsbutton, 500);
}

async function 简要题面(){
    const keywords = [
        "题目大意","题意","题意简述","问题描述","题面","Description"
    ];

    async function getSolutions(){
        let problem = window.location.href.split('/')[4];
        let url = "https://www.luogu.com.cn/problem/solution/" + problem;
        let text = await fetch(url).then(x=>x.text());
        let data = text.split(`JSON.parse(decodeURIComponent("`)[1].split(`"`)[0];
        let res = [];
        JSON.parse(decodeURIComponent(data)).currentData.solutions.result.forEach(x => {
            res.push(x.content.split("\n"));
        });
        return res;
    }

    function getProblemDescr(text){
        let res = [];
        let pre;
        try{
            text.forEach(function(x){
                if(x.split(" ")[0] === pre){
                    throw "parse end!";
                }
                if(keywords.some(kwd=>x.match(kwd))&&!keywords.some(kwd=>x.split(" ")[0].match(kwd))){
                    pre=x.split(" ")[0];
                }
                if(pre){
                    res.push(x);
                }
            });
        }catch(e){
            if(e === "parse end!"){
                let str = "";
                res.forEach(x=>str+=`> ${x}\n`);
                return str;
            }
            throw e;
        }
        return "";
    }

    async function my_marked(code){
        if(code === "") return "";
        let tmp;
        await GM_xmlhttpRequest({
            method:'post',
            url:'http://www.nfls.com.cn:10611/api/markdown',
            data:"s="+encodeURIComponent(code),
            headers:{ "Content-Type": "application/x-www-form-urlencoded" },
            onload:res=>tmp=res.responseText
        });
        async function dfs(dep){
            await new Promise(resolve=>setTimeout(resolve,500));
            if(typeof tmp !== 'undefined'){
                return tmp;
            }
            dep === 8? tmp = '网络错误,请刷新重试': await dfs(dep+1);
        }
        await dfs(1);
        return new DOMParser().parseFromString(tmp,"text/html").all[3].innerHTML;
    }

    async function addElement(){
        let solutions = await getSolutions();
        // window.searchSolutionKeyword=function(s){
        //     return !!window.__solutions.some(x=>x.some(xx=>xx.match(s)));
        // };
        // setTimeout(_=>console.log(window.searchSolutionKeyword,window),2000);


        let tmp = document.querySelector(".operation > span:nth-child(3)");
        let tmp2 = tmp.cloneNode(true);
        tmp2.childNodes[0].childNodes[0].innerText = "搜索题解关键词";
        tmp2.onclick = function() {
            let value = prompt("请输入要找的关键词");
            if(value === '' || value === null){
                return;
            }
            if(!!solutions.some(x=>x.some(xx=>xx.match(value)))){
                alert(`恭喜!题解中有关键词"${value}",快切了此题吧!`);
            }
            else{
                alert(`题解中并没有关键词"${value}"`);
            }
            // await addtrainingproblem(window.location.href.split('/')[4]);
            // window.open(`https://www.luogu.com.cn/training/${TRAINING_ID}#rank`);
        };
        tmp.parentNode.appendChild(tmp2);

        let html = await getSolutions().then(function(x){
            let res = "";
            x.forEach(function(x){
                x = getProblemDescr(x);
                if(x !== ""){
                    res+=x+"\n\n";
                }
            });
            return res;
        });
        await fetch("https://www.luogu.com.cn/paste/edit/"+PASTEID, {
            "headers": {
                "X-Requested-With": "XMLHttpRequest",
                "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content,
                "Content-Type": "application/json"
            },
            "body": JSON.stringify({"data":html}),
            "method": "POST"
        });
        html = await my_marked(html);
        let nodes = [
            document.querySelector("h2.lfe-h2:nth-child(1)"),
            document.querySelector("div.marked:nth-child(2)")];
        let text = nodes[0].parentNode.insertBefore(nodes[1].cloneNode(true),nodes[0]);
        let title = nodes[0].parentNode.insertBefore(nodes[0].cloneNode(true),text);
        title.innerText = "简要题意";
        text.innerHTML = html;
        let index = 0;
        let show = function(){
            let cnt = 0;
            text.children.forEach(function(x){
                x.style.display = (cnt === index?"":"none");
                cnt ++;
            });
        };
        show();
        if(text.children.length === 0){
            text.innerHTML = "未找到简要题意";
            return;
        }
        let but1 = document.createElement("button");
        but1.innerText = "换一个";
        but1.onclick = function(){
            index = (index+1)%text.children.length;
            show();
        };
        if(text.children.length !== 1){
            title.appendChild(but1);
        }
        let but2 = document.createElement("button");
        but2.innerText = "更好的阅读体验";
        but2.onclick = function(){window.open("https://www.luogu.com.cn/paste/"+PASTEID);};
        title.appendChild(but2);
    }

    addElement();
}

async function 首页暂存内容(){
    function inMain(){
        let div = document.querySelector(".am-u-lg-3 > div:nth-child(3)");
        let inn = document.createElement("div");
        inn.innerHTML = "<h2>暂存内容</h2>";
        inn.style.marginTop = "40px";
        div.appendChild(inn);

        let but1=document.createElement("button");
        but1.innerText="编辑内容";
        but1.onclick = function(){window.open(GM_getValue("pasteid"));};
        let but2=document.createElement("button");
        but2.innerText="删除内容";
        but2.onclick = function(){GM_deleteValue("html");alert("删除成功");};

        inn.appendChild(but1);
        inn.appendChild(but2);

        let tmp = document.createElement("div");
        tmp.innerHTML = GM_getValue("html");
        tmp.style.marginTop = "20px";
        if(tmp.innerHTML === undefined){
            tmp.innerHTML = "";
        }
        inn.appendChild(tmp);
    }

    //paste

    function inPaste(){
        let div = document.querySelector(".actions");
        let button = div.childNodes[2].cloneNode(true);
        button.innerText="保存到首页";
        div.appendChild(div.childNodes[1].cloneNode(true));
        div.appendChild(button);
        button.onclick=function(){
            GM_setValue("pasteid",window.location.href);
            GM_setValue("html",document.querySelector(".marked").innerHTML);
            alert("保存成功");
        };
    }

    (function() {
        'use strict';
        if(window.location.href.split('/')[3] === "paste"){
            setTimeout(inPaste,10);
        }
        else{
            setTimeout(inMain,10);
        }
    })();
}

async function 卷题情况(){
    var has_built = false;

    function addtrainingproblem(proName) {
        return fetch(`https://www.luogu.com.cn/api/training/editProblems/${TRAINING_ID}`, {
            "headers": {
                "X-Requested-With": "XMLHttpRequest",
                "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content,
                "Content-Type": "application/json",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-origin"
            },
            "body": "{\"pids\":[\"" + proName + "\", \"P1001\"]}",
            "method": "POST",
        });
    }

    function buildstatisticsbutton() {
        if (has_built) return;
        let tmp = document.querySelector(".operation > span:nth-child(3)");
        let tmp2 = tmp.cloneNode(true);
        tmp2.childNodes[0].childNodes[0].innerText = "卷题情况";
        tmp2.onclick = async function() {
            await addtrainingproblem(window.location.href.split('/')[4]);
            window.open(`https://www.luogu.com.cn/training/${TRAINING_ID}#rank`);
        };
        tmp.parentNode.appendChild(tmp2);
        has_built = true;
    }

    window.addEventListener('load', buildstatisticsbutton);
    setTimeout(buildstatisticsbutton, 500);
}

async function 测试用例(){
    var has_built = false;

    async function _getLojProblem(keyword){
        return await fetch("https://api.loj.ac/api/problem/queryProblemSet", {
            "credentials": "include",
            "headers": {
                "Content-Type": "application/json"
            },
            "body": JSON.stringify({
                "keyword":keyword,"locale":"zh_CN","takeCount":1,
                "skipCount":0,"keywordMatchesId":true,"titleOnly":true
            }),
            "method": "POST",
        }).then((x)=>(x.json())).then(function(x){return x.result[0].meta.id;});
    }

    async function getLojProblem(keyword){
        let value;
        try{
            value = await _getLojProblem(keyword);
        }
        catch(e){
            console.log("error:",e);
            value = await _getLojProblem(keyword.split('」')[1]);
        }
        return value;
    }

    async function getLojSubmission(problem){
        return await fetch("https://api.loj.ac/api/submission/querySubmission", {
            "headers": {
                "Content-Type": "application/json"
            },
            "body": JSON.stringify({"problemDisplayId":problem,"locale":"zh_CN","takeCount":1,"status":"Accepted"}),
            "method": "POST"
        }).then((x)=>(x.json())).then((x)=>x.submissions[0].id);
    }

    function inLuogu(){
        if(has_built || document.querySelector(".tags-wrap").innerText.search("各省省选") === -1){
            return;
        }
        let tmp = document.querySelector(".operation > span:nth-child(3)");
        let tmp2 = tmp.cloneNode(true);
        tmp2.childNodes[0].childNodes[0].innerText = "测试用例";
        tmp2.onclick = function() {
            const p = document.querySelector(".lfe-h1 > span:nth-child(1)").title.split('[')[1].split(']');
            GM_setValue("title",`「${p[0]}」${p[1].trim()}`);
            window.open("https://api.loj.ac");
        };
        tmp.parentNode.appendChild(tmp2);
        has_built = true;
    }

    async function inLoj(){
        if(has_built){
            return;
        }
        has_built = true;
        try{
            const value = await getLojSubmission(await getLojProblem(GM_getValue("title")));
            if(isNaN(value)){
                throw "Cannot get submission!";
            }
            window.location.replace("https://loj.ac/s/" + value);
        }
        catch(err){
            alert("error: \n"+err);
        }
        finally{
            GM_deleteValue("title");
        }
    }

    function main(){
        window.location.href === "https://api.loj.ac/" ? setTimeout(inLoj,500) : inLuogu();
    }

    window.addEventListener('load', main);
    setTimeout(main, 500);
}

async function 显示今日AC(){
    const today = (
        (a)=>(new Date(a.getFullYear()+"/"+String(a.getMonth()+1)+"/"+String(a.getDate())))
    )(new Date()).getTime()/1000;

    async function dfsGetTodayAC(name,page){
        let ans = await fetch(`https://www.luogu.com.cn/record/list?user=${name}&status=12&page=${page}`)
            .then(x=>x.text())
            .then(x=>x.split("JSON.parse(decodeURIComponent(\"")[1])
            .then(x=>x.split("\"))")[0])
            .then(x=>JSON.parse(decodeURIComponent(x)))
            .then(x=>x.currentData.records.result)
            .then(x=>x.filter(xx=>xx.submitTime>=today));
        if(ans.length === 20){
            let res = await dfsGetTodayAC(name,page+1);
            res.forEach(x=>ans.push(x));
        }
        return ans;
    }

    console.log(today);

    let cards = [];
    while(document.querySelector(".row-wrap") === null || cards.length !== document.querySelector(".row-wrap").childElementCount){
        cards = [];
        let app = document.querySelector("#app");
        app.childNodes.forEach(function(x){if(x.className === "dropdown") cards.push(x);});
        if(!cards.length){
            app = document.querySelector("main.wrapped");
            app.childNodes.forEach(function(x){if(x.className === "dropdown") cards.push(x);});
            console.log("cards",cards);
        }
        console.log("cards",cards);
        await new Promise(resolve=>setTimeout(resolve,500));
    }


    cards.forEach(async function(x){
        let name = document.querySelector(
            `div.row:nth-child(${cards.indexOf(x)+1}) > span:nth-child(2) > `+
            `span:nth-child(1) > span:nth-child(1) > span:nth-child(1)`
        ).innerText;

        let ans = await dfsGetTodayAC(name,1);

        let p = document.createElement("p");
        p.innerText = "今日通过的题目:";
        console.log(x);
        x.children[0].children[1].appendChild(p);
        ans = ans.filter((item, index) => {
            const duplicateIndex = ans.findIndex(otherItem => otherItem.problem.pid === item.problem.pid);
            return duplicateIndex === index;
        });
        ans.forEach(function(xx){
            let a = document.createElement("a");
            a.innerText = xx.problem.pid + "  " + xx.problem.title;
            a.href = "https://www.luogu.com.cn/problem/" + xx.problem.pid;
            x.children[0].children[1].appendChild(a);
            x.children[0].children[1].appendChild(document.createElement("p"));
        })
        console.log(name,ans);
    });
}

if(URLmatch("https://www.luogu.com.cn/problem/*") || URLmatch("https://www.luogu.com.cn/paste/*") || URLmatch("https://www.luogu.com.cn/training/*")){
    try{
        浏览记录();
    }catch(e){};
}

if(URLmatch("https://www.luogu.com.cn/problem/*") || (URLmatch("https://www.luogu.com.cn/training/*")&&!URLmatch("rank"))){
    try{
        显示代码长度();
    }catch(e){};
}

if(URLmatch("https://www.luogu.com.cn/problem/*")){
    try{
        简要题面();
    }catch(e){console.log(e);};
}

if(window.location.href === "https://www.luogu.com.cn/"||URLmatch("https://www.luogu.com.cn/paste/*")){
    try{
        首页暂存内容();
    }catch(e){console.log(e);};
}

if(URLmatch("https://www.luogu.com.cn/problem/*")||!URLmatch("https://www.luogu.com.cn/problem/list")){
    try{
        卷题情况();
    }catch(e){console.log(e);};
}

if(URLmatch("https://www.luogu.com.cn/problem/*")||URLmatch("https://api.loj.ac/")){
    try{
        测试用例();
    }catch(e){console.log(e);};
}

let id = setInterval(function(){
    if(window.location.href.split('/')[3] === "training" && Boolean(window.location.href.split('/')[4].match("#rank"))){
        console.log("123");
        try{
            显示今日AC();
        }catch(e){console.log(e);};
        clearInterval(id);
    }
},1000);

(function(){
    'use strict';
    const ob = new MutationObserver(() => {
        const t = document.querySelector(".introduction.marked");
        if (t !== null && t.style.display === "none") {
            t.style.display = 'block';
            for (let i = 0; i < t.parentElement.children.length; i++) {
                if (t.parentElement.children[i].innerText === '系统维护,该内容暂不可见。') {
                    t.parentElement.children[i].remove();
                }
            }
        }
    });
    ob.observe(document.documentElement, {childList: true, subtree: true});
})();

'use strict';
(function(){
	const featureDict = new Map([
		['lgbot1RemoveAd', '屏蔽广告'],
		['lgbot1Removeback', '移除网页出错跳转'],
		['lgbot1AddMessageLink', '私信界面 Ctrl+Click 打开用户主页'],
		['lgbot1RemoveCover', '移除主页遮盖'],
		['lgbot1AddProblemsColor', '显示题目颜色']
	]);
	const problemDifficultyToColor = [[191,191,191],[254,76,97],[243,156,17],[255,193,22],[82,196,26],[52,152,219],[157,61,207],[14,29,105]];
	function addSettingButton(){//增加插件设置
		const navElement = document.querySelector('nav.lfe-body');
		if(!navElement){
			console.log("未找到侧边导航栏");
			console.log(document);
			return;
		}
		const settingElement = document.createElement('a');//外壳,链接功能
		settingElement.setAttribute('data-v-0640126c', '');
		settingElement.setAttribute('data-v-639bc19b', '');
		settingElement.setAttribute('data-v-33633d7e', '');
		settingElement.className = 'color-none';
		settingElement.style.color = 'inherit';
		const settingText = document.createElement('span');
		settingText.setAttribute('data-v-639bc19b', '');
		settingText.className = 'text';
		settingText.textContent = '插件设置';
		settingElement.appendChild(settingText);
		navElement.appendChild(settingElement);
		settingElement.addEventListener('click', () => {//点击后进入临时页面
			function initializeSettings(){
				for(let i of featureDict.keys()){
					if(localStorage.getItem(i) === null){
						localStorage.setItem(i, 'true');
					}
				}
			}
			initializeSettings();
			const pageContent = `
				<!DOCTYPE html>
				<html lang="en">
				<head>
					<meta charset="UTF-8">
					<meta name="viewport" content="width=device-width, initial-scale=1.0">
					<title>luogu_bot1 功能设置</title>
					<style>
						body { font-family: Arial, sans-serif; }
						#featureBox {
							position: fixed;
							top: 20%;
							left: 50%;
							transform: translate(-50%, -50%);
							background-color: white;
							border: 1px solid #ccc;
							padding: 20px;
							z-index: 10001;
						}
					</style>
				</head>
				<body>
					<div id="featureBox">
						<h3>选择插件功能</h3>
						${Array.from(featureDict).map(([key, description]) => `
							<div>
								<label><input type="checkbox" id="${key}">${description}</label>
							</div>
						`).join('')}
						<button id="selectAll">全选</button>
						<button id="saveFeatures">保存</button>
					</div>
					<script>
						document.addEventListener('DOMContentLoaded', () => {//加载设置
							${Array.from(featureDict.keys()).map(key => `
								const ${key} = localStorage.getItem('${key}') === 'true';
								document.getElementById('${key}').checked = ${key};
							`).join('')}
						});
						document.getElementById('saveFeatures').addEventListener('click', () => {//保存设置
							${Array.from(featureDict.keys()).map(key => `
								const ${key} = document.getElementById('${key}').checked;
								localStorage.setItem('${key}', String(${key}));
							`).join('')}
							alert('功能已保存');
						});
						document.getElementById('selectAll').addEventListener('click', () => {//全选
							${Array.from(featureDict.keys()).map(key => `
								document.getElementById('${key}').checked = true;
							`).join('')}
						});
					</script>
				</body>
				</html>
			`;
			const newWindow = window.open();
			newWindow.document.write(pageContent);
			newWindow.document.close();
		});
	}
	function removeAd(){//屏蔽广告
		const adElement = document.querySelector('div[data-v-0a593618][data-v-1143714b]');
		if(adElement) {
			adElement.remove();
			console.log('广告已被删除');
		}
		else console.log('没有找到广告');
	}
	function removeBack(){//移除网页跳转
		function disableRedirect(){
			window.history.go = function() {// 根据实际测试,洛谷使用的是 history.go
				console.log("luogu_bot1:已为您屏蔽 history.go()");
			};
		}
		function checkError(){
			if(document.title === '错误 - 洛谷 | 计算机科学教育新生态'){
				disableRedirect();
				return true;
			}
			return false;
		}
		const observer = new MutationObserver((mutations, obs) => {
			checkError();
		});
		const config = {
			childList: true,
			subtree: true,
		};
		observer.observe(document, config);// 监视 title 变化
		if(document.readyState === 'complete' || document.readyState === 'interactive'){
			checkError();
		}
	}
	async function getUidByUsername(username){// 获取 uid
		const apiUrl = `https://www.luogu.com.cn/api/user/search?keyword=${username}`;
		return await fetch(apiUrl)
		.then(response => response.json())
		.then(data => {
            if(data.users && data.users.length > 0){
        		return data.users[0].uid;
			}
		})
		.catch(error => {
			console.error('Error fetching user data:', error);
		});
	}
	async function processItem(item) { // 添加 eventListener
		item.parentElement.parentElement.addEventListener('click', (event) => {
			if(event.ctrlKey){
				getUidByUsername(item.textContent.trim())
				.then(uid => {
					const userLink = `/user/${uid}`;
					if(userLink){
						window.open(userLink, '_blank');
					}
				})
			}
		});
    }
	function addMessageLink(){ // Ctrl+Click 触发,动态修改网页
		let items = document.querySelectorAll('span[data-v-5b9e5f50] > span[slot="trigger"]');
		console.log("asdf");
		console.log(items);
		for(let i of items){
			processItem(i);
		}
		const callback = async function(mutationsList, observer) {
			for (const mutation of mutationsList) {
				if (mutation.type === 'childList') {
					for (const addedNode of mutation.addedNodes) {
						if (addedNode.nodeType === Node.ELEMENT_NODE) {
							const newItems = addedNode.querySelectorAll('span[data-v-5b9e5f50] > span[slot="trigger"]');
							for (const newItem of newItems) {
								processItem(newItem);
							}
						}
					}
				}
			}
		};
		const observer = new MutationObserver(callback);
		observer.observe(document, { childList: true, subtree: true });
	}
	function removeCover(){
		let profile = document.querySelector(".introduction.marked");
		if(profile && profile.style.display === "none"){
			profile.style.display = "block";
			for(let i=0;i<profile.parentElement.children.length;++i){
				if(profile.parentElement.children[i].innerText === "系统维护,该内容暂不可见。"){
					profile.parentElement.children[i].remove();
				}
			}
		}
	}
	function alwaysRemoveCover(){
		const observer = new MutationObserver(() => removeCover());
		observer.observe(document,{
			childList: true,
			subtree: true
		});
		removeCover();
	}
	const problemToColorMap = new Map();
	class FetchRateLimiter{
		constructor(limit) { // limit 以毫秒为单位,表示相邻两次 fetch 操作间的最小间隔
			this.limit = limit;
			this.queue = [];
			this.queuePrior = [];
			this.active = false;
			this.requestCache = new Map();
		}
		process() {
			this.active = 1;
			let resolve, reject, url;
			if(this.queuePrior.length > 0){
				({resolve, reject, url} = this.queuePrior.shift());
			}
			else if(this.queue.length > 0){
				({resolve, reject, url} = this.queue.shift());
			}
			else{
				this.active = 0;
				return;
			}
			console.log(url);
			fetch(url)
			.then(resolve)
			.catch(reject);
			setTimeout(this.process.bind(this), this.limit);
		}
		push(url, prior) {
			if(this.requestCache.has(url)) return this.requestCache.get(url);
			const request = new Promise((resolve, reject) => {
				if(prior) this.queuePrior.push({url, resolve, reject});
				else this.queue.push({url, resolve, reject});
				if(!this.active) this.process();
			})
			.then((response) => {
				return response.text();
			});
			this.requestCache.set(url,request);
			return request;
		}
	}
	const limiter = new FetchRateLimiter(300);
	async function getProblemColor(problemid, prior=false){
		if(window.location.href.startsWith('https://www.luogu.com.cn/record')){
			const resultList = _feInstance.currentData.records.result;
			if(!resultList.lgbot1Visited){
				for(const item of resultList){
					problemToColorMap.set(item.problem.pid,`rgb(${problemDifficultyToColor[item.problem.difficulty].join(',')})`);
				}
				resultList.lgbot1Visited = true;
			}
		}
		if(/^https:\/\/www\.luogu\.com\.cn\/user\/\d+#practice$/.test(window.location.href)) {
			let problemList = _feInstance.currentData.submittedProblems;
			if(!problemList.lgbot1Visited){
				for(const item of problemList){
					problemToColorMap.set(item.pid,`rgb(${problemDifficultyToColor[item.difficulty].join(',')})`);
				}
				problemList.lgbot1Visited = true;
			}
			problemList = _feInstance.currentData.passedProblems;
			if(!problemList.lgbot1Visited){
				for(const item of problemList){
					problemToColorMap.set(item.pid,`rgb(${problemDifficultyToColor[item.difficulty].join(',')})`);
				}
				problemList.lgbot1Visited = true;
			}
		}
		if(problemToColorMap.has(problemid)) return problemToColorMap.get(problemid);
		const url = '/problem/'+problemid;
		let data;
		try{
			data = await limiter.push(url, prior);
		} catch (error) {
			debugger;
			console.error('Error fetching user data:', error);
			console.log(problemid);
			return;
		}
		const parser = new DOMParser();
		const doc = parser.parseFromString(data, 'text/html');
		let scriptText = doc.querySelector("script").textContent;
		scriptText = scriptText.match(/window\._feInjection = JSON\.parse\(decodeURIComponent\("(.+)"\)\);/);
		if(!scriptText) return;
		scriptText = scriptText[1];
		const _feInjection = JSON.parse(decodeURIComponent(scriptText));
		const problemDifficulty = _feInjection.currentData.problem.difficulty;
		problemToColorMap.set(problemid,`rgb(${problemDifficultyToColor[problemDifficulty].join(',')})`);
		return problemToColorMap.get(problemid);
	}
	function isProblemId(problemid){
		if(problemid.startsWith('AT_')) return true;
		if(!/[a-zA-Z]/.test(problemid)) return false;
		if(!/[0-9]/.test(problemid)) return false;
		return true;
	}
	async function addProblemColor(item){
		let problemid = item.href.split('/').pop();
		let prior = false;
		if(problemid.includes('?forum=')){
			debugger;
			problemid = problemid.split('=').pop();
			prior = true;
		}
		problemid = problemid.split('?')[0];
		problemid = problemid.split('=').pop();
		if(!isProblemId(problemid)) return;
		if(item.innerText.startsWith(problemid)){
			const spanItem = item.children[0];
			if(spanItem && spanItem.matches('span.pid') && spanItem.innerText === problemid){
				const color = await getProblemColor(problemid, prior);
				spanItem.style.color = color;
				spanItem.style.fontWeight = 'bold';
			}
			else{
				const color = await getProblemColor(problemid, prior);
				const content = item.innerHTML;
				item.innerHTML = content.replace(problemid,`<b style="color: ${color};">${problemid}</b>`);
			}
		}
	}
	async function addProblemsColor(){
		const observer = new MutationObserver(async (mutationsList) => {
			for (const mutation of mutationsList) {
				if (mutation.type === 'childList') {
					for (const addedNode of mutation.addedNodes) {
						if (addedNode.nodeType === Node.ELEMENT_NODE) {
							const newItems = addedNode.querySelectorAll('a[href]');
							if(addedNode.matches('a[href]')) addProblemColor(addedNode);
							for (const newItem of newItems) {
								addProblemColor(newItem);
							}
						}
					}
				}
				else if(mutation.type === 'characterData') {
					if(mutation.target.parentElement.matches('span.pid')){
						mutation.target.parentElement.style.color = await getProblemColor(mutation.target.textContent);
						mutation.target.parentElement.style.fontWeight = 'bold';
					}
				}
			}
		});
		observer.observe(document, {
			childList: true,
			subtree: true,
			characterData: true,
		});
		const nodelist = document.querySelectorAll('a[href]');
		for(const i of nodelist){
			addProblemColor(i);
		}
	}
	setTimeout(addSettingButton, 500);
	if(localStorage.getItem('lgbot1RemoveAd') === 'true'){
		setTimeout(removeAd, 500);
	}
	if(localStorage.getItem('lgbot1Removeback') === 'true'){
		removeBack();
	}
	if(localStorage.getItem('lgbot1AddMessageLink') === 'true'){
		if(window.location.href.startsWith('https://www.luogu.com.cn/chat')){
			setTimeout(addMessageLink,500);
		}
	}
	if(localStorage.getItem('lgbot1RemoveCover') === 'true'){
		setTimeout(alwaysRemoveCover, 500);
	}
	if(localStorage.getItem('lgbot1AddProblemsColor') === 'true'){
		setTimeout(addProblemsColor, 500);
	}
    var html = '<button id="clearbenben">清除犇犇</button>'
    var TNode = document.createElement('div');
	TNode.className = 'lg-article';
    TNode.id = 're_log';
	TNode.innerHTML = html;
    document.querySelector('div.lg-index-benben > div:nth-child(3)').insertAdjacentElement('afterend', TNode);
    document.getElementById('clearbenben').addEventListener('click', function() {
        switchMode('my');
        function load() {
            console.log('page ' + feedPage);
            $.get("/feed/" + feedMode + "?page=" + feedPage, function (resp) {
                $feed.append(resp);
                $("#feed-more").children("a").text("点击查看更多...")
                $("[name=feed-delete]").click(function () {
                    $.post("/api/feed/delete/" + $(this).attr('data-feed-id'), function () {
                        switchMode('all');
                    })
                }); feedPage++;
                if (resp.indexOf('没有更多动态了') != -1) {var l =  $('#feed > li > div.am-comment-main > header > div > a:nth-child(2)');
function f(i) {
$ .post("/api/feed/delete/"+ $(l[i]).attr('data-feed-id'), function() {
console.log(i);
if(i<l.length-1)setTimeout(`f(${i+1})`,200);
})
}
f(0);
}
                else setTimeout(load, 200);
            });
        }
        setTimeout(load, 1000);
    });
})();

document.querySelector(".operation").children.forEach(x=>x.style.zIndex=9999);