@jpetit/toolkit 3.0.4 → 3.0.6
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/package.json +11 -6
- package/toolkit/index.ts +18 -1
- package/.prettierignore +0 -11
- package/.prettierrc.json +0 -9
- package/.vscode/settings.json +0 -26
- package/assets.zip +0 -0
- package/eslint.config.mjs +0 -31
- package/lib/ai.ts +0 -138
- package/lib/assets.ts +0 -31
- package/lib/cleaner.ts +0 -58
- package/lib/compilers/_frompython.ts +0 -388
- package/lib/compilers/base.ts +0 -97
- package/lib/compilers/gcc.ts +0 -47
- package/lib/compilers/gxx.ts +0 -47
- package/lib/compilers/index.ts +0 -61
- package/lib/compilers/python3.ts +0 -67
- package/lib/data.ts +0 -19
- package/lib/doctor.ts +0 -104
- package/lib/generate.ts +0 -333
- package/lib/maker.ts +0 -535
- package/lib/settings.ts +0 -42
- package/lib/tui.ts +0 -69
- package/lib/utils.ts +0 -83
- package/problems/maxim2.pbm/Main.java +0 -13
- package/problems/maxim2.pbm/distillation.yml +0 -7
- package/problems/maxim2.pbm/distilled-01.inp +0 -1
- package/problems/maxim2.pbm/distilled-02.inp +0 -1
- package/problems/maxim2.pbm/distilled-03.inp +0 -1
- package/problems/maxim2.pbm/distiller.yml +0 -2
- package/problems/maxim2.pbm/generate-inputs.py +0 -9
- package/problems/maxim2.pbm/handler.yml +0 -2
- package/problems/maxim2.pbm/ma-1.inp +0 -1
- package/problems/maxim2.pbm/ma-2.inp +0 -1
- package/problems/maxim2.pbm/ma-3.inp +0 -1
- package/problems/maxim2.pbm/ma-4.inp +0 -1
- package/problems/maxim2.pbm/ma-5.inp +0 -1
- package/problems/maxim2.pbm/per-doubles.inp +0 -1
- package/problems/maxim2.pbm/problem.ca.html +0 -11
- package/problems/maxim2.pbm/problem.ca.md +0 -19
- package/problems/maxim2.pbm/problem.ca.tex +0 -17
- package/problems/maxim2.pbm/problem.ca.txt +0 -19
- package/problems/maxim2.pbm/problem.ca.yml +0 -3
- package/problems/maxim2.pbm/problem.en.html +0 -11
- package/problems/maxim2.pbm/problem.en.md +0 -19
- package/problems/maxim2.pbm/problem.en.tex +0 -16
- package/problems/maxim2.pbm/problem.en.txt +0 -19
- package/problems/maxim2.pbm/problem.en.yml +0 -4
- package/problems/maxim2.pbm/sample-1.inp +0 -1
- package/problems/maxim2.pbm/sample-2.inp +0 -1
- package/problems/maxim2.pbm/sample-3.inp +0 -1
- package/problems/maxim2.pbm/solution.c +0 -12
- package/problems/maxim2.pbm/solution.cc +0 -13
- package/problems/maxim2.pbm/solution.java +0 -13
- package/problems/maxim2.pbm/solution.pas +0 -9
- package/problems/maxim2.pbm/solution.py +0 -5
- package/problems/maxim2.pbm/tags.yml +0 -2
- package/problems/maxim2.pbm/test_-1_-1.inp +0 -1
- package/problems/maxim2.pbm/test_-1_-2.inp +0 -1
- package/problems/maxim2.pbm/test_-1_0.inp +0 -1
- package/problems/maxim2.pbm/test_-1_1.inp +0 -1
- package/problems/maxim2.pbm/test_-2_-1.inp +0 -1
- package/problems/maxim2.pbm/test_-2_-2.inp +0 -1
- package/problems/maxim2.pbm/test_-2_0.inp +0 -1
- package/problems/maxim2.pbm/test_-2_1.inp +0 -1
- package/problems/maxim2.pbm/test_0_-1.inp +0 -1
- package/problems/maxim2.pbm/test_0_-2.inp +0 -1
- package/problems/maxim2.pbm/test_0_0.inp +0 -1
- package/problems/maxim2.pbm/test_0_1.inp +0 -1
- package/problems/maxim2.pbm/test_1_-1.inp +0 -1
- package/problems/maxim2.pbm/test_1_-2.inp +0 -1
- package/problems/maxim2.pbm/test_1_0.inp +0 -1
- package/problems/maxim2.pbm/test_1_1.inp +0 -1
- package/test.ts +0 -3
- package/toolkit/ai.ts +0 -30
- package/toolkit/clean.ts +0 -19
- package/toolkit/compilers.ts +0 -29
- package/toolkit/create-jutge-ai.ts +0 -101
- package/toolkit/create-template.ts +0 -51
- package/toolkit/create-wizard.ts +0 -4
- package/toolkit/create.ts +0 -75
- package/toolkit/doctor.ts +0 -17
- package/toolkit/init.ts +0 -66
- package/toolkit/make.ts +0 -60
- package/toolkit/verify.ts +0 -19
- package/tsconfig.json +0 -38
- package/types/zip.d.ts +0 -4
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { paths } from '@/lib/settings'
|
|
2
|
-
import * as tui from '@/lib/tui.js'
|
|
3
|
-
import { confirm, select, Separator } from '@inquirer/prompts'
|
|
4
|
-
import { cp } from 'fs/promises'
|
|
5
|
-
import { join } from 'path'
|
|
6
|
-
import { title } from 'radash'
|
|
7
|
-
|
|
8
|
-
async function chooseTemplate(): Promise<string> {
|
|
9
|
-
// build the choices array
|
|
10
|
-
const choices = []
|
|
11
|
-
const path = join(paths.data, 'assets', 'problems')
|
|
12
|
-
const dirsGlob = new Bun.Glob('*')
|
|
13
|
-
for await (const dir of dirsGlob.scan({ cwd: path, onlyFiles: false })) {
|
|
14
|
-
choices.push(new Separator(`◇ ${title(dir)}:`))
|
|
15
|
-
const problemsGlob = new Bun.Glob('*')
|
|
16
|
-
for await (const problem of problemsGlob.scan({ cwd: join(path, dir), onlyFiles: false })) {
|
|
17
|
-
const readme = await Bun.file(join(path, dir, problem, 'README.md')).text()
|
|
18
|
-
const name = // Extract title from README.md
|
|
19
|
-
' ' +
|
|
20
|
-
readme
|
|
21
|
-
.split('\n')
|
|
22
|
-
.filter((line) => line.startsWith('#'))[0]
|
|
23
|
-
?.replace('#', '')
|
|
24
|
-
.trim() || 'No description'
|
|
25
|
-
choices.push({ name, value: join(dir, problem) })
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
while (true) {
|
|
30
|
-
const template = await select({ choices, message: 'Select a problem template:', loop: false })
|
|
31
|
-
|
|
32
|
-
const readme = await Bun.file(join(path, template, 'README.md')).text()
|
|
33
|
-
await tui.markdown(readme)
|
|
34
|
-
console.log()
|
|
35
|
-
|
|
36
|
-
const confirmation = await confirm({
|
|
37
|
-
message: `Use this template?`,
|
|
38
|
-
default: true,
|
|
39
|
-
})
|
|
40
|
-
if (confirmation) return template
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function createProblemWithTemplate(outputDir: string): Promise<void> {
|
|
45
|
-
const template = await chooseTemplate()
|
|
46
|
-
|
|
47
|
-
const source = join(paths.data, 'assets', 'problems', template)
|
|
48
|
-
tui.action(`Creating new problem from template ${template}`)
|
|
49
|
-
await cp(source, outputDir, { recursive: true })
|
|
50
|
-
tui.success(`Problem created at ${outputDir}`)
|
|
51
|
-
}
|
package/toolkit/create-wizard.ts
DELETED
package/toolkit/create.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import * as tui from '@/lib/tui.js'
|
|
2
|
-
import { Command } from '@commander-js/extra-typings'
|
|
3
|
-
import { confirm, input, select } from '@inquirer/prompts'
|
|
4
|
-
import { exists, mkdir, rm } from 'fs/promises'
|
|
5
|
-
import { normalize } from 'path'
|
|
6
|
-
import { createProblemWithJutgeAI } from './create-jutge-ai'
|
|
7
|
-
import { createProblemWithTemplate } from './create-template'
|
|
8
|
-
import { createProblemWithWizard } from './create-wizard'
|
|
9
|
-
|
|
10
|
-
async function selectMethod(): Promise<'template' | 'wizard' | 'jutgeAI'> {
|
|
11
|
-
return await select({
|
|
12
|
-
message: 'Method to create a new problem:',
|
|
13
|
-
choices: [
|
|
14
|
-
{ name: 'Use a template', value: 'template' },
|
|
15
|
-
{ name: 'Use the wizard', value: 'wizard' },
|
|
16
|
-
{ name: 'Use JutgeAI', value: 'jutgeAI' },
|
|
17
|
-
],
|
|
18
|
-
})
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function selectOutputDir(): Promise<string> {
|
|
22
|
-
let dir = 'my-new-problem.pbm'
|
|
23
|
-
while (true) {
|
|
24
|
-
dir = await input({
|
|
25
|
-
message: 'Output directory for the new problem:',
|
|
26
|
-
default: dir,
|
|
27
|
-
})
|
|
28
|
-
dir = normalize(dir)
|
|
29
|
-
if (await exists(dir)) {
|
|
30
|
-
tui.error(`Directory ${dir} already exists.`)
|
|
31
|
-
const remove = await confirm({
|
|
32
|
-
message: 'Remove it?',
|
|
33
|
-
default: false,
|
|
34
|
-
})
|
|
35
|
-
if (!remove) continue
|
|
36
|
-
try {
|
|
37
|
-
tui.action(`Removing directory ${dir}`)
|
|
38
|
-
await rm(dir, { recursive: true, force: true })
|
|
39
|
-
} catch (err) {
|
|
40
|
-
tui.warning(`Failed to remove directory ${dir}. Please try again.`)
|
|
41
|
-
continue
|
|
42
|
-
}
|
|
43
|
-
tui.success(`Removed directory ${dir}`)
|
|
44
|
-
}
|
|
45
|
-
if (!dir.endsWith('.pbm')) {
|
|
46
|
-
tui.warning("The output directory must end with the '.pbm' extension. Please try again.")
|
|
47
|
-
dir += '.pbm'
|
|
48
|
-
continue
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
await mkdir(dir, { recursive: true })
|
|
52
|
-
} catch (err) {
|
|
53
|
-
tui.warning(`Failed to create directory ${dir}. Please try again.`)
|
|
54
|
-
continue
|
|
55
|
-
}
|
|
56
|
-
tui.success(`Created directory ${dir}`)
|
|
57
|
-
return dir
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const create = new Command('create')
|
|
62
|
-
.description('Create a new problem')
|
|
63
|
-
|
|
64
|
-
.action(async () => {
|
|
65
|
-
tui.title('Create new problem')
|
|
66
|
-
const outputDir = await selectOutputDir()
|
|
67
|
-
const method = await selectMethod()
|
|
68
|
-
if (method === 'template') {
|
|
69
|
-
await createProblemWithTemplate(outputDir)
|
|
70
|
-
} else if (method === 'wizard') {
|
|
71
|
-
await createProblemWithWizard(outputDir)
|
|
72
|
-
} else if (method === 'jutgeAI') {
|
|
73
|
-
await createProblemWithJutgeAI(outputDir)
|
|
74
|
-
}
|
|
75
|
-
})
|
package/toolkit/doctor.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as doc from '@/lib/doctor'
|
|
2
|
-
import { Command } from '@commander-js/extra-typings'
|
|
3
|
-
import * as tui from '@/lib/tui.js'
|
|
4
|
-
|
|
5
|
-
export const doctor = new Command('doctor')
|
|
6
|
-
.description('Diagnose and fix common issues with the project setup')
|
|
7
|
-
|
|
8
|
-
.action(async () => {
|
|
9
|
-
tui.title('Doctor')
|
|
10
|
-
|
|
11
|
-
await tui.section('Checking Python3 installation', doc.checkPython3)
|
|
12
|
-
await tui.section('Checking C/C++ installation', doc.checkGCC)
|
|
13
|
-
await tui.section('Checking LaTeX installation', doc.checkLaTeX)
|
|
14
|
-
await tui.section('Checking Pandoc installation', doc.checkPandoc)
|
|
15
|
-
await tui.section('Checking ImageMagick installation', doc.checkImageMagick)
|
|
16
|
-
await tui.section('Checking environment variables', doc.checkEnvVars)
|
|
17
|
-
})
|
package/toolkit/init.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { decompressAssets } from '@/lib/assets'
|
|
2
|
-
import { initializePaths, loadSettings, paths, saveSettings, settingsExist } from '@/lib/settings'
|
|
3
|
-
import { guessUserEmail, guessUserName } from '@/lib/utils'
|
|
4
|
-
import { Command } from '@commander-js/extra-typings'
|
|
5
|
-
import { input, select } from '@inquirer/prompts'
|
|
6
|
-
import chalk from 'chalk'
|
|
7
|
-
import * as tui from '@/lib/tui.js'
|
|
8
|
-
|
|
9
|
-
async function initialize() {
|
|
10
|
-
await tui.section('Initialize', async () => {
|
|
11
|
-
let name = (await guessUserName()) || 'John Doe'
|
|
12
|
-
let email = (await guessUserEmail()) || 'john.doe@example.com'
|
|
13
|
-
name = await input({ message: 'What is your name?', default: name })
|
|
14
|
-
email = await input({ message: 'What is your email?', default: email })
|
|
15
|
-
const notifications = true
|
|
16
|
-
|
|
17
|
-
await initializePaths()
|
|
18
|
-
await saveSettings({ name, email, notifications })
|
|
19
|
-
|
|
20
|
-
tui.success('Settings created')
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function configure() {
|
|
25
|
-
await tui.section('Configure', async () => {
|
|
26
|
-
const settings = await loadSettings()
|
|
27
|
-
|
|
28
|
-
const name = await input({ message: 'What is your name?', default: settings.name })
|
|
29
|
-
const email = await input({ message: 'What is your email?', default: settings.email })
|
|
30
|
-
const notificationsInput = await select({
|
|
31
|
-
message: 'Enable notifications?',
|
|
32
|
-
choices: [
|
|
33
|
-
{ name: 'Yes', value: 'yes' },
|
|
34
|
-
{ name: 'No', value: 'no' },
|
|
35
|
-
],
|
|
36
|
-
default: settings.notifications ? 'yes' : 'no',
|
|
37
|
-
})
|
|
38
|
-
const notifications = notificationsInput === 'yes'
|
|
39
|
-
|
|
40
|
-
await saveSettings({ name, email, notifications })
|
|
41
|
-
|
|
42
|
-
tui.success('Settings updated')
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const init = new Command('init')
|
|
47
|
-
.description('Initialize/configure the toolkit')
|
|
48
|
-
|
|
49
|
-
.action(async () => {
|
|
50
|
-
if (await settingsExist()) {
|
|
51
|
-
await configure()
|
|
52
|
-
} else {
|
|
53
|
-
await initialize()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
await decompressAssets()
|
|
57
|
-
|
|
58
|
-
await tui.section('Directories', async () => {
|
|
59
|
-
await Bun.sleep(0) // hide lint warning
|
|
60
|
-
console.log('config:', chalk.magenta(paths.config))
|
|
61
|
-
console.log('data: ', chalk.magenta(paths.data))
|
|
62
|
-
console.log('cache: ', chalk.magenta(paths.cache))
|
|
63
|
-
console.log('log: ', chalk.magenta(paths.log))
|
|
64
|
-
console.log('temp: ', chalk.magenta(paths.temp))
|
|
65
|
-
})
|
|
66
|
-
})
|
package/toolkit/make.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { newMaker, type MakerOptions } from '@/lib/maker'
|
|
2
|
-
import { Command } from '@commander-js/extra-typings'
|
|
3
|
-
|
|
4
|
-
export const make = new Command('make')
|
|
5
|
-
.description('Make problem components')
|
|
6
|
-
// Add common options here
|
|
7
|
-
.option('-d, --directory <path>', 'problem directory', process.cwd()) // TODO: use '.' when bun fixes it
|
|
8
|
-
.option('-v, --verbose', 'verbose output (TODO)')
|
|
9
|
-
|
|
10
|
-
.action(async (options) => {
|
|
11
|
-
const maker = await newMaker(options)
|
|
12
|
-
await maker.makeProblem()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
make.command('problem')
|
|
16
|
-
.description('Make problem (default)')
|
|
17
|
-
.action(async (options, command) => {
|
|
18
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
19
|
-
const maker = await newMaker(parentOptions)
|
|
20
|
-
await maker.makeProblem()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
make.command('inspection')
|
|
24
|
-
.description('Make inspection')
|
|
25
|
-
.action(async (options, command) => {
|
|
26
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
27
|
-
const maker = await newMaker(parentOptions)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
make.command('executables')
|
|
31
|
-
.description('Make executables')
|
|
32
|
-
.action(async (options, command) => {
|
|
33
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
34
|
-
const maker = await newMaker(parentOptions)
|
|
35
|
-
await maker.makeExecutables()
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
make.command('corrects')
|
|
39
|
-
.description('Make corrects')
|
|
40
|
-
.action(async (options, command) => {
|
|
41
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
42
|
-
const maker = await newMaker(parentOptions)
|
|
43
|
-
await maker.makeCorrects()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
make.command('pdf')
|
|
47
|
-
.description('Make PDF statements')
|
|
48
|
-
.action(async (options, command) => {
|
|
49
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
50
|
-
const maker = await newMaker(parentOptions)
|
|
51
|
-
await maker.makePdfs()
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
make.command('text')
|
|
55
|
-
.description('Make text statements (HTML, TXT, MD)')
|
|
56
|
-
.action(async (options, command) => {
|
|
57
|
-
const parentOptions = (command.parent?.opts() || {}) as any as MakerOptions
|
|
58
|
-
const maker = await newMaker(parentOptions)
|
|
59
|
-
await maker.makeTexts()
|
|
60
|
-
})
|
package/toolkit/verify.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Command } from '@commander-js/extra-typings'
|
|
2
|
-
import { newMaker, type MakerOptions } from '@/lib/maker'
|
|
3
|
-
import { normalize } from 'path'
|
|
4
|
-
|
|
5
|
-
export const verify = new Command('verify')
|
|
6
|
-
.description('Verify candidate programs')
|
|
7
|
-
// Add common options here
|
|
8
|
-
|
|
9
|
-
.argument('<programs...>', 'source programs to verify')
|
|
10
|
-
.option('-d, --directory <path>', 'problem directory', process.cwd()) // TODO: use '.' when bun fixes it
|
|
11
|
-
.option('-v, --verbose', 'verbose output (TODO)')
|
|
12
|
-
|
|
13
|
-
.action(async (programs, { directory, verbose }) => {
|
|
14
|
-
directory = normalize(directory)
|
|
15
|
-
const maker = await newMaker({ verbose, directory })
|
|
16
|
-
for (const program of programs) {
|
|
17
|
-
await maker.verifyCandidate(program)
|
|
18
|
-
}
|
|
19
|
-
})
|
package/tsconfig.json
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Environment setup & latest features
|
|
4
|
-
"lib": ["ESNext"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "Preserve",
|
|
7
|
-
"moduleDetection": "force",
|
|
8
|
-
"jsx": "react-jsx",
|
|
9
|
-
"allowJs": true,
|
|
10
|
-
|
|
11
|
-
// Bundler mode
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"allowImportingTsExtensions": true,
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
// Best practices
|
|
18
|
-
"strict": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
"noImplicitOverride": true,
|
|
23
|
-
|
|
24
|
-
// Some stricter flags (disabled by default)
|
|
25
|
-
"noUnusedLocals": false,
|
|
26
|
-
"noUnusedParameters": false,
|
|
27
|
-
"noPropertyAccessFromIndexSignature": false,
|
|
28
|
-
|
|
29
|
-
// Path aliases
|
|
30
|
-
"baseUrl": ".",
|
|
31
|
-
"paths": {
|
|
32
|
-
"@/*": ["*"]
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
// Types
|
|
36
|
-
"types": ["bun-types"]
|
|
37
|
-
}
|
|
38
|
-
}
|
package/types/zip.d.ts
DELETED