Add contest freeze
This commit is contained in:
parent
2c39774ff7
commit
a35ea0f6d5
13 changed files with 338 additions and 215 deletions
|
@ -158,7 +158,10 @@ class ContestAdmin(CompareVersionAdmin):
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(_("Scheduling"), {"fields": ("start_time", "end_time", "time_limit")}),
|
(
|
||||||
|
_("Scheduling"),
|
||||||
|
{"fields": ("start_time", "end_time", "time_limit", "freeze_after")},
|
||||||
|
),
|
||||||
(
|
(
|
||||||
_("Details"),
|
_("Details"),
|
||||||
{
|
{
|
||||||
|
@ -274,7 +277,8 @@ class ContestAdmin(CompareVersionAdmin):
|
||||||
# We need this flag because `save_related` deals with the inlines, but does not know if we have already rescored
|
# We need this flag because `save_related` deals with the inlines, but does not know if we have already rescored
|
||||||
self._rescored = False
|
self._rescored = False
|
||||||
if form.changed_data and any(
|
if form.changed_data and any(
|
||||||
f in form.changed_data for f in ("format_config", "format_name")
|
f in form.changed_data
|
||||||
|
for f in ("format_config", "format_name", "freeze_after")
|
||||||
):
|
):
|
||||||
self._rescore(obj.key)
|
self._rescore(obj.key)
|
||||||
self._rescored = True
|
self._rescored = True
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy
|
||||||
|
|
||||||
from judge.contest_format.default import DefaultContestFormat
|
from judge.contest_format.default import DefaultContestFormat
|
||||||
from judge.contest_format.registry import register_contest_format
|
from judge.contest_format.registry import register_contest_format
|
||||||
from judge.timezone import from_database_time
|
from judge.timezone import from_database_time, to_database_time
|
||||||
from judge.utils.timedelta import nice_repr
|
from judge.utils.timedelta import nice_repr
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +54,10 @@ class AtCoderContestFormat(DefaultContestFormat):
|
||||||
points = 0
|
points = 0
|
||||||
format_data = {}
|
format_data = {}
|
||||||
|
|
||||||
|
frozen_time = self.contest.end_time
|
||||||
|
if self.contest.freeze_after:
|
||||||
|
frozen_time = participation.start + self.contest.freeze_after
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""
|
"""
|
||||||
|
@ -66,9 +70,10 @@ class AtCoderContestFormat(DefaultContestFormat):
|
||||||
FROM judge_contestproblem cp INNER JOIN
|
FROM judge_contestproblem cp INNER JOIN
|
||||||
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
||||||
judge_submission sub ON (sub.id = cs.submission_id)
|
judge_submission sub ON (sub.id = cs.submission_id)
|
||||||
|
WHERE sub.date < %s
|
||||||
GROUP BY cp.id
|
GROUP BY cp.id
|
||||||
""",
|
""",
|
||||||
(participation.id, participation.id),
|
(participation.id, participation.id, to_database_time(frozen_time)),
|
||||||
)
|
)
|
||||||
|
|
||||||
for score, time, prob in cursor.fetchall():
|
for score, time, prob in cursor.fetchall():
|
||||||
|
@ -100,6 +105,7 @@ class AtCoderContestFormat(DefaultContestFormat):
|
||||||
format_data[str(prob)] = {"time": dt, "points": score, "penalty": prev}
|
format_data[str(prob)] = {"time": dt, "points": score, "penalty": prev}
|
||||||
points += score
|
points += score
|
||||||
|
|
||||||
|
self.handle_frozen_state(participation, format_data)
|
||||||
participation.cumtime = cumtime + penalty
|
participation.cumtime = cumtime + penalty
|
||||||
participation.score = points
|
participation.score = points
|
||||||
participation.tiebreaker = 0
|
participation.tiebreaker = 0
|
||||||
|
@ -114,7 +120,7 @@ class AtCoderContestFormat(DefaultContestFormat):
|
||||||
'<small style="color:red"> ({penalty})</small>',
|
'<small style="color:red"> ({penalty})</small>',
|
||||||
penalty=floatformat(format_data["penalty"]),
|
penalty=floatformat(format_data["penalty"]),
|
||||||
)
|
)
|
||||||
if format_data["penalty"]
|
if format_data.get("penalty")
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
return format_html(
|
return format_html(
|
||||||
|
@ -129,6 +135,7 @@ class AtCoderContestFormat(DefaultContestFormat):
|
||||||
+ self.best_solution_state(
|
+ self.best_solution_state(
|
||||||
format_data["points"], contest_problem.points
|
format_data["points"], contest_problem.points
|
||||||
)
|
)
|
||||||
|
+ (" frozen" if format_data.get("frozen") else "")
|
||||||
),
|
),
|
||||||
url=reverse(
|
url=reverse(
|
||||||
"contest_user_submissions_ajax",
|
"contest_user_submissions_ajax",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||||
|
from django.db.models import Max
|
||||||
|
|
||||||
|
|
||||||
class abstractclassmethod(classmethod):
|
class abstractclassmethod(classmethod):
|
||||||
|
@ -95,3 +96,17 @@ class BaseContestFormat(metaclass=ABCMeta):
|
||||||
if points == total:
|
if points == total:
|
||||||
return "full-score"
|
return "full-score"
|
||||||
return "partial-score"
|
return "partial-score"
|
||||||
|
|
||||||
|
def handle_frozen_state(self, participation, format_data):
|
||||||
|
if not self.contest.freeze_after:
|
||||||
|
return
|
||||||
|
queryset = participation.submissions.values("problem_id").annotate(
|
||||||
|
time=Max("submission__date")
|
||||||
|
)
|
||||||
|
for result in queryset:
|
||||||
|
problem = str(result["problem_id"])
|
||||||
|
if format_data.get(problem):
|
||||||
|
if result["time"] >= self.contest.freeze_after + participation.start:
|
||||||
|
format_data[problem]["frozen"] = True
|
||||||
|
else:
|
||||||
|
format_data[problem] = {"time": 0, "points": 0, "frozen": True}
|
||||||
|
|
|
@ -32,10 +32,19 @@ class DefaultContestFormat(BaseContestFormat):
|
||||||
points = 0
|
points = 0
|
||||||
format_data = {}
|
format_data = {}
|
||||||
|
|
||||||
for result in participation.submissions.values("problem_id").annotate(
|
queryset = participation.submissions
|
||||||
|
|
||||||
|
if self.contest.freeze_after:
|
||||||
|
queryset = queryset.filter(
|
||||||
|
submission__date__lt=participation.start + self.contest.freeze_after
|
||||||
|
)
|
||||||
|
|
||||||
|
queryset = queryset.values("problem_id").annotate(
|
||||||
time=Max("submission__date"),
|
time=Max("submission__date"),
|
||||||
points=Max("points"),
|
points=Max("points"),
|
||||||
):
|
)
|
||||||
|
|
||||||
|
for result in queryset:
|
||||||
dt = (result["time"] - participation.start).total_seconds()
|
dt = (result["time"] - participation.start).total_seconds()
|
||||||
if result["points"]:
|
if result["points"]:
|
||||||
cumtime += dt
|
cumtime += dt
|
||||||
|
@ -45,6 +54,7 @@ class DefaultContestFormat(BaseContestFormat):
|
||||||
}
|
}
|
||||||
points += result["points"]
|
points += result["points"]
|
||||||
|
|
||||||
|
self.handle_frozen_state(participation, format_data)
|
||||||
participation.cumtime = max(cumtime, 0)
|
participation.cumtime = max(cumtime, 0)
|
||||||
participation.score = points
|
participation.score = points
|
||||||
participation.tiebreaker = 0
|
participation.tiebreaker = 0
|
||||||
|
@ -66,6 +76,7 @@ class DefaultContestFormat(BaseContestFormat):
|
||||||
+ self.best_solution_state(
|
+ self.best_solution_state(
|
||||||
format_data["points"], contest_problem.points
|
format_data["points"], contest_problem.points
|
||||||
)
|
)
|
||||||
|
+ (" frozen" if format_data.get("frozen") else "")
|
||||||
),
|
),
|
||||||
url=reverse(
|
url=reverse(
|
||||||
"contest_user_submissions_ajax",
|
"contest_user_submissions_ajax",
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy
|
||||||
|
|
||||||
from judge.contest_format.default import DefaultContestFormat
|
from judge.contest_format.default import DefaultContestFormat
|
||||||
from judge.contest_format.registry import register_contest_format
|
from judge.contest_format.registry import register_contest_format
|
||||||
from judge.timezone import from_database_time
|
from judge.timezone import from_database_time, to_database_time
|
||||||
from judge.utils.timedelta import nice_repr
|
from judge.utils.timedelta import nice_repr
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@ class ECOOContestFormat(DefaultContestFormat):
|
||||||
points = 0
|
points = 0
|
||||||
format_data = {}
|
format_data = {}
|
||||||
|
|
||||||
|
frozen_time = self.contest.end_time
|
||||||
|
if self.contest.freeze_after:
|
||||||
|
frozen_time = participation.start + self.contest.freeze_after
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""
|
"""
|
||||||
|
@ -77,9 +81,15 @@ class ECOOContestFormat(DefaultContestFormat):
|
||||||
FROM judge_contestproblem cp INNER JOIN
|
FROM judge_contestproblem cp INNER JOIN
|
||||||
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
||||||
judge_submission sub ON (sub.id = cs.submission_id)
|
judge_submission sub ON (sub.id = cs.submission_id)
|
||||||
|
WHERE sub.date < %s
|
||||||
GROUP BY cp.id
|
GROUP BY cp.id
|
||||||
""",
|
""",
|
||||||
(participation.id, participation.id, participation.id),
|
(
|
||||||
|
participation.id,
|
||||||
|
participation.id,
|
||||||
|
participation.id,
|
||||||
|
to_database_time(frozen_time),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
for score, time, prob, subs, max_score in cursor.fetchall():
|
for score, time, prob, subs, max_score in cursor.fetchall():
|
||||||
|
@ -105,6 +115,7 @@ class ECOOContestFormat(DefaultContestFormat):
|
||||||
format_data[str(prob)] = {"time": dt, "points": score, "bonus": bonus}
|
format_data[str(prob)] = {"time": dt, "points": score, "bonus": bonus}
|
||||||
points += score
|
points += score
|
||||||
|
|
||||||
|
self.handle_frozen_state(participation, format_data)
|
||||||
participation.cumtime = cumtime
|
participation.cumtime = cumtime
|
||||||
participation.score = points
|
participation.score = points
|
||||||
participation.tiebreaker = 0
|
participation.tiebreaker = 0
|
||||||
|
@ -134,6 +145,7 @@ class ECOOContestFormat(DefaultContestFormat):
|
||||||
+ self.best_solution_state(
|
+ self.best_solution_state(
|
||||||
format_data["points"], contest_problem.points
|
format_data["points"], contest_problem.points
|
||||||
)
|
)
|
||||||
|
+ (" frozen" if format_data.get("frozen") else "")
|
||||||
),
|
),
|
||||||
url=reverse(
|
url=reverse(
|
||||||
"contest_user_submissions_ajax",
|
"contest_user_submissions_ajax",
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy
|
||||||
|
|
||||||
from judge.contest_format.default import DefaultContestFormat
|
from judge.contest_format.default import DefaultContestFormat
|
||||||
from judge.contest_format.registry import register_contest_format
|
from judge.contest_format.registry import register_contest_format
|
||||||
from judge.timezone import from_database_time
|
from judge.timezone import from_database_time, to_database_time
|
||||||
from judge.utils.timedelta import nice_repr
|
from judge.utils.timedelta import nice_repr
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,10 @@ class ICPCContestFormat(DefaultContestFormat):
|
||||||
score = 0
|
score = 0
|
||||||
format_data = {}
|
format_data = {}
|
||||||
|
|
||||||
|
frozen_time = self.contest.end_time
|
||||||
|
if self.contest.freeze_after:
|
||||||
|
frozen_time = participation.start + self.contest.freeze_after
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""
|
"""
|
||||||
|
@ -67,9 +71,10 @@ class ICPCContestFormat(DefaultContestFormat):
|
||||||
FROM judge_contestproblem cp INNER JOIN
|
FROM judge_contestproblem cp INNER JOIN
|
||||||
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
||||||
judge_submission sub ON (sub.id = cs.submission_id)
|
judge_submission sub ON (sub.id = cs.submission_id)
|
||||||
|
WHERE sub.date < %s
|
||||||
GROUP BY cp.id
|
GROUP BY cp.id
|
||||||
""",
|
""",
|
||||||
(participation.id, participation.id),
|
(participation.id, participation.id, to_database_time(frozen_time)),
|
||||||
)
|
)
|
||||||
|
|
||||||
for points, time, prob in cursor.fetchall():
|
for points, time, prob in cursor.fetchall():
|
||||||
|
@ -102,6 +107,7 @@ class ICPCContestFormat(DefaultContestFormat):
|
||||||
format_data[str(prob)] = {"time": dt, "points": points, "penalty": prev}
|
format_data[str(prob)] = {"time": dt, "points": points, "penalty": prev}
|
||||||
score += points
|
score += points
|
||||||
|
|
||||||
|
self.handle_frozen_state(participation, format_data)
|
||||||
participation.cumtime = max(0, cumtime + penalty)
|
participation.cumtime = max(0, cumtime + penalty)
|
||||||
participation.score = score
|
participation.score = score
|
||||||
participation.tiebreaker = last # field is sorted from least to greatest
|
participation.tiebreaker = last # field is sorted from least to greatest
|
||||||
|
@ -116,7 +122,7 @@ class ICPCContestFormat(DefaultContestFormat):
|
||||||
'<small style="color:red"> +{penalty}</small>',
|
'<small style="color:red"> +{penalty}</small>',
|
||||||
penalty=floatformat(format_data["penalty"]),
|
penalty=floatformat(format_data["penalty"]),
|
||||||
)
|
)
|
||||||
if format_data["penalty"]
|
if format_data.get("penalty")
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
return format_html(
|
return format_html(
|
||||||
|
@ -131,6 +137,7 @@ class ICPCContestFormat(DefaultContestFormat):
|
||||||
+ self.best_solution_state(
|
+ self.best_solution_state(
|
||||||
format_data["points"], contest_problem.points
|
format_data["points"], contest_problem.points
|
||||||
)
|
)
|
||||||
|
+ (" frozen" if format_data.get("frozen") else "")
|
||||||
),
|
),
|
||||||
url=reverse(
|
url=reverse(
|
||||||
"contest_user_submissions_ajax",
|
"contest_user_submissions_ajax",
|
||||||
|
|
|
@ -12,6 +12,7 @@ from judge.contest_format.default import DefaultContestFormat
|
||||||
from judge.contest_format.registry import register_contest_format
|
from judge.contest_format.registry import register_contest_format
|
||||||
from judge.timezone import from_database_time
|
from judge.timezone import from_database_time
|
||||||
from judge.utils.timedelta import nice_repr
|
from judge.utils.timedelta import nice_repr
|
||||||
|
from django.db.models import Min, OuterRef, Subquery
|
||||||
|
|
||||||
|
|
||||||
@register_contest_format("ioi")
|
@register_contest_format("ioi")
|
||||||
|
@ -45,41 +46,42 @@ class IOIContestFormat(DefaultContestFormat):
|
||||||
|
|
||||||
def update_participation(self, participation):
|
def update_participation(self, participation):
|
||||||
cumtime = 0
|
cumtime = 0
|
||||||
points = 0
|
score = 0
|
||||||
format_data = {}
|
format_data = {}
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
queryset = participation.submissions
|
||||||
cursor.execute(
|
if self.contest.freeze_after:
|
||||||
"""
|
queryset = queryset.filter(
|
||||||
SELECT MAX(cs.points) as `score`, (
|
submission__date__lt=participation.start + self.contest.freeze_after
|
||||||
SELECT MIN(csub.date)
|
|
||||||
FROM judge_contestsubmission ccs LEFT OUTER JOIN
|
|
||||||
judge_submission csub ON (csub.id = ccs.submission_id)
|
|
||||||
WHERE ccs.problem_id = cp.id AND ccs.participation_id = %s AND ccs.points = MAX(cs.points)
|
|
||||||
) AS `time`, cp.id AS `prob`
|
|
||||||
FROM judge_contestproblem cp INNER JOIN
|
|
||||||
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
|
||||||
judge_submission sub ON (sub.id = cs.submission_id)
|
|
||||||
GROUP BY cp.id
|
|
||||||
""",
|
|
||||||
(participation.id, participation.id),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for score, time, prob in cursor.fetchall():
|
queryset = (
|
||||||
if self.config["cumtime"]:
|
queryset.values("problem_id")
|
||||||
dt = (
|
.filter(
|
||||||
from_database_time(time) - participation.start
|
points=Subquery(
|
||||||
).total_seconds()
|
queryset.filter(problem_id=OuterRef("problem_id"))
|
||||||
if score:
|
.order_by("-points")
|
||||||
cumtime += dt
|
.values("points")[:1]
|
||||||
else:
|
)
|
||||||
dt = 0
|
)
|
||||||
|
.annotate(time=Min("submission__date"))
|
||||||
|
.values_list("problem_id", "time", "points")
|
||||||
|
)
|
||||||
|
|
||||||
format_data[str(prob)] = {"time": dt, "points": score}
|
for problem_id, time, points in queryset:
|
||||||
points += score
|
if self.config["cumtime"]:
|
||||||
|
dt = (time - participation.start).total_seconds()
|
||||||
|
if points:
|
||||||
|
cumtime += dt
|
||||||
|
else:
|
||||||
|
dt = 0
|
||||||
|
|
||||||
|
format_data[str(problem_id)] = {"points": points, "time": dt}
|
||||||
|
score += points
|
||||||
|
|
||||||
|
self.handle_frozen_state(participation, format_data)
|
||||||
participation.cumtime = max(cumtime, 0)
|
participation.cumtime = max(cumtime, 0)
|
||||||
participation.score = points
|
participation.score = score
|
||||||
participation.tiebreaker = 0
|
participation.tiebreaker = 0
|
||||||
participation.format_data = format_data
|
participation.format_data = format_data
|
||||||
participation.save()
|
participation.save()
|
||||||
|
@ -99,6 +101,7 @@ class IOIContestFormat(DefaultContestFormat):
|
||||||
+ self.best_solution_state(
|
+ self.best_solution_state(
|
||||||
format_data["points"], contest_problem.points
|
format_data["points"], contest_problem.points
|
||||||
)
|
)
|
||||||
|
+ (" frozen" if format_data.get("frozen") else "")
|
||||||
),
|
),
|
||||||
url=reverse(
|
url=reverse(
|
||||||
"contest_user_submissions_ajax",
|
"contest_user_submissions_ajax",
|
||||||
|
|
23
judge/migrations/0139_contest_freeze_after.py
Normal file
23
judge/migrations/0139_contest_freeze_after.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 3.2.16 on 2022-11-18 06:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("judge", "0138_bookmark_makebookmark"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="contest",
|
||||||
|
name="freeze_after",
|
||||||
|
field=models.DurationField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Format hh:mm:ss. For example, if you want to freeze contest after 2 hours, enter 02:00:00",
|
||||||
|
null=True,
|
||||||
|
verbose_name="freeze after",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -128,6 +128,14 @@ class Contest(models.Model):
|
||||||
"Format hh:mm:ss. For example, if you want a 2-hour contest, enter 02:00:00"
|
"Format hh:mm:ss. For example, if you want a 2-hour contest, enter 02:00:00"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
freeze_after = models.DurationField(
|
||||||
|
verbose_name=_("freeze after"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
help_text=_(
|
||||||
|
"Format hh:mm:ss. For example, if you want to freeze contest after 2 hours, enter 02:00:00"
|
||||||
|
),
|
||||||
|
)
|
||||||
is_visible = models.BooleanField(
|
is_visible = models.BooleanField(
|
||||||
verbose_name=_("publicly visible"),
|
verbose_name=_("publicly visible"),
|
||||||
default=False,
|
default=False,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import pytz
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.timezone import make_aware
|
from django.utils.timezone import make_aware, make_naive
|
||||||
|
|
||||||
|
|
||||||
class TimezoneMiddleware(object):
|
class TimezoneMiddleware(object):
|
||||||
|
@ -25,3 +25,10 @@ def from_database_time(datetime):
|
||||||
if tz is None:
|
if tz is None:
|
||||||
return datetime
|
return datetime
|
||||||
return make_aware(datetime, tz)
|
return make_aware(datetime, tz)
|
||||||
|
|
||||||
|
|
||||||
|
def to_database_time(datetime):
|
||||||
|
tz = connection.timezone
|
||||||
|
if tz is None:
|
||||||
|
return datetime
|
||||||
|
return make_naive(datetime, tz)
|
||||||
|
|
|
@ -301,6 +301,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
template_name = "submission/list.html"
|
template_name = "submission/list.html"
|
||||||
context_object_name = "submissions"
|
context_object_name = "submissions"
|
||||||
first_page_href = None
|
first_page_href = None
|
||||||
|
include_frozen = False
|
||||||
|
|
||||||
def get_result_data(self):
|
def get_result_data(self):
|
||||||
result = self._get_result_data()
|
result = self._get_result_data()
|
||||||
|
@ -344,6 +345,10 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
queryset = queryset.filter(contest_object=self.contest)
|
queryset = queryset.filter(contest_object=self.contest)
|
||||||
if not self.contest.can_see_full_scoreboard(self.request.user):
|
if not self.contest.can_see_full_scoreboard(self.request.user):
|
||||||
queryset = queryset.filter(user=self.request.profile)
|
queryset = queryset.filter(user=self.request.profile)
|
||||||
|
if self.contest.freeze_after and not self.include_frozen:
|
||||||
|
queryset = queryset.exclude(
|
||||||
|
date__gte=self.contest.freeze_after + self.contest.start_time
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
queryset = queryset.select_related("contest_object").defer(
|
queryset = queryset.select_related("contest_object").defer(
|
||||||
"contest_object__description"
|
"contest_object__description"
|
||||||
|
@ -456,6 +461,9 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
self.selected_languages = set(request.GET.getlist("language"))
|
self.selected_languages = set(request.GET.getlist("language"))
|
||||||
self.selected_statuses = set(request.GET.getlist("status"))
|
self.selected_statuses = set(request.GET.getlist("status"))
|
||||||
|
|
||||||
|
if request.user.is_superuser:
|
||||||
|
self.include_frozen = True
|
||||||
|
|
||||||
if "results" in request.GET:
|
if "results" in request.GET:
|
||||||
return JsonResponse(self.get_result_data())
|
return JsonResponse(self.get_result_data())
|
||||||
|
|
||||||
|
@ -468,6 +476,8 @@ class UserMixin(object):
|
||||||
raise ImproperlyConfigured("Must pass a user")
|
raise ImproperlyConfigured("Must pass a user")
|
||||||
self.profile = get_object_or_404(Profile, user__username=kwargs["user"])
|
self.profile = get_object_or_404(Profile, user__username=kwargs["user"])
|
||||||
self.username = kwargs["user"]
|
self.username = kwargs["user"]
|
||||||
|
if self.profile == request.profile:
|
||||||
|
self.include_frozen = True
|
||||||
return super(UserMixin, self).get(request, *args, **kwargs)
|
return super(UserMixin, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -837,8 +847,8 @@ class UserContestSubmissionsAjax(UserContestSubmissions):
|
||||||
s.contest_time = nice_repr(contest_time, "noday")
|
s.contest_time = nice_repr(contest_time, "noday")
|
||||||
else:
|
else:
|
||||||
s.contest_time = None
|
s.contest_time = None
|
||||||
points = floatformat(s.contest.points, -self.contest.points_precision)
|
|
||||||
total = floatformat(contest_problem.points, -self.contest.points_precision)
|
total = floatformat(contest_problem.points, -self.contest.points_precision)
|
||||||
|
points = floatformat(s.contest.points, -self.contest.points_precision)
|
||||||
s.display_point = f"{points} / {total}"
|
s.display_point = f"{points} / {total}"
|
||||||
filtered_submissions.append(s)
|
filtered_submissions.append(s)
|
||||||
context["submissions"] = filtered_submissions
|
context["submissions"] = filtered_submissions
|
||||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: lqdoj2\n"
|
"Project-Id-Version: lqdoj2\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-11-18 05:10+0700\n"
|
"POT-Creation-Date: 2022-11-19 03:12+0700\n"
|
||||||
"PO-Revision-Date: 2021-07-20 03:44\n"
|
"PO-Revision-Date: 2021-07-20 03:44\n"
|
||||||
"Last-Translator: Icyene\n"
|
"Last-Translator: Icyene\n"
|
||||||
"Language-Team: Vietnamese\n"
|
"Language-Team: Vietnamese\n"
|
||||||
|
@ -19,8 +19,8 @@ msgstr ""
|
||||||
"X-Crowdin-File-ID: 5\n"
|
"X-Crowdin-File-ID: 5\n"
|
||||||
|
|
||||||
#: chat_box/models.py:31 chat_box/models.py:51 chat_box/models.py:65
|
#: chat_box/models.py:31 chat_box/models.py:51 chat_box/models.py:65
|
||||||
#: judge/admin/interface.py:150 judge/models/contest.py:622
|
#: judge/admin/interface.py:150 judge/models/contest.py:630
|
||||||
#: judge/models/contest.py:815 judge/models/profile.py:354
|
#: judge/models/contest.py:823 judge/models/profile.py:354
|
||||||
#: judge/models/profile.py:430
|
#: judge/models/profile.py:430
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "người dùng"
|
msgstr "người dùng"
|
||||||
|
@ -99,72 +99,72 @@ msgstr "Bài tập"
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Cài đặt"
|
msgstr "Cài đặt"
|
||||||
|
|
||||||
#: judge/admin/contest.py:161
|
#: judge/admin/contest.py:162
|
||||||
msgid "Scheduling"
|
msgid "Scheduling"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/admin/contest.py:163
|
#: judge/admin/contest.py:166
|
||||||
msgid "Details"
|
msgid "Details"
|
||||||
msgstr "Chi tiết"
|
msgstr "Chi tiết"
|
||||||
|
|
||||||
#: judge/admin/contest.py:175
|
#: judge/admin/contest.py:178
|
||||||
msgid "Format"
|
msgid "Format"
|
||||||
msgstr "Thể thức"
|
msgstr "Thể thức"
|
||||||
|
|
||||||
#: judge/admin/contest.py:179 templates/contest/ranking-table.html:7
|
#: judge/admin/contest.py:182 templates/contest/ranking-table.html:7
|
||||||
#: templates/user/user-about.html:15 templates/user/user-about.html:45
|
#: templates/user/user-about.html:15 templates/user/user-about.html:45
|
||||||
msgid "Rating"
|
msgid "Rating"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/admin/contest.py:191
|
#: judge/admin/contest.py:194
|
||||||
msgid "Access"
|
msgid "Access"
|
||||||
msgstr "Truy cập"
|
msgstr "Truy cập"
|
||||||
|
|
||||||
#: judge/admin/contest.py:201 judge/admin/problem.py:219
|
#: judge/admin/contest.py:204 judge/admin/problem.py:219
|
||||||
msgid "Justice"
|
msgid "Justice"
|
||||||
msgstr "Xử phạt"
|
msgstr "Xử phạt"
|
||||||
|
|
||||||
#: judge/admin/contest.py:313
|
#: judge/admin/contest.py:317
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%d contest successfully marked as visible."
|
msgid "%d contest successfully marked as visible."
|
||||||
msgid_plural "%d contests successfully marked as visible."
|
msgid_plural "%d contests successfully marked as visible."
|
||||||
msgstr[0] "%d kỳ thi đã được đánh dấu hiển thị."
|
msgstr[0] "%d kỳ thi đã được đánh dấu hiển thị."
|
||||||
|
|
||||||
#: judge/admin/contest.py:320
|
#: judge/admin/contest.py:324
|
||||||
msgid "Mark contests as visible"
|
msgid "Mark contests as visible"
|
||||||
msgstr "Đánh dấu hiển thị các kỳ thi"
|
msgstr "Đánh dấu hiển thị các kỳ thi"
|
||||||
|
|
||||||
#: judge/admin/contest.py:331
|
#: judge/admin/contest.py:335
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%d contest successfully marked as hidden."
|
msgid "%d contest successfully marked as hidden."
|
||||||
msgid_plural "%d contests successfully marked as hidden."
|
msgid_plural "%d contests successfully marked as hidden."
|
||||||
msgstr[0] "%d kỳ thi đã được đánh dấu ẩn."
|
msgstr[0] "%d kỳ thi đã được đánh dấu ẩn."
|
||||||
|
|
||||||
#: judge/admin/contest.py:338
|
#: judge/admin/contest.py:342
|
||||||
msgid "Mark contests as hidden"
|
msgid "Mark contests as hidden"
|
||||||
msgstr "Ẩn các kỳ thi"
|
msgstr "Ẩn các kỳ thi"
|
||||||
|
|
||||||
#: judge/admin/contest.py:359 judge/admin/submission.py:243
|
#: judge/admin/contest.py:363 judge/admin/submission.py:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%d submission was successfully scheduled for rejudging."
|
msgid "%d submission was successfully scheduled for rejudging."
|
||||||
msgid_plural "%d submissions were successfully scheduled for rejudging."
|
msgid_plural "%d submissions were successfully scheduled for rejudging."
|
||||||
msgstr[0] "%d bài nộp đã được lên lịch thành công để chấm lại."
|
msgstr[0] "%d bài nộp đã được lên lịch thành công để chấm lại."
|
||||||
|
|
||||||
#: judge/admin/contest.py:467
|
#: judge/admin/contest.py:471
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%d participation recalculated."
|
msgid "%d participation recalculated."
|
||||||
msgid_plural "%d participations recalculated."
|
msgid_plural "%d participations recalculated."
|
||||||
msgstr[0] "%d thí sinh đã được tính điểm lại."
|
msgstr[0] "%d thí sinh đã được tính điểm lại."
|
||||||
|
|
||||||
#: judge/admin/contest.py:474
|
#: judge/admin/contest.py:478
|
||||||
msgid "Recalculate results"
|
msgid "Recalculate results"
|
||||||
msgstr "Tính toán lại kết quả"
|
msgstr "Tính toán lại kết quả"
|
||||||
|
|
||||||
#: judge/admin/contest.py:479 judge/admin/organization.py:99
|
#: judge/admin/contest.py:483 judge/admin/organization.py:99
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "tên đăng nhập"
|
msgstr "tên đăng nhập"
|
||||||
|
|
||||||
#: judge/admin/contest.py:485 templates/base.html:315
|
#: judge/admin/contest.py:489 templates/base.html:315
|
||||||
msgid "virtual"
|
msgid "virtual"
|
||||||
msgstr "ảo"
|
msgstr "ảo"
|
||||||
|
|
||||||
|
@ -567,13 +567,13 @@ msgstr "Lưu"
|
||||||
msgid "bookmarks"
|
msgid "bookmarks"
|
||||||
msgstr "Lưu"
|
msgstr "Lưu"
|
||||||
|
|
||||||
#: judge/models/bookmark.py:56
|
#: judge/models/bookmark.py:59
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Bookmark"
|
#| msgid "Bookmark"
|
||||||
msgid "make bookmark"
|
msgid "make bookmark"
|
||||||
msgstr "Lưu"
|
msgstr "Lưu"
|
||||||
|
|
||||||
#: judge/models/bookmark.py:57
|
#: judge/models/bookmark.py:60
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Bookmark"
|
#| msgid "Bookmark"
|
||||||
msgid "make bookmarks"
|
msgid "make bookmarks"
|
||||||
|
@ -696,7 +696,7 @@ msgstr ""
|
||||||
msgid "contest tag"
|
msgid "contest tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:74 judge/models/contest.py:234
|
#: judge/models/contest.py:74 judge/models/contest.py:242
|
||||||
msgid "contest tags"
|
msgid "contest tags"
|
||||||
msgstr "nhãn kỳ thi"
|
msgstr "nhãn kỳ thi"
|
||||||
|
|
||||||
|
@ -751,7 +751,7 @@ msgstr "mô tả"
|
||||||
msgid "problems"
|
msgid "problems"
|
||||||
msgstr "bài tập"
|
msgstr "bài tập"
|
||||||
|
|
||||||
#: judge/models/contest.py:121 judge/models/contest.py:627
|
#: judge/models/contest.py:121 judge/models/contest.py:635
|
||||||
msgid "start time"
|
msgid "start time"
|
||||||
msgstr "thời gian bắt đầu"
|
msgstr "thời gian bắt đầu"
|
||||||
|
|
||||||
|
@ -771,11 +771,23 @@ msgstr ""
|
||||||
"Định dạng hh:mm:ss (giờ:phút:giây). Ví dụ, nếu muốn tạo kỳ thi dài 2h, hãy "
|
"Định dạng hh:mm:ss (giờ:phút:giây). Ví dụ, nếu muốn tạo kỳ thi dài 2h, hãy "
|
||||||
"nhập 02:00:00"
|
"nhập 02:00:00"
|
||||||
|
|
||||||
#: judge/models/contest.py:132 judge/models/problem.py:222
|
#: judge/models/contest.py:132
|
||||||
|
msgid "freeze after"
|
||||||
|
msgstr "đóng băng sau"
|
||||||
|
|
||||||
|
#: judge/models/contest.py:136
|
||||||
|
msgid ""
|
||||||
|
"Format hh:mm:ss. For example, if you want to freeze contest after 2 hours, "
|
||||||
|
"enter 02:00:00"
|
||||||
|
msgstr ""
|
||||||
|
"Định dạng hh:mm:ss (giờ:phút:giây). Ví dụ, nếu muốn đóng băng kỳ thi sau 2h, hãy "
|
||||||
|
"nhập 02:00:00"
|
||||||
|
|
||||||
|
#: judge/models/contest.py:140 judge/models/problem.py:222
|
||||||
msgid "publicly visible"
|
msgid "publicly visible"
|
||||||
msgstr "công khai"
|
msgstr "công khai"
|
||||||
|
|
||||||
#: judge/models/contest.py:135
|
#: judge/models/contest.py:143
|
||||||
msgid ""
|
msgid ""
|
||||||
"Should be set even for organization-private contests, where it determines "
|
"Should be set even for organization-private contests, where it determines "
|
||||||
"whether the contest is visible to members of the specified organizations."
|
"whether the contest is visible to members of the specified organizations."
|
||||||
|
@ -783,84 +795,84 @@ msgstr ""
|
||||||
"Đánh dấu ngay cả với các kỳ thi riêng tư của nhóm, quyết định việc kỳ thi có "
|
"Đánh dấu ngay cả với các kỳ thi riêng tư của nhóm, quyết định việc kỳ thi có "
|
||||||
"được hiển thị với các thành viên hay không."
|
"được hiển thị với các thành viên hay không."
|
||||||
|
|
||||||
#: judge/models/contest.py:141
|
#: judge/models/contest.py:149
|
||||||
msgid "contest rated"
|
msgid "contest rated"
|
||||||
msgstr "kỳ thi được xếp hạng"
|
msgstr "kỳ thi được xếp hạng"
|
||||||
|
|
||||||
#: judge/models/contest.py:142
|
#: judge/models/contest.py:150
|
||||||
msgid "Whether this contest can be rated."
|
msgid "Whether this contest can be rated."
|
||||||
msgstr "Quyết định kỳ thi có được xếp hạng không."
|
msgstr "Quyết định kỳ thi có được xếp hạng không."
|
||||||
|
|
||||||
#: judge/models/contest.py:146
|
#: judge/models/contest.py:154
|
||||||
msgid "scoreboard visibility"
|
msgid "scoreboard visibility"
|
||||||
msgstr "khả năng hiển thị của bảng điểm"
|
msgstr "khả năng hiển thị của bảng điểm"
|
||||||
|
|
||||||
#: judge/models/contest.py:149
|
#: judge/models/contest.py:157
|
||||||
msgid "Scoreboard visibility through the duration of the contest"
|
msgid "Scoreboard visibility through the duration of the contest"
|
||||||
msgstr "Khả năng hiển thị của bảng điểm trong thời gian kỳ thi"
|
msgstr "Khả năng hiển thị của bảng điểm trong thời gian kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:154
|
#: judge/models/contest.py:162
|
||||||
msgid "view contest scoreboard"
|
msgid "view contest scoreboard"
|
||||||
msgstr "xem bảng điểm kỳ thi"
|
msgstr "xem bảng điểm kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:157
|
#: judge/models/contest.py:165
|
||||||
msgid "These users will be able to view the scoreboard."
|
msgid "These users will be able to view the scoreboard."
|
||||||
msgstr "Những người dùng này được phép xem bảng điểm."
|
msgstr "Những người dùng này được phép xem bảng điểm."
|
||||||
|
|
||||||
#: judge/models/contest.py:160
|
#: judge/models/contest.py:168
|
||||||
msgid "no comments"
|
msgid "no comments"
|
||||||
msgstr "không bình luận"
|
msgstr "không bình luận"
|
||||||
|
|
||||||
#: judge/models/contest.py:161
|
#: judge/models/contest.py:169
|
||||||
msgid "Use clarification system instead of comments."
|
msgid "Use clarification system instead of comments."
|
||||||
msgstr "Dùng hệ thống thông báo thay vì bình luận."
|
msgstr "Dùng hệ thống thông báo thay vì bình luận."
|
||||||
|
|
||||||
#: judge/models/contest.py:166
|
#: judge/models/contest.py:174
|
||||||
msgid "Rating floor for contest"
|
msgid "Rating floor for contest"
|
||||||
msgstr "Cận dưới rating được xếp hạng trong kỳ thi"
|
msgstr "Cận dưới rating được xếp hạng trong kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:172
|
#: judge/models/contest.py:180
|
||||||
msgid "Rating ceiling for contest"
|
msgid "Rating ceiling for contest"
|
||||||
msgstr "Cận trên rating được xếp hạng trong kỳ thi"
|
msgstr "Cận trên rating được xếp hạng trong kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:177
|
#: judge/models/contest.py:185
|
||||||
msgid "rate all"
|
msgid "rate all"
|
||||||
msgstr "xếp hạng tất cả"
|
msgstr "xếp hạng tất cả"
|
||||||
|
|
||||||
#: judge/models/contest.py:178
|
#: judge/models/contest.py:186
|
||||||
msgid "Rate all users who joined."
|
msgid "Rate all users who joined."
|
||||||
msgstr "Xếp hạng tất cả người dùng đã tham gia (kể cả không nộp)."
|
msgstr "Xếp hạng tất cả người dùng đã tham gia (kể cả không nộp)."
|
||||||
|
|
||||||
#: judge/models/contest.py:183
|
#: judge/models/contest.py:191
|
||||||
msgid "exclude from ratings"
|
msgid "exclude from ratings"
|
||||||
msgstr "không xếp hạng"
|
msgstr "không xếp hạng"
|
||||||
|
|
||||||
#: judge/models/contest.py:188
|
#: judge/models/contest.py:196
|
||||||
msgid "private to specific users"
|
msgid "private to specific users"
|
||||||
msgstr "riêng tư với các người dùng này"
|
msgstr "riêng tư với các người dùng này"
|
||||||
|
|
||||||
#: judge/models/contest.py:193
|
#: judge/models/contest.py:201
|
||||||
msgid "private contestants"
|
msgid "private contestants"
|
||||||
msgstr "thí sinh riêng tư"
|
msgstr "thí sinh riêng tư"
|
||||||
|
|
||||||
#: judge/models/contest.py:194
|
#: judge/models/contest.py:202
|
||||||
msgid "If private, only these users may see the contest"
|
msgid "If private, only these users may see the contest"
|
||||||
msgstr "Nếu riêng tư, chỉ những người dùng này mới thấy kỳ thi"
|
msgstr "Nếu riêng tư, chỉ những người dùng này mới thấy kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:198
|
#: judge/models/contest.py:206
|
||||||
msgid "hide problem tags"
|
msgid "hide problem tags"
|
||||||
msgstr "ẩn nhãn kỳ thi"
|
msgstr "ẩn nhãn kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:199
|
#: judge/models/contest.py:207
|
||||||
msgid "Whether problem tags should be hidden by default."
|
msgid "Whether problem tags should be hidden by default."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Quyết định việc nhãn bài tập (DP, Tham lam, ...) được ẩn trong kỳ thi không."
|
"Quyết định việc nhãn bài tập (DP, Tham lam, ...) được ẩn trong kỳ thi không."
|
||||||
|
|
||||||
#: judge/models/contest.py:203
|
#: judge/models/contest.py:211
|
||||||
msgid "run pretests only"
|
msgid "run pretests only"
|
||||||
msgstr "chỉ chạy pretests"
|
msgstr "chỉ chạy pretests"
|
||||||
|
|
||||||
#: judge/models/contest.py:205
|
#: judge/models/contest.py:213
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether judges should grade pretests only, versus all testcases. Commonly "
|
"Whether judges should grade pretests only, versus all testcases. Commonly "
|
||||||
"set during a contest, then unset prior to rejudging user submissions when "
|
"set during a contest, then unset prior to rejudging user submissions when "
|
||||||
|
@ -869,50 +881,50 @@ msgstr ""
|
||||||
"Quyết định việc các máy chấm chỉ chấm pretests thay vì tất cả các test. Sau "
|
"Quyết định việc các máy chấm chỉ chấm pretests thay vì tất cả các test. Sau "
|
||||||
"kỳ thi, hãy bỏ đánh dấu ô này và chấm lại tất cả các bài."
|
"kỳ thi, hãy bỏ đánh dấu ô này và chấm lại tất cả các bài."
|
||||||
|
|
||||||
#: judge/models/contest.py:212 judge/models/interface.py:92
|
#: judge/models/contest.py:220 judge/models/interface.py:92
|
||||||
#: judge/models/problem.py:279
|
#: judge/models/problem.py:279
|
||||||
msgid "private to organizations"
|
msgid "private to organizations"
|
||||||
msgstr "riêng tư với các tổ chức"
|
msgstr "riêng tư với các tổ chức"
|
||||||
|
|
||||||
#: judge/models/contest.py:217 judge/models/interface.py:88
|
#: judge/models/contest.py:225 judge/models/interface.py:88
|
||||||
#: judge/models/problem.py:275 judge/models/profile.py:126
|
#: judge/models/problem.py:275 judge/models/profile.py:126
|
||||||
msgid "organizations"
|
msgid "organizations"
|
||||||
msgstr "tổ chức"
|
msgstr "tổ chức"
|
||||||
|
|
||||||
#: judge/models/contest.py:218
|
#: judge/models/contest.py:226
|
||||||
msgid "If private, only these organizations may see the contest"
|
msgid "If private, only these organizations may see the contest"
|
||||||
msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ thi"
|
msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:221 judge/models/problem.py:253
|
#: judge/models/contest.py:229 judge/models/problem.py:253
|
||||||
msgid "OpenGraph image"
|
msgid "OpenGraph image"
|
||||||
msgstr "Hình ảnh OpenGraph"
|
msgstr "Hình ảnh OpenGraph"
|
||||||
|
|
||||||
#: judge/models/contest.py:224 judge/models/profile.py:81
|
#: judge/models/contest.py:232 judge/models/profile.py:81
|
||||||
msgid "Logo override image"
|
msgid "Logo override image"
|
||||||
msgstr "Hình ảnh ghi đè logo"
|
msgstr "Hình ảnh ghi đè logo"
|
||||||
|
|
||||||
#: judge/models/contest.py:229
|
#: judge/models/contest.py:237
|
||||||
msgid ""
|
msgid ""
|
||||||
"This image will replace the default site logo for users inside the contest."
|
"This image will replace the default site logo for users inside the contest."
|
||||||
msgstr "Ảnh này sẽ thay thế cho logo mặc định trong kỳ thi."
|
msgstr "Ảnh này sẽ thay thế cho logo mặc định trong kỳ thi."
|
||||||
|
|
||||||
#: judge/models/contest.py:237
|
#: judge/models/contest.py:245
|
||||||
msgid "the amount of live participants"
|
msgid "the amount of live participants"
|
||||||
msgstr "số lượng thí sinh thi trực tiếp"
|
msgstr "số lượng thí sinh thi trực tiếp"
|
||||||
|
|
||||||
#: judge/models/contest.py:241
|
#: judge/models/contest.py:249
|
||||||
msgid "contest summary"
|
msgid "contest summary"
|
||||||
msgstr "tổng kết kỳ thi"
|
msgstr "tổng kết kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:243 judge/models/problem.py:259
|
#: judge/models/contest.py:251 judge/models/problem.py:259
|
||||||
msgid "Plain-text, shown in meta description tag, e.g. for social media."
|
msgid "Plain-text, shown in meta description tag, e.g. for social media."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:247 judge/models/profile.py:76
|
#: judge/models/contest.py:255 judge/models/profile.py:76
|
||||||
msgid "access code"
|
msgid "access code"
|
||||||
msgstr "mật khẩu truy cập"
|
msgstr "mật khẩu truy cập"
|
||||||
|
|
||||||
#: judge/models/contest.py:252
|
#: judge/models/contest.py:260
|
||||||
msgid ""
|
msgid ""
|
||||||
"An optional code to prompt contestants before they are allowed to join the "
|
"An optional code to prompt contestants before they are allowed to join the "
|
||||||
"contest. Leave it blank to disable."
|
"contest. Leave it blank to disable."
|
||||||
|
@ -920,267 +932,267 @@ msgstr ""
|
||||||
"Mật khẩu truy cập cho các thí sinh muốn tham gia kỳ thi. Để trống nếu không "
|
"Mật khẩu truy cập cho các thí sinh muốn tham gia kỳ thi. Để trống nếu không "
|
||||||
"dùng."
|
"dùng."
|
||||||
|
|
||||||
#: judge/models/contest.py:258 judge/models/problem.py:241
|
#: judge/models/contest.py:266 judge/models/problem.py:241
|
||||||
msgid "personae non gratae"
|
msgid "personae non gratae"
|
||||||
msgstr "Chặn tham gia"
|
msgstr "Chặn tham gia"
|
||||||
|
|
||||||
#: judge/models/contest.py:260
|
#: judge/models/contest.py:268
|
||||||
msgid "Bans the selected users from joining this contest."
|
msgid "Bans the selected users from joining this contest."
|
||||||
msgstr "Cấm những người dùng được chọn tham gia kỳ thi."
|
msgstr "Cấm những người dùng được chọn tham gia kỳ thi."
|
||||||
|
|
||||||
#: judge/models/contest.py:263
|
#: judge/models/contest.py:271
|
||||||
msgid "contest format"
|
msgid "contest format"
|
||||||
msgstr "format kỳ thi"
|
msgstr "format kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:267
|
#: judge/models/contest.py:275
|
||||||
msgid "The contest format module to use."
|
msgid "The contest format module to use."
|
||||||
msgstr "Format kỳ thi sử dụng."
|
msgstr "Format kỳ thi sử dụng."
|
||||||
|
|
||||||
#: judge/models/contest.py:270
|
#: judge/models/contest.py:278
|
||||||
msgid "contest format configuration"
|
msgid "contest format configuration"
|
||||||
msgstr "Tùy chỉnh format kỳ thi"
|
msgstr "Tùy chỉnh format kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:274
|
#: judge/models/contest.py:282
|
||||||
msgid ""
|
msgid ""
|
||||||
"A JSON object to serve as the configuration for the chosen contest format "
|
"A JSON object to serve as the configuration for the chosen contest format "
|
||||||
"module. Leave empty to use None. Exact format depends on the contest format "
|
"module. Leave empty to use None. Exact format depends on the contest format "
|
||||||
"selected."
|
"selected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:287
|
#: judge/models/contest.py:295
|
||||||
msgid "precision points"
|
msgid "precision points"
|
||||||
msgstr "Hiển thị điểm"
|
msgstr "Hiển thị điểm"
|
||||||
|
|
||||||
#: judge/models/contest.py:290
|
#: judge/models/contest.py:298
|
||||||
msgid "Number of digits to round points to."
|
msgid "Number of digits to round points to."
|
||||||
msgstr "Số chữ số thập phân trên bảng điểm."
|
msgstr "Số chữ số thập phân trên bảng điểm."
|
||||||
|
|
||||||
#: judge/models/contest.py:595
|
#: judge/models/contest.py:603
|
||||||
msgid "See private contests"
|
msgid "See private contests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:596
|
#: judge/models/contest.py:604
|
||||||
msgid "Edit own contests"
|
msgid "Edit own contests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:597
|
#: judge/models/contest.py:605
|
||||||
msgid "Edit all contests"
|
msgid "Edit all contests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:598
|
#: judge/models/contest.py:606
|
||||||
msgid "Clone contest"
|
msgid "Clone contest"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:599 templates/contest/moss.html:74
|
#: judge/models/contest.py:607 templates/contest/moss.html:74
|
||||||
msgid "MOSS contest"
|
msgid "MOSS contest"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:600
|
#: judge/models/contest.py:608
|
||||||
msgid "Rate contests"
|
msgid "Rate contests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:601
|
#: judge/models/contest.py:609
|
||||||
msgid "Contest access codes"
|
msgid "Contest access codes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:602
|
#: judge/models/contest.py:610
|
||||||
msgid "Create private contests"
|
msgid "Create private contests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:603
|
#: judge/models/contest.py:611
|
||||||
msgid "Change contest visibility"
|
msgid "Change contest visibility"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:604
|
#: judge/models/contest.py:612
|
||||||
msgid "Edit contest problem label script"
|
msgid "Edit contest problem label script"
|
||||||
msgstr "Cách hiển thị thứ tự bài tập"
|
msgstr "Cách hiển thị thứ tự bài tập"
|
||||||
|
|
||||||
#: judge/models/contest.py:606 judge/models/contest.py:744
|
#: judge/models/contest.py:614 judge/models/contest.py:752
|
||||||
#: judge/models/contest.py:818 judge/models/contest.py:848
|
#: judge/models/contest.py:826 judge/models/contest.py:856
|
||||||
#: judge/models/submission.py:116
|
#: judge/models/submission.py:116
|
||||||
msgid "contest"
|
msgid "contest"
|
||||||
msgstr "kỳ thi"
|
msgstr "kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:607
|
#: judge/models/contest.py:615
|
||||||
msgid "contests"
|
msgid "contests"
|
||||||
msgstr "kỳ thi"
|
msgstr "kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:616
|
#: judge/models/contest.py:624
|
||||||
msgid "associated contest"
|
msgid "associated contest"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:629
|
#: judge/models/contest.py:637
|
||||||
msgid "score"
|
msgid "score"
|
||||||
msgstr "điểm"
|
msgstr "điểm"
|
||||||
|
|
||||||
#: judge/models/contest.py:630
|
#: judge/models/contest.py:638
|
||||||
msgid "cumulative time"
|
msgid "cumulative time"
|
||||||
msgstr "tổng thời gian"
|
msgstr "tổng thời gian"
|
||||||
|
|
||||||
#: judge/models/contest.py:632
|
#: judge/models/contest.py:640
|
||||||
msgid "is disqualified"
|
msgid "is disqualified"
|
||||||
msgstr "đã bị loại"
|
msgstr "đã bị loại"
|
||||||
|
|
||||||
#: judge/models/contest.py:634
|
#: judge/models/contest.py:642
|
||||||
msgid "Whether this participation is disqualified."
|
msgid "Whether this participation is disqualified."
|
||||||
msgstr "Quyết định thí sinh có bị loại không."
|
msgstr "Quyết định thí sinh có bị loại không."
|
||||||
|
|
||||||
#: judge/models/contest.py:636
|
#: judge/models/contest.py:644
|
||||||
msgid "tie-breaking field"
|
msgid "tie-breaking field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:638
|
#: judge/models/contest.py:646
|
||||||
msgid "virtual participation id"
|
msgid "virtual participation id"
|
||||||
msgstr "id lần tham gia ảo"
|
msgstr "id lần tham gia ảo"
|
||||||
|
|
||||||
#: judge/models/contest.py:640
|
#: judge/models/contest.py:648
|
||||||
msgid "0 means non-virtual, otherwise the n-th virtual participation."
|
msgid "0 means non-virtual, otherwise the n-th virtual participation."
|
||||||
msgstr "0 nghĩa là tham gia chính thức, ngược lại là lần tham gia ảo thứ n."
|
msgstr "0 nghĩa là tham gia chính thức, ngược lại là lần tham gia ảo thứ n."
|
||||||
|
|
||||||
#: judge/models/contest.py:643
|
#: judge/models/contest.py:651
|
||||||
msgid "contest format specific data"
|
msgid "contest format specific data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:719
|
#: judge/models/contest.py:727
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s spectating in %s"
|
msgid "%s spectating in %s"
|
||||||
msgstr "%s đang theo dõi trong %s"
|
msgstr "%s đang theo dõi trong %s"
|
||||||
|
|
||||||
#: judge/models/contest.py:724
|
#: judge/models/contest.py:732
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s in %s, v%d"
|
msgid "%s in %s, v%d"
|
||||||
msgstr "%s trong %s, v%d"
|
msgstr "%s trong %s, v%d"
|
||||||
|
|
||||||
#: judge/models/contest.py:729
|
#: judge/models/contest.py:737
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s in %s"
|
msgid "%s in %s"
|
||||||
msgstr "%s trong %s"
|
msgstr "%s trong %s"
|
||||||
|
|
||||||
#: judge/models/contest.py:732
|
#: judge/models/contest.py:740
|
||||||
msgid "contest participation"
|
msgid "contest participation"
|
||||||
msgstr "lần tham gia kỳ thi"
|
msgstr "lần tham gia kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:733
|
#: judge/models/contest.py:741
|
||||||
msgid "contest participations"
|
msgid "contest participations"
|
||||||
msgstr "lần tham gia kỳ thi"
|
msgstr "lần tham gia kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:740 judge/models/contest.py:789
|
#: judge/models/contest.py:748 judge/models/contest.py:797
|
||||||
#: judge/models/contest.py:851 judge/models/problem.py:558
|
#: judge/models/contest.py:859 judge/models/problem.py:558
|
||||||
#: judge/models/problem.py:565 judge/models/problem.py:586
|
#: judge/models/problem.py:565 judge/models/problem.py:586
|
||||||
#: judge/models/problem.py:617 judge/models/problem_data.py:50
|
#: judge/models/problem.py:617 judge/models/problem_data.py:50
|
||||||
msgid "problem"
|
msgid "problem"
|
||||||
msgstr "bài tập"
|
msgstr "bài tập"
|
||||||
|
|
||||||
#: judge/models/contest.py:748 judge/models/contest.py:801
|
#: judge/models/contest.py:756 judge/models/contest.py:809
|
||||||
#: judge/models/problem.py:206
|
#: judge/models/problem.py:206
|
||||||
msgid "points"
|
msgid "points"
|
||||||
msgstr "điểm"
|
msgstr "điểm"
|
||||||
|
|
||||||
#: judge/models/contest.py:749
|
#: judge/models/contest.py:757
|
||||||
msgid "partial"
|
msgid "partial"
|
||||||
msgstr "thành phần"
|
msgstr "thành phần"
|
||||||
|
|
||||||
#: judge/models/contest.py:750 judge/models/contest.py:803
|
#: judge/models/contest.py:758 judge/models/contest.py:811
|
||||||
msgid "is pretested"
|
msgid "is pretested"
|
||||||
msgstr "dùng pretest"
|
msgstr "dùng pretest"
|
||||||
|
|
||||||
#: judge/models/contest.py:751 judge/models/interface.py:43
|
#: judge/models/contest.py:759 judge/models/interface.py:43
|
||||||
msgid "order"
|
msgid "order"
|
||||||
msgstr "thứ tự"
|
msgstr "thứ tự"
|
||||||
|
|
||||||
#: judge/models/contest.py:753
|
#: judge/models/contest.py:761
|
||||||
msgid "0 to not show testcases, 1 to show"
|
msgid "0 to not show testcases, 1 to show"
|
||||||
msgstr "0 để ẩn test, 1 để hiện"
|
msgstr "0 để ẩn test, 1 để hiện"
|
||||||
|
|
||||||
#: judge/models/contest.py:754
|
#: judge/models/contest.py:762
|
||||||
msgid "visible testcases"
|
msgid "visible testcases"
|
||||||
msgstr "hiển thị test"
|
msgstr "hiển thị test"
|
||||||
|
|
||||||
#: judge/models/contest.py:761
|
#: judge/models/contest.py:769
|
||||||
msgid "Maximum number of submissions for this problem, or 0 for no limit."
|
msgid "Maximum number of submissions for this problem, or 0 for no limit."
|
||||||
msgstr "Số lần nộp tối đa, đặt là 0 nếu không có giới hạn."
|
msgstr "Số lần nộp tối đa, đặt là 0 nếu không có giới hạn."
|
||||||
|
|
||||||
#: judge/models/contest.py:763
|
#: judge/models/contest.py:771
|
||||||
msgid "max submissions"
|
msgid "max submissions"
|
||||||
msgstr "số lần nộp tối đa"
|
msgstr "số lần nộp tối đa"
|
||||||
|
|
||||||
#: judge/models/contest.py:766
|
#: judge/models/contest.py:774
|
||||||
msgid "Why include a problem you can't submit to?"
|
msgid "Why include a problem you can't submit to?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:776
|
#: judge/models/contest.py:784
|
||||||
msgid "contest problem"
|
msgid "contest problem"
|
||||||
msgstr "bài trong kỳ thi"
|
msgstr "bài trong kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:777
|
#: judge/models/contest.py:785
|
||||||
msgid "contest problems"
|
msgid "contest problems"
|
||||||
msgstr "bài trong kỳ thi"
|
msgstr "bài trong kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:783 judge/models/submission.py:233
|
#: judge/models/contest.py:791 judge/models/submission.py:233
|
||||||
msgid "submission"
|
msgid "submission"
|
||||||
msgstr "bài nộp"
|
msgstr "bài nộp"
|
||||||
|
|
||||||
#: judge/models/contest.py:796 judge/models/contest.py:822
|
#: judge/models/contest.py:804 judge/models/contest.py:830
|
||||||
msgid "participation"
|
msgid "participation"
|
||||||
msgstr "lần tham gia"
|
msgstr "lần tham gia"
|
||||||
|
|
||||||
#: judge/models/contest.py:804
|
#: judge/models/contest.py:812
|
||||||
msgid "Whether this submission was ran only on pretests."
|
msgid "Whether this submission was ran only on pretests."
|
||||||
msgstr "Quyết định bài nộp chỉ được chạy trên pretest không."
|
msgstr "Quyết định bài nộp chỉ được chạy trên pretest không."
|
||||||
|
|
||||||
#: judge/models/contest.py:809
|
#: judge/models/contest.py:817
|
||||||
msgid "contest submission"
|
msgid "contest submission"
|
||||||
msgstr "bài nộp kỳ thi"
|
msgstr "bài nộp kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:810
|
#: judge/models/contest.py:818
|
||||||
msgid "contest submissions"
|
msgid "contest submissions"
|
||||||
msgstr "bài nộp kỳ thi"
|
msgstr "bài nộp kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:826
|
#: judge/models/contest.py:834
|
||||||
msgid "rank"
|
msgid "rank"
|
||||||
msgstr "rank"
|
msgstr "rank"
|
||||||
|
|
||||||
#: judge/models/contest.py:827
|
#: judge/models/contest.py:835
|
||||||
msgid "rating"
|
msgid "rating"
|
||||||
msgstr "rating"
|
msgstr "rating"
|
||||||
|
|
||||||
#: judge/models/contest.py:828
|
#: judge/models/contest.py:836
|
||||||
msgid "raw rating"
|
msgid "raw rating"
|
||||||
msgstr "rating thật"
|
msgstr "rating thật"
|
||||||
|
|
||||||
#: judge/models/contest.py:829
|
#: judge/models/contest.py:837
|
||||||
msgid "contest performance"
|
msgid "contest performance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:830
|
#: judge/models/contest.py:838
|
||||||
msgid "last rated"
|
msgid "last rated"
|
||||||
msgstr "lần cuối được xếp hạng"
|
msgstr "lần cuối được xếp hạng"
|
||||||
|
|
||||||
#: judge/models/contest.py:834
|
#: judge/models/contest.py:842
|
||||||
msgid "contest rating"
|
msgid "contest rating"
|
||||||
msgstr "rating kỳ thi"
|
msgstr "rating kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:835
|
#: judge/models/contest.py:843
|
||||||
msgid "contest ratings"
|
msgid "contest ratings"
|
||||||
msgstr "rating kỳ thi"
|
msgstr "rating kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:859
|
#: judge/models/contest.py:867
|
||||||
msgid "contest moss result"
|
msgid "contest moss result"
|
||||||
msgstr "kết quả MOSS kỳ thi"
|
msgstr "kết quả MOSS kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:860
|
#: judge/models/contest.py:868
|
||||||
msgid "contest moss results"
|
msgid "contest moss results"
|
||||||
msgstr "kết quả MOSS kỳ thi"
|
msgstr "kết quả MOSS kỳ thi"
|
||||||
|
|
||||||
#: judge/models/contest.py:865
|
#: judge/models/contest.py:873
|
||||||
msgid "clarified problem"
|
msgid "clarified problem"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:867
|
#: judge/models/contest.py:875
|
||||||
msgid "clarification body"
|
msgid "clarification body"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:869
|
#: judge/models/contest.py:877
|
||||||
msgid "clarification timestamp"
|
msgid "clarification timestamp"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2554,7 +2566,7 @@ msgid "Editing comment"
|
||||||
msgstr "Chỉnh sửa bình luận"
|
msgstr "Chỉnh sửa bình luận"
|
||||||
|
|
||||||
#: judge/views/contests.py:119 judge/views/contests.py:367
|
#: judge/views/contests.py:119 judge/views/contests.py:367
|
||||||
#: judge/views/contests.py:372 judge/views/contests.py:613
|
#: judge/views/contests.py:372 judge/views/contests.py:619
|
||||||
msgid "No such contest"
|
msgid "No such contest"
|
||||||
msgstr "Không có contest nào như vậy"
|
msgstr "Không có contest nào như vậy"
|
||||||
|
|
||||||
|
@ -2578,113 +2590,113 @@ msgstr "Không tìm thấy kỳ thi nào như vậy."
|
||||||
msgid "Access to contest \"%s\" denied"
|
msgid "Access to contest \"%s\" denied"
|
||||||
msgstr "Truy cập tới kỳ thi \"%s\" bị từ chối"
|
msgstr "Truy cập tới kỳ thi \"%s\" bị từ chối"
|
||||||
|
|
||||||
#: judge/views/contests.py:418
|
#: judge/views/contests.py:424
|
||||||
msgid "Clone Contest"
|
msgid "Clone Contest"
|
||||||
msgstr "Nhân bản kỳ thi"
|
msgstr "Nhân bản kỳ thi"
|
||||||
|
|
||||||
#: judge/views/contests.py:487
|
#: judge/views/contests.py:493
|
||||||
msgid "Contest not ongoing"
|
msgid "Contest not ongoing"
|
||||||
msgstr "Kỳ thi đang không diễn ra"
|
msgstr "Kỳ thi đang không diễn ra"
|
||||||
|
|
||||||
#: judge/views/contests.py:488
|
#: judge/views/contests.py:494
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "\"%s\" is not currently ongoing."
|
msgid "\"%s\" is not currently ongoing."
|
||||||
msgstr "\"%s\" kỳ thi đang không diễn ra."
|
msgstr "\"%s\" kỳ thi đang không diễn ra."
|
||||||
|
|
||||||
#: judge/views/contests.py:495
|
#: judge/views/contests.py:501
|
||||||
msgid "Already in contest"
|
msgid "Already in contest"
|
||||||
msgstr "Đã ở trong kỳ thi"
|
msgstr "Đã ở trong kỳ thi"
|
||||||
|
|
||||||
#: judge/views/contests.py:496
|
#: judge/views/contests.py:502
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You are already in a contest: \"%s\"."
|
msgid "You are already in a contest: \"%s\"."
|
||||||
msgstr "Bạn đã ở trong kỳ thi: \"%s\"."
|
msgstr "Bạn đã ở trong kỳ thi: \"%s\"."
|
||||||
|
|
||||||
#: judge/views/contests.py:506
|
#: judge/views/contests.py:512
|
||||||
msgid "Banned from joining"
|
msgid "Banned from joining"
|
||||||
msgstr "Bị cấm tham gia"
|
msgstr "Bị cấm tham gia"
|
||||||
|
|
||||||
#: judge/views/contests.py:508
|
#: judge/views/contests.py:514
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have been declared persona non grata for this contest. You are "
|
"You have been declared persona non grata for this contest. You are "
|
||||||
"permanently barred from joining this contest."
|
"permanently barred from joining this contest."
|
||||||
msgstr "Bạn không được phép tham gia kỳ thi này."
|
msgstr "Bạn không được phép tham gia kỳ thi này."
|
||||||
|
|
||||||
#: judge/views/contests.py:597
|
#: judge/views/contests.py:603
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Enter access code for \"%s\""
|
msgid "Enter access code for \"%s\""
|
||||||
msgstr "Nhập mật khẩu truy cập cho \"%s\""
|
msgstr "Nhập mật khẩu truy cập cho \"%s\""
|
||||||
|
|
||||||
#: judge/views/contests.py:614
|
#: judge/views/contests.py:620
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You are not in contest \"%s\"."
|
msgid "You are not in contest \"%s\"."
|
||||||
msgstr "Bạn không ở trong kỳ thi \"%s\"."
|
msgstr "Bạn không ở trong kỳ thi \"%s\"."
|
||||||
|
|
||||||
#: judge/views/contests.py:637
|
#: judge/views/contests.py:643
|
||||||
msgid "ContestCalendar requires integer year and month"
|
msgid "ContestCalendar requires integer year and month"
|
||||||
msgstr "Lịch thi yêu cầu giá trị cho năm và tháng là số nguyên"
|
msgstr "Lịch thi yêu cầu giá trị cho năm và tháng là số nguyên"
|
||||||
|
|
||||||
#: judge/views/contests.py:695
|
#: judge/views/contests.py:701
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Contests in %(month)s"
|
msgid "Contests in %(month)s"
|
||||||
msgstr "Các kỳ thi trong %(month)s"
|
msgstr "Các kỳ thi trong %(month)s"
|
||||||
|
|
||||||
#: judge/views/contests.py:696
|
#: judge/views/contests.py:702
|
||||||
msgid "F Y"
|
msgid "F Y"
|
||||||
msgstr "F Y"
|
msgstr "F Y"
|
||||||
|
|
||||||
#: judge/views/contests.py:756
|
#: judge/views/contests.py:762
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s Statistics"
|
msgid "%s Statistics"
|
||||||
msgstr "%s Thống kê"
|
msgstr "%s Thống kê"
|
||||||
|
|
||||||
#: judge/views/contests.py:1013
|
#: judge/views/contests.py:1019
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s Rankings"
|
msgid "%s Rankings"
|
||||||
msgstr "%s Bảng điểm"
|
msgstr "%s Bảng điểm"
|
||||||
|
|
||||||
#: judge/views/contests.py:1024
|
#: judge/views/contests.py:1030
|
||||||
msgid "???"
|
msgid "???"
|
||||||
msgstr "???"
|
msgstr "???"
|
||||||
|
|
||||||
#: judge/views/contests.py:1040
|
#: judge/views/contests.py:1046
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Your participation in %s"
|
msgid "Your participation in %s"
|
||||||
msgstr "Lần tham gia trong %s"
|
msgstr "Lần tham gia trong %s"
|
||||||
|
|
||||||
#: judge/views/contests.py:1041
|
#: judge/views/contests.py:1047
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s's participation in %s"
|
msgid "%s's participation in %s"
|
||||||
msgstr "Lần tham gia của %s trong %s"
|
msgstr "Lần tham gia của %s trong %s"
|
||||||
|
|
||||||
#: judge/views/contests.py:1055
|
#: judge/views/contests.py:1061
|
||||||
msgid "Live"
|
msgid "Live"
|
||||||
msgstr "Trực tiếp"
|
msgstr "Trực tiếp"
|
||||||
|
|
||||||
#: judge/views/contests.py:1074 templates/contest/contest-tabs.html:13
|
#: judge/views/contests.py:1080 templates/contest/contest-tabs.html:13
|
||||||
msgid "Participation"
|
msgid "Participation"
|
||||||
msgstr "Lần tham gia"
|
msgstr "Lần tham gia"
|
||||||
|
|
||||||
#: judge/views/contests.py:1123
|
#: judge/views/contests.py:1129
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s MOSS Results"
|
msgid "%s MOSS Results"
|
||||||
msgstr "%s Kết quả MOSS"
|
msgstr "%s Kết quả MOSS"
|
||||||
|
|
||||||
#: judge/views/contests.py:1159
|
#: judge/views/contests.py:1165
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Running MOSS for %s..."
|
msgid "Running MOSS for %s..."
|
||||||
msgstr "Đang chạy MOSS cho %s..."
|
msgstr "Đang chạy MOSS cho %s..."
|
||||||
|
|
||||||
#: judge/views/contests.py:1182
|
#: judge/views/contests.py:1188
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Contest tag: %s"
|
msgid "Contest tag: %s"
|
||||||
msgstr "Nhãn kỳ thi: %s"
|
msgstr "Nhãn kỳ thi: %s"
|
||||||
|
|
||||||
#: judge/views/contests.py:1197 judge/views/ticket.py:72
|
#: judge/views/contests.py:1203 judge/views/ticket.py:72
|
||||||
msgid "Issue description"
|
msgid "Issue description"
|
||||||
msgstr "Mô tả vấn đề"
|
msgstr "Mô tả vấn đề"
|
||||||
|
|
||||||
#: judge/views/contests.py:1244
|
#: judge/views/contests.py:1250
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "New clarification for %s"
|
msgid "New clarification for %s"
|
||||||
msgstr "Thông báo mới cho %s"
|
msgstr "Thông báo mới cho %s"
|
||||||
|
@ -2930,41 +2942,41 @@ msgstr "Hướng dẫn cho {0}"
|
||||||
msgid "Editorial for <a href=\"{1}\">{0}</a>"
|
msgid "Editorial for <a href=\"{1}\">{0}</a>"
|
||||||
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
|
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
|
||||||
|
|
||||||
#: judge/views/problem.py:443 templates/contest/contest.html:81
|
#: judge/views/problem.py:447 templates/contest/contest.html:81
|
||||||
#: templates/organization/org-left-sidebar.html:4
|
#: templates/organization/org-left-sidebar.html:4
|
||||||
#: templates/user/user-about.html:28 templates/user/user-bookmarks.html:32
|
#: templates/user/user-about.html:28 templates/user/user-bookmarks.html:32
|
||||||
#: templates/user/user-tabs.html:5 templates/user/users-table.html:19
|
#: templates/user/user-tabs.html:5 templates/user/users-table.html:19
|
||||||
msgid "Problems"
|
msgid "Problems"
|
||||||
msgstr "Bài tập"
|
msgstr "Bài tập"
|
||||||
|
|
||||||
#: judge/views/problem.py:823
|
#: judge/views/problem.py:827
|
||||||
msgid "Problem feed"
|
msgid "Problem feed"
|
||||||
msgstr "Bài tập"
|
msgstr "Bài tập"
|
||||||
|
|
||||||
#: judge/views/problem.py:1061
|
#: judge/views/problem.py:1065
|
||||||
msgid "Banned from submitting"
|
msgid "Banned from submitting"
|
||||||
msgstr "Bị cấm nộp bài"
|
msgstr "Bị cấm nộp bài"
|
||||||
|
|
||||||
#: judge/views/problem.py:1063
|
#: judge/views/problem.py:1067
|
||||||
msgid ""
|
msgid ""
|
||||||
"You have been declared persona non grata for this problem. You are "
|
"You have been declared persona non grata for this problem. You are "
|
||||||
"permanently barred from submitting this problem."
|
"permanently barred from submitting this problem."
|
||||||
msgstr "Bạn đã bị cấm nộp bài này."
|
msgstr "Bạn đã bị cấm nộp bài này."
|
||||||
|
|
||||||
#: judge/views/problem.py:1086
|
#: judge/views/problem.py:1090
|
||||||
msgid "Too many submissions"
|
msgid "Too many submissions"
|
||||||
msgstr "Quá nhiều lần nộp"
|
msgstr "Quá nhiều lần nộp"
|
||||||
|
|
||||||
#: judge/views/problem.py:1088
|
#: judge/views/problem.py:1092
|
||||||
msgid "You have exceeded the submission limit for this problem."
|
msgid "You have exceeded the submission limit for this problem."
|
||||||
msgstr "Bạn đã vượt quá số lần nộp cho bài này."
|
msgstr "Bạn đã vượt quá số lần nộp cho bài này."
|
||||||
|
|
||||||
#: judge/views/problem.py:1167 judge/views/problem.py:1172
|
#: judge/views/problem.py:1171 judge/views/problem.py:1176
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Submit to %(problem)s"
|
msgid "Submit to %(problem)s"
|
||||||
msgstr "Nộp bài cho %(problem)s"
|
msgstr "Nộp bài cho %(problem)s"
|
||||||
|
|
||||||
#: judge/views/problem.py:1195
|
#: judge/views/problem.py:1199
|
||||||
msgid "Clone Problem"
|
msgid "Clone Problem"
|
||||||
msgstr "Nhân bản bài tập"
|
msgstr "Nhân bản bài tập"
|
||||||
|
|
||||||
|
@ -3138,39 +3150,39 @@ msgstr "Bài nộp của %(user)s cho bài %(problem)s"
|
||||||
msgid "All submissions"
|
msgid "All submissions"
|
||||||
msgstr "Tất cả bài nộp"
|
msgstr "Tất cả bài nộp"
|
||||||
|
|
||||||
#: judge/views/submission.py:495
|
#: judge/views/submission.py:505
|
||||||
msgid "All my submissions"
|
msgid "All my submissions"
|
||||||
msgstr "Tất cả bài nộp của tôi"
|
msgstr "Tất cả bài nộp của tôi"
|
||||||
|
|
||||||
#: judge/views/submission.py:496
|
#: judge/views/submission.py:506
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "All submissions by %s"
|
msgid "All submissions by %s"
|
||||||
msgstr "Tất cả bài nộp của %s"
|
msgstr "Tất cả bài nộp của %s"
|
||||||
|
|
||||||
#: judge/views/submission.py:541
|
#: judge/views/submission.py:551
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "All submissions for %s"
|
msgid "All submissions for %s"
|
||||||
msgstr "Tất cả bài nộp cho %s"
|
msgstr "Tất cả bài nộp cho %s"
|
||||||
|
|
||||||
#: judge/views/submission.py:569
|
#: judge/views/submission.py:579
|
||||||
msgid "Must pass a problem"
|
msgid "Must pass a problem"
|
||||||
msgstr "Phải làm được một bài"
|
msgstr "Phải làm được một bài"
|
||||||
|
|
||||||
#: judge/views/submission.py:627
|
#: judge/views/submission.py:637
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "My submissions for %(problem)s"
|
msgid "My submissions for %(problem)s"
|
||||||
msgstr "Bài nộp của tôi cho %(problem)s"
|
msgstr "Bài nộp của tôi cho %(problem)s"
|
||||||
|
|
||||||
#: judge/views/submission.py:628
|
#: judge/views/submission.py:638
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(user)s's submissions for %(problem)s"
|
msgid "%(user)s's submissions for %(problem)s"
|
||||||
msgstr "Các bài nộp của %(user)s cho %(problem)s"
|
msgstr "Các bài nộp của %(user)s cho %(problem)s"
|
||||||
|
|
||||||
#: judge/views/submission.py:758
|
#: judge/views/submission.py:768
|
||||||
msgid "Must pass a contest"
|
msgid "Must pass a contest"
|
||||||
msgstr "Phải qua một kỳ thi"
|
msgstr "Phải qua một kỳ thi"
|
||||||
|
|
||||||
#: judge/views/submission.py:788
|
#: judge/views/submission.py:798
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<a href=\"{1}\">{0}</a>'s submissions for <a href=\"{3}\">{2}</a> in <a href="
|
"<a href=\"{1}\">{0}</a>'s submissions for <a href=\"{3}\">{2}</a> in <a href="
|
||||||
|
@ -3179,7 +3191,7 @@ msgstr ""
|
||||||
"Các bài nộp của <a href=\"{1}\">{0}</a> cho <a href=\"{3}\">{2}</a> trong <a "
|
"Các bài nộp của <a href=\"{1}\">{0}</a> cho <a href=\"{3}\">{2}</a> trong <a "
|
||||||
"href=\"{5}\">{4}</a>"
|
"href=\"{5}\">{4}</a>"
|
||||||
|
|
||||||
#: judge/views/submission.py:800
|
#: judge/views/submission.py:810
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<a href=\"{1}\">{0}</a>'s submissions for problem {2} in <a href=\"{4}\">{3}"
|
"<a href=\"{1}\">{0}</a>'s submissions for problem {2} in <a href=\"{4}\">{3}"
|
||||||
|
@ -3188,7 +3200,7 @@ msgstr ""
|
||||||
"Các bài nộp của <a href=\"{1}\">{0}</a> cho bài {2} trong <a href=\"{4}\">{3}"
|
"Các bài nộp của <a href=\"{1}\">{0}</a> cho bài {2} trong <a href=\"{4}\">{3}"
|
||||||
"</a>"
|
"</a>"
|
||||||
|
|
||||||
#: judge/views/submission.py:851
|
#: judge/views/submission.py:861
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "You do not have the permission to rejudge submissions."
|
#| msgid "You do not have the permission to rejudge submissions."
|
||||||
msgid "You don't have permission to access."
|
msgid "You don't have permission to access."
|
||||||
|
@ -3248,48 +3260,48 @@ msgstr "Hủy kích hoạt Two Factor Authentication"
|
||||||
msgid "Perform Two Factor Authentication"
|
msgid "Perform Two Factor Authentication"
|
||||||
msgstr "Thực hiện Two Factor Authentication"
|
msgstr "Thực hiện Two Factor Authentication"
|
||||||
|
|
||||||
#: judge/views/user.py:90
|
#: judge/views/user.py:97
|
||||||
msgid "No such user"
|
msgid "No such user"
|
||||||
msgstr "Không người dùng nào như vậy"
|
msgstr "Không người dùng nào như vậy"
|
||||||
|
|
||||||
#: judge/views/user.py:91
|
#: judge/views/user.py:98
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "No user handle \"%s\"."
|
msgid "No user handle \"%s\"."
|
||||||
msgstr "Không tồn tại tên người dùng \"%s\"."
|
msgstr "Không tồn tại tên người dùng \"%s\"."
|
||||||
|
|
||||||
#: judge/views/user.py:96
|
#: judge/views/user.py:103
|
||||||
msgid "My account"
|
msgid "My account"
|
||||||
msgstr "Tài khoản của tôi"
|
msgstr "Tài khoản của tôi"
|
||||||
|
|
||||||
#: judge/views/user.py:98
|
#: judge/views/user.py:105
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User %s"
|
msgid "User %s"
|
||||||
msgstr "Thành viên %s"
|
msgstr "Thành viên %s"
|
||||||
|
|
||||||
#: judge/views/user.py:196
|
#: judge/views/user.py:203
|
||||||
msgid "M j, Y"
|
msgid "M j, Y"
|
||||||
msgstr "j M, Y"
|
msgstr "j M, Y"
|
||||||
|
|
||||||
#: judge/views/user.py:231
|
#: judge/views/user.py:238
|
||||||
msgid "M j, Y, G:i"
|
msgid "M j, Y, G:i"
|
||||||
msgstr "j M, Y, G:i"
|
msgstr "j M, Y, G:i"
|
||||||
|
|
||||||
#: judge/views/user.py:409
|
#: judge/views/user.py:417
|
||||||
msgid "Updated on site"
|
msgid "Updated on site"
|
||||||
msgstr "Được cập nhật trên web"
|
msgstr "Được cập nhật trên web"
|
||||||
|
|
||||||
#: judge/views/user.py:464 templates/admin/auth/user/change_form.html:14
|
#: judge/views/user.py:472 templates/admin/auth/user/change_form.html:14
|
||||||
#: templates/admin/auth/user/change_form.html:17 templates/base.html:280
|
#: templates/admin/auth/user/change_form.html:17 templates/base.html:280
|
||||||
#: templates/user/user-tabs.html:11
|
#: templates/user/user-tabs.html:11
|
||||||
msgid "Edit profile"
|
msgid "Edit profile"
|
||||||
msgstr "Chỉnh sửa thông tin"
|
msgstr "Chỉnh sửa thông tin"
|
||||||
|
|
||||||
#: judge/views/user.py:475 templates/user/user-left-sidebar.html:2
|
#: judge/views/user.py:483 templates/user/user-left-sidebar.html:2
|
||||||
#: templates/user/user-list-tabs.html:4
|
#: templates/user/user-list-tabs.html:4
|
||||||
msgid "Leaderboard"
|
msgid "Leaderboard"
|
||||||
msgstr "Xếp hạng"
|
msgstr "Xếp hạng"
|
||||||
|
|
||||||
#: judge/views/user.py:574
|
#: judge/views/user.py:582
|
||||||
msgid "Import Users"
|
msgid "Import Users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
background: #00f9a1;
|
background: #00f9a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.frozen {
|
||||||
|
background: #a5c5d9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.rank {
|
.rank {
|
||||||
min-width: 2.5em
|
min-width: 2.5em
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue