@jutge.org/toolkit 4.4.28 → 4.4.29
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.
- package/dist/index.js +1 -1
- package/docs/problem-anatomy.md +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -930,7 +930,7 @@ The new message will be saved as award.html in the problem directory, overriding
|
|
|
930
930
|
|
|
931
931
|
This command will run the quiz problem and print the resulting object to stdout.
|
|
932
932
|
A random seed will be generated if not provided.
|
|
933
|
-
`).option("-d, --directory <directory>","problem directory",".").option("-s, --seed <seed>","random seed").option("-f, --format <format>","output format (json|yaml)","json").action(async({directory:q,seed:$,format:w})=>{let f=$?parseInt($,10):Ak(1e6,9999999),K=await zu(q,f);if(w==="json")u.json(K);else u.yaml(K)});oD.command("play").summary("Play a quiz problem").description("Play an interactive quiz test. Questions are shown in sequence; you can review and change answers before submitting.\nInput is a JSON file from `quiz run`; if --input is omitted, a run is generated with a random seed from the given directory.\nIf --output is given, the results (your answers, correct answers, and score per question) are written to that file.").option("-i, --input <input>","input JSON file from quiz run").option("-o, --output <output>","output file for results").option("-d, --directory <directory>","problem directory (used when --input is not provided)",".").option("-s, --seed <seed>","random seed (used when --input is not provided)").action(async({input:q,output:$,directory:w,seed:f})=>{let K=f!==void 0?parseInt(f,10):void 0,z=await dA_(q,w,K),P=await lA_(z);if($!==void 0)await rA_($,P)});var pA_=new h6("upgrade").description("Upgrade to the latest version").action(async()=>{await QZ_()});import{exists as A88,glob as u88,mkdir as C88}from"fs/promises";import{basename as gy_,join as nO,normalize as V88,resolve as M88,sep as N88}from"path";var Ey_=z6(hy_(),1);import{createWriteStream as G88}from"fs";async function iO(q,$){let w=G88($),f=Ey_.default("zip",{zlib:{level:9}}),K=new Promise((z,P)=>{w.on("close",()=>z()),w.on("error",P),f.on("error",P),f.on("warning",(D)=>{if(D.code==="ENOENT")console.warn(D);else P(D)})});f.pipe(w);for(let z of q)f.file(z.sourcePath,{name:z.archivePath});await f.finalize(),await K}async function by_(q){function $(
|
|
933
|
+
`).option("-d, --directory <directory>","problem directory",".").option("-s, --seed <seed>","random seed").option("-f, --format <format>","output format (json|yaml)","json").action(async({directory:q,seed:$,format:w})=>{let f=$?parseInt($,10):Ak(1e6,9999999),K=await zu(q,f);if(w==="json")u.json(K);else u.yaml(K)});oD.command("play").summary("Play a quiz problem").description("Play an interactive quiz test. Questions are shown in sequence; you can review and change answers before submitting.\nInput is a JSON file from `quiz run`; if --input is omitted, a run is generated with a random seed from the given directory.\nIf --output is given, the results (your answers, correct answers, and score per question) are written to that file.").option("-i, --input <input>","input JSON file from quiz run").option("-o, --output <output>","output file for results").option("-d, --directory <directory>","problem directory (used when --input is not provided)",".").option("-s, --seed <seed>","random seed (used when --input is not provided)").action(async({input:q,output:$,directory:w,seed:f})=>{let K=f!==void 0?parseInt(f,10):void 0,z=await dA_(q,w,K),P=await lA_(z);if($!==void 0)await rA_($,P)});var pA_=new h6("upgrade").description("Upgrade to the latest version").action(async()=>{await QZ_()});import{exists as A88,glob as u88,mkdir as C88}from"fs/promises";import{basename as gy_,join as nO,normalize as V88,resolve as M88,sep as N88}from"path";var Ey_=z6(hy_(),1);import{createWriteStream as G88}from"fs";async function iO(q,$){let w=G88($),f=Ey_.default("zip",{zlib:{level:9}}),K=new Promise((z,P)=>{w.on("close",()=>z()),w.on("error",P),f.on("error",P),f.on("warning",(D)=>{if(D.code==="ENOENT")console.warn(D);else P(D)})});f.pipe(w);for(let z of q)f.file(z.sourcePath,{name:z.archivePath});await f.finalize(),await K}async function by_(q){function $(P){let D=[".exe",".o",".hi","~",".bak",".class",".pyc",".pyo"],Y=[C8()+"-","__MACOSX",".DS_Store",".","__pycache__"];for(let Z of D)if(P.endsWith(Z))return!1;let J=V88(P).split(N88);for(let Z of J)for(let k of Y)if(Z.startsWith(k))return!1;return!0}let w=M88(q);if(!w.endsWith(".pbm"))throw Error(`Directory ${q} is not a problem directory (missing .pbm suffix)`);let f=nO(q,C8()+"-zip",wq()),K=gy_(w),z=nO(f,`${K}.zip`);await C88(f,{recursive:!0}),await u.section(`Zipping problem to ${z}`,async()=>{let P=[],D=await Array.fromAsync(u88("**/*",{cwd:q}));for(let J of D)if($(J)){let Z=nO(q,J),k=nO(gy_(w),J);u.print(`adding ${k}`),P.push({sourcePath:Z,archivePath:k})}u.print("Creating zip file..."),await iO(P,z);let Y=await h88(q,z);E88(Y)})}async function h88(q,$){let w=nO(q,"problem.yml");if(await A88(w)){let f=V$.parse(await X3(w));return await b88(q,f,$)}else return await g88(q,$)}function E88(q){let $={"problem.yml":q};u.yaml($),u.url(`https://jutge.org/problems/${q.problem_nm}`)}async function g88(q,$){return await u.section("Creating problem in Jutge.org",async()=>{let w=await a4(),z={problem_nm:"",email:(await w.student.profile.get()).email,passcode:jP(),shared_testcases:!1,shared_solutions:!1,created_at:"",updated_at:""};return await u.section("Creating problem in Jutge.org",async()=>{let P=await dH($,"application/zip"),{id:D}=await w.instructor.problems.create(z.passcode,P),Y=await Iy_(D);if(!Y)throw Error("Upload failed");z.problem_nm=Y,z.created_at=new Date().toISOString(),z.updated_at=new Date().toISOString()}),await Ry_(q,z,"Created"),u.print(""),u.success(`Problem ${z.problem_nm} created successfully`),z})}async function b88(q,$,w){return await u.section("Updating problem in Jutge.org",async()=>{let f=await a4();return await u.section("Updating problem in Jutge.org",async()=>{let K=await dH(w,"application/zip"),{id:z}=await f.instructor.problems.update($.problem_nm,K);if(!await Iy_(z))throw Error("Upload failed");$.updated_at=new Date().toISOString()}),await Ry_(q,$,"Updated"),u.print(""),u.success(`Problem ${$.problem_nm} updated successfully`),$})}async function Ry_(q,$,w){await u.section(`${w==="Created"?"Creating":"Updating"} problem.yml`,async()=>{await w1(q,"problem.yml",$),u.success(`${w} problem.yml`)})}async function Iy_(q){let $=new wK,w=await fetch(`${$.JUTGE_API_URL}/webstreams/${q}`);if(w.body===null)return null;let f=void 0,K=w.body.getReader();while(!0){let{done:z,value:P}=await K.read();if(z)return f||null;let D=new TextDecoder().decode(P);u.print(D.trim());let Y=D.match(/Problem ([A-Z]\d{5}) created\./);if(Y)f=Y[1];let J=D.match(/Problem ([A-Z]\d{5}) updated\./);if(J)f=J[1]}}var yy_=new h6("upload").summary("Upload problem to Jutge.org").description(`Upload problem to Jutge.org
|
|
934
934
|
|
|
935
935
|
If problem.yml exists, the problem will be updated at Jutge.org using that information (which includes its problem id).
|
|
936
936
|
If problem.yml does not exist, a new problem will be created at Jutge.org and problem.yml will be generated.
|
package/docs/problem-anatomy.md
CHANGED
|
@@ -89,7 +89,7 @@ Problem statements are stored in LaTeX files named `problem.lang.tex`, where `la
|
|
|
89
89
|
|
|
90
90
|
### Demo problem
|
|
91
91
|
|
|
92
|
-
The clonable `demo` problem contains an example of a problem statement with many features that can be used in your own problem statements; see [demo.tex](demo.tex) for examples and inspiration.
|
|
92
|
+
The clonable `demo` problem contains an example of a problem statement with many features that can be used in your own problem statements; see [demo.tex](../assets/problems/demo/demo.pbm/problem.en.tex) for examples and inspiration.
|
|
93
93
|
|
|
94
94
|
### Structure
|
|
95
95
|
|