@dodona/papyros 1.0.0 → 2.0.0-beta.0
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/LICENSE +0 -0
- package/README.md +0 -0
- package/dist/App.d.ts +1 -1
- package/dist/App.js +73 -0
- package/dist/App.js.map +1 -0
- package/dist/Backend.d.ts +0 -48
- package/dist/Backend.js +76 -0
- package/dist/Backend.js.map +1 -0
- package/dist/BackendEvent.d.ts +0 -0
- package/dist/BackendEvent.js +24 -0
- package/dist/BackendEvent.js.map +1 -0
- package/dist/BackendEventQueue.d.ts +0 -0
- package/dist/BackendEventQueue.js +135 -0
- package/dist/BackendEventQueue.js.map +1 -0
- package/dist/BackendManager.d.ts +1 -1
- package/dist/BackendManager.js +94 -0
- package/dist/BackendManager.js.map +1 -0
- package/dist/CodeRunner.d.ts +0 -0
- package/dist/CodeRunner.js +372 -0
- package/dist/CodeRunner.js.map +1 -0
- package/dist/Constants.d.ts +0 -0
- package/dist/Constants.js +36 -0
- package/dist/Constants.js.map +1 -0
- package/dist/InputManager.d.ts +0 -0
- package/dist/InputManager.js +102 -0
- package/dist/InputManager.js.map +1 -0
- package/dist/InputServiceWorker.d.ts +0 -0
- package/dist/InputServiceWorker.js +37 -0
- package/dist/InputServiceWorker.js.map +1 -0
- package/dist/Library.d.ts +2 -2
- package/dist/Library.js +9 -1
- package/dist/Library.js.map +1 -0
- package/dist/OutputManager.d.ts +0 -0
- package/dist/OutputManager.js +161 -0
- package/dist/OutputManager.js.map +1 -0
- package/dist/Papyros.css +563 -0
- package/dist/Papyros.d.ts +0 -1
- package/dist/Papyros.js +268 -0
- package/dist/Papyros.js.map +1 -0
- package/dist/ProgrammingLanguage.d.ts +0 -0
- package/dist/ProgrammingLanguage.js +9 -0
- package/dist/ProgrammingLanguage.js.map +1 -0
- package/dist/Translations.d.ts +74 -74
- package/dist/Translations.js +164 -0
- package/dist/Translations.js.map +1 -0
- package/dist/editor/BatchInputEditor.d.ts +0 -0
- package/dist/editor/BatchInputEditor.js +71 -0
- package/dist/editor/BatchInputEditor.js.map +1 -0
- package/dist/editor/CodeEditor.d.ts +0 -5
- package/dist/editor/CodeEditor.js +180 -0
- package/dist/editor/CodeEditor.js.map +1 -0
- package/dist/editor/CodeMirrorEditor.d.ts +0 -0
- package/dist/editor/CodeMirrorEditor.js +168 -0
- package/dist/editor/CodeMirrorEditor.js.map +1 -0
- package/dist/editor/DarkTheme.d.ts +0 -0
- package/dist/editor/DarkTheme.js +73 -0
- package/dist/editor/DarkTheme.js.map +1 -0
- package/dist/editor/Gutters.d.ts +0 -0
- package/dist/editor/Gutters.js +162 -0
- package/dist/editor/Gutters.js.map +1 -0
- package/dist/examples/Examples.d.ts +0 -0
- package/dist/examples/Examples.js +23 -0
- package/dist/examples/Examples.js.map +1 -0
- package/dist/examples/JavaScriptExamples.d.ts +0 -0
- package/dist/examples/JavaScriptExamples.js +16 -0
- package/dist/examples/JavaScriptExamples.js.map +1 -0
- package/dist/examples/PythonExamples.d.ts +0 -0
- package/dist/examples/PythonExamples.js +163 -0
- package/dist/examples/PythonExamples.js.map +1 -0
- package/dist/input/BatchInputHandler.d.ts +0 -0
- package/dist/input/BatchInputHandler.js +112 -0
- package/dist/input/BatchInputHandler.js.map +1 -0
- package/dist/input/InteractiveInputHandler.d.ts +0 -0
- package/dist/input/InteractiveInputHandler.js +90 -0
- package/dist/input/InteractiveInputHandler.js.map +1 -0
- package/dist/input/UserInputHandler.d.ts +0 -0
- package/dist/input/UserInputHandler.js +40 -0
- package/dist/input/UserInputHandler.js.map +1 -0
- package/dist/util/HTMLShapes.d.ts +0 -0
- package/dist/util/HTMLShapes.js +25 -0
- package/dist/util/HTMLShapes.js.map +1 -0
- package/dist/util/Logging.d.ts +0 -0
- package/dist/util/Logging.js +30 -0
- package/dist/util/Logging.js.map +1 -0
- package/dist/util/Rendering.d.ts +0 -0
- package/dist/util/Rendering.js +139 -0
- package/dist/util/Rendering.js.map +1 -0
- package/dist/util/Util.d.ts +1 -1
- package/dist/util/Util.js +148 -0
- package/dist/util/Util.js.map +1 -0
- package/dist/workers/input/InputWorker.d.ts +0 -0
- package/dist/workers/input/InputWorker.js +63 -1
- package/dist/workers/input/InputWorker.js.map +1 -0
- package/dist/workers/javascript/JavaScriptWorker.d.ts +39 -0
- package/dist/workers/javascript/JavaScriptWorker.js +148 -0
- package/dist/workers/javascript/JavaScriptWorker.js.map +1 -0
- package/dist/workers/javascript/worker.d.ts +1 -0
- package/dist/workers/javascript/worker.js +5 -0
- package/dist/workers/javascript/worker.js.map +1 -0
- package/dist/workers/python/PythonWorker.d.ts +31 -0
- package/dist/workers/python/PythonWorker.js +106 -0
- package/dist/workers/python/PythonWorker.js.map +1 -0
- package/dist/workers/python/python_package.tar.gz +0 -0
- package/dist/workers/python/worker.d.ts +1 -0
- package/dist/workers/python/worker.js +5 -0
- package/dist/workers/python/worker.js.map +1 -0
- package/package.json +45 -42
- package/dist/workers/javascript/JavaScriptWorker.worker.d.ts +0 -2
- package/dist/workers/python/PythonWorker.worker.d.ts +0 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Backend } from "../../Backend";
|
|
11
|
+
import { BackendEventType } from "../../BackendEvent";
|
|
12
|
+
/**
|
|
13
|
+
* Implementation of a JavaScript backend for Papyros
|
|
14
|
+
* by using eval and overriding some builtins
|
|
15
|
+
*/
|
|
16
|
+
export class JavaScriptWorker extends Backend {
|
|
17
|
+
/**
|
|
18
|
+
* Convert varargs to a string, similar to how the console does it
|
|
19
|
+
* @param {any[]} args The values to join into a string
|
|
20
|
+
* @return {string} The string representation
|
|
21
|
+
*/
|
|
22
|
+
static stringify(...args) {
|
|
23
|
+
const asString = args.map(a => {
|
|
24
|
+
if (Array.isArray(a)) {
|
|
25
|
+
return JSON.stringify(a);
|
|
26
|
+
}
|
|
27
|
+
else if (typeof (a) === "string") {
|
|
28
|
+
return a;
|
|
29
|
+
}
|
|
30
|
+
else if (typeof a === "number") {
|
|
31
|
+
return a + "";
|
|
32
|
+
}
|
|
33
|
+
else if (typeof (a) === "object" && "toString" in a) {
|
|
34
|
+
let aString = a.toString();
|
|
35
|
+
if (aString === "[object Object]") { // useless toString, so use JSON
|
|
36
|
+
aString = JSON.stringify(a);
|
|
37
|
+
}
|
|
38
|
+
return aString;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return JSON.stringify(args);
|
|
42
|
+
}
|
|
43
|
+
}).join(" ");
|
|
44
|
+
return asString;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Prompt the user for input with a message
|
|
48
|
+
* @param {string} text The message to show when asking for input
|
|
49
|
+
* @return {string} The value the user gave
|
|
50
|
+
*/
|
|
51
|
+
prompt(text = "") {
|
|
52
|
+
return this.onEvent({
|
|
53
|
+
type: BackendEventType.Input,
|
|
54
|
+
data: text,
|
|
55
|
+
contentType: "text/plain"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Print values to the output screen
|
|
60
|
+
* @param {any[]} args The values to log
|
|
61
|
+
*/
|
|
62
|
+
consoleLog(...args) {
|
|
63
|
+
this.queue.put(BackendEventType.Output, JavaScriptWorker.stringify(...args) + "\n", "text/plain");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Print values to the error screen
|
|
67
|
+
* @param {any[]} args The error values to log
|
|
68
|
+
*/
|
|
69
|
+
consoleError(...args) {
|
|
70
|
+
this.queue.put(BackendEventType.Error, JavaScriptWorker.stringify(...args) + "\n", "text/plain");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Helper method to generate suggestions based on properties in an object
|
|
74
|
+
* @param {number} from Where in the document the autocompletion starts
|
|
75
|
+
* @param {any} object Object with properties that might be relevant
|
|
76
|
+
* @return {CompletionResult} Autocompletion suggestions
|
|
77
|
+
*/
|
|
78
|
+
static completeProperties(from, object) {
|
|
79
|
+
const options = Object.keys(object).map(name => {
|
|
80
|
+
return {
|
|
81
|
+
label: name,
|
|
82
|
+
type: typeof object[name] === "function" ? "function" : "variable"
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
from,
|
|
87
|
+
options,
|
|
88
|
+
validFor: /^[\w$]*$/
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
runCode(extras, code) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
this.extras = extras;
|
|
94
|
+
this.queue.reset();
|
|
95
|
+
// Builtins to store before execution and restore afterwards
|
|
96
|
+
// Workers do not have access to prompt
|
|
97
|
+
const oldContent = {
|
|
98
|
+
"console.log": console.log,
|
|
99
|
+
"console.error": console.error
|
|
100
|
+
};
|
|
101
|
+
// Overrides for the builtins
|
|
102
|
+
const newContext = {
|
|
103
|
+
"prompt": this.prompt.bind(this),
|
|
104
|
+
"console.log": this.consoleLog.bind(this),
|
|
105
|
+
"console.error": this.consoleError.bind(this)
|
|
106
|
+
};
|
|
107
|
+
// Override the builtins
|
|
108
|
+
new Function("ctx", Object.keys(newContext).map(k => `${k} = ctx['${k}'];`).join("\n"))(newContext);
|
|
109
|
+
let result = null;
|
|
110
|
+
try { // run the user's code
|
|
111
|
+
this.onEvent({
|
|
112
|
+
type: BackendEventType.Start,
|
|
113
|
+
contentType: "text/plain",
|
|
114
|
+
data: "RunCode"
|
|
115
|
+
});
|
|
116
|
+
result = yield eval(code);
|
|
117
|
+
}
|
|
118
|
+
catch (error) { // try to create a friendly traceback
|
|
119
|
+
Error.captureStackTrace(error);
|
|
120
|
+
result = yield this.onEvent({
|
|
121
|
+
type: BackendEventType.Error,
|
|
122
|
+
contentType: "application/json",
|
|
123
|
+
data: {
|
|
124
|
+
name: error.constructor.name,
|
|
125
|
+
what: error.message,
|
|
126
|
+
traceback: error.stack
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
finally { // restore the old builtins
|
|
131
|
+
new Function("ctx", Object.keys(oldContent).map(k => `${k} = ctx['${k}'];`).join("\n"))(oldContent);
|
|
132
|
+
this.queue.flush();
|
|
133
|
+
this.onEvent({
|
|
134
|
+
type: BackendEventType.End,
|
|
135
|
+
contentType: "text/plain",
|
|
136
|
+
data: "CodeFinished"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
lintCode() {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
return Promise.resolve([]);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=JavaScriptWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JavaScriptWorker.js","sourceRoot":"","sources":["../../../src/workers/javascript/JavaScriptWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/workers/javascript/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;AACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Backend, RunMode, WorkerDiagnostic } from "../../Backend";
|
|
2
|
+
import { BackendEvent } from "../../BackendEvent";
|
|
3
|
+
import { PyodideExtras } from "pyodide-worker-runner";
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of a Python backend for Papyros
|
|
6
|
+
* Powered by Pyodide (https://pyodide.org/)
|
|
7
|
+
*/
|
|
8
|
+
export declare class PythonWorker extends Backend<PyodideExtras> {
|
|
9
|
+
private pyodide;
|
|
10
|
+
private papyros;
|
|
11
|
+
/**
|
|
12
|
+
* Promise to asynchronously install imports needed by the code
|
|
13
|
+
*/
|
|
14
|
+
private installPromise;
|
|
15
|
+
constructor();
|
|
16
|
+
private static convert;
|
|
17
|
+
/**
|
|
18
|
+
* @return {any} Function to expose a method with Pyodide support
|
|
19
|
+
*/
|
|
20
|
+
protected syncExpose(): any;
|
|
21
|
+
private static getPyodide;
|
|
22
|
+
launch(onEvent: (e: BackendEvent) => void, onOverflow: () => void): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Helper method to install imports and prevent race conditions with double downloading
|
|
25
|
+
* @param {string} code The code containing import statements
|
|
26
|
+
*/
|
|
27
|
+
private installImports;
|
|
28
|
+
runModes(code: string): Array<RunMode>;
|
|
29
|
+
runCode(extras: PyodideExtras, code: string, mode?: string): Promise<any>;
|
|
30
|
+
lintCode(code: string): Promise<Array<WorkerDiagnostic>>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Backend } from "../../Backend";
|
|
11
|
+
import { pyodideExpose, loadPyodideAndPackage } from "pyodide-worker-runner";
|
|
12
|
+
/* eslint-disable-next-line */
|
|
13
|
+
const pythonPackageUrl = require("!!file-loader!./python_package.tar.gz").default;
|
|
14
|
+
/**
|
|
15
|
+
* Implementation of a Python backend for Papyros
|
|
16
|
+
* Powered by Pyodide (https://pyodide.org/)
|
|
17
|
+
*/
|
|
18
|
+
export class PythonWorker extends Backend {
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
this.pyodide = {};
|
|
22
|
+
this.papyros = {};
|
|
23
|
+
this.installPromise = null;
|
|
24
|
+
}
|
|
25
|
+
static convert(data) {
|
|
26
|
+
return data.toJs ? data.toJs({ dict_converter: Object.fromEntries }) : data;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @return {any} Function to expose a method with Pyodide support
|
|
30
|
+
*/
|
|
31
|
+
syncExpose() {
|
|
32
|
+
return pyodideExpose;
|
|
33
|
+
}
|
|
34
|
+
static getPyodide() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
return yield loadPyodideAndPackage({ url: pythonPackageUrl, format: ".tgz" });
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
launch(onEvent, onOverflow) {
|
|
40
|
+
const _super = Object.create(null, {
|
|
41
|
+
launch: { get: () => super.launch }
|
|
42
|
+
});
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
yield _super.launch.call(this, onEvent, onOverflow);
|
|
45
|
+
this.pyodide = yield PythonWorker.getPyodide();
|
|
46
|
+
// Python calls our function with a PyProxy dict or a Js Map,
|
|
47
|
+
// These must be converted to a PapyrosEvent (JS Object) to allow message passing
|
|
48
|
+
this.papyros = this.pyodide.pyimport("papyros").Papyros.callKwargs({
|
|
49
|
+
callback: (e) => {
|
|
50
|
+
const converted = PythonWorker.convert(e);
|
|
51
|
+
return this.onEvent(converted);
|
|
52
|
+
},
|
|
53
|
+
buffer_constructor: (cb) => {
|
|
54
|
+
this.queue.setCallback(cb);
|
|
55
|
+
return this.queue;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// preload micropip to allow installing packages
|
|
59
|
+
yield this.pyodide.loadPackage("micropip");
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Helper method to install imports and prevent race conditions with double downloading
|
|
64
|
+
* @param {string} code The code containing import statements
|
|
65
|
+
*/
|
|
66
|
+
installImports(code) {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
if (this.installPromise == null) {
|
|
69
|
+
this.installPromise = this.papyros.install_imports.callKwargs({
|
|
70
|
+
source_code: code,
|
|
71
|
+
ignore_missing: true
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
yield this.installPromise;
|
|
75
|
+
this.installPromise = null;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
runModes(code) {
|
|
79
|
+
const modes = super.runModes(code);
|
|
80
|
+
modes.push({
|
|
81
|
+
mode: "doctest",
|
|
82
|
+
active: this.papyros.has_doctests(code)
|
|
83
|
+
});
|
|
84
|
+
return modes;
|
|
85
|
+
}
|
|
86
|
+
runCode(extras, code, mode = "exec") {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
this.extras = extras;
|
|
89
|
+
if (extras.interruptBuffer) {
|
|
90
|
+
this.pyodide.setInterruptBuffer(extras.interruptBuffer);
|
|
91
|
+
}
|
|
92
|
+
yield this.installImports(code);
|
|
93
|
+
return yield this.papyros.run_async.callKwargs({
|
|
94
|
+
source_code: code,
|
|
95
|
+
mode: mode
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
lintCode(code) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
yield this.installImports(code);
|
|
102
|
+
return PythonWorker.convert(this.papyros.lint(code));
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=PythonWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PythonWorker.js","sourceRoot":"","sources":["../../../src/workers/python/PythonWorker.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/workers/python/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;AAClC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,61 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dodona/papyros",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"homepage": ".",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@types/escape-html": "^1.0.
|
|
8
|
-
"@types/i18n-js": "^3.8.
|
|
9
|
-
"@types/jest": "
|
|
10
|
-
"@types/serviceworker": "^0.0.
|
|
11
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
12
|
-
"@typescript-eslint/parser": "^
|
|
13
|
-
"autoprefixer": "^10.4.
|
|
14
|
-
"css-loader": "^6.
|
|
15
|
-
"eslint": "^8.
|
|
7
|
+
"@types/escape-html": "^1.0.3",
|
|
8
|
+
"@types/i18n-js": "^3.8.7",
|
|
9
|
+
"@types/jest": "^29.5.10",
|
|
10
|
+
"@types/serviceworker": "^0.0.79",
|
|
11
|
+
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
12
|
+
"@typescript-eslint/parser": "^6.9.0",
|
|
13
|
+
"autoprefixer": "^10.4.16",
|
|
14
|
+
"css-loader": "^6.8.1",
|
|
15
|
+
"eslint": "^8.52.0",
|
|
16
16
|
"eslint-config-google": "^0.14.0",
|
|
17
|
-
"eslint-plugin-jest": "^
|
|
17
|
+
"eslint-plugin-jest": "^27.6.0",
|
|
18
|
+
"file-loader": "^6.2.0",
|
|
18
19
|
"i18n-extract": "^0.6.7",
|
|
19
|
-
"jest": "
|
|
20
|
-
"
|
|
21
|
-
"postcss
|
|
22
|
-
"postcss-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"ts-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"webpack
|
|
32
|
-
"webpack-
|
|
20
|
+
"jest": "^29.7.0",
|
|
21
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
22
|
+
"postcss": "^8.4.31",
|
|
23
|
+
"postcss-import": "^15.1.0",
|
|
24
|
+
"postcss-loader": "^7.3.3",
|
|
25
|
+
"style-loader": "^3.3.3",
|
|
26
|
+
"tailwindcss": "^3.3.5",
|
|
27
|
+
"terser-webpack-plugin": "^5.3.9",
|
|
28
|
+
"ts-jest": "^29.1.1",
|
|
29
|
+
"ts-jest-mock-import-meta": "^1.1.0",
|
|
30
|
+
"ts-loader": "^9.5.0",
|
|
31
|
+
"typescript": "^5.2.2",
|
|
32
|
+
"webpack": "^5.89.0",
|
|
33
|
+
"webpack-cli": "^5.1.4",
|
|
34
|
+
"webpack-dev-server": "^4.15.1",
|
|
33
35
|
"worker-loader": "^3.0.8"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@codemirror/autocomplete": "^6.
|
|
37
|
-
"@codemirror/commands": "^6.
|
|
38
|
-
"@codemirror/lang-javascript": "^6.
|
|
39
|
-
"@codemirror/lang-python": "^6.
|
|
40
|
-
"@codemirror/language": "^6.
|
|
41
|
-
"@codemirror/lint": "^6.
|
|
42
|
-
"@codemirror/search": "^6.
|
|
43
|
-
"@codemirror/state": "^6.
|
|
44
|
-
"@codemirror/theme-one-dark": "^6.
|
|
45
|
-
"@codemirror/view": "^6.
|
|
46
|
-
"@lezer/common": "^1.
|
|
47
|
-
"comlink": "^4.
|
|
48
|
-
"comsync": "^0.0.
|
|
38
|
+
"@codemirror/autocomplete": "^6.11.1",
|
|
39
|
+
"@codemirror/commands": "^6.3.1",
|
|
40
|
+
"@codemirror/lang-javascript": "^6.2.1",
|
|
41
|
+
"@codemirror/lang-python": "^6.1.3",
|
|
42
|
+
"@codemirror/language": "^6.9.3",
|
|
43
|
+
"@codemirror/lint": "^6.4.2",
|
|
44
|
+
"@codemirror/search": "^6.5.4",
|
|
45
|
+
"@codemirror/state": "^6.3.2",
|
|
46
|
+
"@codemirror/theme-one-dark": "^6.1.2",
|
|
47
|
+
"@codemirror/view": "^6.22.1",
|
|
48
|
+
"@lezer/common": "^1.1.0",
|
|
49
|
+
"comlink": "^4.4.1",
|
|
50
|
+
"comsync": "^0.0.9",
|
|
49
51
|
"escape-html": "^1.0.3",
|
|
50
52
|
"i18n-js": "^3.8.0",
|
|
51
|
-
"pyodide
|
|
52
|
-
"
|
|
53
|
+
"pyodide": "^0.22.0",
|
|
54
|
+
"pyodide-worker-runner": "1.3.2",
|
|
55
|
+
"sync-message": "^0.0.12"
|
|
53
56
|
},
|
|
54
57
|
"scripts": {
|
|
55
58
|
"start": "webpack serve --mode development",
|
|
56
59
|
"setup": "bash scripts/setup.sh",
|
|
57
|
-
"build:app": "bash scripts/
|
|
58
|
-
"build:library": "bash scripts/
|
|
60
|
+
"build:app": "bash scripts/build.sh development",
|
|
61
|
+
"build:library": "bash scripts/build_library.sh",
|
|
59
62
|
"test": "jest",
|
|
60
63
|
"lint": "eslint --ext '.js' --ext '.ts' src",
|
|
61
64
|
"validate:translations": "node scripts/ValidateTranslations.js"
|