remove contest type
Some checks failed
Deploy / deploy (build, debian, 22, /root/OJDeploy/data/clientnext) (push) Has been cancelled
Deploy / deploy (build:staging, school, 8822, /root/OJ/data/dist) (push) Has been cancelled

This commit is contained in:
2026-05-26 23:10:15 -06:00
parent c1678c9060
commit cb7743367a
11 changed files with 246 additions and 89 deletions

View File

@@ -56,9 +56,7 @@ const contest = reactive<BlankContest & { id: number }>({
tag: "练习", tag: "练习",
start_time: "", start_time: "",
end_time: "", end_time: "",
rule_type: "ACM",
password: "", password: "",
real_time_rank: true,
visible: false, visible: false,
allowed_ip_ranges: [], allowed_ip_ranges: [],
}) })
@@ -79,9 +77,7 @@ async function getContestDetail() {
contest.tag = data.tag contest.tag = data.tag
contest.start_time = data.start_time contest.start_time = data.start_time
contest.end_time = data.end_time contest.end_time = data.end_time
contest.rule_type = "ACM"
contest.password = data.password contest.password = data.password
contest.real_time_rank = true
contest.visible = data.visible contest.visible = data.visible
contest.allowed_ip_ranges = [] contest.allowed_ip_ranges = []

View File

@@ -24,23 +24,41 @@ const emit = defineEmits<{
const activeTab = ref(props.languages[0] || "Python3") const activeTab = ref(props.languages[0] || "Python3")
const ENGINE_OPTIONS: SelectOption[] = [ const ENGINE_OPTIONS: SelectOption[] = [
{ label: "节点检查", type: "group", key: "node_group", children: [ {
{ label: "必须存在", value: "must_exist_node" }, label: "节点检查",
{ label: "不能存在", value: "must_not_exist_node" }, type: "group",
{ label: "出现次数", value: "count_node" }, key: "node_group",
]}, children: [
{ label: "函数调用", type: "group", key: "func_group", children: [ { label: "必须存在", value: "must_exist_node" },
{ label: "必须调用函数", value: "must_call_function" }, { label: "不能存在", value: "must_not_exist_node" },
{ label: "不能调用函数", value: "must_not_call_function" }, { label: "出现次数", value: "count_node" },
{ label: "函数调用次数", value: "count_function_call" }, ],
]}, },
{ label: "方法调用", type: "group", key: "method_group", children: [ {
{ label: "必须调用方法", value: "must_call_method" }, label: "函数调用",
{ label: "不能调用方法", value: "must_not_call_method" }, type: "group",
]}, key: "func_group",
{ label: "运算符", type: "group", key: "op_group", children: [ children: [
{ label: "必须使用运算符", value: "must_use_operator" }, { label: "必须调用函数", value: "must_call_function" },
]}, { label: "不能调用函数", value: "must_not_call_function" },
{ label: "函数调用次数", value: "count_function_call" },
],
},
{
label: "方法调用",
type: "group",
key: "method_group",
children: [
{ label: "必须调用方法", value: "must_call_method" },
{ label: "不能调用方法", value: "must_not_call_method" },
],
},
{
label: "运算符",
type: "group",
key: "op_group",
children: [{ label: "必须使用运算符", value: "must_use_operator" }],
},
] ]
const NODE_TARGET_OPTIONS: SelectOption[] = [ const NODE_TARGET_OPTIONS: SelectOption[] = [
@@ -83,16 +101,30 @@ const OPERATOR_TARGET_OPTIONS: SelectOption[] = [
] ]
const NODE_ENGINES = ["must_exist_node", "must_not_exist_node", "count_node"] const NODE_ENGINES = ["must_exist_node", "must_not_exist_node", "count_node"]
const FUNCTION_ENGINES = ["must_call_function", "must_not_call_function", "count_function_call"] const FUNCTION_ENGINES = [
"must_call_function",
"must_not_call_function",
"count_function_call",
]
const METHOD_ENGINES = ["must_call_method", "must_not_call_method"] const METHOD_ENGINES = ["must_call_method", "must_not_call_method"]
const OPERATOR_ENGINES = ["must_use_operator"] const OPERATOR_ENGINES = ["must_use_operator"]
const COUNT_ENGINES = ["count_node", "count_function_call"] const COUNT_ENGINES = ["count_node", "count_function_call"]
function isNodeEngine(engine: string) { return NODE_ENGINES.includes(engine) } function isNodeEngine(engine: string) {
function isFunctionEngine(engine: string) { return FUNCTION_ENGINES.includes(engine) } return NODE_ENGINES.includes(engine)
function isMethodEngine(engine: string) { return METHOD_ENGINES.includes(engine) } }
function isOperatorEngine(engine: string) { return OPERATOR_ENGINES.includes(engine) } function isFunctionEngine(engine: string) {
function isCountEngine(engine: string) { return COUNT_ENGINES.includes(engine) } return FUNCTION_ENGINES.includes(engine)
}
function isMethodEngine(engine: string) {
return METHOD_ENGINES.includes(engine)
}
function isOperatorEngine(engine: string) {
return OPERATOR_ENGINES.includes(engine)
}
function isCountEngine(engine: string) {
return COUNT_ENGINES.includes(engine)
}
const COUNT_MODE_OPTIONS: SelectOption[] = [ const COUNT_MODE_OPTIONS: SelectOption[] = [
{ label: "精确", value: "exact" }, { label: "精确", value: "exact" },
@@ -126,9 +158,15 @@ function updateExactCount(lang: string, index: number, v: number | null) {
updateRules(lang, rules) updateRules(lang, rules)
} }
function needsTargetDropdown(engine: string) { return isNodeEngine(engine) } function needsTargetDropdown(engine: string) {
function needsTargetInput(engine: string) { return isFunctionEngine(engine) || isMethodEngine(engine) } return isNodeEngine(engine)
function needsOperatorDropdown(engine: string) { return isOperatorEngine(engine) } }
function needsTargetInput(engine: string) {
return isFunctionEngine(engine) || isMethodEngine(engine)
}
function needsOperatorDropdown(engine: string) {
return isOperatorEngine(engine)
}
function getRulesForLang(lang: string): AstRule[] { function getRulesForLang(lang: string): AstRule[] {
if (!props.modelValue) return [] if (!props.modelValue) return []
@@ -149,13 +187,19 @@ function getTargetLabel(engine: string, target: string): string | undefined {
if (isNodeEngine(engine)) if (isNodeEngine(engine))
return (NODE_TARGET_OPTIONS.find((o) => o.value === target) as any)?.label return (NODE_TARGET_OPTIONS.find((o) => o.value === target) as any)?.label
if (isOperatorEngine(engine)) if (isOperatorEngine(engine))
return (OPERATOR_TARGET_OPTIONS.find((o) => o.value === target) as any)?.label return (OPERATOR_TARGET_OPTIONS.find((o) => o.value === target) as any)
?.label
return undefined return undefined
} }
function addRule(lang: string) { function addRule(lang: string) {
const rules = [...getRulesForLang(lang)] const rules = [...getRulesForLang(lang)]
rules.push({ engine: "must_exist_node", target: "for_loop", label: "for 循环", message: "" }) rules.push({
engine: "must_exist_node",
target: "for_loop",
label: "for 循环",
message: "",
})
updateRules(lang, rules) updateRules(lang, rules)
} }
@@ -171,9 +215,16 @@ function updateRule(lang: string, index: number, field: string, value: any) {
if (field === "engine") { if (field === "engine") {
rule.engine = value rule.engine = value
if (isNodeEngine(value)) { rule.target = "for_loop"; rule.label = "for 循环" } if (isNodeEngine(value)) {
else if (isOperatorEngine(value)) { rule.target = "+"; rule.label = "+" } rule.target = "for_loop"
else { rule.target = ""; delete rule.label } rule.label = "for 循环"
} else if (isOperatorEngine(value)) {
rule.target = "+"
rule.label = "+"
} else {
rule.target = ""
delete rule.label
}
delete rule.min delete rule.min
delete rule.max delete rule.max
delete rule.exact delete rule.exact
@@ -196,25 +247,39 @@ function updateRule(lang: string, index: number, field: string, value: any) {
updateRules(lang, rules) updateRules(lang, rules)
} }
watch(() => props.languages, (langs) => { watch(
if (langs.length && !langs.includes(activeTab.value as LANGUAGE)) { () => props.languages,
activeTab.value = langs[0] (langs) => {
} if (langs.length && !langs.includes(activeTab.value as LANGUAGE)) {
}) activeTab.value = langs[0]
}
},
)
</script> </script>
<template> <template>
<n-collapse> <n-collapse>
<n-collapse-item title="代码规则检查(选填)" name="ast-rules"> <n-collapse-item title="代码规则检查(选填)" name="ast-rules">
<n-tabs v-if="languages.length" type="segment" v-model:value="activeTab"> <n-tabs v-if="languages.length" type="segment" v-model:value="activeTab">
<n-tab-pane v-for="lang in languages" :key="lang" :name="lang" :tab="lang"> <n-tab-pane
v-for="lang in languages"
:key="lang"
:name="lang"
:tab="lang"
>
<n-flex vertical> <n-flex vertical>
<div v-for="(rule, index) in getRulesForLang(lang)" :key="index" style="margin-bottom: 8px"> <div
v-for="(rule, index) in getRulesForLang(lang)"
:key="index"
style="margin-bottom: 8px"
>
<n-flex align="center" :wrap="false"> <n-flex align="center" :wrap="false">
<n-select <n-select
:options="ENGINE_OPTIONS" :options="ENGINE_OPTIONS"
:value="rule.engine" :value="rule.engine"
@update:value="(v: string) => updateRule(lang, index, 'engine', v)" @update:value="
(v: string) => updateRule(lang, index, 'engine', v)
"
style="width: 150px" style="width: 150px"
size="small" size="small"
/> />
@@ -222,7 +287,9 @@ watch(() => props.languages, (langs) => {
v-if="needsTargetDropdown(rule.engine)" v-if="needsTargetDropdown(rule.engine)"
:options="NODE_TARGET_OPTIONS" :options="NODE_TARGET_OPTIONS"
:value="rule.target" :value="rule.target"
@update:value="(v: string) => updateRule(lang, index, 'target', v)" @update:value="
(v: string) => updateRule(lang, index, 'target', v)
"
style="width: 150px" style="width: 150px"
size="small" size="small"
filterable filterable
@@ -230,7 +297,9 @@ watch(() => props.languages, (langs) => {
<n-input <n-input
v-if="needsTargetInput(rule.engine)" v-if="needsTargetInput(rule.engine)"
:value="rule.target" :value="rule.target"
@update:value="(v: string) => updateRule(lang, index, 'target', v)" @update:value="
(v: string) => updateRule(lang, index, 'target', v)
"
placeholder="函数/方法名" placeholder="函数/方法名"
style="width: 150px" style="width: 150px"
size="small" size="small"
@@ -239,7 +308,9 @@ watch(() => props.languages, (langs) => {
v-if="needsOperatorDropdown(rule.engine)" v-if="needsOperatorDropdown(rule.engine)"
:options="OPERATOR_TARGET_OPTIONS" :options="OPERATOR_TARGET_OPTIONS"
:value="rule.target" :value="rule.target"
@update:value="(v: string) => updateRule(lang, index, 'target', v)" @update:value="
(v: string) => updateRule(lang, index, 'target', v)
"
style="width: 150px" style="width: 150px"
size="small" size="small"
/> />
@@ -247,14 +318,18 @@ watch(() => props.languages, (langs) => {
<n-select <n-select
:options="COUNT_MODE_OPTIONS" :options="COUNT_MODE_OPTIONS"
:value="getCountMode(rule)" :value="getCountMode(rule)"
@update:value="(v: 'exact' | 'range') => updateCountMode(lang, index, v)" @update:value="
(v: 'exact' | 'range') => updateCountMode(lang, index, v)
"
style="width: 80px" style="width: 80px"
size="small" size="small"
/> />
<n-input-number <n-input-number
v-if="getCountMode(rule) === 'exact'" v-if="getCountMode(rule) === 'exact'"
:value="rule.exact ?? null" :value="rule.exact ?? null"
@update:value="(v: number | null) => updateExactCount(lang, index, v)" @update:value="
(v: number | null) => updateExactCount(lang, index, v)
"
placeholder="次数" placeholder="次数"
style="width: 100px" style="width: 100px"
size="small" size="small"
@@ -264,7 +339,9 @@ watch(() => props.languages, (langs) => {
<template v-else> <template v-else>
<n-input-number <n-input-number
:value="rule.min ?? null" :value="rule.min ?? null"
@update:value="(v: number | null) => updateRule(lang, index, 'min', v)" @update:value="
(v: number | null) => updateRule(lang, index, 'min', v)
"
placeholder="最少" placeholder="最少"
style="width: 100px" style="width: 100px"
size="small" size="small"
@@ -273,7 +350,9 @@ watch(() => props.languages, (langs) => {
/> />
<n-input-number <n-input-number
:value="rule.max ?? null" :value="rule.max ?? null"
@update:value="(v: number | null) => updateRule(lang, index, 'max', v)" @update:value="
(v: number | null) => updateRule(lang, index, 'max', v)
"
placeholder="最多" placeholder="最多"
style="width: 100px" style="width: 100px"
size="small" size="small"
@@ -284,17 +363,29 @@ watch(() => props.languages, (langs) => {
</template> </template>
<n-input <n-input
:value="rule.message" :value="rule.message"
@update:value="(v: string) => updateRule(lang, index, 'message', v)" @update:value="
(v: string) => updateRule(lang, index, 'message', v)
"
placeholder="错误提示(选填)" placeholder="错误提示(选填)"
style="flex: 1" style="flex: 1"
size="small" size="small"
/> />
<n-button size="small" tertiary type="error" @click="removeRule(lang, index)"> <n-button
size="small"
tertiary
type="error"
@click="removeRule(lang, index)"
>
删除 删除
</n-button> </n-button>
</n-flex> </n-flex>
</div> </div>
<n-button size="small" tertiary type="primary" @click="addRule(lang)"> <n-button
size="small"
tertiary
type="primary"
@click="addRule(lang)"
>
添加规则 添加规则
</n-button> </n-button>
</n-flex> </n-flex>

View File

@@ -87,12 +87,24 @@ const columns: DataTableColumn<AdminProblemFiltered>[] = [
render: (row) => render: (row) =>
h(NFlex, { size: 4, align: "center" }, () => [ h(NFlex, { size: 4, align: "center" }, () => [
row.allow_flowchart row.allow_flowchart
? h(Icon, { width: 18, icon: "vscode-icons:file-type-drawio", title: "绘图" }) ? h(Icon, {
width: 18,
icon: "vscode-icons:file-type-drawio",
title: "绘图",
})
: row.show_flowchart : row.show_flowchart
? h(Icon, { width: 18, icon: "vscode-icons:file-type-graphql", title: "流程图" }) ? h(Icon, {
width: 18,
icon: "vscode-icons:file-type-graphql",
title: "流程图",
})
: null, : null,
row.has_ast_rules row.has_ast_rules
? h(Icon, { width: 18, icon: "vscode-icons:file-type-light-todo", title: "AST" }) ? h(Icon, {
width: 18,
icon: "vscode-icons:file-type-light-todo",
title: "AST",
})
: null, : null,
]), ]),
}, },

View File

@@ -211,7 +211,7 @@ export async function getContestProblems(contestID: string) {
export function getContestRank( export function getContestRank(
contestID: string, contestID: string,
query: { limit: number; offset: number; force_refresh: "1" | "0" }, query: { limit: number; offset: number },
) { ) {
return http.get("contest_rank", { return http.get("contest_rank", {
params: { params: {

View File

@@ -95,7 +95,6 @@ async function listRanks() {
const res = await getContestRank(props.contestID, { const res = await getContestRank(props.contestID, {
limit: query.limit, limit: query.limit,
offset: query.limit * (query.page - 1), offset: query.limit * (query.page - 1),
force_refresh: "1",
}) })
total.value = res.data.total total.value = res.data.total
data.value = res.data.results data.value = res.data.results
@@ -225,7 +224,6 @@ async function downloadExcel() {
const res = await getContestRank(props.contestID, { const res = await getContestRank(props.contestID, {
limit: total.value || 10000, limit: total.value || 10000,
offset: 0, offset: 0,
force_refresh: "1",
}) })
const allRanks: ContestRank[] = res.data.results const allRanks: ContestRank[] = res.data.results

View File

@@ -119,29 +119,41 @@ function ruleDescription(rule: AstRule): string {
const targetLabel = rule.label || NODE_TARGET_LABELS[target] || target const targetLabel = rule.label || NODE_TARGET_LABELS[target] || target
const countDesc = () => { const countDesc = () => {
if (rule.exact !== undefined) return `出现 ${rule.exact}` if (rule.exact !== undefined) return `出现 ${rule.exact}`
if (rule.min !== undefined && rule.max !== undefined) return `出现 ${rule.min}${rule.max}` if (rule.min !== undefined && rule.max !== undefined)
return `出现 ${rule.min}${rule.max}`
if (rule.min !== undefined) return `至少出现 ${rule.min}` if (rule.min !== undefined) return `至少出现 ${rule.min}`
if (rule.max !== undefined) return `至多出现 ${rule.max}` if (rule.max !== undefined) return `至多出现 ${rule.max}`
return "" return ""
} }
const callDesc = () => { const callDesc = () => {
if (rule.exact !== undefined) return `调用 ${rule.exact}` if (rule.exact !== undefined) return `调用 ${rule.exact}`
if (rule.min !== undefined && rule.max !== undefined) return `调用 ${rule.min}${rule.max}` if (rule.min !== undefined && rule.max !== undefined)
return `调用 ${rule.min}${rule.max}`
if (rule.min !== undefined) return `至少调用 ${rule.min}` if (rule.min !== undefined) return `至少调用 ${rule.min}`
if (rule.max !== undefined) return `至多调用 ${rule.max}` if (rule.max !== undefined) return `至多调用 ${rule.max}`
return "" return ""
} }
switch (rule.engine) { switch (rule.engine) {
case "must_exist_node": return `必须使用 ${targetLabel}` case "must_exist_node":
case "must_not_exist_node": return `不能使用 ${targetLabel}` return `必须使用 ${targetLabel}`
case "count_node": return `${targetLabel} ${countDesc()}` case "must_not_exist_node":
case "must_call_function": return `必须调${target}()` return `不能使${targetLabel}`
case "must_not_call_function": return `不能调用 ${target}()` case "count_node":
case "count_function_call": return `${target}() ${callDesc()}` return `${targetLabel} ${countDesc()}`
case "must_call_method": return `必须调用 .${target}()` case "must_call_function":
case "must_not_call_method": return `不能调用 .${target}()` return `必须调用 ${target}()`
case "must_use_operator": return `必须使用 ${target} 运算符` case "must_not_call_function":
default: return rule.engine return `不能调用 ${target}()`
case "count_function_call":
return `${target}() ${callDesc()}`
case "must_call_method":
return `必须调用 .${target}()`
case "must_not_call_method":
return `不能调用 .${target}()`
case "must_use_operator":
return `必须使用 ${target} 运算符`
default:
return rule.engine
} }
} }
@@ -153,7 +165,9 @@ function ruleTagType(engine: string): "error" | "success" | "info" {
const astRulesForDisplay = computed(() => { const astRulesForDisplay = computed(() => {
if (!problem.value?.ast_rules) return [] if (!problem.value?.ast_rules) return []
return Object.entries(problem.value.ast_rules).filter(([, rules]) => rules.length > 0) return Object.entries(problem.value.ast_rules).filter(
([, rules]) => rules.length > 0,
)
}) })
async function test(sample: Sample, index: number) { async function test(sample: Sample, index: number) {
@@ -302,14 +316,18 @@ function type(status: ProblemStatus) {
</n-flex> </n-flex>
</p> </p>
<div v-for="[lang, rules] in astRulesForDisplay" :key="lang"> <div v-for="[lang, rules] in astRulesForDisplay" :key="lang">
<p v-if="astRulesForDisplay.length > 1" class="lang-label">{{ lang }}</p> <p v-if="astRulesForDisplay.length > 1" class="lang-label">
{{ lang }}
</p>
<n-list bordered style="margin-bottom: 8px"> <n-list bordered style="margin-bottom: 8px">
<n-list-item v-for="(rule, i) in rules" :key="i"> <n-list-item v-for="(rule, i) in rules" :key="i">
<n-flex align="center"> <n-flex align="center">
<n-tag :type="ruleTagType(rule.engine)"> <n-tag :type="ruleTagType(rule.engine)">
{{ ruleDescription(rule) }} {{ ruleDescription(rule) }}
</n-tag> </n-tag>
<span v-if="rule.message" class="rule-message">{{ rule.message }}</span> <span v-if="rule.message" class="rule-message">{{
rule.message
}}</span>
</n-flex> </n-flex>
</n-list-item> </n-list-item>
</n-list> </n-list>

View File

@@ -43,7 +43,10 @@ const msg = computed(() => {
msg += "请仔细检查,看看代码的格式是不是写错了!\n\n" msg += "请仔细检查,看看代码的格式是不是写错了!\n\n"
} }
if (result !== SubmissionStatus.ast_check_failed && props.submission.statistic_info?.err_info) { if (
result !== SubmissionStatus.ast_check_failed &&
props.submission.statistic_info?.err_info
) {
msg += props.submission.statistic_info.err_info msg += props.submission.statistic_info.err_info
} }
@@ -153,7 +156,14 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
:title="JUDGE_STATUS[submission.result]['title']" :title="JUDGE_STATUS[submission.result]['title']"
class="mb-3" class="mb-3"
/> />
<n-flex vertical v-if="msg || infoTable.length || submission.statistic_info?.ast_results?.length"> <n-flex
vertical
v-if="
msg ||
infoTable.length ||
submission.statistic_info?.ast_results?.length
"
>
<n-card v-if="submission.statistic_info?.ast_results?.length" embedded> <n-card v-if="submission.statistic_info?.ast_results?.length" embedded>
<n-flex vertical :size="8"> <n-flex vertical :size="8">
<n-flex <n-flex
@@ -162,7 +172,9 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
align="center" align="center"
:size="6" :size="6"
> >
<n-icon :color="rule.passed ? theme.successColor : theme.errorColor"> <n-icon
:color="rule.passed ? theme.successColor : theme.errorColor"
>
<Icon :icon="rule.passed ? 'ep:select' : 'ep:close-bold'" /> <Icon :icon="rule.passed ? 'ep:select' : 'ep:close-bold'" />
</n-icon> </n-icon>
<span>{{ rule.description }}</span> <span>{{ rule.description }}</span>

View File

@@ -149,7 +149,10 @@ watch(
result === SubmissionStatus.submitting result === SubmissionStatus.submitting
) )
return return
if (result !== SubmissionStatus.accepted && result !== SubmissionStatus.ast_check_failed) { if (
result !== SubmissionStatus.accepted &&
result !== SubmissionStatus.ast_check_failed
) {
problemStore.incrementFailCount() problemStore.incrementFailCount()
} }
}, },
@@ -159,7 +162,11 @@ watch(
watch( watch(
() => submission.value?.result, () => submission.value?.result,
async (result) => { async (result) => {
if (result !== SubmissionStatus.accepted && result !== SubmissionStatus.ast_check_failed) return if (
result !== SubmissionStatus.accepted &&
result !== SubmissionStatus.ast_check_failed
)
return
// 1. 刷新题目状态 // 1. 刷新题目状态
problem.value!.my_status = 0 problem.value!.my_status = 0

View File

@@ -267,7 +267,11 @@ watch(isMobile, (value) => {
> >
<ProblemComment /> <ProblemComment />
</n-tab-pane> </n-tab-pane>
<n-tab-pane v-if="myFlowchartStore.showing" name="my-flowchart" tab="我的流程图"> <n-tab-pane
v-if="myFlowchartStore.showing"
name="my-flowchart"
tab="我的流程图"
>
<MyFlowchartTab /> <MyFlowchartTab />
</n-tab-pane> </n-tab-pane>
<n-tab-pane name="submission" tab="提交" :disabled="!!props.problemSetId"> <n-tab-pane name="submission" tab="提交" :disabled="!!props.problemSetId">

View File

@@ -102,11 +102,11 @@ export function secondsToDuration(seconds: number): string {
start: 0, start: 0,
end: seconds * 1000, end: seconds * 1000,
}) })
return [ const hours = (duration.days ?? 0) * 24 + (duration.hours ?? 0)
duration.hours ?? 0, const pad = (n: number) => String(n).padStart(2, "0")
duration.minutes ?? 0, return [hours, pad(duration.minutes ?? 0), pad(duration.seconds ?? 0)].join(
duration.seconds ?? 0, ":",
].join(":") )
} }
export function submissionMemoryFormat(memory: number | string | undefined) { export function submissionMemoryFormat(memory: number | string | undefined) {

View File

@@ -65,7 +65,20 @@ export type LANGUAGE =
export type LANGUAGE_SHOW_LABEL = export type LANGUAGE_SHOW_LABEL =
(typeof LANGUAGE_SHOW_VALUE)[keyof typeof LANGUAGE_SHOW_VALUE] (typeof LANGUAGE_SHOW_VALUE)[keyof typeof LANGUAGE_SHOW_VALUE]
export type SUBMISSION_RESULT = -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 export type SUBMISSION_RESULT =
| -2
| -1
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
export type ProblemStatus = "passed" | "failed" | "not_test" export type ProblemStatus = "passed" | "failed" | "not_test"
@@ -137,7 +150,15 @@ export interface Problem {
flowchart_data?: Record<string, any> flowchart_data?: Record<string, any>
flowchart_hint?: string flowchart_hint?: string
show_flowchart?: boolean show_flowchart?: boolean
ast_rules?: { [key: string]: { engine: string; target?: string; min?: number; max?: number; message: string }[] } | null ast_rules?: {
[key: string]: {
engine: string
target?: string
min?: number
max?: number
message: string
}[]
} | null
has_ast_rules?: boolean has_ast_rules?: boolean
} }
@@ -482,9 +503,7 @@ export interface BlankContest {
tag: string tag: string
start_time: string start_time: string
end_time: string end_time: string
rule_type: "ACM" | "OI"
password: string password: string
real_time_rank: boolean
visible: boolean visible: boolean
allowed_ip_ranges: { value: string }[] allowed_ip_ranges: { value: string }[]
} }