// ==UserScript==
// @name Fast-Codeforces
// @namespace xcxcli
// @version 0.3.5.4
// @match *://codeforces.com/*
// @match *://codeforces.ml/*
// @description Make Codeforces convenient
// @author xcxcli
// @downloadURL https://update.greasyfork.icu/scripts/393752/Fast-Codeforces.user.js
// @updateURL https://update.greasyfork.icu/scripts/393752/Fast-Codeforces.meta.js
// ==/UserScript==
unsafeWindow.onload=function(){
let $=unsafeWindow.jQuery,math=unsafeWindow.MathJax.Hub,Codeforces=unsafeWindow.Codeforces;
$.default=function(obj,val){
for(let i in obj)if(!(i in val))delete obj[i];
for(let i in val)if(!(i in obj))obj[i]=val[i];
return obj;
};
String.prototype.frl=function(c){
if(this.indexOf(c)===-1)return this;
return this.slice(0,this.indexOf(c));
};
String.prototype.frr=function(c){
if(this.indexOf(c)===-1)return this;
return this.slice(this.indexOf(c)+c.length);
};
String.prototype.last=function(){return this[this.length-1];}
String.prototype.replaceAll=function(s1,s2){return this.split(s1).join(s2);};
let gets=function(dir,val){
if(("fc-"+dir)in localStorage===false||localStorage["fc-"+dir]==="undefined")return val;
return JSON.parse(localStorage["fc-"+dir]);
},puts=function(dir,val){
if(val!==void 0)localStorage["fc-"+dir]=JSON.stringify(val);
else localStorage["fc-"+dir]="undefined";
},noop=function(){},Alert=Codeforces.alert,version="v0.3.5.4",
Confirm=function(str,fy,fn=noop,y="确定",n="取消"){Codeforces.confirm(str,fy,fn,y,n);$("#fc-input").focus();},
URLmatch=function(url){
if(!url)url=location.href;
if(url[0]==="/")url=location.origin+url;
if(url[0]===".")url=location.href+url;
url=new URL(url);
if(url.pathname.slice(-1)==='/')url.pathname=url.pathname.slice(0,-1);
return{host:url.origin,path:url.pathname,parr:url.pathname.split('/').slice(1)};
},
GetTitle=function(val){return val.slice(0,val.indexOf("")).slice(val.indexOf("
")+7);},
fc=$.default(gets("fc",{}),{version:version,ele:[],using:false,mode:[]}),
user=$(".lang-chooser>div:eq(1)>a:eq(0)").html(),user_csrf=$("[name=X-Csrf-Token]").attr("content"),
show_pre=function(){$("#pageContent,#pre-bar").show();},hide_pre=function(){$("#pageContent,#pre-bar").hide();},
menu,fc_need=["fc","pro-user","sub-user","sta-user"],Clear=function(){
for(let i in localStorage){
if(i.slice(0,3)!=="fc-")continue;
let j=i.slice(3);
if(fc_need.indexOf(j)<0)delete localStorage[i];
}
},default_set=function(){for(let i in localStorage)if(i.slice(0,3)==="fc-"&&i!=="fc-fc")delete localStorage[i];},
add_menu=function(id){
$("#fc-setting-menu-add").append(` `);
$("#fc-setting-menu-"+id).click(function(){$(this).parent().remove(),menu.splice(menu.indexOf(id),1),sub_menu(id);});
},
sub_menu=function(id){
$("#fc-setting-menu-sub").append(` `);
$("#fc-setting-menu-"+id).click(function(){$(this).parent().remove(),menu.push(id),add_menu(id);});
},
sta_default={auto_open:true,interval:5000},sta_user,sta_t=0,sta_cnt=0,
get_sta=function(user,cnt,page=1,show=true){
let tmp={csrf_token:user_csrf,action:"toggleShowUnofficial"},load=$("#fc-status-load"),loadstr="",t=sta_t;
if(show)tmp.showUnofficial="on";
clearInterval(sta_t),load.html("");
if(cnt!==sta_cnt)return;
sta_t=setInterval(function(){loadstr=loadstr.length===2?"":loadstr+".",$("#fc-status-load").html("Loading"+loadstr);},500);
$.ajax({url:"/submissions/"+user+"/page/"+page,type:"POST",data:tmp,error:function(e){Alert("出错了");return;},
success:function(e){
clearInterval(sta_t),load.html("");
if(cnt!==sta_cnt)return;
let val=$(e),tpage=val.find(".active").attr("pageindex");
try{if(val.find(".second-level-menu-list a:eq(0)").html().toLowerCase()!==user.toLowerCase()){Alert("该用户不存在");return;}}
catch(e){Alert("该用户不存在");return;}
if(tpage!=page&&(tpage!==void 0||page!=1)){Alert("该记录不存在");return;}
val=val.find("#pageContent"),val.children(":eq(0)").remove(),val.children(":eq(0)").remove(),val.find(".pagination").remove(),$("#fc-status-main").html(val.html());
if(sta_user.interval>=0)setTimeout(function(){get_sta(user,cnt,page,show);},sta_user.interval);
}});
},
sub_default={auto_open:true},sub_user,
getsub=function(func){
let sub=gets("sub");
if(sub!==void 0){$("#fc-submit-form").html(sub),func();return;}
$.ajax({type:"GET",data:{},url:"/problemset/submit",error:function(e){Alert("获取提交界面失败");},
success:function(e){
sub=$(e).find(".submit-form"),sub.find("tr:nth-child(5)").remove(),sub.find(".submit").attr("id","fc-submit-button");
sub.find(".aceEditorTd").html(` `);
sub.find("[name=submittedProblemCode]").attr("name","submittedProblemIndex"),sub=sub.html(),puts("sub",sub),$("#fc-submit-form").html(sub),func();
}});
},
pro_default={mem:0,auto_open:false},pro_user,prepro,prolist,focpro,promap={},
showpro=function(id){$("#fc-problem-menu-"+id).addClass("focpro"),$("#fc-problem-"+id+",#fc-bar-problem-"+id).show();},
hidepro=function(id){$("#fc-problem-menu-"+id).removeClass("focpro"),$("#fc-problem-"+id+",#fc-bar-problem-"+id).hide();},
add_pro=function(pro,x,y){
pro.find(".sample-test .title").each(function(){//Changed Form Codeforces
let preId=("id"+Math.random()).replaceAll(".","0"),cpyId=("id"+Math.random()).replaceAll(".", "0");
let $copy=$(`Copy
`);
$(this).parent().find("pre").attr("id", preId),$(this).append($copy);
let clipboard=new unsafeWindow.Clipboard('#'+cpyId,{
text:function(trigger){return Codeforces.filterClipboardText(document.querySelector('#'+preId).innerText);}
}),isInput=$(this).parent().hasClass("input");
clipboard.on('success',function(e){Alert("The example "+(isInput?"input":"output")+" has been copied into the clipboard");e.clearSelection();});
});
x+=y,pro=[pro.find(`.problem-statement`),pro.find(`#sidebar`)],promap[x]=0;
$("#fc-problem-menu-add").before(``);
$("#fc-problem-menu-"+x+">a:eq(0)").click(function(){if(focpro!==void 0)hidepro(focpro),showpro(focpro=this.innerHTML);});
$("#fc-problem-menu-"+x+">a:eq(1)").click(function(){
let fa=$(this).parent(),id=fa.children()[0].innerHTML,pos=prolist.indexOf(id);delete promap[prolist[pos]],prolist.splice(pos,1);
if(focpro===id){
if(pos===prolist.length)--pos;
if(pos!==-1)focpro=prolist[pos],showpro(focpro);
else focpro=void 0;
}
fa.remove(),$("#fc-problem-"+id).remove(),$("#fc-bar-problem-"+id).remove(),puts("pro-list",prolist);
});
$("#fc-problem-contain").append(pro[0].attr("id","fc-problem-"+x));$("#fc-bar-problem").append(pro[1].attr("id","fc-bar-problem-"+x));
if(focpro!==void 0)hidepro(focpro);
showpro(x),prolist.push(focpro=x),math.Queue(["Typeset",math,"fc-problem-"+x]),puts("pro-list",prolist);
},
addpro=function(x,y){
let load=$(` `),loadstr="";promap[x+y]=1,$("#fc-problem-menu").append(load);
let t=setInterval(function(){loadstr=loadstr.length===2?"":loadstr+".",load.find("a").html("Loading "+x+y+loadstr);},400);
$.ajax({type:"GET",data:{},url:"/contest/"+x+"/problem/"+y,error:function(e){clearInterval(t),load.remove(),Alert("出错了!");},
success:function(e){
clearInterval(t),load.remove();let pro=$(e),title=GetTitle(e);
if((title!=="Problem - "+y+" - Codeforces (Unofficial mirror site by GGAutomaton, accelerated for Chinese users)"&&title!=="Problem - "+y+
" - Codeforces")||!pro.find(`#sidebar a[href="/contest/`+x+`"]`).length){delete promap[x+y],Alert("题目"+x+y+"不存在");return;}
add_pro(pro,x,y);
}});
},
newpro=function(Id){
if(Id===""||Id===null)return;
if(typeof Id!=="string"){Alert("请输入正确的题号");return;}
if(promap[Id]===0){Alert("该题目已在序列中");return;}
if(promap[Id]===1){Alert("该题目已在加载中");return;}
if(!/^[0-9]+[A-Za-z][1|2]?$/.test(Id)){Alert("请输入正确的题号");return;}
let id=Id.last(),cid;
if(parseInt(id)>0)id=Id.slice(-2),cid=parseInt(Id.slice(0,Id.length-2));
else cid=parseInt(Id.slice(0,Id.length-1));
addpro(cid,id);
},
pre_pro=function(){for(let i=0;i`));
$("#fc-problem-submit").click(function(){
if(ele.indexOf("submit")<0){Alert("请先在设置中打开“快速提交”功能");return;}
Change("submit"),$("#fc-submit .ace_text-input").focus();
if(focpro!==void 0)$("#fc-submit [name=submittedProblemIndex]").val(focpro);
});
$("#fc-problem-menu-close").click(function(){Change("problem");});$("#fc-bar-menu").after(`
`);
$("#fc-problem-menu-add").click(function(){Confirm(`请输入题目编号: `,function(){newpro($("#fc-input").val());});});
$("#fc-problem-menu-add").hover(function(){let x=$("#fc-problem-menu>.backLava");if(x.length>0)x.remove();});
var url=URLmatch();
if(/https+:\/\/codeforces\.[com|ml]/.test(url.host)&&(/^\/problemset\/problem\/[1-9][0-9]*\/[A-Z]$/.test(url.path)||/^\/contest\/[1-9][0-9]*\/problem\/[A-Z]$/.test(url.path)))
$(`添加到题目 `).prependTo($('#pageContent .problemindexholder')).click(function(){
Change("problem");var x=url.path.match(/[1-9][0-9]*/)[0],y=url.path.match(/[A-Z]/)[0];
if(prolist.indexOf(x+y)>=0){$('#fc-problem-menu-'+x+y).click(),Alert("该题目已在序列中");return;}
add_pro($('#pageContent .problemindexholder').clone(),x,y);
});
if(pro_user.mem==2)pre_pro();
else if(pro_user.mem==1&&prepro.length>0)Confirm("您上次浏览的题目未关闭,要重新加载吗?",function(){Change("problem"),pre_pro();},function(){puts("pro-list",[]);});
else puts("pro-list",[]);
if(pro_user.auto_open)$(document).click(function(e){
let url=$(e.toElement).attr("href");if(url==null)return true;url=URLmatch(url);
if(!/https+:\/\/codeforces\.[com|ml]/.test(url.host))return true;
if(!/^\/problemset\/problem\/[1-9][0-9]*\/[A-Z]$/.test(url.path)&&!/^\/contest\/[1-9][0-9]*\/problem\/[A-Z]$/.test(url.path))return true;
Change("problem"),newpro(url.path.match(/[1-9][0-9]*/)[0]+"/"+url.path.match(/[A-Z]/)[0]);return false;
});
},remove:function(){$("#fc-problem").remove(),$("#fc-bar-problem").remove();},
hide:function(){$("#fc-problem,#fc-bar-problem").hide(),$("#fc-menu-problem").css("background-color","white");},
show:function(){$("#fc-problem,#fc-bar-problem").show(),$("#fc-menu-problem").css("background-color","#AAAAAA");},
set:function(){
$("#fc-setting-clear").before($(``));
if(pro_user.auto_open)$("#fc-setting-problem-auto_open").attr("checked","checked");
$("#fc-setting-problem-end").click(function(){
pro_user={mem:$("#fc-setting-problem-memory>option:selected").val(),auto_open:$("#fc-setting-problem-auto_open:checked").length===1};
puts("pro-user",pro_user),Alert("修改成功");
});
$("#fc-setting-problem-memory>option:eq("+pro_user.mem+")").attr("selected","selected");
}},"submit":{name:"提交代码",js:[],css:[],
init:function(){
sub_user=$.default(gets("sub-user",{}),sub_default),puts("sub-user",sub_user);
$("#pageContent").after($(`
`));
getsub(function(){$("#fc-submit-button").click(function(){
$("#fc-submit .fc-care").remove();let val=$("#fc-submit [name=submittedProblemIndex]").val();
if(val===""){$("#fc-submit .error__submittedProblemIndex").html(`Choose the problem `);return false;}
if(!/^[0-9]+[A-Za-z][1|2]?$/.test(val)){$("#fc-submit .error__submittedProblemIndex").html(`Input a legal problem `);return false;}
let id=val.last(),cid;
if(parseInt(id)>0)id=val.slice(-2),cid=parseInt(val.slice(0,val.length-2));
else cid=parseInt(val.slice(0,val.length-1));
if($("#fc-submit [name=source]").val()===""){$("#fc-submit .aceEditorTd").append(`Put you source into the textarea `);return false;}
$("#fc-submit [name=submittedProblemIndex]").val(id);
if(!sub_user.auto_open||ele.indexOf("status")<0){$("#fc-submit-form").attr("action",`/contest/`+cid+`/submit?csrf_token=`+user_csrf);return true;}
$.ajax({type:"POST",url:`/contest/`+cid+`/submit?csrf_token=`+user_csrf,error:function(e){Alert("提交失败");return;},data:{
csrf_token:user_csrf,action:"submitSolutionFormSubmitted",submittedProblemIndex:$("#fc-submit [name=submittedProblemIndex]").val(),
programTypeId:$("#fc-submit [name=programTypeId]>option:selected").val(),source:$("#fc-submit [name=source]").val()},
success:function(e){
let sub=$(e);
if(!sub.find(`#sidebar a[href="/contest/`+cid+`"]`).length){Alert("该题目不存在!");return;}
if(sub.find(".error.for__source").length){Alert("您已经提交过相同的代码!");return;}
if(GetTitle(e).substr(0,6)!=="Status"){Alert("该题目不存在!");return;}
}
});
Change("status"),$("#fc-status-user").val(user),$("#fc-status-page").val(1),$("#fc-status-show").attr("checked","checked");
$("#fc-status-see").click(),document.documentElement.scrollTop=0;return false;
});});
},set:function(){
$("#fc-setting-clear").before(`提交设置
点击提交时:
若开启了“查看状态”,则进行跳转 打开“status”页面
* 保存 `);
$("#fc-setting-submit-auto_open>option:eq("+(sub_user.auto_open===true?0:1)+")").attr("selected","selected");
$("#fc-setting-submit-end").click(function(){sub_user={auto_open:$("#fc-setting-submit-auto_open>option:selected").val()==="true"},puts("sub-user",sub_user);});
}},"status":{name:"查看状态",js:["facebox"],css:["status","facebox"],
init:function(){
sta_user=$.default(gets("sta-user",{}),sta_default),puts("sta-user",sta_user);
$("#pageContent").after($(``));
$("#fc-status-stop").click(function(){++sta_cnt,clearInterval(sta_t),$("#fc-status-load").html("");});
$("#fc-status-see").click(function(){get_sta($("#fc-status-user").val(),++sta_cnt,$("#fc-status-page").val(),$("#fc-status-show:checked").length===1);});
if(sta_user.auto_open)get_sta(user,0);
},set:function(){
$("#fc-setting-clear").before(``);
if(sta_user.auto_open)$("#fc-setting-status-auto_open").attr("checked","checked");
$("#fc-setting-status-end").click(function(){
let interval=parseInt($("#fc-setting-status-interval").val());
if(typeof interval!=="number"||interval!==interval){Alert("自动刷新间隔应为大于等于-1的整数");return;}
if(interval<0)interval=1;$("#fc-setting-status-interval").val(interval);
sta_user={auto_open:$("#fc-setting-status-auto_open:checked").length===1,interval:interval},puts("sta-user",sta_user),Alert("修改成功");
});
}},"setting":{name:"设置",js:[],css:[],
init:function(){
$("#pageContent").after($(`
Fast Codeforces版本:`+version+`
清理缓存
恢复默认设置 `));
for(let i=0;i目录设置*
当前目录
剩余目录 `));
for(let i=0;i`)),js_ready.push(js[i]);
for(let i=0;i `)),css_ready.push(css[i]);
$("#fc-stop").before($(`
↻ `)),obj.init();
if(!("show" in eles[id]))eles[id].show=function(){$("#fc-"+id).show(),$("#fc-menu-"+id).css("background-color","#AAAAAA");};
if(!("hide" in eles[id]))eles[id].hide=function(){$("#fc-"+id).hide(),$("#fc-menu-"+id).css("background-color","white");};
if(!("remove" in eles[id]))eles[id].remove=function(){$("#fc-"+id).remove();};
if(!("set" in eles[id]))eles[id].set=function(){};
$("#fc-menu-"+id).click(function(){Change(id);});
$("#fc-menu-"+id).siblings().click(function(){
if(nele===id)Change(id);
obj.remove(),obj.init(),Alert("加载成功!");
});
},
Reload=function(){
if(nele!=="pre")Change(nele);
for(let i=0;i开始使用Fast Codeforces`);
$("#fc-start").click(function(){Confirm("Fast Codeforces需要使用您的CSRF-token,您确定要授权吗?",function(){fc.using=true,puts("fc",fc),Alert("授权成功"),showMain();});});
},
showMain=function(){
ele=fc.ele;
if(ele.length===0)ele=["problem","submit","status","setting"];
if(ele.indexOf("setting")===-1)ele.push("setting");
fc.ele=ele,puts("fc",fc),len=ele.length,nele="pre",$("#fc-menu").html(`停止使用Fast Codeforces `);
$("#fc-stop").click(function(){Confirm("您确认要停止使用Fast Codeforces?",function(){fc.using=false,puts("fc",fc),Alert("Fast Codeforces已停止"),showLogin();});});
for(let i=0;i=0)CreateEle("setting");
};puts("fc",fc);
$(function(){
if($("#sidebar").length===0)return;
let sidebar=$("#sidebar").html();
$("#sidebar").html(`
`+sidebar+`
`);
$("#fc-menu-turn").click(function(){
let x=$("#fc-menu-turn");
if(x.html()==="-")x.html("+"),$("#fc-menu").hide();
else x.html("-"),$("#fc-menu").show();
});
Codeforces.countdown();
if($(".header-bell").length===0)$("#fc-menu").html(`请登录后再使用! `);
else if(fc.using)showMain();
else showLogin();
if(version!==fc.version)fc.version=version,puts("fc",fc),setTimeout(function(){Alert("Fast Codeforces的版本已经更新了,赶快去设置看看呗");},500);
});};