@jutge.org/toolkit 4.4.40 → 4.4.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -607,7 +607,7 @@ main = do
607
607
  `))if(D.trim()==="")P+=`
608
608
  `;else P+=`(println ${D})
609
609
  `;await G4(oG(q,f),P)}}class UG extends N8{id(){return"Verilog"}name(){return"Verilog"}type(){return"formal methods"}language(){return"Verilog"}async version(){return await a6(),"Verilog Fake Compiler"}flags1(){return""}flags2(){return""}tool(){return"Verilog"}extension(){return"v"}async compileNormal(q,$,w){let f=`${w}.exe`;return await A8($,f,`echo "This is a fake executable for Verilog source ${w}"
610
- `),f}async execute(q,$,w,f,K){}}import{cp as Vd,glob as TW_,mkdir as NE6,rm as hE6}from"fs/promises";import{basename as EE6,extname as gE6,join as Uf}from"path";class QG extends N8{id(){return"PRO2"}name(){return"PRO2 Project C++ Compiler"}type(){return"compiler"}language(){return"C++"}async version(){return await this.getVersion("g++ --version",0)}flags1(){return"-std=c++17 -D_JUDGE_ -O2 -D_GLIBCXX_DEBUG -DNDEBUG -Wall -Wextra -Wno-sign-compare -Wshadow"}flags2(){return"-std=c++17 -D_JUDGE_ -O2 -D_GLIBCXX_DEBUG -DNDEBUG -Wall -Wextra -Wno-sign-compare -Wshadow"}tool(){return"g++"}extension(){return"hh"}async compileNormal(q,$,w){let f=`${w}.exe`,K=Uf($,`${u8()}-PRO2/${$q()}`);await hE6(K,{recursive:!0,force:!0}),await NE6(K,{recursive:!0}),u.print(`Using working directory ${u.hyperlink($,K)}`);for(let D of["public","private"]){let Y=await Array.fromAsync(TW_(`${D}/*.{cc,hh}`,{cwd:$}));for(let J of Y){let Z=Uf(K,EE6(J));await Vd(Uf($,J),Z)}}let z=gE6(w);await Vd(Uf($,w),Uf(K,`program${z}`));let P=await Array.fromAsync(TW_("*.cc",{cwd:K}));if(await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:K})`${this.tool()} ${this.flags1().split(" ")} -o ${f} ${P}`,!await l8(K,f))throw Error(`Compilation failed for ${w}`);return await Vd(Uf(K,f),Uf($,f)),f}}import{cp as Md,glob as XW_,mkdir as RE6,rm as bE6}from"fs/promises";import{basename as IE6,join as d5}from"path";class tG extends N8{id(){return"MakePRO2"}name(){return"PRO2 Makefile C++ Compiler"}type(){return"compiler"}language(){return"C++"}async version(){return await this.getVersion("g++ --version",0)}flags1(){return""}flags2(){return""}tool(){return"make"}extension(){return"tar"}async compileNormal(q,$,w){let f=`${w}.exe`,K=`${u8()}-MakePRO2/${$q()}`;await bE6(K,{recursive:!0,force:!0}),await RE6(K,{recursive:!0}),u.print(`Using working directory ${u.hyperlink($,K)}`);for(let P of["public","private","solution"]){let D=await Array.fromAsync(XW_(`${P}/*.{cc,hh}`,{cwd:$}));for(let Y of D){let J=d5(K,IE6(Y));await Md(d5($,Y),J)}if(await l8(d5($,P),"Makefile")){let Y=d5(K,"Makefile");await Md(d5($,P,"Makefile"),Y)}}if(!await l8($,"solution"))await p_({cwd:K})`tar xf ${d5($,w)}`;let z=await Array.fromAsync(XW_("*.cc",{cwd:K}));if(await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:K})`${this.tool()}`,!await l8(K,"program.exe"))throw Error(`"program.exe" not found after calling 'make'`);return await Md(d5(K,"program.exe"),d5($,f)),f}}import{join as yE6}from"path";class eG extends N8{id(){return"R"}name(){return"R"}type(){return"interpreter"}language(){return"R"}async version(){return await this.getVersion("R --version",0)}flags1(){return""}flags2(){return""}tool(){return"R"}extension(){return"R"}async compileNormal(q,$,w){return await a6(),u.warning("No compilation available for R"),w}async compileWithMain(q,$,w){return await a6(),u.warning("No compilation available for R"),w}async execute(q,$,w,f,K){let z=w;await this.rmInDir($,K);let P=await this.getInput($,f);u.command(`Rscript ${z} < ${f} > ${K}`);let{exitCode:D}=await p_({reject:!1,input:P,stdout:{file:yE6($,K)},stderr:"inherit",cwd:$})`Rscript ${z}`;if(D!==0)throw Error(`Execution failed for ${z}`)}}var Y9=/\r?\n/;function Dq(q,$){let w=new Map;return(...f)=>{let K=$?$(...f):JSON.stringify(f);if(!w.has(K))w.set(K,q(...f));return w.get(K)}}async function SE6(){let{stdout:q}=await p_({reject:!1})`python3 --version`,$=q.trim();return{result:$.startsWith("Python 3"),version:$,stdout:q}}var jW_=Dq(SE6);async function GW_(){let{result:q}=await jW_();return q}async function mE6(){let{stdout:q}=await p_({reject:!1})`R --version`,$=q.split(Y9)[0].trim();return{result:$.startsWith("R version"),version:$,stdout:q}}var AW_=Dq(mE6);async function uW_(){let{result:q}=await AW_();return q}async function LE6(q){let{exitCode:$,stdout:w,stderr:f}=await p_({reject:!1})`python3 -m pip show ${q}`;return{result:$===0,version:$===0?"installed":"not installed",stdout:w,stderr:f}}var cE6=Dq(LE6,(q)=>q);async function xE6(){let{stdout:q}=await p_({reject:!1})`g++ --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("Apple clang")||q.startsWith("g++"),version:$,stdout:q}}var CW_=Dq(xE6);async function Hk(){let{result:q}=await CW_();return q}async function dE6(){let{stdout:q}=await p_({reject:!1})`ghc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("The Glorious Glasgow Haskell Compilation System"),version:$,stdout:q}}var VW_=Dq(dE6);async function MW_(){let{result:q}=await VW_();return q}async function lE6(){let{stdout:q}=await p_({reject:!1})`clj --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("Clojure"),version:$,stdout:q}}var NW_=Dq(lE6);async function hW_(){let{result:q}=await NW_();return q}async function rE6(){let{stdout:q,stderr:$}=await p_({reject:!1})`javac -version`,w=q||$,f=w.split(Y9)[0].trim();return{result:w.startsWith("javac"),version:f,stdout:q,stderr:$}}var EW_=Dq(rE6);async function gW_(){let{result:q}=await EW_();return q}async function pE6(){let{stdout:q}=await p_({reject:!1})`rustc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("rustc"),version:$,stdout:q}}var RW_=Dq(pE6);async function bW_(){let{result:q}=await RW_();return q}async function iE6(){return await a6(),{result:!1,version:"not implemented",stdout:""}}var IW_=Dq(iE6);async function yW_(){let{result:q}=await IW_();return q}async function nE6(){let{stdout:q,exitCode:$}=await p_({reject:!1})`jutge-code-metrics`,w="not reported";return{result:$===0,version:"not reported",stdout:q}}var SW_=Dq(nE6);async function mW_(){let{result:q}=await SW_();return q}async function aE6(){let{stdout:q}=await p_({reject:!1})`pdflatex --version`,$=q.split(Y9)[0].trim();return{result:q.includes("pdfTeX"),version:$,stdout:q}}var ah8=Dq(aE6);async function BE6(){let{stdout:q}=await p_({reject:!1})`xelatex --version`,$=q.split(Y9)[0].trim();return{result:q.includes("XeTeX"),version:$,stdout:q}}var LW_=Dq(BE6);async function cW_(){let{result:q}=await LW_();return q}async function FE6(){let{stdout:q}=await p_({reject:!1})`pandoc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("pandoc")&&q.includes("+lua"),version:$,stdout:q}}var xW_=Dq(FE6);async function dW_(){let{result:q}=await xW_();return q}async function lW_(){u.command("python3 --version");let{result:q,version:$}=await jW_();if(u.print($),q){u.success("Python3 seems installed");let w="turtle-pil yogi easyinput multimetric".split(" ");for(let f of w){u.command(`python3 -m pip show ${f}`);let{result:K}=await cE6(f);if(K)u.success(`Module ${f} is installed`);else u.warning(`Module ${f} is not installed`)}}else u.warning("Python3 does not appear to be installed"),u.print("This is not a problem if you do not plan to use Python solutions"),u.print("See https://www.python.org/downloads/")}async function rW_(){u.command("g++ --version");let{result:q,version:$}=await CW_();if(u.print($),q)u.success("C/C++ seems installed");else u.warning("C/C++ does not appear to be installed"),u.print("This is not a problem if you do not plan to use C or C++ solutions"),u.print("Please install GCC or Clang")}async function pW_(){u.command("ghc --version");let{result:q,version:$}=await VW_();if(u.print($),q)u.success("Haskell seems installed");else u.warning("Haskell does not appear to be installed"),u.print("This is not a problem if you do not plan to use Haskell solutions"),u.print("See https://www.haskell.org/ghc/download.html")}async function iW_(){u.command("clj --version");let{result:q,version:$}=await NW_();if(u.print($),q)u.success("Clojure seems installed");else u.warning("Clojure does not appear to be installed"),u.print("This is not a problem if you do not plan to use Clojure solutions"),u.print("See https://clojure.org/guides/getting_started")}async function nW_(){u.command("javac -version");let{result:q,version:$}=await EW_();if(u.print($),q)u.success("Java seems installed");else u.warning("Java does not appear to be installed"),u.print("You will not be able to compile/execute Java solutions"),u.print("See https://www.oracle.com/java/technologies/javase-jdk11-downloads.html")}async function aW_(){u.command("rustc --version");let{result:q,version:$}=await RW_();if(u.print($),q)u.success("Rust seems installed");else u.warning("Rust does not appear to be installed"),u.print("You will not be able to compile/execute Rust solutions"),u.print("See https://www.rust-lang.org/tools/install")}async function BW_(){u.command("not implemented");let{result:q,version:$}=await IW_();if(u.print($),q)u.success("Verilog seems installed");else u.warning("Verilog does not appear to be installed, but this is not important for circuit problems")}async function FW_(){u.command("R --version");let{result:q,version:$}=await AW_();if(u.print($),q)u.success("R seems installed");else u.warning("R does not appear to be installed"),u.print("You will not be able to compile/execute R solutions"),u.print("See Google")}async function oW_(){u.command("jutge-code-metrics");let{result:q,version:$}=await SW_();if(u.print($),q)u.success("jutge-code-metrics seems installed");else u.warning("jutge-code-metrics does not appear to be installed"),u.print("You will not be able to compute code metrics when staging solutions"),u.print("Use python3 -m pip install jutge-toolkit to install it")}async function UW_(){u.command("xelatex --version");let{result:q,version:$}=await LW_();if(u.print($),q)u.success("XeLaTeX seems installed");else u.warning("XeLaTeX does not appear to be installed"),u.print("You will not be able to generate PDF statements"),u.print("Install a TeX distribution: macOS: brew install --cask mactex (or basictex for smaller install)"),u.print(" Ubuntu/Debian: sudo apt install texlive-full"),u.print(" Other: https://www.tug.org/texlive/ or https://miktex.org/")}async function QW_(){u.command("pandoc --version");let{result:q,version:$}=await xW_();if(u.print($),q)u.success("Pandoc with Lua support seems installed");else u.warning("Pandoc with Lua support does not appear to be installed"),u.print("You will not be able to generate text statements (HTML, TXT, MD)"),u.print("See https://pandoc.org/installing.html")}async function tW_(){if(await a6(),process.stdout.isTTY)u.success("Terminal supports TTY");else u.warning("Terminal does not support TTY"),u.print("Some output features may not work as expected");if(zq.isSupported)u.success("Terminal supports hyperlinks");else u.warning("Terminal does not support hyperlinks"),u.print("Links to files may not be clickable");let q=["EDITOR","VISUAL"];for(let $ of q)if(process.env[$])u.success(`${$} environment variable is set to "${process.env[$]}"`);else u.warning(`${$} environment variable is not set`)}var Zk={C:dG,"C++":lG,Python3:rG,Haskell:pG,Clojure:iG,Java:nG,Rust:aG,Verilog:UG,R:eG,PRO2:QG,MakePRO2:tG,RunPython:Ad,RunHaskell:ud,RunClojure:Cd},oE6={c:dG,cc:lG,hh:QG,tar:tG,py:rG,hs:pG,clj:iG,java:nG,rs:aG,v:UG,R:eG},hd={c:Hk,cc:Hk,hh:Hk,tar:Hk,py:GW_,hs:MW_,clj:hW_,java:gW_,rs:bW_,v:yW_,R:uW_};function Qf(q){let $=Zk[q];if(!$)throw Error(`Compiler '${q}' is not defined`);return new $}function kk(q){let $=oE6[q];if(!$)throw Error(`No compiler defined for extension '.${q}'`);return new $}async function sG(){return await a6(),Object.keys(Zk)}async function eW_(){let q=[];for(let $ of Object.keys(Zk))if(await new Zk[$]().available())q.push($);return q}async function UE6(q){let $=Qf(q);if(!$)throw Error(`Compiler '${q}' is not defined`);return await $.info()}async function sW_(){let q={};for(let $ of Object.keys(Zk))q[$]=await UE6($);return q}Yq();import{exists as OD,glob as l5}from"fs/promises";import{basename as eE6,join as a2,normalize as Dv_,sep as Yv_}from"path";Yq();async function B2(q){let $=new Jv_(q);return await $.load(),$}class Jv_{directory;structure="multi";language=null;handler;languages=[];originalLanguage=null;problemYml=null;problemLangYmls={};solutions=[];goldenSolution=null;testcases=[];constructor(q){if(q==="."||q==="./"||!q)this.directory=Dv_(process.cwd());else this.directory=Dv_(a2(q,"."))}async load(){await u.section(`Loading problem from ${this.directory}`,async()=>{if(await this.loadStructure(),await this.loadLanguages(),await this.loadHandler(),await this.loadProblemYml(),await this.loadOriginalLanguage(),this.handler.handler!=="game")await this.loadSolutions(),await this.loadGoldenSolution(),await this.loadTestcases(),await this.loadScores();await this.loadAwards()});let q=!1;if(!this.originalLanguage)u.error("No original language found"),q=!0;if(!this.goldenSolution)if(this.handler.handler==="game"||this.handler.handler==="quiz");else u.error("No golden solution found"),q=!0;if(q)throw Error("Inspection failed due to errors")}async loadStructure(){await u.section("Determining structure",async()=>{if(await a6(),this.directory.endsWith(".pbm"))this.structure="multi";else{this.structure="single";let q=a2(this.directory,"..");if(!q.endsWith(".pbm"))throw Error(`Parent directory ${q} is not a problem root directory (missing .pbm suffix)`)}u.print(this.structure)})}async loadLanguages(){await u.section("Loading languages",async()=>{if(this.structure==="multi")await this.loadLanguagesMulti();else await this.loadLanguagesSingle()})}async loadLanguagesMulti(){let $=(await Array.fromAsync(l5("problem.*.yml",{cwd:this.directory}))).map((w)=>{let f=w.match(/problem\.(.+)\.yml/);return f?f[1]:null}).filter((w)=>w&&(w in l6));this.languages=$,u.yaml(this.languages);for(let w of this.languages)await u.section(`Loading problem.${w}.yml`,async()=>{this.problemLangYmls[w]=await y1(this.directory,`problem.${w}.yml`),u.yaml(this.problemLangYmls[w]),jP.parse(this.problemLangYmls[w])})}async loadLanguagesSingle(){for(let q of Object.keys(l6)){let $=a2(this.directory,"..",q,`problem.${q}.yml`);if(await OD($))this.languages.push(q)}u.yaml(this.languages);for(let q of this.languages)await u.section(`Loading ..${Yv_}${q}${Yv_}problem.${q}.yml`,async()=>{this.problemLangYmls[q]=await y1(a2(this.directory,"..",q),`problem.${q}.yml`),u.yaml(this.problemLangYmls[q])});this.language=eE6(this.directory)}async loadHandler(){await u.section("Loading handler.yml",async()=>{let q=await y1(this.directory,"handler.yml");if(this.handler=WX.parse(q),this.handler.source_modifier==="structs")u.warning('source_modifier "structs" is deprecated, using "no_main" instead. please update handler.yml'),this.handler.source_modifier="no_main";if(this.handler.handler==="circuits")this.handler.solution="Verilog";if(this.handler.handler==="std"&&this.handler.solution==="C++"){let $=await Array.fromAsync(l5("solution.*",{cwd:this.directory}));if($.length===1){let w=$[0].split(".").pop(),f=P4[w];if(f)u.warning(`Assuming solution is in ${f} based on file extension .${w} (please update handler.yml)`),this.handler.solution=f}}u.yaml(this.handler)})}async loadScores(){await u.section("Loading scores.yml",async()=>{if(await OD(a2(this.directory,"scores.yml"))){let q=await y1(this.directory,"scores.yml"),$=I8_.parse(q);u.yaml($)}else u.print("no scoring, scores.yml not defined")})}async loadProblemYml(){await u.section("Loading problem.yml",async()=>{if(await OD(a2(this.directory,"problem.yml"))){let q=await y1(this.directory,"problem.yml"),$=mq.parse(q);u.yaml($)}else u.print("problem.yml not defined")})}async loadOriginalLanguage(){await u.section("Determining original language",async()=>{await a6();for(let q of this.languages)if("author"in this.problemLangYmls[q]){this.originalLanguage=q;break}if(!this.originalLanguage)throw Error("No original language found (a language with an author field)");u.print(this.originalLanguage)})}async loadSolutions(){if(this.handler.handler==="quiz")return;await u.section("Loading solutions",async()=>{if(this.handler.compilers==="PRO2"){let q=await Array.fromAsync(l5("solution{.tar,.cc,.hh}",{cwd:this.directory}));this.solutions=q.sort()}else if(this.handler.compilers==="MakePRO2")this.solutions=["solution.tar"];else{let{proglangNames:q}=await Promise.resolve().then(() => (Yq(),_A)),$=Object.keys(q).join(","),w=await Array.fromAsync(l5(`solution.{${$}}`,{cwd:this.directory}));this.solutions=w.sort()}if(u.yaml(this.solutions),this.solutions.length===0)throw Error("No solutions found")})}async loadGoldenSolution(){if(this.handler.handler==="quiz")return;await u.section("Determining golden solution",async()=>{let{proglangExtensions:q}=await Promise.resolve().then(() => (Yq(),_A));if(this.handler.handler==="circuits")this.goldenSolution="solution.v";else if(this.handler.compilers==="RunPython")this.goldenSolution="solution.py";else if(this.handler.compilers==="RunHaskell"||this.handler.compilers==="GHC")this.goldenSolution="solution.hs";else if(this.handler.compilers==="RunClojure"||this.handler.compilers==="Clojure")this.goldenSolution="solution.clj";else if(this.handler.compilers==="PRO2")if(await l8(this.directory,"solution.hh"))this.goldenSolution="solution.hh";else if(await l8(this.directory,"solution.cc"))this.goldenSolution="solution.cc";else throw Error(`Didn't find "solution.hh" or "solution.cc" for PRO2!`);else if(this.handler.compilers==="MakePRO2")if(await l8(this.directory,"solution")||await l8(this.directory,"solution.tar"))this.goldenSolution="solution.tar";else throw Error(`Didn't find "solution" or "solution.tar" for MakePRO2!`);else{let $=this.handler.solution,w=q[$];if(!w)throw Error(`Unknown programming language ${$} for solution`);let f=a2(this.directory,`solution.${w}`);if(!await OD(f))throw Error(`Golden solution file ${f} not found`);this.goldenSolution=`solution.${w}`}u.print(this.goldenSolution)})}async loadTestcases(){if(this.handler.handler==="quiz")return;await u.section("Loading testcases",async()=>{let q=await Array.fromAsync(l5("*.inp",{cwd:this.directory}));this.testcases=q.map(($)=>$.replace(".inp","")).sort(),u.yaml(this.testcases)})}async reloadTestcases(){if(this.handler.handler==="quiz")return;let q=await Array.fromAsync(l5("*.inp",{cwd:this.directory}));this.testcases=q.map(($)=>$.replace(".inp","")).sort()}async reloadSolutions(){if(this.handler.handler==="quiz")return;let{proglangNames:q,proglangExtensions:$}=await Promise.resolve().then(() => (Yq(),_A));if(this.handler.compilers==="PRO2"){let w=await Array.fromAsync(l5("solution{.tar,.cc,.hh}",{cwd:this.directory}));this.solutions=w.sort()}else if(this.handler.compilers==="MakePRO2")this.solutions=await l8(this.directory,"solution")?["solution.tar"]:[];else{let w=Object.keys(q).join(","),f=await Array.fromAsync(l5(`solution.{${w}}`,{cwd:this.directory}));this.solutions=f.sort()}if(this.solutions.length===0)return;if(this.handler.handler==="circuits")this.goldenSolution="solution.v";else if(this.handler.compilers==="RunPython")this.goldenSolution="solution.py";else if(this.handler.compilers==="RunHaskell"||this.handler.compilers==="GHC")this.goldenSolution="solution.hs";else if(this.handler.compilers==="RunClojure"||this.handler.compilers==="Clojure")this.goldenSolution="solution.clj";else if(this.handler.compilers==="PRO2"){if(await l8(this.directory,"solution.hh"))this.goldenSolution="solution.hh";else if(await l8(this.directory,"solution.cc"))this.goldenSolution="solution.cc"}else if(this.handler.compilers==="MakePRO2"){if(await l8(this.directory,"solution"))this.goldenSolution="solution.tar"}else{let w=this.handler.solution,f=$[w];if(f&&await l8(this.directory,`solution.${f}`))this.goldenSolution=`solution.${f}`}}async loadAwards(){await u.section("Loading awards",async()=>{if(await OD(a2(this.directory,"award.html")))u.success(u.hyperlink(this.directory,"award.html")+" found");else u.warning("award.html not found");if(await OD(a2(this.directory,"award.png"))){u.success(u.hyperlink(this.directory,"award.png")+" found");let q=await xG(a2(this.directory,"award.png"));await u.image(a2(this.directory,"award.png"),6,3),u.print(`${q.width}x${q.height}`)}else u.warning("award.png not found")})}}var Zv_=Z6(H8(),"assets","latex");async function $A(q,$="DRAFT"){let w=await B2(q);return new kv_(w,$)}class kv_{problem;problem_nm;constructor(q,$){this.problem=q,this.problem_nm=$}async showDirectory(){await u.section("Directory",async()=>{await a6(),u.directory(Hv_(this.problem.directory));let q=wg6(Hv_(this.problem.directory));if(!q.endsWith(".pbm")){let $=qg6(q),w=$g6(q);if(!Object.keys(l6).includes($)||!w.endsWith(".pbm"))throw Error("The problem directory should end with .pbm or be a language id inside a .pbm directory")}})}async makeProblem(){if(this.problem.handler.handler==="game")return await this.makeGameProblem();else if(this.problem.handler.handler==="quiz")return await this.makeQuizProblem();else await this.makeTarFiles(),await this.makeGoldenExecutable(),await this.makeCorrectOutputs(),await this.checkSolutions(),await this.makePdfStatements(),await this.makeFullTextualStatements(),await this.makeShortTextualStatements()}async makeQuizProblem(){}async makeGameProblem(){let q=Z6(this.problem.directory,"Doc");await u.section(`Creating documentation in ${u.hyperlink(this.problem.directory,"Doc")}`,async()=>{u.command("make all");let{exitCode:f}=await p_({stderr:"inherit",cwd:q})`make all`;if(f===0)u.success("make completed successfully");else throw u.error("make failed"),Error("make failed")});let $=Z6(this.problem.directory,"Runner");await u.section(`Compiling files in ${u.hyperlink(this.problem.directory,"Runner")}`,async()=>{u.command("make all");let{exitCode:f}=await p_({stdout:"inherit",stderr:"inherit",cwd:$})`make all`;if(f===0)u.success("make completed successfully");else throw u.error("make failed"),Error("make failed")});let w=Z6(this.problem.directory,"Public");await u.section(`Preparing files in ${u.hyperlink(this.problem.directory,"Public")}`,async()=>{await _g6(w,{recursive:!0,force:!0}),await Xk(w,{recursive:!0});let f=[],K=[],z=["README.{txt,md}","Makefile","*.cc","*.hh","*.cnf"];for(let P of z){let D=await Array.fromAsync(bd(P,{cwd:$}));for(let Y of D.sort()){let J=Z6($,Y),Z=Z6(w,Y);if(this.problem.handler.game?.hide.includes(Y))K.push(Y);else f.push(Y),await Jq(J,Z)}}u.success(`Published files: ${f.join(" ")}`),u.warning(`Hidden files: ${K.join(" ")}`)})}async makeExecutable(q){if(this.problem.handler.handler!=="circuits"){let f=q.split(".").pop(),K=hd[f];if(!K)throw Error(`No compiler found for .${f} files`);if(!await K())throw Error(`Compiler for .${f} files is not available`)}let $=this.selectCompiler(),w=`${u8()}-${q}`;await u.section(`Copying ${u.hyperlink(this.problem.directory,q)} to ${u.hyperlink(this.problem.directory,w)}`,async()=>{await Jq(Z6(this.problem.directory,q),Z6(this.problem.directory,w))}),await u.section(`Compiling ${u.hyperlink(this.problem.directory,w)} with ${$.name()} (${this.problem.handler.source_modifier})`,async()=>{try{let f;if(this.problem.handler.source_modifier==="none")f=await $.compileNormal(this.problem.handler,this.problem.directory,w);else if(this.problem.handler.source_modifier==="no_main")f=await $.compileWithMain(this.problem.handler,this.problem.directory,w);else throw Error(`Unknown source modifier: ${this.problem.handler.source_modifier}`);if(!await qA(Z6(this.problem.directory,f)))throw Error(`Compilation failed for ${w}`);u.success(`Compiled ${w} to ${f}`)}catch(f){throw Error("Compilation failed",{cause:f})}})}async makeExecutables(){await u.section("Compiling solutions",async()=>{for(let q of this.problem.solutions)await this.makeExecutable(q)})}async makeGoldenExecutable(){await u.section(`Compiling golden solution from ${u.hyperlink(this.problem.directory,this.problem.goldenSolution)}`,async()=>{if(!this.problem.goldenSolution)throw Error("Golden solution not set");await this.makeExecutable(this.problem.goldenSolution)})}async checkSolutions(){for(let q of this.problem.solutions)if(q!==this.problem.goldenSolution)await this.verifyCandidate(q)}async makeCorrectOutput(q,$,w){return await this.runTestcase(q,`${q}.inp`,`${q}.cor`,$,u8()+"-"+w)}async runTestcase(q,$,w,f,K){let z=!1,P=Date.now();try{await f.execute(this.problem.handler,this.problem.directory,K,$,w)}catch(k){u.error(`Execution failed for testcase '${q}'`),z=!0}let Y=Date.now()-P;if(this.problem.handler.handler==="graphic")await sE6(Z6(this.problem.directory,"output.png"),Z6(this.problem.directory,w));let J=await Sy(Z6(this.problem.directory,$)),Z=await Sy(Z6(this.problem.directory,w));return{testcase:q,error:z,time:Y,inputSize:J,outputSize:Z}}selectCompiler(){if(this.problem.handler.compilers==="PRO2")return Qf("PRO2");else if(this.problem.handler.compilers==="MakePRO2")return Qf("MakePRO2");else if(this.problem.handler.compilers==="RunPython")return Qf("RunPython");else if(this.problem.handler.compilers==="RunHaskell")return Qf("RunHaskell");else if(this.problem.handler.compilers==="RunClojure")return Qf("RunClojure");else{let q=this.problem.goldenSolution.split(".").pop();return kk(q)}}async makeCorrectOutputs(){let q=this.selectCompiler();await u.section("Making correct outputs with golden solution",async()=>{await u.section(`Using ${q.name()}`,async()=>{let $=[];for(let f of this.problem.testcases)$.push(await this.makeCorrectOutput(f,q,this.problem.goldenSolution));u.print(),u.print("testcase time input output");for(let f of $){let K=Bw(f.time),z=ZD(f.inputSize).replace(" ",""),P=ZD(f.outputSize).replace(" ","");u.print((f.error?y_.red:y_.green)(`${f.testcase.padEnd(12)} ${K.padStart(10)} ${z.padStart(10)} ${P.padStart(10)}`))}let w=$.filter((f)=>f.error).length;if(w>0)throw u.print(),Error(`${w} errors occurred while making correct answers`)})})}async makeCorrectOutputForTestcase(q){if(!this.problem.goldenSolution)return;let $=this.selectCompiler();await u.section(`Making correct output for ${q}`,async()=>{await u.section(`Using ${$.name()}`,async()=>{let w=await this.makeCorrectOutput(q,$,this.problem.goldenSolution),f=Bw(w.time),K=ZD(w.inputSize).replace(" ",""),z=ZD(w.outputSize).replace(" ","");if(u.print("testcase time input output"),u.print((w.error?y_.red:y_.green)(`${w.testcase.padEnd(12)} ${f.padStart(10)} ${K.padStart(10)} ${z.padStart(10)}`)),w.error)throw Error(`Error making correct output for ${q}`)})})}async remakeStatements(){await this.makePdfStatements(),await this.makeFullTextualStatements(["txt","html","md"]),await this.makeShortTextualStatements(["txt","html","md"])}async makePdfStatements(){await u.section("Making PDF statements",async()=>{let q=Z6(this.problem.directory,u8()+"-pdf",$q());await Xk(q,{recursive:!0}),await u.section("Creating working directory",async()=>{await a6(),u.directory(q)});for(let $ of this.problem.languages)if(this.problem.structure==="multi"||this.problem.structure==="single"&&$===this.problem.language)await u.section(`Making PDF statement for ${l6[$]}`,async()=>{await this.makePdfStatement(q,$)})})}async makeSamples(q,$){let w=this.problem.handler.handler==="graphic",f=[],K=[],z=0;for(let D of this.problem.testcases)if(D.includes("sample"))z++;let P=1;for(let D of this.problem.testcases)if(D.includes("sample")){let Y="";if(w){await Jq(Z6(this.problem.directory,`${D}.cor`),Z6(q,`${D}.cor.png`));let J=await xG(Z6(q,`${D}.cor.png`));Y=`(${J.width}$\\times$${J.height})`}if(z>1)f.push(`
610
+ `),f}async execute(q,$,w,f,K){}}import{cp as Vd,glob as TW_,mkdir as NE6,rm as hE6}from"fs/promises";import{basename as EE6,extname as gE6,join as Uf}from"path";class QG extends N8{id(){return"PRO2"}name(){return"PRO2 Project C++ Compiler"}type(){return"compiler"}language(){return"C++"}async version(){return await this.getVersion("g++ --version",0)}flags1(){return"-std=c++17 -D_JUDGE_ -O2 -D_GLIBCXX_DEBUG -DNDEBUG -Wall -Wextra -Wno-sign-compare -Wshadow"}flags2(){return"-std=c++17 -D_JUDGE_ -O2 -D_GLIBCXX_DEBUG -DNDEBUG -Wall -Wextra -Wno-sign-compare -Wshadow"}tool(){return"g++"}extension(){return"hh"}async compileNormal(q,$,w){let f=`${w}.exe`,K=Uf($,`${u8()}-PRO2/${$q()}`);await hE6(K,{recursive:!0,force:!0}),await NE6(K,{recursive:!0}),u.print(`Using working directory ${u.hyperlink($,K)}`);for(let D of["public","private"]){let Y=await Array.fromAsync(TW_(`${D}/*.{cc,hh}`,{cwd:$}));for(let J of Y){let Z=Uf(K,EE6(J));await Vd(Uf($,J),Z)}}let z=gE6(w);await Vd(Uf($,w),Uf(K,`program${z}`));let P=await Array.fromAsync(TW_("*.cc",{cwd:K}));if(await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:K})`${this.tool()} ${this.flags1().split(" ")} -o ${f} ${P}`,!await l8(K,f))throw Error(`Compilation failed for ${w}`);return await Vd(Uf(K,f),Uf($,f)),f}}import{cp as Md,glob as XW_,mkdir as RE6,rm as bE6}from"fs/promises";import{basename as IE6,join as d5}from"path";class tG extends N8{id(){return"MakePRO2"}name(){return"PRO2 Makefile C++ Compiler"}type(){return"compiler"}language(){return"C++"}async version(){return await this.getVersion("g++ --version",0)}flags1(){return""}flags2(){return""}tool(){return"make"}extension(){return"tar"}async compileNormal(q,$,w){let f=`${w}.exe`,K=`${u8()}-MakePRO2/${$q()}`;await bE6(K,{recursive:!0,force:!0}),await RE6(K,{recursive:!0}),u.print(`Using working directory ${u.hyperlink($,K)}`);for(let P of["public","private","solution"]){let D=await Array.fromAsync(XW_(`${P}/*.{cc,hh,cpp,hpp,tpp}`,{cwd:$}));for(let Y of D){let J=d5(K,IE6(Y));await Md(d5($,Y),J)}if(await l8(d5($,P),"Makefile")){let Y=d5(K,"Makefile");await Md(d5($,P,"Makefile"),Y)}}if(!await l8($,"solution"))await p_({cwd:K})`tar xf ${d5($,w)}`;let z=await Array.fromAsync(XW_("*.cc",{cwd:K}));if(await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:K})`${this.tool()}`,!await l8(K,"program.exe"))throw Error(`"program.exe" not found after calling 'make'`);return await Md(d5(K,"program.exe"),d5($,f)),f}}import{join as yE6}from"path";class eG extends N8{id(){return"R"}name(){return"R"}type(){return"interpreter"}language(){return"R"}async version(){return await this.getVersion("R --version",0)}flags1(){return""}flags2(){return""}tool(){return"R"}extension(){return"R"}async compileNormal(q,$,w){return await a6(),u.warning("No compilation available for R"),w}async compileWithMain(q,$,w){return await a6(),u.warning("No compilation available for R"),w}async execute(q,$,w,f,K){let z=w;await this.rmInDir($,K);let P=await this.getInput($,f);u.command(`Rscript ${z} < ${f} > ${K}`);let{exitCode:D}=await p_({reject:!1,input:P,stdout:{file:yE6($,K)},stderr:"inherit",cwd:$})`Rscript ${z}`;if(D!==0)throw Error(`Execution failed for ${z}`)}}var Y9=/\r?\n/;function Dq(q,$){let w=new Map;return(...f)=>{let K=$?$(...f):JSON.stringify(f);if(!w.has(K))w.set(K,q(...f));return w.get(K)}}async function SE6(){let{stdout:q}=await p_({reject:!1})`python3 --version`,$=q.trim();return{result:$.startsWith("Python 3"),version:$,stdout:q}}var jW_=Dq(SE6);async function GW_(){let{result:q}=await jW_();return q}async function mE6(){let{stdout:q}=await p_({reject:!1})`R --version`,$=q.split(Y9)[0].trim();return{result:$.startsWith("R version"),version:$,stdout:q}}var AW_=Dq(mE6);async function uW_(){let{result:q}=await AW_();return q}async function LE6(q){let{exitCode:$,stdout:w,stderr:f}=await p_({reject:!1})`python3 -m pip show ${q}`;return{result:$===0,version:$===0?"installed":"not installed",stdout:w,stderr:f}}var cE6=Dq(LE6,(q)=>q);async function xE6(){let{stdout:q}=await p_({reject:!1})`g++ --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("Apple clang")||q.startsWith("g++"),version:$,stdout:q}}var CW_=Dq(xE6);async function Hk(){let{result:q}=await CW_();return q}async function dE6(){let{stdout:q}=await p_({reject:!1})`ghc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("The Glorious Glasgow Haskell Compilation System"),version:$,stdout:q}}var VW_=Dq(dE6);async function MW_(){let{result:q}=await VW_();return q}async function lE6(){let{stdout:q}=await p_({reject:!1})`clj --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("Clojure"),version:$,stdout:q}}var NW_=Dq(lE6);async function hW_(){let{result:q}=await NW_();return q}async function rE6(){let{stdout:q,stderr:$}=await p_({reject:!1})`javac -version`,w=q||$,f=w.split(Y9)[0].trim();return{result:w.startsWith("javac"),version:f,stdout:q,stderr:$}}var EW_=Dq(rE6);async function gW_(){let{result:q}=await EW_();return q}async function pE6(){let{stdout:q}=await p_({reject:!1})`rustc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("rustc"),version:$,stdout:q}}var RW_=Dq(pE6);async function bW_(){let{result:q}=await RW_();return q}async function iE6(){return await a6(),{result:!1,version:"not implemented",stdout:""}}var IW_=Dq(iE6);async function yW_(){let{result:q}=await IW_();return q}async function nE6(){let{stdout:q,exitCode:$}=await p_({reject:!1})`jutge-code-metrics`,w="not reported";return{result:$===0,version:"not reported",stdout:q}}var SW_=Dq(nE6);async function mW_(){let{result:q}=await SW_();return q}async function aE6(){let{stdout:q}=await p_({reject:!1})`pdflatex --version`,$=q.split(Y9)[0].trim();return{result:q.includes("pdfTeX"),version:$,stdout:q}}var ah8=Dq(aE6);async function BE6(){let{stdout:q}=await p_({reject:!1})`xelatex --version`,$=q.split(Y9)[0].trim();return{result:q.includes("XeTeX"),version:$,stdout:q}}var LW_=Dq(BE6);async function cW_(){let{result:q}=await LW_();return q}async function FE6(){let{stdout:q}=await p_({reject:!1})`pandoc --version`,$=q.split(Y9)[0].trim();return{result:q.startsWith("pandoc")&&q.includes("+lua"),version:$,stdout:q}}var xW_=Dq(FE6);async function dW_(){let{result:q}=await xW_();return q}async function lW_(){u.command("python3 --version");let{result:q,version:$}=await jW_();if(u.print($),q){u.success("Python3 seems installed");let w="turtle-pil yogi easyinput multimetric".split(" ");for(let f of w){u.command(`python3 -m pip show ${f}`);let{result:K}=await cE6(f);if(K)u.success(`Module ${f} is installed`);else u.warning(`Module ${f} is not installed`)}}else u.warning("Python3 does not appear to be installed"),u.print("This is not a problem if you do not plan to use Python solutions"),u.print("See https://www.python.org/downloads/")}async function rW_(){u.command("g++ --version");let{result:q,version:$}=await CW_();if(u.print($),q)u.success("C/C++ seems installed");else u.warning("C/C++ does not appear to be installed"),u.print("This is not a problem if you do not plan to use C or C++ solutions"),u.print("Please install GCC or Clang")}async function pW_(){u.command("ghc --version");let{result:q,version:$}=await VW_();if(u.print($),q)u.success("Haskell seems installed");else u.warning("Haskell does not appear to be installed"),u.print("This is not a problem if you do not plan to use Haskell solutions"),u.print("See https://www.haskell.org/ghc/download.html")}async function iW_(){u.command("clj --version");let{result:q,version:$}=await NW_();if(u.print($),q)u.success("Clojure seems installed");else u.warning("Clojure does not appear to be installed"),u.print("This is not a problem if you do not plan to use Clojure solutions"),u.print("See https://clojure.org/guides/getting_started")}async function nW_(){u.command("javac -version");let{result:q,version:$}=await EW_();if(u.print($),q)u.success("Java seems installed");else u.warning("Java does not appear to be installed"),u.print("You will not be able to compile/execute Java solutions"),u.print("See https://www.oracle.com/java/technologies/javase-jdk11-downloads.html")}async function aW_(){u.command("rustc --version");let{result:q,version:$}=await RW_();if(u.print($),q)u.success("Rust seems installed");else u.warning("Rust does not appear to be installed"),u.print("You will not be able to compile/execute Rust solutions"),u.print("See https://www.rust-lang.org/tools/install")}async function BW_(){u.command("not implemented");let{result:q,version:$}=await IW_();if(u.print($),q)u.success("Verilog seems installed");else u.warning("Verilog does not appear to be installed, but this is not important for circuit problems")}async function FW_(){u.command("R --version");let{result:q,version:$}=await AW_();if(u.print($),q)u.success("R seems installed");else u.warning("R does not appear to be installed"),u.print("You will not be able to compile/execute R solutions"),u.print("See Google")}async function oW_(){u.command("jutge-code-metrics");let{result:q,version:$}=await SW_();if(u.print($),q)u.success("jutge-code-metrics seems installed");else u.warning("jutge-code-metrics does not appear to be installed"),u.print("You will not be able to compute code metrics when staging solutions"),u.print("Use python3 -m pip install jutge-toolkit to install it")}async function UW_(){u.command("xelatex --version");let{result:q,version:$}=await LW_();if(u.print($),q)u.success("XeLaTeX seems installed");else u.warning("XeLaTeX does not appear to be installed"),u.print("You will not be able to generate PDF statements"),u.print("Install a TeX distribution: macOS: brew install --cask mactex (or basictex for smaller install)"),u.print(" Ubuntu/Debian: sudo apt install texlive-full"),u.print(" Other: https://www.tug.org/texlive/ or https://miktex.org/")}async function QW_(){u.command("pandoc --version");let{result:q,version:$}=await xW_();if(u.print($),q)u.success("Pandoc with Lua support seems installed");else u.warning("Pandoc with Lua support does not appear to be installed"),u.print("You will not be able to generate text statements (HTML, TXT, MD)"),u.print("See https://pandoc.org/installing.html")}async function tW_(){if(await a6(),process.stdout.isTTY)u.success("Terminal supports TTY");else u.warning("Terminal does not support TTY"),u.print("Some output features may not work as expected");if(zq.isSupported)u.success("Terminal supports hyperlinks");else u.warning("Terminal does not support hyperlinks"),u.print("Links to files may not be clickable");let q=["EDITOR","VISUAL"];for(let $ of q)if(process.env[$])u.success(`${$} environment variable is set to "${process.env[$]}"`);else u.warning(`${$} environment variable is not set`)}var Zk={C:dG,"C++":lG,Python3:rG,Haskell:pG,Clojure:iG,Java:nG,Rust:aG,Verilog:UG,R:eG,PRO2:QG,MakePRO2:tG,RunPython:Ad,RunHaskell:ud,RunClojure:Cd},oE6={c:dG,cc:lG,hh:QG,tar:tG,py:rG,hs:pG,clj:iG,java:nG,rs:aG,v:UG,R:eG},hd={c:Hk,cc:Hk,hh:Hk,tar:Hk,py:GW_,hs:MW_,clj:hW_,java:gW_,rs:bW_,v:yW_,R:uW_};function Qf(q){let $=Zk[q];if(!$)throw Error(`Compiler '${q}' is not defined`);return new $}function kk(q){let $=oE6[q];if(!$)throw Error(`No compiler defined for extension '.${q}'`);return new $}async function sG(){return await a6(),Object.keys(Zk)}async function eW_(){let q=[];for(let $ of Object.keys(Zk))if(await new Zk[$]().available())q.push($);return q}async function UE6(q){let $=Qf(q);if(!$)throw Error(`Compiler '${q}' is not defined`);return await $.info()}async function sW_(){let q={};for(let $ of Object.keys(Zk))q[$]=await UE6($);return q}Yq();import{exists as OD,glob as l5}from"fs/promises";import{basename as eE6,join as a2,normalize as Dv_,sep as Yv_}from"path";Yq();async function B2(q){let $=new Jv_(q);return await $.load(),$}class Jv_{directory;structure="multi";language=null;handler;languages=[];originalLanguage=null;problemYml=null;problemLangYmls={};solutions=[];goldenSolution=null;testcases=[];constructor(q){if(q==="."||q==="./"||!q)this.directory=Dv_(process.cwd());else this.directory=Dv_(a2(q,"."))}async load(){await u.section(`Loading problem from ${this.directory}`,async()=>{if(await this.loadStructure(),await this.loadLanguages(),await this.loadHandler(),await this.loadProblemYml(),await this.loadOriginalLanguage(),this.handler.handler!=="game")await this.loadSolutions(),await this.loadGoldenSolution(),await this.loadTestcases(),await this.loadScores();await this.loadAwards()});let q=!1;if(!this.originalLanguage)u.error("No original language found"),q=!0;if(!this.goldenSolution)if(this.handler.handler==="game"||this.handler.handler==="quiz");else u.error("No golden solution found"),q=!0;if(q)throw Error("Inspection failed due to errors")}async loadStructure(){await u.section("Determining structure",async()=>{if(await a6(),this.directory.endsWith(".pbm"))this.structure="multi";else{this.structure="single";let q=a2(this.directory,"..");if(!q.endsWith(".pbm"))throw Error(`Parent directory ${q} is not a problem root directory (missing .pbm suffix)`)}u.print(this.structure)})}async loadLanguages(){await u.section("Loading languages",async()=>{if(this.structure==="multi")await this.loadLanguagesMulti();else await this.loadLanguagesSingle()})}async loadLanguagesMulti(){let $=(await Array.fromAsync(l5("problem.*.yml",{cwd:this.directory}))).map((w)=>{let f=w.match(/problem\.(.+)\.yml/);return f?f[1]:null}).filter((w)=>w&&(w in l6));this.languages=$,u.yaml(this.languages);for(let w of this.languages)await u.section(`Loading problem.${w}.yml`,async()=>{this.problemLangYmls[w]=await y1(this.directory,`problem.${w}.yml`),u.yaml(this.problemLangYmls[w]),jP.parse(this.problemLangYmls[w])})}async loadLanguagesSingle(){for(let q of Object.keys(l6)){let $=a2(this.directory,"..",q,`problem.${q}.yml`);if(await OD($))this.languages.push(q)}u.yaml(this.languages);for(let q of this.languages)await u.section(`Loading ..${Yv_}${q}${Yv_}problem.${q}.yml`,async()=>{this.problemLangYmls[q]=await y1(a2(this.directory,"..",q),`problem.${q}.yml`),u.yaml(this.problemLangYmls[q])});this.language=eE6(this.directory)}async loadHandler(){await u.section("Loading handler.yml",async()=>{let q=await y1(this.directory,"handler.yml");if(this.handler=WX.parse(q),this.handler.source_modifier==="structs")u.warning('source_modifier "structs" is deprecated, using "no_main" instead. please update handler.yml'),this.handler.source_modifier="no_main";if(this.handler.handler==="circuits")this.handler.solution="Verilog";if(this.handler.handler==="std"&&this.handler.solution==="C++"){let $=await Array.fromAsync(l5("solution.*",{cwd:this.directory}));if($.length===1){let w=$[0].split(".").pop(),f=P4[w];if(f)u.warning(`Assuming solution is in ${f} based on file extension .${w} (please update handler.yml)`),this.handler.solution=f}}u.yaml(this.handler)})}async loadScores(){await u.section("Loading scores.yml",async()=>{if(await OD(a2(this.directory,"scores.yml"))){let q=await y1(this.directory,"scores.yml"),$=I8_.parse(q);u.yaml($)}else u.print("no scoring, scores.yml not defined")})}async loadProblemYml(){await u.section("Loading problem.yml",async()=>{if(await OD(a2(this.directory,"problem.yml"))){let q=await y1(this.directory,"problem.yml"),$=mq.parse(q);u.yaml($)}else u.print("problem.yml not defined")})}async loadOriginalLanguage(){await u.section("Determining original language",async()=>{await a6();for(let q of this.languages)if("author"in this.problemLangYmls[q]){this.originalLanguage=q;break}if(!this.originalLanguage)throw Error("No original language found (a language with an author field)");u.print(this.originalLanguage)})}async loadSolutions(){if(this.handler.handler==="quiz")return;await u.section("Loading solutions",async()=>{if(this.handler.compilers==="PRO2"){let q=await Array.fromAsync(l5("solution{.tar,.cc,.hh}",{cwd:this.directory}));this.solutions=q.sort()}else if(this.handler.compilers==="MakePRO2")this.solutions=["solution.tar"];else{let{proglangNames:q}=await Promise.resolve().then(() => (Yq(),_A)),$=Object.keys(q).join(","),w=await Array.fromAsync(l5(`solution.{${$}}`,{cwd:this.directory}));this.solutions=w.sort()}if(u.yaml(this.solutions),this.solutions.length===0)throw Error("No solutions found")})}async loadGoldenSolution(){if(this.handler.handler==="quiz")return;await u.section("Determining golden solution",async()=>{let{proglangExtensions:q}=await Promise.resolve().then(() => (Yq(),_A));if(this.handler.handler==="circuits")this.goldenSolution="solution.v";else if(this.handler.compilers==="RunPython")this.goldenSolution="solution.py";else if(this.handler.compilers==="RunHaskell"||this.handler.compilers==="GHC")this.goldenSolution="solution.hs";else if(this.handler.compilers==="RunClojure"||this.handler.compilers==="Clojure")this.goldenSolution="solution.clj";else if(this.handler.compilers==="PRO2")if(await l8(this.directory,"solution.hh"))this.goldenSolution="solution.hh";else if(await l8(this.directory,"solution.cc"))this.goldenSolution="solution.cc";else throw Error(`Didn't find "solution.hh" or "solution.cc" for PRO2!`);else if(this.handler.compilers==="MakePRO2")if(await l8(this.directory,"solution")||await l8(this.directory,"solution.tar"))this.goldenSolution="solution.tar";else throw Error(`Didn't find "solution" or "solution.tar" for MakePRO2!`);else{let $=this.handler.solution,w=q[$];if(!w)throw Error(`Unknown programming language ${$} for solution`);let f=a2(this.directory,`solution.${w}`);if(!await OD(f))throw Error(`Golden solution file ${f} not found`);this.goldenSolution=`solution.${w}`}u.print(this.goldenSolution)})}async loadTestcases(){if(this.handler.handler==="quiz")return;await u.section("Loading testcases",async()=>{let q=await Array.fromAsync(l5("*.inp",{cwd:this.directory}));this.testcases=q.map(($)=>$.replace(".inp","")).sort(),u.yaml(this.testcases)})}async reloadTestcases(){if(this.handler.handler==="quiz")return;let q=await Array.fromAsync(l5("*.inp",{cwd:this.directory}));this.testcases=q.map(($)=>$.replace(".inp","")).sort()}async reloadSolutions(){if(this.handler.handler==="quiz")return;let{proglangNames:q,proglangExtensions:$}=await Promise.resolve().then(() => (Yq(),_A));if(this.handler.compilers==="PRO2"){let w=await Array.fromAsync(l5("solution{.tar,.cc,.hh}",{cwd:this.directory}));this.solutions=w.sort()}else if(this.handler.compilers==="MakePRO2")this.solutions=await l8(this.directory,"solution")?["solution.tar"]:[];else{let w=Object.keys(q).join(","),f=await Array.fromAsync(l5(`solution.{${w}}`,{cwd:this.directory}));this.solutions=f.sort()}if(this.solutions.length===0)return;if(this.handler.handler==="circuits")this.goldenSolution="solution.v";else if(this.handler.compilers==="RunPython")this.goldenSolution="solution.py";else if(this.handler.compilers==="RunHaskell"||this.handler.compilers==="GHC")this.goldenSolution="solution.hs";else if(this.handler.compilers==="RunClojure"||this.handler.compilers==="Clojure")this.goldenSolution="solution.clj";else if(this.handler.compilers==="PRO2"){if(await l8(this.directory,"solution.hh"))this.goldenSolution="solution.hh";else if(await l8(this.directory,"solution.cc"))this.goldenSolution="solution.cc"}else if(this.handler.compilers==="MakePRO2"){if(await l8(this.directory,"solution"))this.goldenSolution="solution.tar"}else{let w=this.handler.solution,f=$[w];if(f&&await l8(this.directory,`solution.${f}`))this.goldenSolution=`solution.${f}`}}async loadAwards(){await u.section("Loading awards",async()=>{if(await OD(a2(this.directory,"award.html")))u.success(u.hyperlink(this.directory,"award.html")+" found");else u.warning("award.html not found");if(await OD(a2(this.directory,"award.png"))){u.success(u.hyperlink(this.directory,"award.png")+" found");let q=await xG(a2(this.directory,"award.png"));await u.image(a2(this.directory,"award.png"),6,3),u.print(`${q.width}x${q.height}`)}else u.warning("award.png not found")})}}var Zv_=Z6(H8(),"assets","latex");async function $A(q,$="DRAFT"){let w=await B2(q);return new kv_(w,$)}class kv_{problem;problem_nm;constructor(q,$){this.problem=q,this.problem_nm=$}async showDirectory(){await u.section("Directory",async()=>{await a6(),u.directory(Hv_(this.problem.directory));let q=wg6(Hv_(this.problem.directory));if(!q.endsWith(".pbm")){let $=qg6(q),w=$g6(q);if(!Object.keys(l6).includes($)||!w.endsWith(".pbm"))throw Error("The problem directory should end with .pbm or be a language id inside a .pbm directory")}})}async makeProblem(){if(this.problem.handler.handler==="game")return await this.makeGameProblem();else if(this.problem.handler.handler==="quiz")return await this.makeQuizProblem();else await this.makeTarFiles(),await this.makeGoldenExecutable(),await this.makeCorrectOutputs(),await this.checkSolutions(),await this.makePdfStatements(),await this.makeFullTextualStatements(),await this.makeShortTextualStatements()}async makeQuizProblem(){}async makeGameProblem(){let q=Z6(this.problem.directory,"Doc");await u.section(`Creating documentation in ${u.hyperlink(this.problem.directory,"Doc")}`,async()=>{u.command("make all");let{exitCode:f}=await p_({stderr:"inherit",cwd:q})`make all`;if(f===0)u.success("make completed successfully");else throw u.error("make failed"),Error("make failed")});let $=Z6(this.problem.directory,"Runner");await u.section(`Compiling files in ${u.hyperlink(this.problem.directory,"Runner")}`,async()=>{u.command("make all");let{exitCode:f}=await p_({stdout:"inherit",stderr:"inherit",cwd:$})`make all`;if(f===0)u.success("make completed successfully");else throw u.error("make failed"),Error("make failed")});let w=Z6(this.problem.directory,"Public");await u.section(`Preparing files in ${u.hyperlink(this.problem.directory,"Public")}`,async()=>{await _g6(w,{recursive:!0,force:!0}),await Xk(w,{recursive:!0});let f=[],K=[],z=["README.{txt,md}","Makefile","*.cc","*.hh","*.cnf"];for(let P of z){let D=await Array.fromAsync(bd(P,{cwd:$}));for(let Y of D.sort()){let J=Z6($,Y),Z=Z6(w,Y);if(this.problem.handler.game?.hide.includes(Y))K.push(Y);else f.push(Y),await Jq(J,Z)}}u.success(`Published files: ${f.join(" ")}`),u.warning(`Hidden files: ${K.join(" ")}`)})}async makeExecutable(q){if(this.problem.handler.handler!=="circuits"){let f=q.split(".").pop(),K=hd[f];if(!K)throw Error(`No compiler found for .${f} files`);if(!await K())throw Error(`Compiler for .${f} files is not available`)}let $=this.selectCompiler(),w=`${u8()}-${q}`;await u.section(`Copying ${u.hyperlink(this.problem.directory,q)} to ${u.hyperlink(this.problem.directory,w)}`,async()=>{await Jq(Z6(this.problem.directory,q),Z6(this.problem.directory,w))}),await u.section(`Compiling ${u.hyperlink(this.problem.directory,w)} with ${$.name()} (${this.problem.handler.source_modifier})`,async()=>{try{let f;if(this.problem.handler.source_modifier==="none")f=await $.compileNormal(this.problem.handler,this.problem.directory,w);else if(this.problem.handler.source_modifier==="no_main")f=await $.compileWithMain(this.problem.handler,this.problem.directory,w);else throw Error(`Unknown source modifier: ${this.problem.handler.source_modifier}`);if(!await qA(Z6(this.problem.directory,f)))throw Error(`Compilation failed for ${w}`);u.success(`Compiled ${w} to ${f}`)}catch(f){throw Error("Compilation failed",{cause:f})}})}async makeExecutables(){await u.section("Compiling solutions",async()=>{for(let q of this.problem.solutions)await this.makeExecutable(q)})}async makeGoldenExecutable(){await u.section(`Compiling golden solution from ${u.hyperlink(this.problem.directory,this.problem.goldenSolution)}`,async()=>{if(!this.problem.goldenSolution)throw Error("Golden solution not set");await this.makeExecutable(this.problem.goldenSolution)})}async checkSolutions(){for(let q of this.problem.solutions)if(q!==this.problem.goldenSolution)await this.verifyCandidate(q)}async makeCorrectOutput(q,$,w){return await this.runTestcase(q,`${q}.inp`,`${q}.cor`,$,u8()+"-"+w)}async runTestcase(q,$,w,f,K){let z=!1,P=Date.now();try{await f.execute(this.problem.handler,this.problem.directory,K,$,w)}catch(k){u.error(`Execution failed for testcase '${q}'`),z=!0}let Y=Date.now()-P;if(this.problem.handler.handler==="graphic")await sE6(Z6(this.problem.directory,"output.png"),Z6(this.problem.directory,w));let J=await Sy(Z6(this.problem.directory,$)),Z=await Sy(Z6(this.problem.directory,w));return{testcase:q,error:z,time:Y,inputSize:J,outputSize:Z}}selectCompiler(){if(this.problem.handler.compilers==="PRO2")return Qf("PRO2");else if(this.problem.handler.compilers==="MakePRO2")return Qf("MakePRO2");else if(this.problem.handler.compilers==="RunPython")return Qf("RunPython");else if(this.problem.handler.compilers==="RunHaskell")return Qf("RunHaskell");else if(this.problem.handler.compilers==="RunClojure")return Qf("RunClojure");else{let q=this.problem.goldenSolution.split(".").pop();return kk(q)}}async makeCorrectOutputs(){let q=this.selectCompiler();await u.section("Making correct outputs with golden solution",async()=>{await u.section(`Using ${q.name()}`,async()=>{let $=[];for(let f of this.problem.testcases)$.push(await this.makeCorrectOutput(f,q,this.problem.goldenSolution));u.print(),u.print("testcase time input output");for(let f of $){let K=Bw(f.time),z=ZD(f.inputSize).replace(" ",""),P=ZD(f.outputSize).replace(" ","");u.print((f.error?y_.red:y_.green)(`${f.testcase.padEnd(12)} ${K.padStart(10)} ${z.padStart(10)} ${P.padStart(10)}`))}let w=$.filter((f)=>f.error).length;if(w>0)throw u.print(),Error(`${w} errors occurred while making correct answers`)})})}async makeCorrectOutputForTestcase(q){if(!this.problem.goldenSolution)return;let $=this.selectCompiler();await u.section(`Making correct output for ${q}`,async()=>{await u.section(`Using ${$.name()}`,async()=>{let w=await this.makeCorrectOutput(q,$,this.problem.goldenSolution),f=Bw(w.time),K=ZD(w.inputSize).replace(" ",""),z=ZD(w.outputSize).replace(" ","");if(u.print("testcase time input output"),u.print((w.error?y_.red:y_.green)(`${w.testcase.padEnd(12)} ${f.padStart(10)} ${K.padStart(10)} ${z.padStart(10)}`)),w.error)throw Error(`Error making correct output for ${q}`)})})}async remakeStatements(){await this.makePdfStatements(),await this.makeFullTextualStatements(["txt","html","md"]),await this.makeShortTextualStatements(["txt","html","md"])}async makePdfStatements(){await u.section("Making PDF statements",async()=>{let q=Z6(this.problem.directory,u8()+"-pdf",$q());await Xk(q,{recursive:!0}),await u.section("Creating working directory",async()=>{await a6(),u.directory(q)});for(let $ of this.problem.languages)if(this.problem.structure==="multi"||this.problem.structure==="single"&&$===this.problem.language)await u.section(`Making PDF statement for ${l6[$]}`,async()=>{await this.makePdfStatement(q,$)})})}async makeSamples(q,$){let w=this.problem.handler.handler==="graphic",f=[],K=[],z=0;for(let D of this.problem.testcases)if(D.includes("sample"))z++;let P=1;for(let D of this.problem.testcases)if(D.includes("sample")){let Y="";if(w){await Jq(Z6(this.problem.directory,`${D}.cor`),Z6(q,`${D}.cor.png`));let J=await xG(Z6(q,`${D}.cor.png`));Y=`(${J.width}$\\times$${J.height})`}if(z>1)f.push(`
611
611
  \\SampleOneColInputOutput[${Y}]{${D}}{${P}}
612
612
  `),K.push(`
613
613
  \\SampleTwoColInputOutput[${Y}]{${D}}{${P}}
@@ -617,7 +617,7 @@ main = do
617
617
  \\SampleTwoColInputOutput[${Y}]{${D}}{}
618
618
  `);P++}return[f.join(`
619
619
  `),K.join(`
620
- `)]}async makePdfStatement(q,$){let w=Z6(q,$);await Xk(w);let f=new Date().toISOString(),K=new Date().getFullYear(),z=this.problem.problemLangYmls[this.problem.originalLanguage].author||"Unknown",P=this.problem.problemLangYmls[this.problem.originalLanguage].author_email||"unknown email",D=this.problem.problemLangYmls[$].translator||"",Y=this.problem.problemLangYmls[$].event||this.problem.problemLangYmls[this.problem.originalLanguage].event,J=this.problem.problemLangYmls[$].date||this.problem.problemLangYmls[this.problem.originalLanguage].date,[Z,k]=await this.makeSamples(w,$),W=await j6(Z6(Zv_,"root-pdf.tpl.tex"));jk.default.registerHelper("curly",function(A){return"{"+A+"}"});let v=jk.default.compile(W)({language:$,jutgeLanguage:`jutge.${$}`,id:`${this.problem_nm}\\_${$}`,samples1c:Z,samples2c:k,author:z,translator:D,date:f,year:K,event:Y,eventDate:J});for await(let A of bd("*",{cwd:this.problem.directory})){if(A.startsWith(u8())||A.endsWith(".exe")||A.endsWith(".html")||A.endsWith(".md")||A.endsWith(".txt")||await Ly(this.problem.directory,A))continue;await Jq(Z6(this.problem.directory,A),Z6(w,A))}if(await qA(Z6(w,`original.${$}.pdf`))){u.warning(`Found original.${$}.pdf`),await Jq(Z6(w,`original.${$}.pdf`),Z6(this.problem.directory,`problem.${$}.pdf`));return}await G4(Z6(w,"root.tex"),v);let j=(await j6(Z6(w,`problem.${$}.tex`))).replace(/\\begin{htmlonly}[\s\S]*?\\end{htmlonly}/g,"").replace(/\\begin{latexonly}/g,"").replace(/\\end{latexonly}/g,"").replace(/\.eps}/g,"}");if(await G4(Z6(w,`problem.${$}.tex`),j),await this.copyStyleFiles(w,$),!await cW_()){u.error("xelatex not found");return}try{u.command("xelatex -no-shell-escape -interaction=nonstopmode -file-line-error root.tex"),await p_({stderr:"inherit",cwd:w,env:{max_print_line:"100000"}})`xelatex -no-shell-escape -interaction=nonstopmode -file-line-error root.tex`,await Jq(Z6(w,"root.pdf"),Z6(this.problem.directory,`problem.${$}.pdf`)),u.success(`Generated ${u.hyperlink(this.problem.directory,`problem.${$}.pdf`)} see ${u.hyperlink(w,"root.log")}`)}catch(A){u.error(`Error in LaTeX: ${u.hyperlink(w,"root.log")}`)}}async copyStyleFiles(q,$){let w=async(f)=>{let K=Z6(H8(),"assets","sty",f);await Jq(K,Z6(q,f))};if(await w("picins.sty"),await w("jutge.sty"),$==="ca")await w("jutge.ca.sty");if($==="es")await w("jutge.es.sty");if($==="en")await w("jutge.en.sty");if($==="fr")await w("jutge.fr.sty");if($==="de")await w("jutge.de.sty")}async makeFullTextualStatements(q=["txt","html","md"]){await this.makeTextualStatements(q,"full")}async makeShortTextualStatements(q=["txt","html","md"]){await this.makeTextualStatements(q,"short")}async makeTextualStatements(q=["txt","html","md"],$){await u.section(`Making textual statements (${$})`,async()=>{let w=Z6(this.problem.directory,u8()+"-text",$q());await Xk(w,{recursive:!0}),await u.section("Creating working directory",async()=>{await a6(),u.directory(w)});try{for(let f of this.problem.languages)if(this.problem.structure==="multi"||this.problem.structure==="single"&&f===this.problem.language)await u.section(`Making ${$} textual statements for ${l6[f]}`,async()=>{await this.makeTextualStatement(w,f,q,$)})}finally{}})}async makeTextualStatement(q,$,w,f){let K=Z6(q,$);await Xk(K);let z=new Date().toISOString(),P=new Date().getFullYear(),D=this.problem.problemLangYmls[$].author||"Unknown",Y=this.problem.problemLangYmls[$].author_email||"unknown email",J=this.problem.problemLangYmls[$].translator||"",Z=this.problem.problemLangYmls[$].event||this.problem.problemLangYmls[this.problem.originalLanguage].event,k=this.problem.problemLangYmls[$].date||this.problem.problemLangYmls[this.problem.originalLanguage].date,W=await j6(Z6(Zv_,`root-text-${f}.tpl.tex`));jk.default.registerHelper("curly",function(N){return"{"+N+"}"});let v=jk.default.compile(W)({language:$,jutgeLanguage:`jutge.${$}`,id:`${this.problem_nm}\\_${$}`,year:P,author:D,translator:J,date:z,event:Z,eventDate:k});for await(let N of bd("*",{cwd:this.problem.directory})){if(N.startsWith(u8())||N.endsWith(".exe")||N.endsWith(".html")||N.endsWith(".md")||N.endsWith(".txt")||await Ly(this.problem.directory,N))continue;await Jq(Z6(this.problem.directory,N),Z6(K,N))}if(await qA(Z6(K,`original.${$}.pdf`))){u.warning(`Found original.${$}.pdf`);return}let X=f==="full"?`problem.${$}`:`problem.${$}.short`;await G4(Z6(K,"root.tex"),v);let A=(await j6(Z6(K,`problem.${$}.tex`))).replace(/\\begin{latexonly}[\s\S]*?\\end{latexonly}/g,"").replace(/\\begin{htmlonly}/g,"").replace(/\\end{htmlonly}/g,"").replace(/\\begin{minipage}/g,"").replace(/\\end{minipage}/g,"");if(await G4(Z6(K,`problem.${$}.tex`),A),await this.copyStyleFiles(K,$),!await dW_()){u.error("pandoc with lua support not found");return}let C=Z6(H8(),"assets","lua","fixCodeBlocks.lua");if(await Jq(C,Z6(K,"fixCodeBlocks.lua")),w.includes("txt"))try{u.command("pandoc --quiet root.tex --to plain --output root.txt"),await p_({cwd:K})`pandoc --quiet root.tex --to plain --output root.txt`,await Jq(Z6(K,"root.txt"),Z6(this.problem.directory,`${X}.txt`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.txt`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}if(w.includes("md"))try{u.command("pandoc --quiet root.tex --to markdown --to markdown-header_attributes --lua-filter=fixCodeBlocks.lua --output root.md"),await p_({cwd:K})`pandoc --quiet root.tex --to markdown --to markdown-header_attributes --lua-filter=fixCodeBlocks.lua --output root.md`,await Jq(Z6(K,"root.md"),Z6(this.problem.directory,`${X}.md`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.md`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}if(w.includes("html"))try{u.command("pandoc --quiet root.tex --to html --mathml --embed-resources --output root.html"),await p_({cwd:K})`pandoc --quiet root.tex --to html --mathml --embed-resources --output root.html`,await Jq(Z6(K,"root.html"),Z6(this.problem.directory,`${X}.html`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.html`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}}async verifyCandidate(q,$,w){let f=$??this.problem.testcases,K=w?.skipCompile??!1;await u.section(`Verifying ${q}`,async()=>{let z=q.split(".").pop(),P=hd[z];if(!P)throw Error(`No compiler found for .${z} files`);if(!await P()){u.warning(`Compiler for .${z} files is not available, skipping verification of ${q}`);return}let D=kk(z),Y=`${u8()}-${q}`;if(!K)await u.section(`Copying ${u.hyperlink(this.problem.directory,q)} to ${u.hyperlink(this.problem.directory,Y)}`,async()=>{await Jq(Z6(this.problem.directory,q),Z6(this.problem.directory,Y))}),await u.section(`Using compiler ${D.name()} to compile ${u.hyperlink(this.problem.directory,Y)}`,async()=>{try{let Z;if(this.problem.handler.source_modifier==="none")Z=await D.compileNormal(this.problem.handler,this.problem.directory,Y);else if(this.problem.handler.source_modifier==="no_main")Z=await D.compileWithMain(this.problem.handler,this.problem.directory,Y);else throw Error(`Unknown source modifier: ${this.problem.handler.source_modifier}`);if(!await qA(Z6(this.problem.directory,Z)))throw Error(`Compilation failed for ${Y}`);u.success(`Compiled ${Y} to ${Z}`)}catch(Z){throw Error("Compilation failed",{cause:Z})}});let J=[];await u.section("Executing testcases",async()=>{for(let k of f)J.push(await this.runTestcase(k,`${k}.inp`,`${u8()}-${k}.${z}.out`,D,Y));u.print(),u.print("testcase time status");let Z=0;for(let k of J){let W=k.error?"EE":await N8_(Z6(this.problem.directory,`${k.testcase}.cor`),Z6(this.problem.directory,`${u8()}-${k.testcase}.${z}.out`))?"OK":"WA",v=Bw(k.time);if(u.print((W!=="OK"?y_.red:y_.green)(`${k.testcase.padEnd(12)} ${v.padStart(10)} ${W.padStart(10)}`)),W!=="OK")Z++}if(u.print(),Z)u.error(`${Z} errors found for ${q}`);else if(f.length===this.problem.testcases.length)u.success(`All testcases passed successfully for ${q}`)})})}async makeTarFiles(){let{handler:q,directory:$}=this.problem,{compilers:w}=q;if(w==="PRO2"||w==="MakePRO2")await u.section("Making `.tar` files",async()=>{for(let f of["public","private","solution"])if(await l8($,f)){let{exitCode:K}=await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:Z6($,f)})`tar cf ../${f}.tar .`;if(K!==0)throw console.log(K),Error(`Error making ${f}.tar`);u.success(`Created ${u.hyperlink($,`${f}.tar`)}`)}})}}var Ov_=new G6("verify").description("Verify programs against golden solution").argument("<programs...>","source programs to verify").option("-d, --directory <path>","problem directory",".").action(async(q,{directory:$})=>{let w=await $A($);for(let f of q)await w.verifyCandidate(f)});import fg6 from"path";import{readdir as Kg6,rm as zg6}from"fs/promises";async function Wv_(q,$,w){let f=[`^${u8()}-`,"\\.exe$","\\.dSYM$","\\.out$","\\.pyc$","\\.tar$","\\.class$","\\.o$","\\.hi$","\\.bak$","~$","^a\\.out$","^__pycache__$"],K=["\\.cor$","^problem\\.[a-z][a-z]\\.ps$","^problem\\.[a-z][a-z]\\.pdf$","^problem\\.[a-z][a-z]\\.md$","^problem\\.[a-z][a-z]\\.txt$","^problem\\.[a-z][a-z]\\.html$","^problem\\.[a-z][a-z]\\.short\\.md$","^problem\\.[a-z][a-z]\\.short\\.txt$","^problem\\.[a-z][a-z]\\.short\\.html$"];if($)f.push(...K);let z=new RegExp(f.join("|")),P=await Kg6(w,{withFileTypes:!0}),D=[];for(let J of P){let Z=fg6.join(w,J.name);if(z.test(J.name))D.push(Z)}if(D.length===0){u.success("No entries to remove");return}u.warning(`The following ${D.length} entries will be removed:`);for(let J of D.sort())u.print(u.hyperlink(w,J));if(!q){if(u.print(),!await G3({message:`Remove ${D.length} entries?`,default:!1}))return}let Y=0;for(let J of D)try{await zg6(J,{recursive:!0,force:!0}),Y++}catch(Z){u.error(`Could not remove entry ${J}`)}if(u.success(`Removed ${Y} entries`),!$)u.warning("You can use the --all option to remove generated statement and correct files as well")}import{exists as Id}from"fs/promises";Yq();import{join as yd}from"path";import{normalize as vv_,resolve as Tv_}from"path";function WD(q){let $=/\\Problem\{(.*?)\}/,w=q.match($);if(w)return w[1].trim();return null}async function Sd(q){let $=yd(H8(),"assets","prompts","io","proglangs",`io-${q}.md`);if(await Id($))return await j6($);else return u.warning(`Prompt for ${q} not found at ${$}`),""}async function i$(q){let $=[];for(let w of q){if(w===".")w=vv_(Tv_(process.cwd()));if(await Id(yd(w,"handler.yml")))$.push(w);else for(let f of Object.keys(l6).sort()){let K=yd(w,f,"handler.yml");if(await Id(K))$.push(Tv_(w,f))}}return $.map((w)=>vv_(w)).sort()}var Gk="No problem directories found: did not find handler.yml under the path(s) you used. A problem folder must contain handler.yml at its root, or use <language>/handler.yml under each language subfolder.";function ef(q){if(q.length===0)return"<none>";return q.map(($)=>`- ${$}`).join(`
620
+ `)]}async makePdfStatement(q,$){let w=Z6(q,$);await Xk(w);let f=new Date().toISOString(),K=new Date().getFullYear(),z=this.problem.problemLangYmls[this.problem.originalLanguage].author||"Unknown",P=this.problem.problemLangYmls[this.problem.originalLanguage].author_email||"unknown email",D=this.problem.problemLangYmls[$].translator||"",Y=this.problem.problemLangYmls[$].event||this.problem.problemLangYmls[this.problem.originalLanguage].event,J=this.problem.problemLangYmls[$].date||this.problem.problemLangYmls[this.problem.originalLanguage].date,[Z,k]=await this.makeSamples(w,$),W=await j6(Z6(Zv_,"root-pdf.tpl.tex"));jk.default.registerHelper("curly",function(A){return"{"+A+"}"});let v=jk.default.compile(W,{noEscape:!0})({language:$,jutgeLanguage:`jutge.${$}`,id:`${this.problem_nm}\\_${$}`,samples1c:Z,samples2c:k,author:z,translator:D,date:f,year:K,event:Y,eventDate:J});for await(let A of bd("*",{cwd:this.problem.directory})){if(A.startsWith(u8())||A.endsWith(".exe")||A.endsWith(".html")||A.endsWith(".md")||A.endsWith(".txt")||await Ly(this.problem.directory,A))continue;await Jq(Z6(this.problem.directory,A),Z6(w,A))}if(await qA(Z6(w,`original.${$}.pdf`))){u.warning(`Found original.${$}.pdf`),await Jq(Z6(w,`original.${$}.pdf`),Z6(this.problem.directory,`problem.${$}.pdf`));return}await G4(Z6(w,"root.tex"),v);let j=(await j6(Z6(w,`problem.${$}.tex`))).replace(/\\begin{htmlonly}[\s\S]*?\\end{htmlonly}/g,"").replace(/\\begin{latexonly}/g,"").replace(/\\end{latexonly}/g,"").replace(/\.eps}/g,"}");if(await G4(Z6(w,`problem.${$}.tex`),j),await this.copyStyleFiles(w,$),!await cW_()){u.error("xelatex not found");return}try{u.command("xelatex -no-shell-escape -interaction=nonstopmode -file-line-error root.tex"),await p_({stderr:"inherit",cwd:w,env:{max_print_line:"100000"}})`xelatex -no-shell-escape -interaction=nonstopmode -file-line-error root.tex`,await Jq(Z6(w,"root.pdf"),Z6(this.problem.directory,`problem.${$}.pdf`)),u.success(`Generated ${u.hyperlink(this.problem.directory,`problem.${$}.pdf`)} see ${u.hyperlink(w,"root.log")}`)}catch(A){u.error(`Error in LaTeX: ${u.hyperlink(w,"root.log")}`)}}async copyStyleFiles(q,$){let w=async(f)=>{let K=Z6(H8(),"assets","sty",f);await Jq(K,Z6(q,f))};if(await w("picins.sty"),await w("jutge.sty"),$==="ca")await w("jutge.ca.sty");if($==="es")await w("jutge.es.sty");if($==="en")await w("jutge.en.sty");if($==="fr")await w("jutge.fr.sty");if($==="de")await w("jutge.de.sty")}async makeFullTextualStatements(q=["txt","html","md"]){await this.makeTextualStatements(q,"full")}async makeShortTextualStatements(q=["txt","html","md"]){await this.makeTextualStatements(q,"short")}async makeTextualStatements(q=["txt","html","md"],$){await u.section(`Making textual statements (${$})`,async()=>{let w=Z6(this.problem.directory,u8()+"-text",$q());await Xk(w,{recursive:!0}),await u.section("Creating working directory",async()=>{await a6(),u.directory(w)});try{for(let f of this.problem.languages)if(this.problem.structure==="multi"||this.problem.structure==="single"&&f===this.problem.language)await u.section(`Making ${$} textual statements for ${l6[f]}`,async()=>{await this.makeTextualStatement(w,f,q,$)})}finally{}})}async makeTextualStatement(q,$,w,f){let K=Z6(q,$);await Xk(K);let z=new Date().toISOString(),P=new Date().getFullYear(),D=this.problem.problemLangYmls[$].author||"Unknown",Y=this.problem.problemLangYmls[$].author_email||"unknown email",J=this.problem.problemLangYmls[$].translator||"",Z=this.problem.problemLangYmls[$].event||this.problem.problemLangYmls[this.problem.originalLanguage].event,k=this.problem.problemLangYmls[$].date||this.problem.problemLangYmls[this.problem.originalLanguage].date,W=await j6(Z6(Zv_,`root-text-${f}.tpl.tex`));jk.default.registerHelper("curly",function(N){return"{"+N+"}"});let v=jk.default.compile(W,{noEscape:!0})({language:$,jutgeLanguage:`jutge.${$}`,id:`${this.problem_nm}\\_${$}`,year:P,author:D,translator:J,date:z,event:Z,eventDate:k});for await(let N of bd("*",{cwd:this.problem.directory})){if(N.startsWith(u8())||N.endsWith(".exe")||N.endsWith(".html")||N.endsWith(".md")||N.endsWith(".txt")||await Ly(this.problem.directory,N))continue;await Jq(Z6(this.problem.directory,N),Z6(K,N))}if(await qA(Z6(K,`original.${$}.pdf`))){u.warning(`Found original.${$}.pdf`);return}let X=f==="full"?`problem.${$}`:`problem.${$}.short`;await G4(Z6(K,"root.tex"),v);let A=(await j6(Z6(K,`problem.${$}.tex`))).replace(/\\begin{latexonly}[\s\S]*?\\end{latexonly}/g,"").replace(/\\begin{htmlonly}/g,"").replace(/\\end{htmlonly}/g,"").replace(/\\begin{minipage}/g,"").replace(/\\end{minipage}/g,"");if(await G4(Z6(K,`problem.${$}.tex`),A),await this.copyStyleFiles(K,$),!await dW_()){u.error("pandoc with lua support not found");return}let C=Z6(H8(),"assets","lua","fixCodeBlocks.lua");if(await Jq(C,Z6(K,"fixCodeBlocks.lua")),w.includes("txt"))try{u.command("pandoc --quiet root.tex --to plain --output root.txt"),await p_({cwd:K})`pandoc --quiet root.tex --to plain --output root.txt`,await Jq(Z6(K,"root.txt"),Z6(this.problem.directory,`${X}.txt`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.txt`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}if(w.includes("md"))try{u.command("pandoc --quiet root.tex --to markdown --to markdown-header_attributes --lua-filter=fixCodeBlocks.lua --output root.md"),await p_({cwd:K})`pandoc --quiet root.tex --to markdown --to markdown-header_attributes --lua-filter=fixCodeBlocks.lua --output root.md`,await Jq(Z6(K,"root.md"),Z6(this.problem.directory,`${X}.md`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.md`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}if(w.includes("html"))try{u.command("pandoc --quiet root.tex --to html --mathml --embed-resources --output root.html"),await p_({cwd:K})`pandoc --quiet root.tex --to html --mathml --embed-resources --output root.html`,await Jq(Z6(K,"root.html"),Z6(this.problem.directory,`${X}.html`)),u.success("Generated "+u.hyperlink(this.problem.directory,`${X}.html`))}catch(N){u.error(`pandoc error: ${N instanceof Error?N.message:"unknown error"}`)}}async verifyCandidate(q,$,w){let f=$??this.problem.testcases,K=w?.skipCompile??!1;await u.section(`Verifying ${q}`,async()=>{let z=q.split(".").pop(),P=hd[z];if(!P)throw Error(`No compiler found for .${z} files`);if(!await P()){u.warning(`Compiler for .${z} files is not available, skipping verification of ${q}`);return}let D=kk(z),Y=`${u8()}-${q}`;if(!K)await u.section(`Copying ${u.hyperlink(this.problem.directory,q)} to ${u.hyperlink(this.problem.directory,Y)}`,async()=>{await Jq(Z6(this.problem.directory,q),Z6(this.problem.directory,Y))}),await u.section(`Using compiler ${D.name()} to compile ${u.hyperlink(this.problem.directory,Y)}`,async()=>{try{let Z;if(this.problem.handler.source_modifier==="none")Z=await D.compileNormal(this.problem.handler,this.problem.directory,Y);else if(this.problem.handler.source_modifier==="no_main")Z=await D.compileWithMain(this.problem.handler,this.problem.directory,Y);else throw Error(`Unknown source modifier: ${this.problem.handler.source_modifier}`);if(!await qA(Z6(this.problem.directory,Z)))throw Error(`Compilation failed for ${Y}`);u.success(`Compiled ${Y} to ${Z}`)}catch(Z){throw Error("Compilation failed",{cause:Z})}});let J=[];await u.section("Executing testcases",async()=>{for(let k of f)J.push(await this.runTestcase(k,`${k}.inp`,`${u8()}-${k}.${z}.out`,D,Y));u.print(),u.print("testcase time status");let Z=0;for(let k of J){let W=k.error?"EE":await N8_(Z6(this.problem.directory,`${k.testcase}.cor`),Z6(this.problem.directory,`${u8()}-${k.testcase}.${z}.out`))?"OK":"WA",v=Bw(k.time);if(u.print((W!=="OK"?y_.red:y_.green)(`${k.testcase.padEnd(12)} ${v.padStart(10)} ${W.padStart(10)}`)),W!=="OK")Z++}if(u.print(),Z)u.error(`${Z} errors found for ${q}`);else if(f.length===this.problem.testcases.length)u.success(`All testcases passed successfully for ${q}`)})})}async makeTarFiles(){let{handler:q,directory:$}=this.problem,{compilers:w}=q;if(w==="PRO2"||w==="MakePRO2")await u.section("Making `.tar` files",async()=>{for(let f of["public","private","solution"])if(await l8($,f)){let{exitCode:K}=await p_({reject:!1,stderr:"inherit",stdout:"inherit",cwd:Z6($,f)})`tar cf ../${f}.tar .`;if(K!==0)throw console.log(K),Error(`Error making ${f}.tar`);u.success(`Created ${u.hyperlink($,`${f}.tar`)}`)}})}}var Ov_=new G6("verify").description("Verify programs against golden solution").argument("<programs...>","source programs to verify").option("-d, --directory <path>","problem directory",".").action(async(q,{directory:$})=>{let w=await $A($);for(let f of q)await w.verifyCandidate(f)});import fg6 from"path";import{readdir as Kg6,rm as zg6}from"fs/promises";async function Wv_(q,$,w){let f=[`^${u8()}-`,"\\.exe$","\\.dSYM$","\\.out$","\\.pyc$","\\.tar$","\\.class$","\\.o$","\\.hi$","\\.bak$","~$","^a\\.out$","^__pycache__$"],K=["\\.cor$","^problem\\.[a-z][a-z]\\.ps$","^problem\\.[a-z][a-z]\\.pdf$","^problem\\.[a-z][a-z]\\.md$","^problem\\.[a-z][a-z]\\.txt$","^problem\\.[a-z][a-z]\\.html$","^problem\\.[a-z][a-z]\\.short\\.md$","^problem\\.[a-z][a-z]\\.short\\.txt$","^problem\\.[a-z][a-z]\\.short\\.html$"];if($)f.push(...K);let z=new RegExp(f.join("|")),P=await Kg6(w,{withFileTypes:!0}),D=[];for(let J of P){let Z=fg6.join(w,J.name);if(z.test(J.name))D.push(Z)}if(D.length===0){u.success("No entries to remove");return}u.warning(`The following ${D.length} entries will be removed:`);for(let J of D.sort())u.print(u.hyperlink(w,J));if(!q){if(u.print(),!await G3({message:`Remove ${D.length} entries?`,default:!1}))return}let Y=0;for(let J of D)try{await zg6(J,{recursive:!0,force:!0}),Y++}catch(Z){u.error(`Could not remove entry ${J}`)}if(u.success(`Removed ${Y} entries`),!$)u.warning("You can use the --all option to remove generated statement and correct files as well")}import{exists as Id}from"fs/promises";Yq();import{join as yd}from"path";import{normalize as vv_,resolve as Tv_}from"path";function WD(q){let $=/\\Problem\{(.*?)\}/,w=q.match($);if(w)return w[1].trim();return null}async function Sd(q){let $=yd(H8(),"assets","prompts","io","proglangs",`io-${q}.md`);if(await Id($))return await j6($);else return u.warning(`Prompt for ${q} not found at ${$}`),""}async function i$(q){let $=[];for(let w of q){if(w===".")w=vv_(Tv_(process.cwd()));if(await Id(yd(w,"handler.yml")))$.push(w);else for(let f of Object.keys(l6).sort()){let K=yd(w,f,"handler.yml");if(await Id(K))$.push(Tv_(w,f))}}return $.map((w)=>vv_(w)).sort()}var Gk="No problem directories found: did not find handler.yml under the path(s) you used. A problem folder must contain handler.yml at its root, or use <language>/handler.yml under each language subfolder.";function ef(q){if(q.length===0)return"<none>";return q.map(($)=>`- ${$}`).join(`
621
621
  `)}import{resolve as Pg6}from"path";var Xv_=new G6("clean").description("Clean disposable files").option("-d, --directory <directory>","problem directory",".").option("-a, --all","clean all disposable files (including generated statement and correct files",!1).addOption(new WJ("-f, --force","force removal").conflicts("dryRun")).addOption(new WJ("-n, --dry-run","show but do not remove files").conflicts("force")).action(async({directory:q,all:$,force:w,dryRun:f})=>{let K=w||!1;await u.section(`Cleaning disposable files in ${u.hyperlink(Pg6(q))}`,async()=>{let z=await i$([q]);for(let P of z)await u.section(`Cleaning directory ${u.hyperlink(P)}`,async()=>{await Wv_(K,$,P)})})});var wA=new G6("compilers").description("Query compiler information").action(async()=>{let q=await sW_();console.dir(q)});wA.command("list-defined").description("List all defined compiler names").action(async()=>{let q=await sG();console.dir(q)});wA.command("list-available").description("List all available compiler names").action(async()=>{let q=await eW_();console.dir(q)});var md=z6(vP(),1);var r5=new G6("config").summary("Manage configuration").description(`Manage configuration
622
622
 
623
623
  The actual configuration file is stored at ${dH()}`).action(()=>{r5.help()});r5.command("show").alias("list").description("Show configuration options").action(async()=>{let q=await xy();u.yaml(q)});r5.command("get <key>").description("Get the value of a configuration option").action((q)=>{if(!(q in z8))throw Error(`Configuration key ${q} does not exist`);console.log(z8[q])});r5.command("set <key> <value>").description("Set the value of a configuration option").action(async(q,$)=>{if(!(q in z8))throw Error(`Configuration key ${q} does not exist`);let w=b8_($),f=C$.parse({...z8,[q]:w});await lH(f),u.success(`Configuration key ${q} updated successfully`)});r5.command("edit").description("Open an editor (uses $EDITOR or $VISUAL) to modify the configuration options").action(async()=>{let q=md.default.stringify(z8,null,4);while(!0){let $=await M5({message:"Edit configuration",default:q,postfix:".yml",waitForUserInput:!1});try{let w=C$.parse(md.default.parse($));await lH(w),u.success("Configuration options updated successfully");return}catch(w){if(w instanceof d7)console.error(D5(w).toString());else console.error(w);if(!await G3({message:"Edit again?",default:!0})){u.warning("No changes made to the configuration options");return}q=$}}});r5.command("reset").description("Reset configuration to default values").option("-f, --force","force reset without confirmation",!1).action(async({force:q})=>{if(!q){if(!await G3({message:"Are you sure you want to reset the configuration to default values?",default:!1})){u.warning("Reset cancelled");return}}let $=C$.parse({});await lH($),u.success("Configuration reset to default values successfully")});sq();var Ld=z6(XD(),1);import{cp as Vg6,exists as bv_,glob as Iv_}from"fs/promises";import Ak from"path";var fA=Ak.join(H8(),"assets","problems");async function Mg6(q){let $=[],w=await Array.fromAsync(Iv_("*",{cwd:fA}));w.sort();for(let K of w){$.push(new S1(gd(K)));let z=await Array.fromAsync(Iv_("*.pbm",{cwd:Ak.join(fA,K)}));z.sort();for(let P of z)$.push({name:P,value:Ak.join(K,P)})}let f=void 0;while(!0){f=await x4({message:"Select a template to clone:",choices:$,default:f});let K=Ak.join(fA,f),z=await F8(K,"README.md"),P=Ld.default(K,{allFiles:!0,dirsFirst:!1});if(console.log(),await u.markdown(z),console.log(P),await G3({message:`Clone template ${f} to ${q}?`,default:!0}))return f}}async function yv_(q,$){if(await bv_(q))throw Error(`Directory ${q} already exists`);if(!q.endsWith(".pbm"))throw Error("The output directory must end with .pbm");if(!$)$=await Mg6(q);let w=Ak.join(fA,$);if(!await bv_(w))throw Error(`Template ${$} does not exist`);await Vg6(w,q,{recursive:!0}),await XP(q),u.success(`Created problem ${u.hyperlink(q)} from template ${$}`);let f=Ld.default(q,{allFiles:!0,dirsFirst:!1});console.log(f)}var Sv_=new G6("clone").description("Clone a template into a new problem").argument("[template]","template to use (empty to interactive selection)").option("-d, --directory <path>","output directory","new-problem.pbm").action(async(q,{directory:$})=>{await yv_($,q)});var GT_=z6(k0_(),1);import{cp as jT_,exists as FR6,mkdir as oR6,readdir as AT_,rm as UR6,stat as QR6}from"fs/promises";import sd from"process";import b0_ from"path";import{fileURLToPath as gR6}from"url";import RR6 from"child_process";import bR6,{constants as IR6}from"fs/promises";import{promisify as DR6}from"util";import YR6 from"child_process";import ad,{constants as G0_}from"fs/promises";import v0_ from"process";import $R6 from"os";import wR6 from"fs";import _R6 from"fs";import O0_ from"fs";var rd;function eg6(){try{return O0_.statSync("/.dockerenv"),!0}catch{return!1}}function sg6(){try{return O0_.readFileSync("/proc/self/cgroup","utf8").includes("docker")}catch{return!1}}function pd(){if(rd===void 0)rd=eg6()||sg6();return rd}var id,qR6=()=>{try{return _R6.statSync("/run/.containerenv"),!0}catch{return!1}};function uD(){if(id===void 0)id=qR6()||pd();return id}var W0_=()=>{if(v0_.platform!=="linux")return!1;if($R6.release().toLowerCase().includes("microsoft")){if(uD())return!1;return!0}try{return wR6.readFileSync("/proc/version","utf8").toLowerCase().includes("microsoft")?!uD():!1}catch{return!1}},H9=v0_.env.__IS_WSL_TEST__?W0_:W0_();import T0_ from"process";import{Buffer as fR6}from"buffer";import{promisify as KR6}from"util";import zR6 from"child_process";var PR6=KR6(zR6.execFile),nd=()=>`${T0_.env.SYSTEMROOT||T0_.env.windir||String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;var Hq=async(q,$={})=>{let{powerShellPath:w,...f}=$,K=Hq.encodeCommand(q);return PR6(w??nd(),[...Hq.argumentsPrefix,K],{encoding:"utf8",...f})};Hq.argumentsPrefix=["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand"];Hq.encodeCommand=(q)=>fR6.from(q,"utf16le").toString("base64");Hq.escapeArgument=(q)=>`'${String(q).replaceAll("'","''")}'`;function X0_(q){for(let $ of q.split(`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jutge.org/toolkit",
3
3
  "description": "Toolkit to prepare problems for Jutge.org",
4
- "version": "4.4.40",
4
+ "version": "4.4.43",
5
5
  "homepage": "https://jutge.org",
6
6
  "author": {
7
7
  "name": "Jutge.org",