@xcpcio/core 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +283 -118
- package/dist/index.d.ts +31 -10
- package/dist/index.mjs +281 -119
- package/package.json +2 -2
- package/src/award.ts +21 -0
- package/src/contest.ts +46 -0
- package/src/export.ts +114 -0
- package/src/index.ts +2 -0
- package/src/rank.ts +3 -1
- package/src/team.ts +34 -0
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,22 @@ const minMax__default = /*#__PURE__*/_interopDefaultLegacy(minMax);
|
|
|
27
27
|
const relativeTime__default = /*#__PURE__*/_interopDefaultLegacy(relativeTime);
|
|
28
28
|
const ___default = /*#__PURE__*/_interopDefaultLegacy(_);
|
|
29
29
|
|
|
30
|
+
var MedalType = /* @__PURE__ */ ((MedalType2) => {
|
|
31
|
+
MedalType2[MedalType2["UNKNOWN"] = 0] = "UNKNOWN";
|
|
32
|
+
MedalType2[MedalType2["GOLD"] = 1] = "GOLD";
|
|
33
|
+
MedalType2[MedalType2["SILVER"] = 2] = "SILVER";
|
|
34
|
+
MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
|
|
35
|
+
MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
|
|
36
|
+
return MedalType2;
|
|
37
|
+
})(MedalType || {});
|
|
38
|
+
class Award {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.medalType = 0 /* UNKNOWN */;
|
|
41
|
+
this.minRank = 0;
|
|
42
|
+
this.maxRank = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
30
46
|
function calcDict(attemptedNum, solvedNum) {
|
|
31
47
|
if (solvedNum === 0) {
|
|
32
48
|
return 0;
|
|
@@ -300,6 +316,40 @@ function createContest(contestJSON) {
|
|
|
300
316
|
}
|
|
301
317
|
c.badge = contestJSON.badge;
|
|
302
318
|
c.medal = contestJSON.medal;
|
|
319
|
+
(() => {
|
|
320
|
+
if (contestJSON.medal === void 0 || contestJSON.medal === null) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
c.awards = /* @__PURE__ */ new Map();
|
|
324
|
+
for (const k in contestJSON.medal) {
|
|
325
|
+
const v = contestJSON.medal[k];
|
|
326
|
+
{
|
|
327
|
+
const award = [];
|
|
328
|
+
let rank = 1;
|
|
329
|
+
const work = (key, medalType) => {
|
|
330
|
+
if (Object.keys(v).includes(key)) {
|
|
331
|
+
const a = new Award();
|
|
332
|
+
a.medalType = medalType;
|
|
333
|
+
a.minRank = rank;
|
|
334
|
+
rank += Number(v[key]);
|
|
335
|
+
a.maxRank = rank - 1;
|
|
336
|
+
award.push(a);
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
work("gold", MedalType.GOLD);
|
|
340
|
+
work("silver", MedalType.SILVER);
|
|
341
|
+
work("bronze", MedalType.BRONZE);
|
|
342
|
+
{
|
|
343
|
+
const a = new Award();
|
|
344
|
+
a.medalType = MedalType.HONORABLE;
|
|
345
|
+
a.minRank = rank;
|
|
346
|
+
a.maxRank = 1061109567;
|
|
347
|
+
award.push(a);
|
|
348
|
+
}
|
|
349
|
+
c.awards.set(k, award);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
})();
|
|
303
353
|
c.organization = contestJSON.organization;
|
|
304
354
|
{
|
|
305
355
|
const g = new Group();
|
|
@@ -390,6 +440,208 @@ function createContestIndexList(contestListJSON) {
|
|
|
390
440
|
return contestIndexList;
|
|
391
441
|
}
|
|
392
442
|
|
|
443
|
+
function stringToSubmissionStatus(status) {
|
|
444
|
+
status = status.toUpperCase().replace(" ", "_");
|
|
445
|
+
if (["OK", "AC", types.SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
446
|
+
return types.SubmissionStatus.ACCEPTED;
|
|
447
|
+
}
|
|
448
|
+
if ([types.SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
449
|
+
return types.SubmissionStatus.CORRECT;
|
|
450
|
+
}
|
|
451
|
+
if ([types.SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
452
|
+
return types.SubmissionStatus.PARTIALLY_CORRECT;
|
|
453
|
+
}
|
|
454
|
+
if (["WA", types.SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
455
|
+
return types.SubmissionStatus.WRONG_ANSWER;
|
|
456
|
+
}
|
|
457
|
+
if (["RJ", "INCORRECT", types.SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
458
|
+
return types.SubmissionStatus.REJECTED;
|
|
459
|
+
}
|
|
460
|
+
if (["PD", types.SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
461
|
+
return types.SubmissionStatus.PENDING;
|
|
462
|
+
}
|
|
463
|
+
if ([types.SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
464
|
+
return types.SubmissionStatus.WAITING;
|
|
465
|
+
}
|
|
466
|
+
if ([types.SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
467
|
+
return types.SubmissionStatus.JUDGING;
|
|
468
|
+
}
|
|
469
|
+
if ([types.SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
470
|
+
return types.SubmissionStatus.FROZEN;
|
|
471
|
+
}
|
|
472
|
+
if (["CE", types.SubmissionStatus.COMPILE_ERROR.toString()].includes(status)) {
|
|
473
|
+
return types.SubmissionStatus.COMPILE_ERROR;
|
|
474
|
+
}
|
|
475
|
+
if (["PE", types.SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
476
|
+
return types.SubmissionStatus.PRESENTATION_ERROR;
|
|
477
|
+
}
|
|
478
|
+
if (["TL", "TLE", types.SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
479
|
+
return types.SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
480
|
+
}
|
|
481
|
+
if (["ML", "MLE", types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
482
|
+
return types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
483
|
+
}
|
|
484
|
+
if (["OL", "OLE", types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
485
|
+
return types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
486
|
+
}
|
|
487
|
+
if (["IL", "ILE", types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
488
|
+
return types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
489
|
+
}
|
|
490
|
+
if (["RT", "RE", "RTE", types.SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
491
|
+
return types.SubmissionStatus.RUNTIME_ERROR;
|
|
492
|
+
}
|
|
493
|
+
if (["JE", types.SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
494
|
+
return types.SubmissionStatus.JUDGEMENT_FAILED;
|
|
495
|
+
}
|
|
496
|
+
if (["SE", types.SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
497
|
+
return types.SubmissionStatus.SYSTEM_ERROR;
|
|
498
|
+
}
|
|
499
|
+
if ([types.SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
500
|
+
return types.SubmissionStatus.HACKED;
|
|
501
|
+
}
|
|
502
|
+
if ([types.SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
503
|
+
return types.SubmissionStatus.CONFIGURATION_ERROR;
|
|
504
|
+
}
|
|
505
|
+
if ([types.SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
506
|
+
return types.SubmissionStatus.CANCELED;
|
|
507
|
+
}
|
|
508
|
+
if ([types.SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
509
|
+
return types.SubmissionStatus.SKIPPED;
|
|
510
|
+
}
|
|
511
|
+
if ([types.SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
512
|
+
return types.SubmissionStatus.SECURITY_VIOLATED;
|
|
513
|
+
}
|
|
514
|
+
if ([types.SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
515
|
+
return types.SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
516
|
+
}
|
|
517
|
+
return types.SubmissionStatus.UNKNOWN;
|
|
518
|
+
}
|
|
519
|
+
function isAccepted(status) {
|
|
520
|
+
const acceptedArray = [types.SubmissionStatus.ACCEPTED, types.SubmissionStatus.CORRECT];
|
|
521
|
+
return acceptedArray.includes(status);
|
|
522
|
+
}
|
|
523
|
+
function isRejected(status) {
|
|
524
|
+
const rejectArray = [
|
|
525
|
+
types.SubmissionStatus.RUNTIME_ERROR,
|
|
526
|
+
types.SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
527
|
+
types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
528
|
+
types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
529
|
+
types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
530
|
+
types.SubmissionStatus.WRONG_ANSWER,
|
|
531
|
+
types.SubmissionStatus.REJECTED,
|
|
532
|
+
types.SubmissionStatus.JUDGEMENT_FAILED,
|
|
533
|
+
types.SubmissionStatus.HACKED
|
|
534
|
+
];
|
|
535
|
+
return rejectArray.includes(status);
|
|
536
|
+
}
|
|
537
|
+
function isPending(status) {
|
|
538
|
+
const pendingArray = [
|
|
539
|
+
types.SubmissionStatus.PENDING,
|
|
540
|
+
types.SubmissionStatus.WAITING,
|
|
541
|
+
types.SubmissionStatus.JUDGING,
|
|
542
|
+
types.SubmissionStatus.FROZEN
|
|
543
|
+
];
|
|
544
|
+
return pendingArray.includes(status);
|
|
545
|
+
}
|
|
546
|
+
function isNotCalculatedPenaltyStatus(status) {
|
|
547
|
+
const isNotCalculatedPenaltyArray = [
|
|
548
|
+
types.SubmissionStatus.COMPILE_ERROR,
|
|
549
|
+
types.SubmissionStatus.PRESENTATION_ERROR,
|
|
550
|
+
types.SubmissionStatus.CONFIGURATION_ERROR,
|
|
551
|
+
types.SubmissionStatus.SYSTEM_ERROR,
|
|
552
|
+
types.SubmissionStatus.CANCELED,
|
|
553
|
+
types.SubmissionStatus.SKIPPED,
|
|
554
|
+
types.SubmissionStatus.UNKNOWN,
|
|
555
|
+
types.SubmissionStatus.UNDEFINED
|
|
556
|
+
];
|
|
557
|
+
return isNotCalculatedPenaltyArray.includes(status);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function submissionStatusToCodeforcesGymDatStatus(status) {
|
|
561
|
+
if (isAccepted(status)) {
|
|
562
|
+
return "OK";
|
|
563
|
+
}
|
|
564
|
+
if (status === types.SubmissionStatus.WRONG_ANSWER) {
|
|
565
|
+
return "WA";
|
|
566
|
+
}
|
|
567
|
+
if (status === types.SubmissionStatus.TIME_LIMIT_EXCEEDED) {
|
|
568
|
+
return "TL";
|
|
569
|
+
}
|
|
570
|
+
if (status === types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
|
|
571
|
+
return "ML";
|
|
572
|
+
}
|
|
573
|
+
if (status === types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
|
|
574
|
+
return "IL";
|
|
575
|
+
}
|
|
576
|
+
if (status === types.SubmissionStatus.PRESENTATION_ERROR) {
|
|
577
|
+
return "PE";
|
|
578
|
+
}
|
|
579
|
+
if (status === types.SubmissionStatus.RUNTIME_ERROR) {
|
|
580
|
+
return "RT";
|
|
581
|
+
}
|
|
582
|
+
if (status === types.SubmissionStatus.COMPILE_ERROR || isNotCalculatedPenaltyStatus(status)) {
|
|
583
|
+
return "CE";
|
|
584
|
+
}
|
|
585
|
+
if (isPending(status)) {
|
|
586
|
+
return "PD";
|
|
587
|
+
}
|
|
588
|
+
return "RJ";
|
|
589
|
+
}
|
|
590
|
+
function rankToCodeforcesGymDAT(rank) {
|
|
591
|
+
let res = "";
|
|
592
|
+
res += `@contest "${rank.contest.name}"
|
|
593
|
+
@contlen ${Math.floor(rank.contest.endTime.diff(rank.contest.startTime) / 1e3 / 60)}
|
|
594
|
+
@problems ${rank.contest.problems.length}
|
|
595
|
+
@teams ${rank.teams.length + 100}
|
|
596
|
+
@submissions ${rank.submissions.length}
|
|
597
|
+
`;
|
|
598
|
+
rank.contest.problems.forEach((p) => {
|
|
599
|
+
res += `@p ${p.label},${p.label},20,0
|
|
600
|
+
`;
|
|
601
|
+
});
|
|
602
|
+
let teamIndex = 1;
|
|
603
|
+
const teamIdMap = /* @__PURE__ */ new Map();
|
|
604
|
+
const submissionsIdMap = /* @__PURE__ */ new Map();
|
|
605
|
+
rank.teams.forEach((team) => {
|
|
606
|
+
let name = team.name;
|
|
607
|
+
if (team.organization) {
|
|
608
|
+
name = `${team.organization} - ${name}`;
|
|
609
|
+
}
|
|
610
|
+
if (team.members) {
|
|
611
|
+
name = `${name} - ${team.membersToString}`;
|
|
612
|
+
}
|
|
613
|
+
res += `@t ${teamIndex},0,1,${name}
|
|
614
|
+
`;
|
|
615
|
+
teamIdMap.set(team.id, teamIndex);
|
|
616
|
+
teamIndex++;
|
|
617
|
+
{
|
|
618
|
+
const mp = /* @__PURE__ */ new Map();
|
|
619
|
+
rank.contest.problems.forEach((p) => {
|
|
620
|
+
mp.set(p.id, 0);
|
|
621
|
+
});
|
|
622
|
+
submissionsIdMap.set(team.id, mp);
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
for (let i = 0; i < 100; i++) {
|
|
626
|
+
res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
|
|
627
|
+
`;
|
|
628
|
+
teamIndex++;
|
|
629
|
+
}
|
|
630
|
+
rank.submissions.forEach((submission) => {
|
|
631
|
+
const teamId = submission.teamId;
|
|
632
|
+
const problemId = submission.problemId;
|
|
633
|
+
const problem = rank.contest.problemsMap.get(problemId);
|
|
634
|
+
if (!problem) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const status = submissionStatusToCodeforcesGymDatStatus(submission.status);
|
|
638
|
+
submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
|
|
639
|
+
res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
|
|
640
|
+
`;
|
|
641
|
+
});
|
|
642
|
+
return res;
|
|
643
|
+
}
|
|
644
|
+
|
|
393
645
|
function getImageSource(image) {
|
|
394
646
|
if (image?.url) {
|
|
395
647
|
return image.url;
|
|
@@ -437,6 +689,7 @@ class Team {
|
|
|
437
689
|
this.problemStatisticsMap = /* @__PURE__ */ new Map();
|
|
438
690
|
this.submissions = [];
|
|
439
691
|
this.placeChartPoints = [];
|
|
692
|
+
this.awards = [];
|
|
440
693
|
}
|
|
441
694
|
reset() {
|
|
442
695
|
this.rank = 0;
|
|
@@ -460,6 +713,12 @@ class Team {
|
|
|
460
713
|
const solvedNum = this.solvedProblemNum;
|
|
461
714
|
return calcDict(attemptedNum, solvedNum);
|
|
462
715
|
}
|
|
716
|
+
get membersToString() {
|
|
717
|
+
if (typeof this.members === "string") {
|
|
718
|
+
return this.members;
|
|
719
|
+
}
|
|
720
|
+
return this.members?.join(", ");
|
|
721
|
+
}
|
|
463
722
|
calcSolvedData() {
|
|
464
723
|
this.solvedProblemNum = 0;
|
|
465
724
|
this.attemptedProblemNum = 0;
|
|
@@ -472,6 +731,16 @@ class Team {
|
|
|
472
731
|
}
|
|
473
732
|
}
|
|
474
733
|
}
|
|
734
|
+
calcAwards(awards) {
|
|
735
|
+
if (!awards) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
for (const award of awards) {
|
|
739
|
+
if (this.rank >= award.minRank && this.rank <= award.maxRank) {
|
|
740
|
+
this.awards.push(award.medalType);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
475
744
|
isEqualRank(otherTeam) {
|
|
476
745
|
return this.solvedProblemNum === otherTeam.solvedProblemNum && this.penalty === otherTeam.penalty;
|
|
477
746
|
}
|
|
@@ -530,6 +799,14 @@ function createTeam(teamJSON) {
|
|
|
530
799
|
if (Boolean(teamJSON.girl) === true) {
|
|
531
800
|
t.group.push("girl");
|
|
532
801
|
}
|
|
802
|
+
{
|
|
803
|
+
const tt = teamJSON;
|
|
804
|
+
for (const key of Object.keys(tt)) {
|
|
805
|
+
if (tt[key] === 1 || tt[key] === true) {
|
|
806
|
+
t.group.push(key);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
533
810
|
t.group = [...new Set(t.group)];
|
|
534
811
|
t.group.sort();
|
|
535
812
|
return t;
|
|
@@ -545,123 +822,6 @@ function createTeams(teamsJSON) {
|
|
|
545
822
|
}
|
|
546
823
|
}
|
|
547
824
|
|
|
548
|
-
function stringToSubmissionStatus(status) {
|
|
549
|
-
status = status.toUpperCase().replace(" ", "_");
|
|
550
|
-
if (["OK", "AC", types.SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
551
|
-
return types.SubmissionStatus.ACCEPTED;
|
|
552
|
-
}
|
|
553
|
-
if ([types.SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
554
|
-
return types.SubmissionStatus.CORRECT;
|
|
555
|
-
}
|
|
556
|
-
if ([types.SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
557
|
-
return types.SubmissionStatus.PARTIALLY_CORRECT;
|
|
558
|
-
}
|
|
559
|
-
if (["WA", types.SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
560
|
-
return types.SubmissionStatus.WRONG_ANSWER;
|
|
561
|
-
}
|
|
562
|
-
if (["RJ", "INCORRECT", types.SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
563
|
-
return types.SubmissionStatus.REJECTED;
|
|
564
|
-
}
|
|
565
|
-
if (["PD", types.SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
566
|
-
return types.SubmissionStatus.PENDING;
|
|
567
|
-
}
|
|
568
|
-
if ([types.SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
569
|
-
return types.SubmissionStatus.WAITING;
|
|
570
|
-
}
|
|
571
|
-
if ([types.SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
572
|
-
return types.SubmissionStatus.JUDGING;
|
|
573
|
-
}
|
|
574
|
-
if ([types.SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
575
|
-
return types.SubmissionStatus.FROZEN;
|
|
576
|
-
}
|
|
577
|
-
if (["CE", types.SubmissionStatus.COMPILE_ERROR.toString()].includes(status)) {
|
|
578
|
-
return types.SubmissionStatus.COMPILE_ERROR;
|
|
579
|
-
}
|
|
580
|
-
if (["PE", types.SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
581
|
-
return types.SubmissionStatus.PRESENTATION_ERROR;
|
|
582
|
-
}
|
|
583
|
-
if (["TL", "TLE", types.SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
584
|
-
return types.SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
585
|
-
}
|
|
586
|
-
if (["ML", "MLE", types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
587
|
-
return types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
588
|
-
}
|
|
589
|
-
if (["OL", "OLE", types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
590
|
-
return types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
591
|
-
}
|
|
592
|
-
if (["IL", "ILE", types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
593
|
-
return types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
594
|
-
}
|
|
595
|
-
if (["RT", "RE", "RTE", types.SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
596
|
-
return types.SubmissionStatus.RUNTIME_ERROR;
|
|
597
|
-
}
|
|
598
|
-
if (["JE", types.SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
599
|
-
return types.SubmissionStatus.JUDGEMENT_FAILED;
|
|
600
|
-
}
|
|
601
|
-
if (["SE", types.SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
602
|
-
return types.SubmissionStatus.SYSTEM_ERROR;
|
|
603
|
-
}
|
|
604
|
-
if ([types.SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
605
|
-
return types.SubmissionStatus.HACKED;
|
|
606
|
-
}
|
|
607
|
-
if ([types.SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
608
|
-
return types.SubmissionStatus.CONFIGURATION_ERROR;
|
|
609
|
-
}
|
|
610
|
-
if ([types.SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
611
|
-
return types.SubmissionStatus.CANCELED;
|
|
612
|
-
}
|
|
613
|
-
if ([types.SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
614
|
-
return types.SubmissionStatus.SKIPPED;
|
|
615
|
-
}
|
|
616
|
-
if ([types.SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
617
|
-
return types.SubmissionStatus.SECURITY_VIOLATED;
|
|
618
|
-
}
|
|
619
|
-
if ([types.SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
620
|
-
return types.SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
621
|
-
}
|
|
622
|
-
return types.SubmissionStatus.UNKNOWN;
|
|
623
|
-
}
|
|
624
|
-
function isAccepted(status) {
|
|
625
|
-
const acceptedArray = [types.SubmissionStatus.ACCEPTED, types.SubmissionStatus.CORRECT];
|
|
626
|
-
return acceptedArray.includes(status);
|
|
627
|
-
}
|
|
628
|
-
function isRejected(status) {
|
|
629
|
-
const rejectArray = [
|
|
630
|
-
types.SubmissionStatus.RUNTIME_ERROR,
|
|
631
|
-
types.SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
632
|
-
types.SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
633
|
-
types.SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
634
|
-
types.SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
635
|
-
types.SubmissionStatus.WRONG_ANSWER,
|
|
636
|
-
types.SubmissionStatus.REJECTED,
|
|
637
|
-
types.SubmissionStatus.JUDGEMENT_FAILED,
|
|
638
|
-
types.SubmissionStatus.HACKED
|
|
639
|
-
];
|
|
640
|
-
return rejectArray.includes(status);
|
|
641
|
-
}
|
|
642
|
-
function isPending(status) {
|
|
643
|
-
const pendingArray = [
|
|
644
|
-
types.SubmissionStatus.PENDING,
|
|
645
|
-
types.SubmissionStatus.WAITING,
|
|
646
|
-
types.SubmissionStatus.JUDGING,
|
|
647
|
-
types.SubmissionStatus.FROZEN
|
|
648
|
-
];
|
|
649
|
-
return pendingArray.includes(status);
|
|
650
|
-
}
|
|
651
|
-
function isNotCalculatedPenaltyStatus(status) {
|
|
652
|
-
const isNotCalculatedPenaltyArray = [
|
|
653
|
-
types.SubmissionStatus.COMPILE_ERROR,
|
|
654
|
-
types.SubmissionStatus.PRESENTATION_ERROR,
|
|
655
|
-
types.SubmissionStatus.CONFIGURATION_ERROR,
|
|
656
|
-
types.SubmissionStatus.SYSTEM_ERROR,
|
|
657
|
-
types.SubmissionStatus.CANCELED,
|
|
658
|
-
types.SubmissionStatus.SKIPPED,
|
|
659
|
-
types.SubmissionStatus.UNKNOWN,
|
|
660
|
-
types.SubmissionStatus.UNDEFINED
|
|
661
|
-
];
|
|
662
|
-
return isNotCalculatedPenaltyArray.includes(status);
|
|
663
|
-
}
|
|
664
|
-
|
|
665
825
|
class Submission {
|
|
666
826
|
constructor() {
|
|
667
827
|
this.status = types.SubmissionStatus.UNKNOWN;
|
|
@@ -728,7 +888,7 @@ class RankOptions {
|
|
|
728
888
|
this.width = 0;
|
|
729
889
|
this.timestamp = 0;
|
|
730
890
|
this.enableFilterTeamsByGroup = false;
|
|
731
|
-
this.group = "";
|
|
891
|
+
this.group = "all";
|
|
732
892
|
this.filterOrganizations = [];
|
|
733
893
|
this.filterOrganizationMap = /* @__PURE__ */ new Map();
|
|
734
894
|
this.filterTeams = [];
|
|
@@ -751,6 +911,7 @@ class RankOptions {
|
|
|
751
911
|
}
|
|
752
912
|
disableFilterTeamsByGroup() {
|
|
753
913
|
this.enableFilterTeamsByGroup = false;
|
|
914
|
+
this.group = "all";
|
|
754
915
|
}
|
|
755
916
|
setFilterOrganizations(filterOrganizations) {
|
|
756
917
|
const m = /* @__PURE__ */ new Map();
|
|
@@ -908,6 +1069,7 @@ class Rank {
|
|
|
908
1069
|
this.teams.sort(Team.compare);
|
|
909
1070
|
this.buildTeamRank();
|
|
910
1071
|
this.buildOrgRank();
|
|
1072
|
+
this.teams.forEach((t) => t.calcAwards(this.contest.awards?.get(this.options.group)));
|
|
911
1073
|
this.teams.forEach((t) => t.postProcessPlaceChartPoints());
|
|
912
1074
|
})();
|
|
913
1075
|
(() => {
|
|
@@ -1080,9 +1242,11 @@ class Resolver extends Rank {
|
|
|
1080
1242
|
}
|
|
1081
1243
|
|
|
1082
1244
|
exports.dayjs = dayjs__default;
|
|
1245
|
+
exports.Award = Award;
|
|
1083
1246
|
exports.Contest = Contest;
|
|
1084
1247
|
exports.ContestIndex = ContestIndex;
|
|
1085
1248
|
exports.ContestIndexConfig = ContestIndexConfig;
|
|
1249
|
+
exports.MedalType = MedalType;
|
|
1086
1250
|
exports.PlaceChartPointData = PlaceChartPointData;
|
|
1087
1251
|
exports.Problem = Problem;
|
|
1088
1252
|
exports.ProblemStatistics = ProblemStatistics;
|
|
@@ -1112,4 +1276,5 @@ exports.isAccepted = isAccepted;
|
|
|
1112
1276
|
exports.isNotCalculatedPenaltyStatus = isNotCalculatedPenaltyStatus;
|
|
1113
1277
|
exports.isPending = isPending;
|
|
1114
1278
|
exports.isRejected = isRejected;
|
|
1279
|
+
exports.rankToCodeforcesGymDAT = rankToCodeforcesGymDAT;
|
|
1115
1280
|
exports.stringToSubmissionStatus = stringToSubmissionStatus;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,21 @@ import dayjs from 'dayjs';
|
|
|
2
2
|
export { default as dayjs } from 'dayjs';
|
|
3
3
|
import { SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Lang, StatusTimeDisplay, Image, ContestState, Contest as Contest$1, ContestIndex as ContestIndex$1, Team as Team$1, Teams as Teams$1 } from '@xcpcio/types';
|
|
4
4
|
|
|
5
|
+
declare enum MedalType {
|
|
6
|
+
UNKNOWN = 0,
|
|
7
|
+
GOLD = 1,
|
|
8
|
+
SILVER = 2,
|
|
9
|
+
BRONZE = 3,
|
|
10
|
+
HONORABLE = 4
|
|
11
|
+
}
|
|
12
|
+
declare class Award {
|
|
13
|
+
medalType: MedalType;
|
|
14
|
+
minRank: number;
|
|
15
|
+
maxRank: number;
|
|
16
|
+
constructor();
|
|
17
|
+
}
|
|
18
|
+
type Awards = Map<string, Award[]>;
|
|
19
|
+
|
|
5
20
|
declare class Submission {
|
|
6
21
|
id: string;
|
|
7
22
|
teamId: string;
|
|
@@ -98,6 +113,7 @@ declare class Contest {
|
|
|
98
113
|
statusTimeDisplay: StatusTimeDisplay;
|
|
99
114
|
badge?: string;
|
|
100
115
|
medal?: Record<string, Record<string, number>>;
|
|
116
|
+
awards?: Awards;
|
|
101
117
|
organization?: string;
|
|
102
118
|
group: Map<string, Group>;
|
|
103
119
|
tag: Map<string, string>;
|
|
@@ -134,15 +150,6 @@ type ContestIndexList = Array<ContestIndex>;
|
|
|
134
150
|
declare function createContestIndex(contestIndexJSON: ContestIndex$1): ContestIndex;
|
|
135
151
|
declare function createContestIndexList(contestListJSON: any): ContestIndexList;
|
|
136
152
|
|
|
137
|
-
declare function getImageSource(image: Image): string;
|
|
138
|
-
|
|
139
|
-
declare class RankStatistics {
|
|
140
|
-
teamSolvedNum: Array<number>;
|
|
141
|
-
maxSolvedProblems: number;
|
|
142
|
-
constructor();
|
|
143
|
-
reset(): void;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
153
|
declare class PlaceChartPointData {
|
|
147
154
|
timePoint: number;
|
|
148
155
|
rank: number;
|
|
@@ -170,11 +177,14 @@ declare class Team {
|
|
|
170
177
|
problemStatisticsMap: Map<string, TeamProblemStatistics>;
|
|
171
178
|
submissions: Submissions;
|
|
172
179
|
placeChartPoints: Array<PlaceChartPointData>;
|
|
180
|
+
awards: MedalType[];
|
|
173
181
|
constructor();
|
|
174
182
|
reset(): void;
|
|
175
183
|
get penaltyToMinute(): number;
|
|
176
184
|
get dict(): number;
|
|
185
|
+
get membersToString(): string | undefined;
|
|
177
186
|
calcSolvedData(): void;
|
|
187
|
+
calcAwards(awards?: Award[]): void;
|
|
178
188
|
isEqualRank(otherTeam: Team): boolean;
|
|
179
189
|
postProcessPlaceChartPoints(): void;
|
|
180
190
|
static compare(lhs: Team, rhs: Team): number;
|
|
@@ -183,6 +193,13 @@ type Teams = Array<Team>;
|
|
|
183
193
|
declare function createTeam(teamJSON: Team$1): Team;
|
|
184
194
|
declare function createTeams(teamsJSON: Teams$1): Teams;
|
|
185
195
|
|
|
196
|
+
declare class RankStatistics {
|
|
197
|
+
teamSolvedNum: Array<number>;
|
|
198
|
+
maxSolvedProblems: number;
|
|
199
|
+
constructor();
|
|
200
|
+
reset(): void;
|
|
201
|
+
}
|
|
202
|
+
|
|
186
203
|
interface SelectOptionItem {
|
|
187
204
|
value: string;
|
|
188
205
|
text: string;
|
|
@@ -225,6 +242,10 @@ declare class Rank {
|
|
|
225
242
|
getSubmissions(): Submissions;
|
|
226
243
|
}
|
|
227
244
|
|
|
245
|
+
declare function rankToCodeforcesGymDAT(rank: Rank): string;
|
|
246
|
+
|
|
247
|
+
declare function getImageSource(image: Image): string;
|
|
248
|
+
|
|
228
249
|
declare class ResolverOperation {
|
|
229
250
|
id: number;
|
|
230
251
|
team: Team;
|
|
@@ -249,4 +270,4 @@ declare function isRejected(status: SubmissionStatus): boolean;
|
|
|
249
270
|
declare function isPending(status: SubmissionStatus): boolean;
|
|
250
271
|
declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
|
|
251
272
|
|
|
252
|
-
export { Contest, ContestIndex, ContestIndexConfig, ContestIndexList, PlaceChartPointData, Problem, ProblemStatistics, Problems, Rank, RankOptions, RankStatistics, Resolver, SelectOptionItem, Submission, Submissions, Team, TeamProblemStatistics, Teams, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, stringToSubmissionStatus };
|
|
273
|
+
export { Award, Awards, Contest, ContestIndex, ContestIndexConfig, ContestIndexList, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Problems, Rank, RankOptions, RankStatistics, Resolver, SelectOptionItem, Submission, Submissions, Team, TeamProblemStatistics, Teams, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, rankToCodeforcesGymDAT, stringToSubmissionStatus };
|
package/dist/index.mjs
CHANGED
|
@@ -11,6 +11,22 @@ import relativeTime from 'dayjs/plugin/relativeTime';
|
|
|
11
11
|
import { ContestState, SubmissionStatus } from '@xcpcio/types';
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
|
|
14
|
+
var MedalType = /* @__PURE__ */ ((MedalType2) => {
|
|
15
|
+
MedalType2[MedalType2["UNKNOWN"] = 0] = "UNKNOWN";
|
|
16
|
+
MedalType2[MedalType2["GOLD"] = 1] = "GOLD";
|
|
17
|
+
MedalType2[MedalType2["SILVER"] = 2] = "SILVER";
|
|
18
|
+
MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
|
|
19
|
+
MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
|
|
20
|
+
return MedalType2;
|
|
21
|
+
})(MedalType || {});
|
|
22
|
+
class Award {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.medalType = 0 /* UNKNOWN */;
|
|
25
|
+
this.minRank = 0;
|
|
26
|
+
this.maxRank = 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
14
30
|
function calcDict(attemptedNum, solvedNum) {
|
|
15
31
|
if (solvedNum === 0) {
|
|
16
32
|
return 0;
|
|
@@ -284,6 +300,40 @@ function createContest(contestJSON) {
|
|
|
284
300
|
}
|
|
285
301
|
c.badge = contestJSON.badge;
|
|
286
302
|
c.medal = contestJSON.medal;
|
|
303
|
+
(() => {
|
|
304
|
+
if (contestJSON.medal === void 0 || contestJSON.medal === null) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
c.awards = /* @__PURE__ */ new Map();
|
|
308
|
+
for (const k in contestJSON.medal) {
|
|
309
|
+
const v = contestJSON.medal[k];
|
|
310
|
+
{
|
|
311
|
+
const award = [];
|
|
312
|
+
let rank = 1;
|
|
313
|
+
const work = (key, medalType) => {
|
|
314
|
+
if (Object.keys(v).includes(key)) {
|
|
315
|
+
const a = new Award();
|
|
316
|
+
a.medalType = medalType;
|
|
317
|
+
a.minRank = rank;
|
|
318
|
+
rank += Number(v[key]);
|
|
319
|
+
a.maxRank = rank - 1;
|
|
320
|
+
award.push(a);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
work("gold", MedalType.GOLD);
|
|
324
|
+
work("silver", MedalType.SILVER);
|
|
325
|
+
work("bronze", MedalType.BRONZE);
|
|
326
|
+
{
|
|
327
|
+
const a = new Award();
|
|
328
|
+
a.medalType = MedalType.HONORABLE;
|
|
329
|
+
a.minRank = rank;
|
|
330
|
+
a.maxRank = 1061109567;
|
|
331
|
+
award.push(a);
|
|
332
|
+
}
|
|
333
|
+
c.awards.set(k, award);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
})();
|
|
287
337
|
c.organization = contestJSON.organization;
|
|
288
338
|
{
|
|
289
339
|
const g = new Group();
|
|
@@ -374,6 +424,208 @@ function createContestIndexList(contestListJSON) {
|
|
|
374
424
|
return contestIndexList;
|
|
375
425
|
}
|
|
376
426
|
|
|
427
|
+
function stringToSubmissionStatus(status) {
|
|
428
|
+
status = status.toUpperCase().replace(" ", "_");
|
|
429
|
+
if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
430
|
+
return SubmissionStatus.ACCEPTED;
|
|
431
|
+
}
|
|
432
|
+
if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
433
|
+
return SubmissionStatus.CORRECT;
|
|
434
|
+
}
|
|
435
|
+
if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
436
|
+
return SubmissionStatus.PARTIALLY_CORRECT;
|
|
437
|
+
}
|
|
438
|
+
if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
439
|
+
return SubmissionStatus.WRONG_ANSWER;
|
|
440
|
+
}
|
|
441
|
+
if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
442
|
+
return SubmissionStatus.REJECTED;
|
|
443
|
+
}
|
|
444
|
+
if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
445
|
+
return SubmissionStatus.PENDING;
|
|
446
|
+
}
|
|
447
|
+
if ([SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
448
|
+
return SubmissionStatus.WAITING;
|
|
449
|
+
}
|
|
450
|
+
if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
451
|
+
return SubmissionStatus.JUDGING;
|
|
452
|
+
}
|
|
453
|
+
if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
454
|
+
return SubmissionStatus.FROZEN;
|
|
455
|
+
}
|
|
456
|
+
if (["CE", SubmissionStatus.COMPILE_ERROR.toString()].includes(status)) {
|
|
457
|
+
return SubmissionStatus.COMPILE_ERROR;
|
|
458
|
+
}
|
|
459
|
+
if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
460
|
+
return SubmissionStatus.PRESENTATION_ERROR;
|
|
461
|
+
}
|
|
462
|
+
if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
463
|
+
return SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
464
|
+
}
|
|
465
|
+
if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
466
|
+
return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
467
|
+
}
|
|
468
|
+
if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
469
|
+
return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
470
|
+
}
|
|
471
|
+
if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
472
|
+
return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
473
|
+
}
|
|
474
|
+
if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
475
|
+
return SubmissionStatus.RUNTIME_ERROR;
|
|
476
|
+
}
|
|
477
|
+
if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
478
|
+
return SubmissionStatus.JUDGEMENT_FAILED;
|
|
479
|
+
}
|
|
480
|
+
if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
481
|
+
return SubmissionStatus.SYSTEM_ERROR;
|
|
482
|
+
}
|
|
483
|
+
if ([SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
484
|
+
return SubmissionStatus.HACKED;
|
|
485
|
+
}
|
|
486
|
+
if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
487
|
+
return SubmissionStatus.CONFIGURATION_ERROR;
|
|
488
|
+
}
|
|
489
|
+
if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
490
|
+
return SubmissionStatus.CANCELED;
|
|
491
|
+
}
|
|
492
|
+
if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
493
|
+
return SubmissionStatus.SKIPPED;
|
|
494
|
+
}
|
|
495
|
+
if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
496
|
+
return SubmissionStatus.SECURITY_VIOLATED;
|
|
497
|
+
}
|
|
498
|
+
if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
499
|
+
return SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
500
|
+
}
|
|
501
|
+
return SubmissionStatus.UNKNOWN;
|
|
502
|
+
}
|
|
503
|
+
function isAccepted(status) {
|
|
504
|
+
const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
|
|
505
|
+
return acceptedArray.includes(status);
|
|
506
|
+
}
|
|
507
|
+
function isRejected(status) {
|
|
508
|
+
const rejectArray = [
|
|
509
|
+
SubmissionStatus.RUNTIME_ERROR,
|
|
510
|
+
SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
511
|
+
SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
512
|
+
SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
513
|
+
SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
514
|
+
SubmissionStatus.WRONG_ANSWER,
|
|
515
|
+
SubmissionStatus.REJECTED,
|
|
516
|
+
SubmissionStatus.JUDGEMENT_FAILED,
|
|
517
|
+
SubmissionStatus.HACKED
|
|
518
|
+
];
|
|
519
|
+
return rejectArray.includes(status);
|
|
520
|
+
}
|
|
521
|
+
function isPending(status) {
|
|
522
|
+
const pendingArray = [
|
|
523
|
+
SubmissionStatus.PENDING,
|
|
524
|
+
SubmissionStatus.WAITING,
|
|
525
|
+
SubmissionStatus.JUDGING,
|
|
526
|
+
SubmissionStatus.FROZEN
|
|
527
|
+
];
|
|
528
|
+
return pendingArray.includes(status);
|
|
529
|
+
}
|
|
530
|
+
function isNotCalculatedPenaltyStatus(status) {
|
|
531
|
+
const isNotCalculatedPenaltyArray = [
|
|
532
|
+
SubmissionStatus.COMPILE_ERROR,
|
|
533
|
+
SubmissionStatus.PRESENTATION_ERROR,
|
|
534
|
+
SubmissionStatus.CONFIGURATION_ERROR,
|
|
535
|
+
SubmissionStatus.SYSTEM_ERROR,
|
|
536
|
+
SubmissionStatus.CANCELED,
|
|
537
|
+
SubmissionStatus.SKIPPED,
|
|
538
|
+
SubmissionStatus.UNKNOWN,
|
|
539
|
+
SubmissionStatus.UNDEFINED
|
|
540
|
+
];
|
|
541
|
+
return isNotCalculatedPenaltyArray.includes(status);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function submissionStatusToCodeforcesGymDatStatus(status) {
|
|
545
|
+
if (isAccepted(status)) {
|
|
546
|
+
return "OK";
|
|
547
|
+
}
|
|
548
|
+
if (status === SubmissionStatus.WRONG_ANSWER) {
|
|
549
|
+
return "WA";
|
|
550
|
+
}
|
|
551
|
+
if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
|
|
552
|
+
return "TL";
|
|
553
|
+
}
|
|
554
|
+
if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
|
|
555
|
+
return "ML";
|
|
556
|
+
}
|
|
557
|
+
if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
|
|
558
|
+
return "IL";
|
|
559
|
+
}
|
|
560
|
+
if (status === SubmissionStatus.PRESENTATION_ERROR) {
|
|
561
|
+
return "PE";
|
|
562
|
+
}
|
|
563
|
+
if (status === SubmissionStatus.RUNTIME_ERROR) {
|
|
564
|
+
return "RT";
|
|
565
|
+
}
|
|
566
|
+
if (status === SubmissionStatus.COMPILE_ERROR || isNotCalculatedPenaltyStatus(status)) {
|
|
567
|
+
return "CE";
|
|
568
|
+
}
|
|
569
|
+
if (isPending(status)) {
|
|
570
|
+
return "PD";
|
|
571
|
+
}
|
|
572
|
+
return "RJ";
|
|
573
|
+
}
|
|
574
|
+
function rankToCodeforcesGymDAT(rank) {
|
|
575
|
+
let res = "";
|
|
576
|
+
res += `@contest "${rank.contest.name}"
|
|
577
|
+
@contlen ${Math.floor(rank.contest.endTime.diff(rank.contest.startTime) / 1e3 / 60)}
|
|
578
|
+
@problems ${rank.contest.problems.length}
|
|
579
|
+
@teams ${rank.teams.length + 100}
|
|
580
|
+
@submissions ${rank.submissions.length}
|
|
581
|
+
`;
|
|
582
|
+
rank.contest.problems.forEach((p) => {
|
|
583
|
+
res += `@p ${p.label},${p.label},20,0
|
|
584
|
+
`;
|
|
585
|
+
});
|
|
586
|
+
let teamIndex = 1;
|
|
587
|
+
const teamIdMap = /* @__PURE__ */ new Map();
|
|
588
|
+
const submissionsIdMap = /* @__PURE__ */ new Map();
|
|
589
|
+
rank.teams.forEach((team) => {
|
|
590
|
+
let name = team.name;
|
|
591
|
+
if (team.organization) {
|
|
592
|
+
name = `${team.organization} - ${name}`;
|
|
593
|
+
}
|
|
594
|
+
if (team.members) {
|
|
595
|
+
name = `${name} - ${team.membersToString}`;
|
|
596
|
+
}
|
|
597
|
+
res += `@t ${teamIndex},0,1,${name}
|
|
598
|
+
`;
|
|
599
|
+
teamIdMap.set(team.id, teamIndex);
|
|
600
|
+
teamIndex++;
|
|
601
|
+
{
|
|
602
|
+
const mp = /* @__PURE__ */ new Map();
|
|
603
|
+
rank.contest.problems.forEach((p) => {
|
|
604
|
+
mp.set(p.id, 0);
|
|
605
|
+
});
|
|
606
|
+
submissionsIdMap.set(team.id, mp);
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
for (let i = 0; i < 100; i++) {
|
|
610
|
+
res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
|
|
611
|
+
`;
|
|
612
|
+
teamIndex++;
|
|
613
|
+
}
|
|
614
|
+
rank.submissions.forEach((submission) => {
|
|
615
|
+
const teamId = submission.teamId;
|
|
616
|
+
const problemId = submission.problemId;
|
|
617
|
+
const problem = rank.contest.problemsMap.get(problemId);
|
|
618
|
+
if (!problem) {
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
const status = submissionStatusToCodeforcesGymDatStatus(submission.status);
|
|
622
|
+
submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
|
|
623
|
+
res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
|
|
624
|
+
`;
|
|
625
|
+
});
|
|
626
|
+
return res;
|
|
627
|
+
}
|
|
628
|
+
|
|
377
629
|
function getImageSource(image) {
|
|
378
630
|
if (image?.url) {
|
|
379
631
|
return image.url;
|
|
@@ -421,6 +673,7 @@ class Team {
|
|
|
421
673
|
this.problemStatisticsMap = /* @__PURE__ */ new Map();
|
|
422
674
|
this.submissions = [];
|
|
423
675
|
this.placeChartPoints = [];
|
|
676
|
+
this.awards = [];
|
|
424
677
|
}
|
|
425
678
|
reset() {
|
|
426
679
|
this.rank = 0;
|
|
@@ -444,6 +697,12 @@ class Team {
|
|
|
444
697
|
const solvedNum = this.solvedProblemNum;
|
|
445
698
|
return calcDict(attemptedNum, solvedNum);
|
|
446
699
|
}
|
|
700
|
+
get membersToString() {
|
|
701
|
+
if (typeof this.members === "string") {
|
|
702
|
+
return this.members;
|
|
703
|
+
}
|
|
704
|
+
return this.members?.join(", ");
|
|
705
|
+
}
|
|
447
706
|
calcSolvedData() {
|
|
448
707
|
this.solvedProblemNum = 0;
|
|
449
708
|
this.attemptedProblemNum = 0;
|
|
@@ -456,6 +715,16 @@ class Team {
|
|
|
456
715
|
}
|
|
457
716
|
}
|
|
458
717
|
}
|
|
718
|
+
calcAwards(awards) {
|
|
719
|
+
if (!awards) {
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
for (const award of awards) {
|
|
723
|
+
if (this.rank >= award.minRank && this.rank <= award.maxRank) {
|
|
724
|
+
this.awards.push(award.medalType);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
459
728
|
isEqualRank(otherTeam) {
|
|
460
729
|
return this.solvedProblemNum === otherTeam.solvedProblemNum && this.penalty === otherTeam.penalty;
|
|
461
730
|
}
|
|
@@ -514,6 +783,14 @@ function createTeam(teamJSON) {
|
|
|
514
783
|
if (Boolean(teamJSON.girl) === true) {
|
|
515
784
|
t.group.push("girl");
|
|
516
785
|
}
|
|
786
|
+
{
|
|
787
|
+
const tt = teamJSON;
|
|
788
|
+
for (const key of Object.keys(tt)) {
|
|
789
|
+
if (tt[key] === 1 || tt[key] === true) {
|
|
790
|
+
t.group.push(key);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
517
794
|
t.group = [...new Set(t.group)];
|
|
518
795
|
t.group.sort();
|
|
519
796
|
return t;
|
|
@@ -529,123 +806,6 @@ function createTeams(teamsJSON) {
|
|
|
529
806
|
}
|
|
530
807
|
}
|
|
531
808
|
|
|
532
|
-
function stringToSubmissionStatus(status) {
|
|
533
|
-
status = status.toUpperCase().replace(" ", "_");
|
|
534
|
-
if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
535
|
-
return SubmissionStatus.ACCEPTED;
|
|
536
|
-
}
|
|
537
|
-
if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
538
|
-
return SubmissionStatus.CORRECT;
|
|
539
|
-
}
|
|
540
|
-
if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
541
|
-
return SubmissionStatus.PARTIALLY_CORRECT;
|
|
542
|
-
}
|
|
543
|
-
if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
544
|
-
return SubmissionStatus.WRONG_ANSWER;
|
|
545
|
-
}
|
|
546
|
-
if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
547
|
-
return SubmissionStatus.REJECTED;
|
|
548
|
-
}
|
|
549
|
-
if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
550
|
-
return SubmissionStatus.PENDING;
|
|
551
|
-
}
|
|
552
|
-
if ([SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
553
|
-
return SubmissionStatus.WAITING;
|
|
554
|
-
}
|
|
555
|
-
if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
556
|
-
return SubmissionStatus.JUDGING;
|
|
557
|
-
}
|
|
558
|
-
if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
559
|
-
return SubmissionStatus.FROZEN;
|
|
560
|
-
}
|
|
561
|
-
if (["CE", SubmissionStatus.COMPILE_ERROR.toString()].includes(status)) {
|
|
562
|
-
return SubmissionStatus.COMPILE_ERROR;
|
|
563
|
-
}
|
|
564
|
-
if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
565
|
-
return SubmissionStatus.PRESENTATION_ERROR;
|
|
566
|
-
}
|
|
567
|
-
if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
568
|
-
return SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
569
|
-
}
|
|
570
|
-
if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
571
|
-
return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
572
|
-
}
|
|
573
|
-
if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
574
|
-
return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
575
|
-
}
|
|
576
|
-
if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
577
|
-
return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
578
|
-
}
|
|
579
|
-
if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
580
|
-
return SubmissionStatus.RUNTIME_ERROR;
|
|
581
|
-
}
|
|
582
|
-
if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
583
|
-
return SubmissionStatus.JUDGEMENT_FAILED;
|
|
584
|
-
}
|
|
585
|
-
if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
586
|
-
return SubmissionStatus.SYSTEM_ERROR;
|
|
587
|
-
}
|
|
588
|
-
if ([SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
589
|
-
return SubmissionStatus.HACKED;
|
|
590
|
-
}
|
|
591
|
-
if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
592
|
-
return SubmissionStatus.CONFIGURATION_ERROR;
|
|
593
|
-
}
|
|
594
|
-
if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
595
|
-
return SubmissionStatus.CANCELED;
|
|
596
|
-
}
|
|
597
|
-
if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
598
|
-
return SubmissionStatus.SKIPPED;
|
|
599
|
-
}
|
|
600
|
-
if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
601
|
-
return SubmissionStatus.SECURITY_VIOLATED;
|
|
602
|
-
}
|
|
603
|
-
if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
604
|
-
return SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
605
|
-
}
|
|
606
|
-
return SubmissionStatus.UNKNOWN;
|
|
607
|
-
}
|
|
608
|
-
function isAccepted(status) {
|
|
609
|
-
const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
|
|
610
|
-
return acceptedArray.includes(status);
|
|
611
|
-
}
|
|
612
|
-
function isRejected(status) {
|
|
613
|
-
const rejectArray = [
|
|
614
|
-
SubmissionStatus.RUNTIME_ERROR,
|
|
615
|
-
SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
616
|
-
SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
617
|
-
SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
618
|
-
SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
619
|
-
SubmissionStatus.WRONG_ANSWER,
|
|
620
|
-
SubmissionStatus.REJECTED,
|
|
621
|
-
SubmissionStatus.JUDGEMENT_FAILED,
|
|
622
|
-
SubmissionStatus.HACKED
|
|
623
|
-
];
|
|
624
|
-
return rejectArray.includes(status);
|
|
625
|
-
}
|
|
626
|
-
function isPending(status) {
|
|
627
|
-
const pendingArray = [
|
|
628
|
-
SubmissionStatus.PENDING,
|
|
629
|
-
SubmissionStatus.WAITING,
|
|
630
|
-
SubmissionStatus.JUDGING,
|
|
631
|
-
SubmissionStatus.FROZEN
|
|
632
|
-
];
|
|
633
|
-
return pendingArray.includes(status);
|
|
634
|
-
}
|
|
635
|
-
function isNotCalculatedPenaltyStatus(status) {
|
|
636
|
-
const isNotCalculatedPenaltyArray = [
|
|
637
|
-
SubmissionStatus.COMPILE_ERROR,
|
|
638
|
-
SubmissionStatus.PRESENTATION_ERROR,
|
|
639
|
-
SubmissionStatus.CONFIGURATION_ERROR,
|
|
640
|
-
SubmissionStatus.SYSTEM_ERROR,
|
|
641
|
-
SubmissionStatus.CANCELED,
|
|
642
|
-
SubmissionStatus.SKIPPED,
|
|
643
|
-
SubmissionStatus.UNKNOWN,
|
|
644
|
-
SubmissionStatus.UNDEFINED
|
|
645
|
-
];
|
|
646
|
-
return isNotCalculatedPenaltyArray.includes(status);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
809
|
class Submission {
|
|
650
810
|
constructor() {
|
|
651
811
|
this.status = SubmissionStatus.UNKNOWN;
|
|
@@ -712,7 +872,7 @@ class RankOptions {
|
|
|
712
872
|
this.width = 0;
|
|
713
873
|
this.timestamp = 0;
|
|
714
874
|
this.enableFilterTeamsByGroup = false;
|
|
715
|
-
this.group = "";
|
|
875
|
+
this.group = "all";
|
|
716
876
|
this.filterOrganizations = [];
|
|
717
877
|
this.filterOrganizationMap = /* @__PURE__ */ new Map();
|
|
718
878
|
this.filterTeams = [];
|
|
@@ -735,6 +895,7 @@ class RankOptions {
|
|
|
735
895
|
}
|
|
736
896
|
disableFilterTeamsByGroup() {
|
|
737
897
|
this.enableFilterTeamsByGroup = false;
|
|
898
|
+
this.group = "all";
|
|
738
899
|
}
|
|
739
900
|
setFilterOrganizations(filterOrganizations) {
|
|
740
901
|
const m = /* @__PURE__ */ new Map();
|
|
@@ -892,6 +1053,7 @@ class Rank {
|
|
|
892
1053
|
this.teams.sort(Team.compare);
|
|
893
1054
|
this.buildTeamRank();
|
|
894
1055
|
this.buildOrgRank();
|
|
1056
|
+
this.teams.forEach((t) => t.calcAwards(this.contest.awards?.get(this.options.group)));
|
|
895
1057
|
this.teams.forEach((t) => t.postProcessPlaceChartPoints());
|
|
896
1058
|
})();
|
|
897
1059
|
(() => {
|
|
@@ -1063,4 +1225,4 @@ class Resolver extends Rank {
|
|
|
1063
1225
|
}
|
|
1064
1226
|
}
|
|
1065
1227
|
|
|
1066
|
-
export { Contest, ContestIndex, ContestIndexConfig, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, stringToSubmissionStatus };
|
|
1228
|
+
export { Award, Contest, ContestIndex, ContestIndexConfig, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, rankToCodeforcesGymDAT, stringToSubmissionStatus };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcpcio/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "XCPCIO Core",
|
|
5
5
|
"author": "Dup4 <lyuzhi.pan@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"dayjs": "^1.11.8",
|
|
44
44
|
"lodash": "^4.17.21",
|
|
45
|
-
"@xcpcio/types": "0.
|
|
45
|
+
"@xcpcio/types": "0.9.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@babel/types": "^7.22.4",
|
package/src/award.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export enum MedalType {
|
|
2
|
+
UNKNOWN,
|
|
3
|
+
GOLD,
|
|
4
|
+
SILVER,
|
|
5
|
+
BRONZE,
|
|
6
|
+
HONORABLE,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class Award {
|
|
10
|
+
medalType: MedalType;
|
|
11
|
+
minRank: number;
|
|
12
|
+
maxRank: number;
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
this.medalType = MedalType.UNKNOWN;
|
|
16
|
+
this.minRank = 0;
|
|
17
|
+
this.maxRank = 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Awards = Map<string, Award[]>;
|
package/src/contest.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type { Problem, Problems } from "./problem";
|
|
|
5
5
|
import { createProblems, createProblemsByProblemIds } from "./problem";
|
|
6
6
|
import { createDayJS, dayjs, getTimeDiff } from "./utils";
|
|
7
7
|
import { Group } from "./group";
|
|
8
|
+
import { Award } from "./award";
|
|
9
|
+
import { type Awards, MedalType } from "./award";
|
|
8
10
|
|
|
9
11
|
export class Contest {
|
|
10
12
|
name = "";
|
|
@@ -26,6 +28,7 @@ export class Contest {
|
|
|
26
28
|
|
|
27
29
|
badge?: string;
|
|
28
30
|
medal?: Record<string, Record<string, number>>;
|
|
31
|
+
awards?: Awards;
|
|
29
32
|
organization?: string;
|
|
30
33
|
|
|
31
34
|
group: Map<string, Group>;
|
|
@@ -189,6 +192,49 @@ export function createContest(contestJSON: IContest): Contest {
|
|
|
189
192
|
|
|
190
193
|
c.badge = contestJSON.badge;
|
|
191
194
|
c.medal = contestJSON.medal;
|
|
195
|
+
|
|
196
|
+
(() => {
|
|
197
|
+
if (contestJSON.medal === undefined || contestJSON.medal === null) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
c.awards = new Map<string, Award[]>();
|
|
202
|
+
|
|
203
|
+
for (const k in contestJSON.medal) {
|
|
204
|
+
const v = contestJSON.medal[k];
|
|
205
|
+
|
|
206
|
+
{
|
|
207
|
+
const award: Award[] = [];
|
|
208
|
+
|
|
209
|
+
let rank = 1;
|
|
210
|
+
const work = (key: string, medalType: MedalType) => {
|
|
211
|
+
if (Object.keys(v).includes(key)) {
|
|
212
|
+
const a = new Award();
|
|
213
|
+
a.medalType = medalType;
|
|
214
|
+
a.minRank = rank;
|
|
215
|
+
rank += Number(v[key]);
|
|
216
|
+
a.maxRank = rank - 1;
|
|
217
|
+
award.push(a);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
work("gold", MedalType.GOLD);
|
|
222
|
+
work("silver", MedalType.SILVER);
|
|
223
|
+
work("bronze", MedalType.BRONZE);
|
|
224
|
+
|
|
225
|
+
{
|
|
226
|
+
const a = new Award();
|
|
227
|
+
a.medalType = MedalType.HONORABLE;
|
|
228
|
+
a.minRank = rank;
|
|
229
|
+
a.maxRank = 0x3F3F3F3F;
|
|
230
|
+
award.push(a);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
c.awards.set(k, award);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
})();
|
|
237
|
+
|
|
192
238
|
c.organization = contestJSON.organization;
|
|
193
239
|
|
|
194
240
|
{
|
package/src/export.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { SubmissionStatus } from "@xcpcio/types";
|
|
2
|
+
|
|
3
|
+
import type { Rank } from "./rank";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
isAccepted,
|
|
7
|
+
isNotCalculatedPenaltyStatus,
|
|
8
|
+
isPending,
|
|
9
|
+
} from "./submission-status";
|
|
10
|
+
|
|
11
|
+
function submissionStatusToCodeforcesGymDatStatus(status: SubmissionStatus): string {
|
|
12
|
+
if (isAccepted(status)) {
|
|
13
|
+
return "OK";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (status === SubmissionStatus.WRONG_ANSWER) {
|
|
17
|
+
return "WA";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
|
|
21
|
+
return "TL";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
|
|
25
|
+
return "ML";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
|
|
29
|
+
return "IL";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (status === SubmissionStatus.PRESENTATION_ERROR) {
|
|
33
|
+
return "PE";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (status === SubmissionStatus.RUNTIME_ERROR) {
|
|
37
|
+
return "RT";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (status === SubmissionStatus.COMPILE_ERROR || isNotCalculatedPenaltyStatus(status)) {
|
|
41
|
+
return "CE";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (isPending(status)) {
|
|
45
|
+
return "PD";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return "RJ";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function rankToCodeforcesGymDAT(rank: Rank) {
|
|
52
|
+
let res = "";
|
|
53
|
+
|
|
54
|
+
res += `@contest "${rank.contest.name}"
|
|
55
|
+
@contlen ${Math.floor(rank.contest.endTime.diff(rank.contest.startTime) / 1000 / 60)}
|
|
56
|
+
@problems ${rank.contest.problems.length}
|
|
57
|
+
@teams ${rank.teams.length + 100}
|
|
58
|
+
@submissions ${rank.submissions.length}
|
|
59
|
+
`;
|
|
60
|
+
|
|
61
|
+
rank.contest.problems.forEach((p) => {
|
|
62
|
+
res += `@p ${p.label},${p.label},20,0\n`;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
let teamIndex = 1;
|
|
66
|
+
const teamIdMap = new Map<string, number>();
|
|
67
|
+
const submissionsIdMap = new Map<string, Map<string, number>>();
|
|
68
|
+
|
|
69
|
+
rank.teams.forEach((team) => {
|
|
70
|
+
let name = team.name;
|
|
71
|
+
|
|
72
|
+
if (team.organization) {
|
|
73
|
+
name = `${team.organization} - ${name}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (team.members) {
|
|
77
|
+
name = `${name} - ${team.membersToString}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
res += `@t ${teamIndex},0,1,${name}\n`;
|
|
81
|
+
teamIdMap.set(team.id, teamIndex);
|
|
82
|
+
teamIndex++;
|
|
83
|
+
|
|
84
|
+
{
|
|
85
|
+
const mp = new Map<string, number>();
|
|
86
|
+
rank.contest.problems.forEach((p) => {
|
|
87
|
+
mp.set(p.id, 0);
|
|
88
|
+
});
|
|
89
|
+
submissionsIdMap.set(team.id, mp);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < 100; i++) {
|
|
94
|
+
res += `@t ${teamIndex},0,1,Пополнить команду\n`;
|
|
95
|
+
teamIndex++;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
rank.submissions.forEach((submission) => {
|
|
99
|
+
const teamId = submission.teamId;
|
|
100
|
+
const problemId = submission.problemId;
|
|
101
|
+
const problem = rank.contest.problemsMap.get(problemId);
|
|
102
|
+
|
|
103
|
+
if (!problem) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const status = submissionStatusToCodeforcesGymDatStatus(submission.status);
|
|
108
|
+
submissionsIdMap.get(teamId)!.set(problemId, submissionsIdMap.get(teamId)!.get(problemId)! + 1);
|
|
109
|
+
|
|
110
|
+
res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}\n`;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return res;
|
|
114
|
+
}
|
package/src/index.ts
CHANGED
package/src/rank.ts
CHANGED
|
@@ -32,7 +32,7 @@ export class RankOptions {
|
|
|
32
32
|
this.timestamp = 0;
|
|
33
33
|
|
|
34
34
|
this.enableFilterTeamsByGroup = false;
|
|
35
|
-
this.group = "";
|
|
35
|
+
this.group = "all";
|
|
36
36
|
|
|
37
37
|
this.filterOrganizations = [];
|
|
38
38
|
this.filterOrganizationMap = new Map<string, SelectOptionItem>();
|
|
@@ -62,6 +62,7 @@ export class RankOptions {
|
|
|
62
62
|
|
|
63
63
|
disableFilterTeamsByGroup() {
|
|
64
64
|
this.enableFilterTeamsByGroup = false;
|
|
65
|
+
this.group = "all";
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
setFilterOrganizations(filterOrganizations: Array<SelectOptionItem>) {
|
|
@@ -285,6 +286,7 @@ export class Rank {
|
|
|
285
286
|
this.buildTeamRank();
|
|
286
287
|
this.buildOrgRank();
|
|
287
288
|
|
|
289
|
+
this.teams.forEach(t => t.calcAwards(this.contest.awards?.get(this.options.group)));
|
|
288
290
|
this.teams.forEach(t => t.postProcessPlaceChartPoints());
|
|
289
291
|
})();
|
|
290
292
|
|
package/src/team.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Team as ITeam, Teams as ITeams, Image } from "@xcpcio/types";
|
|
|
3
3
|
import type { Problem, TeamProblemStatistics } from "./problem";
|
|
4
4
|
import { calcDict } from "./utils";
|
|
5
5
|
import type { Submissions } from "./submission";
|
|
6
|
+
import type { Award, MedalType } from "./award";
|
|
6
7
|
|
|
7
8
|
export class PlaceChartPointData {
|
|
8
9
|
timePoint: number;
|
|
@@ -48,6 +49,8 @@ export class Team {
|
|
|
48
49
|
|
|
49
50
|
placeChartPoints: Array<PlaceChartPointData>;
|
|
50
51
|
|
|
52
|
+
awards: MedalType[];
|
|
53
|
+
|
|
51
54
|
constructor() {
|
|
52
55
|
this.id = "";
|
|
53
56
|
this.name = "";
|
|
@@ -75,6 +78,8 @@ export class Team {
|
|
|
75
78
|
this.submissions = [];
|
|
76
79
|
|
|
77
80
|
this.placeChartPoints = [];
|
|
81
|
+
|
|
82
|
+
this.awards = [];
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
reset() {
|
|
@@ -109,6 +114,14 @@ export class Team {
|
|
|
109
114
|
return calcDict(attemptedNum, solvedNum);
|
|
110
115
|
}
|
|
111
116
|
|
|
117
|
+
get membersToString() {
|
|
118
|
+
if (typeof this.members === "string") {
|
|
119
|
+
return this.members;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return this.members?.join(", ");
|
|
123
|
+
}
|
|
124
|
+
|
|
112
125
|
calcSolvedData() {
|
|
113
126
|
this.solvedProblemNum = 0;
|
|
114
127
|
this.attemptedProblemNum = 0;
|
|
@@ -125,6 +138,18 @@ export class Team {
|
|
|
125
138
|
}
|
|
126
139
|
}
|
|
127
140
|
|
|
141
|
+
calcAwards(awards?: Award[]) {
|
|
142
|
+
if (!awards) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const award of awards) {
|
|
147
|
+
if (this.rank >= award.minRank && this.rank <= award.maxRank) {
|
|
148
|
+
this.awards.push(award.medalType);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
128
153
|
isEqualRank(otherTeam: Team) {
|
|
129
154
|
return this.solvedProblemNum === otherTeam.solvedProblemNum && this.penalty === otherTeam.penalty;
|
|
130
155
|
}
|
|
@@ -205,6 +230,15 @@ export function createTeam(teamJSON: ITeam): Team {
|
|
|
205
230
|
t.group.push("girl");
|
|
206
231
|
}
|
|
207
232
|
|
|
233
|
+
{
|
|
234
|
+
const tt: any = teamJSON as any;
|
|
235
|
+
for (const key of Object.keys(tt)) {
|
|
236
|
+
if (tt[key] === 1 || tt[key] === true) {
|
|
237
|
+
t.group.push(key);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
208
242
|
t.group = [...new Set(t.group)];
|
|
209
243
|
t.group.sort();
|
|
210
244
|
|