mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
bug fixes
This commit is contained in:
18 files changed
+70
-52
No files matched your search
@@ -4,12 +4,12 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "base.mjs",
|
"main": "base.mjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/eslint-plugin": "^1.37.3",
|
"@eslint-react/eslint-plugin": "^1.38.2",
|
||||||
"@eslint/compat": "^1.2.7",
|
"@eslint/compat": "^1.2.7",
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
"@stylistic/eslint-plugin": "^4.2.0",
|
"@stylistic/eslint-plugin": "^4.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.27.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-plugin-de-morgan": "^1.2.1",
|
"eslint-plugin-de-morgan": "^1.2.1",
|
||||||
"eslint-plugin-github": "^6.0.0",
|
"eslint-plugin-github": "^6.0.0",
|
||||||
|
|||||||
+3
-3
@@ -36,7 +36,7 @@
|
|||||||
"@types/chai": "^5.2.1",
|
"@types/chai": "^5.2.1",
|
||||||
"@types/cross-spawn": "^6.0.6",
|
"@types/cross-spawn": "^6.0.6",
|
||||||
"@types/node": "22.13.8",
|
"@types/node": "22.13.8",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.7.0",
|
||||||
"autocannon": "^8.0.0",
|
"autocannon": "^8.0.0",
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
"chai": "^5.2.0",
|
"chai": "^5.2.0",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"cross-spawn": "^7.0.6",
|
"cross-spawn": "^7.0.6",
|
||||||
"esbuild": "0.25.0",
|
"esbuild": "0.25.0",
|
||||||
"eslint": "^9.23.0",
|
"eslint": "^9.23.0",
|
||||||
"eslint-import-resolver-typescript": "^4.2.2",
|
"eslint-import-resolver-typescript": "^4.2.5",
|
||||||
"eslint-import-resolver-webpack": "^0.13.10",
|
"eslint-import-resolver-webpack": "^0.13.10",
|
||||||
"fs-extra": "^11.3.0",
|
"fs-extra": "^11.3.0",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"mongodb-memory-server": "10.1.4",
|
"mongodb-memory-server": "10.1.4",
|
||||||
"nyc": "^17.1.0",
|
"nyc": "^17.1.0",
|
||||||
"ora": "^8.2.0",
|
"ora": "^8.2.0",
|
||||||
"oxlint": "^0.16.2",
|
"oxlint": "^0.16.3",
|
||||||
"package-json": "^10.0.1",
|
"package-json": "^10.0.1",
|
||||||
"semver": "^7.7.1",
|
"semver": "^7.7.1",
|
||||||
"simple-git": "^3.27.0",
|
"simple-git": "^3.27.0",
|
||||||
|
|||||||
@@ -42,9 +42,16 @@ function MonacoContainer({
|
|||||||
editor.layout();
|
editor.layout();
|
||||||
}, [size]);
|
}, [size]);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!editor) return;
|
if (!editor || !model) return;
|
||||||
|
const decoration = editor.createDecorationsCollection();
|
||||||
|
const updateDecoration = () => {
|
||||||
|
const found = model.findMatches("'[hidden]'", true, false, true, '', true).map((i) => i.range);
|
||||||
|
decoration.set(found.map((range) => ({ range, options: { inlineClassName: 'decoration-hide' } })));
|
||||||
|
};
|
||||||
|
updateDecoration();
|
||||||
const disposable = editor.onDidChangeModelContent(() => {
|
const disposable = editor.onDidChangeModelContent(() => {
|
||||||
const val = editor.getValue({ lineEnding: '\n', preserveBOM: false });
|
const val = editor.getValue({ lineEnding: '\n', preserveBOM: false });
|
||||||
|
updateDecoration();
|
||||||
try {
|
try {
|
||||||
const loaded = yaml.load(val);
|
const loaded = yaml.load(val);
|
||||||
schema(loaded);
|
schema(loaded);
|
||||||
@@ -55,7 +62,7 @@ function MonacoContainer({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () => disposable.dispose(); // eslint-disable-line
|
return () => disposable.dispose(); // eslint-disable-line
|
||||||
}, [editor, setValue, setError]);
|
}, [editor, model, setValue, setError]);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!editorRef.current || loading) return;
|
if (!editorRef.current || loading) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { omit } from 'lodash';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function DomComponent(props: React.HTMLAttributes<HTMLDivElement> & { childDom: HTMLElement }) {
|
||||||
|
const [dom, setDom] = React.useState<HTMLElement | null>(null);
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!dom) return;
|
||||||
|
dom.appendChild(props.childDom);
|
||||||
|
return () => { // eslint-disable-line consistent-return
|
||||||
|
dom.removeChild(props.childDom);
|
||||||
|
};
|
||||||
|
}, [dom]);
|
||||||
|
return <div {...omit(props, 'childDom')} ref={setDom}></div>;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ToastContainer } from 'react-toastify';
|
import { Slide, ToastContainer } from 'react-toastify';
|
||||||
|
|
||||||
interface C {
|
interface C {
|
||||||
i18n: (key: string, ...args: any[]) => string;
|
i18n: (key: string, ...args: any[]) => string;
|
||||||
@@ -19,14 +19,15 @@ export default function ComponentsProvider(props: { children: React.ReactNode }
|
|||||||
<ToastContainer
|
<ToastContainer
|
||||||
position="bottom-left"
|
position="bottom-left"
|
||||||
autoClose={5000}
|
autoClose={5000}
|
||||||
hideProgressBar={false}
|
hideProgressBar
|
||||||
newestOnTop={false}
|
newestOnTop={false}
|
||||||
closeOnClick={false}
|
closeOnClick={false}
|
||||||
rtl={false}
|
rtl={false}
|
||||||
pauseOnFocusLoss
|
pauseOnFocusLoss
|
||||||
draggable
|
draggable
|
||||||
pauseOnHover
|
pauseOnHover
|
||||||
theme={props.theme}
|
theme="colored"
|
||||||
|
transition={Slide}
|
||||||
/>
|
/>
|
||||||
{props.children}
|
{props.children}
|
||||||
</ComponentsContext.Provider>;
|
</ComponentsContext.Provider>;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/adm-zip": "^0.4.34",
|
"@types/adm-zip": "^0.5.7",
|
||||||
"@types/shell-quote": "^1.7.5",
|
"@types/shell-quote": "^1.7.5",
|
||||||
"@types/ws": "^8.18.0"
|
"@types/ws": "^8.18.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@babel/code-frame": "^7.26.2",
|
||||||
"@types/adm-zip": "^0.4.34",
|
"@types/adm-zip": "^0.5.7",
|
||||||
"@types/babel__code-frame": "^7.0.6",
|
"@types/babel__code-frame": "^7.0.6",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
"@types/notp": "^2.0.5",
|
"@types/notp": "^2.0.5",
|
||||||
"@types/saslprep": "^1.0.3",
|
"@types/saslprep": "^1.0.3",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.7.0",
|
||||||
"@types/superagent": "^8.1.9",
|
"@types/superagent": "^8.1.9",
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"moment": "^2.30.1"
|
"moment": "^2.30.1"
|
||||||
|
|||||||
@@ -117,15 +117,17 @@ export async function load(ctx: Context) {
|
|||||||
resolve(c);
|
resolve(c);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
await ctx.loader.reloadPlugin(require.resolve('../service/storage'), 'file');
|
await Promise.all([
|
||||||
|
ctx.loader.reloadPlugin(require.resolve('../service/storage'), 'file'),
|
||||||
|
ctx.loader.reloadPlugin(require.resolve('../service/worker'), 'worker'),
|
||||||
|
ctx.loader.reloadPlugin(require.resolve('../service/server'), 'server'),
|
||||||
|
]);
|
||||||
require('../lib/index');
|
require('../lib/index');
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
service(pending, fail, ctx),
|
service(pending, fail, ctx),
|
||||||
]);
|
]);
|
||||||
ctx.plugin(require('../service/worker'));
|
|
||||||
await builtinModel(ctx);
|
await builtinModel(ctx);
|
||||||
await model(pending, fail, ctx);
|
await model(pending, fail, ctx);
|
||||||
ctx.plugin(require('../service/server'));
|
|
||||||
ctx = await new Promise((resolve) => {
|
ctx = await new Promise((resolve) => {
|
||||||
ctx.inject(['server', 'setting', 'worker'], (c) => {
|
ctx.inject(['server', 'setting', 'worker'], (c) => {
|
||||||
resolve(c);
|
resolve(c);
|
||||||
|
|||||||
@@ -110,9 +110,12 @@ export class Loader extends Service {
|
|||||||
if (!plugin) return;
|
if (!plugin) return;
|
||||||
const config = await this.resolveConfig(plugin, configScope);
|
const config = await this.resolveConfig(plugin, configScope);
|
||||||
let fork = this.state[key];
|
let fork = this.state[key];
|
||||||
|
const displayPath = key.includes('node_modules')
|
||||||
|
? key.split('node_modules').pop()
|
||||||
|
: path.relative(process.cwd(), key);
|
||||||
logger.info(
|
logger.info(
|
||||||
`%s plugin %c${configScope ? ' with scope %c' : ''}`,
|
`%s plugin %c${configScope ? ' with scope %c' : ''}`,
|
||||||
fork ? 'reload' : 'apply', key.split('node_modules').pop(), configScope,
|
fork ? 'reload' : 'apply', displayPath, configScope,
|
||||||
);
|
);
|
||||||
if (fork) {
|
if (fork) {
|
||||||
fork.update(config);
|
fork.update(config);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import path from 'path';
|
|||||||
import AdmZip from 'adm-zip';
|
import AdmZip from 'adm-zip';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { pick } from 'lodash';
|
import { keyBy, pick } from 'lodash';
|
||||||
import { Filter, ObjectId } from 'mongodb';
|
import { Filter, ObjectId } from 'mongodb';
|
||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
import { ProblemConfigFile, ProblemType } from '@hydrooj/common';
|
import { ProblemConfigFile, ProblemType } from '@hydrooj/common';
|
||||||
@@ -409,12 +409,7 @@ export class ProblemModel {
|
|||||||
const psdocs = await ProblemModel.getMultiStatus(
|
const psdocs = await ProblemModel.getMultiStatus(
|
||||||
domainId, { uid, docId: { $in: Array.from(new Set(pids)) } },
|
domainId, { uid, docId: { $in: Array.from(new Set(pids)) } },
|
||||||
).toArray();
|
).toArray();
|
||||||
const r: Record<string, ProblemStatusDoc> = {};
|
return keyBy(psdocs, 'docId');
|
||||||
for (const psdoc of psdocs) {
|
|
||||||
r[psdoc.docId] = psdoc;
|
|
||||||
r[`${psdoc.domainId}#${psdoc.docId}`] = psdoc;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async updateStatus(
|
static async updateStatus(
|
||||||
@@ -468,7 +463,7 @@ export class ProblemModel {
|
|||||||
throw new ValidationError('zip', null, e.message);
|
throw new ValidationError('zip', null, e.message);
|
||||||
}
|
}
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
zip.extractAllToAsync(tmpdir, true, (err) => {
|
zip.extractAllToAsync(tmpdir, true, false, (err) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
resolve(null);
|
resolve(null);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ export default class RecordModel {
|
|||||||
RecordModel.collStat.deleteMany({ _id: { $in: rids } }),
|
RecordModel.collStat.deleteMany({ _id: { $in: rids } }),
|
||||||
task.deleteMany({ rid: { $in: rids } }),
|
task.deleteMany({ rid: { $in: rids } }),
|
||||||
]);
|
]);
|
||||||
await RecordModel.collHistory.insertMany(rdocs.map((rdoc) => ({
|
await RecordModel.collHistory.insertMany(rdocs.filter((rdoc) => rdoc.judgeAt).map((rdoc) => ({
|
||||||
...pick(rdoc, [
|
...pick(rdoc, [
|
||||||
'compilerTexts', 'judgeTexts', 'testCases', 'subtasks',
|
'compilerTexts', 'judgeTexts', 'testCases', 'subtasks',
|
||||||
'score', 'time', 'memory', 'status', 'judgeAt', 'judger',
|
'score', 'time', 'memory', 'status', 'judgeAt', 'judger',
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ async function cleanFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apply(ctx: Context) {
|
export async function apply(ctx: Context) {
|
||||||
ctx.inject(['worker'], (c) => {
|
ctx.inject(['worker'], (c) => {
|
||||||
c.worker.addHandler('storage.prune', cleanFiles);
|
c.worker.addHandler('storage.prune', cleanFiles);
|
||||||
});
|
});
|
||||||
@@ -190,9 +190,7 @@ export function apply(ctx: Context) {
|
|||||||
]);
|
]);
|
||||||
await StorageModel.del(problemFiles.concat(contestFiles).concat(trainingFiles).map((i) => i.path));
|
await StorageModel.del(problemFiles.concat(contestFiles).concat(trainingFiles).map((i) => i.path));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.NODE_APP_INSTANCE !== '0') return;
|
if (process.env.NODE_APP_INSTANCE !== '0') return;
|
||||||
ctx.on('ready', async () => {
|
|
||||||
await db.ensureIndexes(
|
await db.ensureIndexes(
|
||||||
StorageModel.coll,
|
StorageModel.coll,
|
||||||
{ key: { path: 1 }, name: 'path' },
|
{ key: { path: 1 }, name: 'path' },
|
||||||
@@ -207,7 +205,6 @@ export function apply(ctx: Context) {
|
|||||||
interval: [1, 'hour'],
|
interval: [1, 'hour'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.model.storage = StorageModel;
|
global.Hydro.model.storage = StorageModel;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export class MongoService extends Service {
|
|||||||
yield () => { this.client.close(); };
|
yield () => { this.client.close(); };
|
||||||
this.db = this.client.db(url.database || 'hydro');
|
this.db = this.client.db(url.database || 'hydro');
|
||||||
await bus.parallel('database/connect', this.db);
|
await bus.parallel('database/connect', this.db);
|
||||||
this.ctx.setInterval(() => this.fixExpireAfter(), Time.hour);
|
yield this.ctx.setInterval(() => this.fixExpireAfter(), Time.hour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public collection<K extends keyof Collections>(c: K) {
|
public collection<K extends keyof Collections>(c: K) {
|
||||||
|
|||||||
@@ -98,17 +98,14 @@ export async function updateJudge(args) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apply(ctx: Context) {
|
export async function apply(ctx: Context) {
|
||||||
if (process.env.NODE_APP_INSTANCE !== '0') return;
|
if (process.env.NODE_APP_INSTANCE !== '0') return;
|
||||||
ctx.on('app/started', async () => {
|
const info = await sysinfo.get();
|
||||||
sysinfo.get().then((info) => {
|
|
||||||
coll.updateOne(
|
coll.updateOne(
|
||||||
{ mid: info.mid, type: 'server' },
|
{ mid: info.mid, type: 'server' },
|
||||||
{ $set: { ...info, updateAt: new Date(), type: 'server' } },
|
{ $set: { ...info, updateAt: new Date(), type: 'server' } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
feedback();
|
feedback();
|
||||||
setInterval(update, 1800 * 1000);
|
return ctx.setInterval(update, 1800 * 1000); // eslint-disable-line
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,14 @@ export default class WorkerService extends Service {
|
|||||||
|
|
||||||
constructor(ctx: Context) {
|
constructor(ctx: Context) {
|
||||||
super(ctx, 'worker');
|
super(ctx, 'worker');
|
||||||
|
}
|
||||||
|
|
||||||
|
async *[Context.init]() {
|
||||||
this.consume();
|
this.consume();
|
||||||
|
yield () => {
|
||||||
|
this.consuming = false;
|
||||||
|
return this.promise;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirst() {
|
async getFirst() {
|
||||||
@@ -79,9 +86,4 @@ export default class WorkerService extends Service {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async stop() {
|
|
||||||
this.consuming = false;
|
|
||||||
await this.promise;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
"@fontsource/source-code-pro": "^5.2.5",
|
"@fontsource/source-code-pro": "^5.2.5",
|
||||||
"@fontsource/ubuntu-mono": "^5.2.5",
|
"@fontsource/ubuntu-mono": "^5.2.5",
|
||||||
"@hydrooj/utils": "workspace:^",
|
"@hydrooj/utils": "workspace:^",
|
||||||
"@sentry/browser": "^9.9.0",
|
"@sentry/browser": "^9.10.0",
|
||||||
"@sentry/webpack-plugin": "^3.2.2",
|
"@sentry/webpack-plugin": "^3.2.3",
|
||||||
"@simplewebauthn/browser": "13.1.0",
|
"@simplewebauthn/browser": "13.1.0",
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@types/html-to-text": "^9.0.4",
|
"@types/html-to-text": "^9.0.4",
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
"jquery.easing": "^1.4.1",
|
"jquery.easing": "^1.4.1",
|
||||||
"jquery.transit": "^0.9.12",
|
"jquery.transit": "^0.9.12",
|
||||||
"matchmedia-polyfill": "^0.3.2",
|
"matchmedia-polyfill": "^0.3.2",
|
||||||
"md-editor-rt": "^5.4.4",
|
"md-editor-rt": "^5.4.5",
|
||||||
"mini-css-extract-plugin": "^2.9.2",
|
"mini-css-extract-plugin": "^2.9.2",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"monaco-editor": "0.52.2",
|
"monaco-editor": "0.52.2",
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"web-streams-polyfill": "^4.1.0",
|
"web-streams-polyfill": "^4.1.0",
|
||||||
"webpack": "^5.98.0",
|
"webpack": "^5.98.0",
|
||||||
"webpack-bundle-analyzer": "^4.10.2",
|
"webpack-bundle-analyzer": "^4.10.2",
|
||||||
"webpack-dev-server": "^5.2.0",
|
"webpack-dev-server": "^5.2.1",
|
||||||
"webpack-manifest-plugin": "^5.0.1",
|
"webpack-manifest-plugin": "^5.0.1",
|
||||||
"webpackbar": "^7.0.0"
|
"webpackbar": "^7.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -48,8 +48,8 @@
|
|||||||
<script>
|
<script>
|
||||||
var _htmlNode = document.documentElement;
|
var _htmlNode = document.documentElement;
|
||||||
_htmlNode.className = _htmlNode.className.replace(' nojs', ' hasjs');
|
_htmlNode.className = _htmlNode.className.replace(' nojs', ' hasjs');
|
||||||
var UiContext = '{{ UiContext|json|jsesc|safe }}';
|
window.UiContext = '{{ UiContext|json|jsesc|safe }}';
|
||||||
var UserContext = '{{ UserContext|json|jsesc|safe }}';
|
window.UserContext = '{{ UserContext|json|jsesc|safe }}';
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% set UiContext = Object.create(UiContext) %}
|
{% set UiContext = Object.create(UiContext) %}
|
||||||
@@ -65,8 +65,8 @@
|
|||||||
{% block script %}{% endblock %}
|
{% block script %}{% endblock %}
|
||||||
{% if not isIE(handler.request.headers['user-agent']) and not handler.session.legacy %}
|
{% if not isIE(handler.request.headers['user-agent']) and not handler.session.legacy %}
|
||||||
<script>
|
<script>
|
||||||
var UiContextNew = '{{ UiContext|json|jsesc|safe }}';
|
window.UiContextNew = '{{ UiContext|json|jsesc|safe }}';
|
||||||
var UserContextNew = '{{ UserContext|json|jsesc|safe }}';
|
window.UserContextNew = '{{ UserContext|json|jsesc|safe }}';
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
"@types/react": "^19.0.12",
|
"@types/react": "^19.0.12",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@vitejs/plugin-react-swc": "^3.8.1",
|
"@vitejs/plugin-react-swc": "^3.8.1",
|
||||||
"vite": "^6.2.2"
|
"vite": "^6.2.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user