@xcpcio/core 0.58.3 → 0.59.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/package.json +11 -22
- package/src/award.ts +0 -32
- package/src/balloon.ts +0 -25
- package/src/basic-types.ts +0 -4
- package/src/battle-of-giants.ts +0 -154
- package/src/contest-index.ts +0 -99
- package/src/contest-options.ts +0 -49
- package/src/contest.ts +0 -351
- package/src/export/cf.ts +0 -125
- package/src/export/general-excel.ts +0 -257
- package/src/export/icpc-standings-csv.ts +0 -89
- package/src/export/index.ts +0 -3
- package/src/group.ts +0 -13
- package/src/image.ts +0 -21
- package/src/index.ts +0 -19
- package/src/person.ts +0 -42
- package/src/problem.ts +0 -222
- package/src/rank-statistics.ts +0 -33
- package/src/rank.ts +0 -613
- package/src/rating/index.ts +0 -5
- package/src/rating/rating-calculator.ts +0 -100
- package/src/rating/rating-history.ts +0 -81
- package/src/rating/rating-user.ts +0 -99
- package/src/rating/rating-utility.ts +0 -80
- package/src/rating/rating.ts +0 -136
- package/src/resolver-operation.ts +0 -22
- package/src/resolver-vue.ts +0 -183
- package/src/resolver.ts +0 -138
- package/src/submission-status.ts +0 -157
- package/src/submission.ts +0 -177
- package/src/team.ts +0 -339
- package/src/utils/calc.ts +0 -7
- package/src/utils/color.ts +0 -28
- package/src/utils/dayjs.ts +0 -59
- package/src/utils/index.ts +0 -3
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcpcio/core",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.59.0",
|
|
5
|
+
"description": "The core library for XCPCIO",
|
|
5
6
|
"author": "Dup4 <hi@dup4.com>",
|
|
6
7
|
"license": "MIT",
|
|
7
|
-
"
|
|
8
|
+
"funding": "https://github.com/sponsors/Dup4",
|
|
9
|
+
"homepage": "https://xcpcio.com",
|
|
8
10
|
"repository": {
|
|
9
11
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/xcpcio/xcpcio.git"
|
|
12
|
+
"url": "git+https://github.com/xcpcio/xcpcio.git",
|
|
13
|
+
"directory": "packages/libs/core"
|
|
11
14
|
},
|
|
12
15
|
"bugs": {
|
|
13
16
|
"url": "https://github.com/xcpcio/xcpcio/issues"
|
|
@@ -19,25 +22,14 @@
|
|
|
19
22
|
"sideEffects": false,
|
|
20
23
|
"exports": {
|
|
21
24
|
".": {
|
|
22
|
-
"types": "./dist/index.d.ts",
|
|
23
25
|
"import": "./dist/index.mjs",
|
|
24
26
|
"require": "./dist/index.cjs"
|
|
25
27
|
}
|
|
26
28
|
},
|
|
27
|
-
"main": "
|
|
28
|
-
"module": "
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"typesVersions": {
|
|
31
|
-
"*": {
|
|
32
|
-
"*": [
|
|
33
|
-
"./dist/*",
|
|
34
|
-
"./dist/index.d.ts"
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
},
|
|
29
|
+
"main": "dist/index.cjs",
|
|
30
|
+
"module": "dist/index.mjs",
|
|
38
31
|
"files": [
|
|
39
|
-
"dist"
|
|
40
|
-
"src"
|
|
32
|
+
"dist"
|
|
41
33
|
],
|
|
42
34
|
"dependencies": {
|
|
43
35
|
"chroma-js": "^3.1.2",
|
|
@@ -49,7 +41,7 @@
|
|
|
49
41
|
"papaparse": "^5.5.3",
|
|
50
42
|
"string-width": "^8.1.0",
|
|
51
43
|
"xlsx-js-style": "^1.2.0",
|
|
52
|
-
"@xcpcio/types": "0.
|
|
44
|
+
"@xcpcio/types": "0.59.0"
|
|
53
45
|
},
|
|
54
46
|
"devDependencies": {
|
|
55
47
|
"@babel/types": "^7.28.4",
|
|
@@ -74,9 +66,6 @@
|
|
|
74
66
|
"scripts": {
|
|
75
67
|
"build": "unbuild",
|
|
76
68
|
"dev": "unbuild --stub",
|
|
77
|
-
"start": "esmo src/index.ts",
|
|
78
|
-
"test": "vitest",
|
|
79
|
-
"lint": "run-p lint:*",
|
|
80
69
|
"lint:build": "# tsc --noEmit"
|
|
81
70
|
}
|
|
82
71
|
}
|
package/src/award.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export enum MedalType {
|
|
2
|
-
UNKNOWN = "Unknown",
|
|
3
|
-
GOLD = "Gold",
|
|
4
|
-
SILVER = "Silver",
|
|
5
|
-
BRONZE = "Bronze",
|
|
6
|
-
HONORABLE = "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 function isValidMedalType(medal: MedalType): boolean {
|
|
22
|
-
const validMedalType = [
|
|
23
|
-
MedalType.GOLD,
|
|
24
|
-
MedalType.SILVER,
|
|
25
|
-
MedalType.BRONZE,
|
|
26
|
-
MedalType.HONORABLE,
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
return validMedalType.includes(medal);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type Awards = Map<string, Award[]>;
|
package/src/balloon.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Problem } from "./problem";
|
|
2
|
-
import { Submission } from "./submission";
|
|
3
|
-
import { Team } from "./team";
|
|
4
|
-
|
|
5
|
-
export class Balloon {
|
|
6
|
-
problem: Problem;
|
|
7
|
-
team: Team;
|
|
8
|
-
submission: Submission;
|
|
9
|
-
|
|
10
|
-
constructor() {
|
|
11
|
-
this.problem = new Problem();
|
|
12
|
-
this.team = new Team();
|
|
13
|
-
this.submission = new Submission();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
get key() {
|
|
17
|
-
return `balloon-${this.team.id}-${this.problem.id}`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static compare(lhs: Balloon, rhs: Balloon): number {
|
|
21
|
-
return Submission.compare(lhs.submission, rhs.submission);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type Balloons = Array<Balloon>;
|
package/src/basic-types.ts
DELETED
package/src/battle-of-giants.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import type { SelectOptionItem } from "./basic-types";
|
|
2
|
-
import type { Team } from "./team";
|
|
3
|
-
|
|
4
|
-
import { Base64 } from "js-base64";
|
|
5
|
-
|
|
6
|
-
export enum GiantsType {
|
|
7
|
-
BLUE,
|
|
8
|
-
RED,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class Giants {
|
|
12
|
-
type: GiantsType;
|
|
13
|
-
name: string;
|
|
14
|
-
|
|
15
|
-
filterOrganizations: Array<SelectOptionItem>;
|
|
16
|
-
filterOrganizationMap: Map<string, SelectOptionItem>;
|
|
17
|
-
filterTeams: Array<SelectOptionItem>;
|
|
18
|
-
filterTeamMap: Map<string, SelectOptionItem>;
|
|
19
|
-
|
|
20
|
-
teams: Array<Team>;
|
|
21
|
-
|
|
22
|
-
constructor(type: GiantsType = GiantsType.BLUE) {
|
|
23
|
-
this.type = type;
|
|
24
|
-
this.name = `${type === GiantsType.BLUE ? "Blue" : "Red"} Team`;
|
|
25
|
-
this.teams = [];
|
|
26
|
-
|
|
27
|
-
this.filterOrganizations = [];
|
|
28
|
-
this.filterOrganizationMap = new Map<string, SelectOptionItem>();
|
|
29
|
-
this.filterTeams = [];
|
|
30
|
-
this.filterTeamMap = new Map<string, SelectOptionItem>();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
setFilterOrganizations(filterOrganizations: Array<SelectOptionItem>) {
|
|
34
|
-
const m = new Map<string, SelectOptionItem>();
|
|
35
|
-
filterOrganizations.forEach((item) => {
|
|
36
|
-
m.set(item.value, item);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
this.filterOrganizations = filterOrganizations;
|
|
40
|
-
this.filterOrganizationMap = m;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
setFilterTeams(filterTeams: Array<SelectOptionItem>) {
|
|
44
|
-
const m = new Map<string, SelectOptionItem>();
|
|
45
|
-
filterTeams.forEach((item) => {
|
|
46
|
-
m.set(item.value, item);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
this.filterTeams = filterTeams;
|
|
50
|
-
this.filterTeamMap = m;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
refreshName() {
|
|
54
|
-
if (this.filterOrganizations.length > 0) {
|
|
55
|
-
this.name = this.filterOrganizations[0].text;
|
|
56
|
-
} else {
|
|
57
|
-
this.name = `${this.type === GiantsType.BLUE ? "Blue" : "Red"} Team`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return this.name;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get totalSolvedProblemNum(): number {
|
|
64
|
-
let total = 0;
|
|
65
|
-
this.teams.forEach((team) => {
|
|
66
|
-
total += team.solvedProblemNum;
|
|
67
|
-
});
|
|
68
|
-
return total;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get totalPenalty(): number {
|
|
72
|
-
let total = 0;
|
|
73
|
-
this.teams.forEach((team) => {
|
|
74
|
-
total += team.penaltyToMinute;
|
|
75
|
-
});
|
|
76
|
-
return total;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
get totalPenaltyToString(): string {
|
|
80
|
-
const penalty = this.totalPenalty;
|
|
81
|
-
const two = (a: number) => {
|
|
82
|
-
if (a < 10) {
|
|
83
|
-
return `0${a}`;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return String(a);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const h = Math.floor(penalty / 60);
|
|
90
|
-
const m = Math.floor(penalty % 60);
|
|
91
|
-
|
|
92
|
-
return [two(h), two(m)].join(":");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
toJSON() {
|
|
96
|
-
return {
|
|
97
|
-
type: this.type,
|
|
98
|
-
name: this.name,
|
|
99
|
-
filterOrganizations: this.filterOrganizations,
|
|
100
|
-
filterTeams: this.filterTeams,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export class BattleOfGiants {
|
|
106
|
-
enable: boolean;
|
|
107
|
-
topX: number;
|
|
108
|
-
equalTeams: boolean;
|
|
109
|
-
persist: boolean;
|
|
110
|
-
|
|
111
|
-
blueTeam: Giants;
|
|
112
|
-
redTeam: Giants;
|
|
113
|
-
|
|
114
|
-
constructor() {
|
|
115
|
-
this.enable = false;
|
|
116
|
-
this.topX = 5;
|
|
117
|
-
this.equalTeams = true;
|
|
118
|
-
this.persist = false;
|
|
119
|
-
|
|
120
|
-
this.blueTeam = new Giants(GiantsType.BLUE);
|
|
121
|
-
this.redTeam = new Giants(GiantsType.RED);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
ToBase64(): string {
|
|
125
|
-
return Base64.encode(JSON.stringify(this));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
FromBase64(base64: string) {
|
|
129
|
-
if (base64.length === 0) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (Base64.isValid(base64) === false) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const j = JSON.parse(Base64.decode(base64));
|
|
138
|
-
|
|
139
|
-
this.enable = j.enable;
|
|
140
|
-
this.topX = j.topX;
|
|
141
|
-
this.equalTeams = j.equalTeams;
|
|
142
|
-
this.persist = j.persist;
|
|
143
|
-
|
|
144
|
-
this.blueTeam = new Giants(GiantsType.BLUE);
|
|
145
|
-
this.blueTeam.name = j.blueTeam.name;
|
|
146
|
-
this.blueTeam.setFilterOrganizations(j.blueTeam.filterOrganizations);
|
|
147
|
-
this.blueTeam.setFilterTeams(j.blueTeam.filterTeams);
|
|
148
|
-
|
|
149
|
-
this.redTeam = new Giants(GiantsType.RED);
|
|
150
|
-
this.redTeam.name = j.redTeam.name;
|
|
151
|
-
this.redTeam.setFilterOrganizations(j.redTeam.filterOrganizations);
|
|
152
|
-
this.redTeam.setFilterTeams(j.redTeam.filterTeams);
|
|
153
|
-
}
|
|
154
|
-
}
|
package/src/contest-index.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { Contest as IContest, ContestIndex as IContestIndex, Image } from "@xcpcio/types";
|
|
2
|
-
import type dayjs from "dayjs";
|
|
3
|
-
|
|
4
|
-
import { Contest, createContest } from "./contest";
|
|
5
|
-
import { createDayJS } from "./utils";
|
|
6
|
-
|
|
7
|
-
export class ContestIndexConfig {
|
|
8
|
-
contestName: string;
|
|
9
|
-
|
|
10
|
-
startTime: dayjs.Dayjs;
|
|
11
|
-
endTime: dayjs.Dayjs;
|
|
12
|
-
freezeTime: dayjs.Dayjs;
|
|
13
|
-
|
|
14
|
-
totalDurationTimestamp: number;
|
|
15
|
-
freezeDurationTimestamp: number;
|
|
16
|
-
unFreezeDurationTimestamp: number;
|
|
17
|
-
|
|
18
|
-
logo?: Image;
|
|
19
|
-
|
|
20
|
-
constructor() {
|
|
21
|
-
this.contestName = "";
|
|
22
|
-
|
|
23
|
-
this.startTime = createDayJS();
|
|
24
|
-
this.endTime = createDayJS();
|
|
25
|
-
this.freezeTime = createDayJS();
|
|
26
|
-
|
|
27
|
-
this.totalDurationTimestamp = 0;
|
|
28
|
-
this.freezeDurationTimestamp = 0;
|
|
29
|
-
this.unFreezeDurationTimestamp = 0;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export class ContestIndex {
|
|
34
|
-
contest: Contest;
|
|
35
|
-
boardLink: string;
|
|
36
|
-
|
|
37
|
-
constructor() {
|
|
38
|
-
this.contest = new Contest();
|
|
39
|
-
this.boardLink = "";
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type ContestIndexList = Array<ContestIndex>;
|
|
44
|
-
|
|
45
|
-
export function createContestIndex(contestIndexJSON: IContestIndex): ContestIndex {
|
|
46
|
-
const c = new ContestIndex();
|
|
47
|
-
const cjc = contestIndexJSON.config;
|
|
48
|
-
|
|
49
|
-
c.contest = createContest(cjc as IContest);
|
|
50
|
-
c.boardLink = contestIndexJSON.board_link;
|
|
51
|
-
|
|
52
|
-
return c;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function createContestIndexList(contestListJSON: any): ContestIndexList {
|
|
56
|
-
const contestIndexList = [] as ContestIndexList;
|
|
57
|
-
|
|
58
|
-
const dfs = (contestList: any) => {
|
|
59
|
-
if (Object.prototype.hasOwnProperty.call(contestList, "config")) {
|
|
60
|
-
contestIndexList.push(createContestIndex(contestList));
|
|
61
|
-
} else {
|
|
62
|
-
for (const k in contestList) {
|
|
63
|
-
dfs(contestList[k]);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
dfs(contestListJSON);
|
|
69
|
-
|
|
70
|
-
contestIndexList.sort((a: ContestIndex, b: ContestIndex) => {
|
|
71
|
-
if (a.contest.startTime.isBefore(b.contest.startTime)) {
|
|
72
|
-
return 1;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (a.contest.startTime.isAfter(b.contest.startTime)) {
|
|
76
|
-
return -1;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (a.contest.endTime.isBefore(b.contest.endTime)) {
|
|
80
|
-
return 1;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (a.contest.endTime.isAfter(b.contest.endTime)) {
|
|
84
|
-
return -1;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (a.contest.name < b.contest.name) {
|
|
88
|
-
return 1;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (a.contest.name > b.contest.name) {
|
|
92
|
-
return -1;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return 0;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
return contestIndexList;
|
|
99
|
-
}
|
package/src/contest-options.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { CalculationOfPenalty, ContestOptions as IContestOptions, TimeUnit } from "@xcpcio/types";
|
|
2
|
-
|
|
3
|
-
export class ContestOptions {
|
|
4
|
-
calculationOfPenalty: CalculationOfPenalty;
|
|
5
|
-
submissionTimestampUnit: TimeUnit;
|
|
6
|
-
|
|
7
|
-
submissionHasTimeField: boolean;
|
|
8
|
-
submissionHasLanguageField: boolean;
|
|
9
|
-
|
|
10
|
-
submissionEnableActionField: boolean;
|
|
11
|
-
submissionHasReactionField: boolean;
|
|
12
|
-
|
|
13
|
-
reactionVideoUrlTemplate?: string;
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
this.calculationOfPenalty = "in_minutes";
|
|
17
|
-
this.submissionTimestampUnit = "second";
|
|
18
|
-
|
|
19
|
-
this.submissionHasTimeField = false;
|
|
20
|
-
this.submissionHasLanguageField = false;
|
|
21
|
-
|
|
22
|
-
this.submissionEnableActionField = false;
|
|
23
|
-
this.submissionHasReactionField = false;
|
|
24
|
-
|
|
25
|
-
this.reactionVideoUrlTemplate = undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function createContestOptions(contestOptionsJSON: IContestOptions = {}): ContestOptions {
|
|
30
|
-
const j = contestOptionsJSON;
|
|
31
|
-
const o = new ContestOptions();
|
|
32
|
-
|
|
33
|
-
if (j.calculation_of_penalty) {
|
|
34
|
-
o.calculationOfPenalty = j.calculation_of_penalty;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (j.submission_timestamp_unit) {
|
|
38
|
-
o.submissionTimestampUnit = j.submission_timestamp_unit;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (j.submission_has_reaction || j.has_reaction_videos) {
|
|
42
|
-
o.submissionHasReactionField = true;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
o.submissionEnableActionField = o.submissionHasReactionField;
|
|
46
|
-
o.reactionVideoUrlTemplate = j.reaction_video_url_template;
|
|
47
|
-
|
|
48
|
-
return o;
|
|
49
|
-
}
|