@xcpcio/core 0.5.3 → 0.6.1

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 CHANGED
@@ -404,9 +404,11 @@ function getImageSource(image) {
404
404
  class RankStatistics {
405
405
  constructor() {
406
406
  this.teamSolvedNum = [];
407
+ this.maxSolvedProblems = 0;
407
408
  }
408
409
  reset() {
409
410
  this.teamSolvedNum = [];
411
+ this.maxSolvedProblems = 0;
410
412
  }
411
413
  }
412
414
 
@@ -425,6 +427,7 @@ class Team {
425
427
  this.group = [];
426
428
  this.tag = [];
427
429
  this.rank = 0;
430
+ this.originalRank = 0;
428
431
  this.organizationRank = -1;
429
432
  this.solvedProblemNum = 0;
430
433
  this.attemptedProblemNum = 0;
@@ -438,6 +441,7 @@ class Team {
438
441
  }
439
442
  reset() {
440
443
  this.rank = 0;
444
+ this.originalRank = 0;
441
445
  this.organizationRank = -1;
442
446
  this.solvedProblemNum = 0;
443
447
  this.attemptedProblemNum = 0;
@@ -726,6 +730,10 @@ class RankOptions {
726
730
  this.timestamp = 0;
727
731
  this.enableFilterTeamsByGroup = false;
728
732
  this.group = "";
733
+ this.filterOrganizations = [];
734
+ this.filterOrganizationMap = /* @__PURE__ */ new Map();
735
+ this.filterTeams = [];
736
+ this.filterTeamMap = /* @__PURE__ */ new Map();
729
737
  }
730
738
  setWidth(width, contest) {
731
739
  this.width = width;
@@ -745,6 +753,22 @@ class RankOptions {
745
753
  disableFilterTeamsByGroup() {
746
754
  this.enableFilterTeamsByGroup = false;
747
755
  }
756
+ setFilterOrganizations(filterOrganizations) {
757
+ const m = /* @__PURE__ */ new Map();
758
+ filterOrganizations.forEach((item) => {
759
+ m.set(item.value, item);
760
+ });
761
+ this.filterOrganizations = filterOrganizations;
762
+ this.filterOrganizationMap = m;
763
+ }
764
+ setFilterTeams(filterTeams) {
765
+ const m = /* @__PURE__ */ new Map();
766
+ filterTeams.forEach((item) => {
767
+ m.set(item.value, item);
768
+ });
769
+ this.filterTeams = filterTeams;
770
+ this.filterTeamMap = m;
771
+ }
748
772
  }
749
773
  class Rank {
750
774
  constructor(contest, teams, submissions) {
@@ -753,6 +777,9 @@ class Rank {
753
777
  this.teamsMap = new Map(this.teams.map((t) => [t.id, t]));
754
778
  this.submissions = ___default.cloneDeep(submissions).sort(Submission.compare);
755
779
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
780
+ this.organizations = this.buildOrganizations();
781
+ this.originTeams = this.teams.map((t) => t);
782
+ this.originTeams.sort(Team.compare);
756
783
  this.rankStatistics = new RankStatistics();
757
784
  this.options = new RankOptions();
758
785
  }
@@ -856,8 +883,11 @@ class Rank {
856
883
  }
857
884
  preSubmissionTimestampToMinute = s.timestampToMinute;
858
885
  }
859
- this.teams.forEach((t) => t.postProcessPlaceChartPoints());
886
+ this.teams.forEach((t) => t.calcSolvedData());
887
+ this.teams.sort(Team.compare);
888
+ this.buildTeamRank();
860
889
  this.buildOrgRank();
890
+ this.teams.forEach((t) => t.postProcessPlaceChartPoints());
861
891
  })();
862
892
  (() => {
863
893
  this.rankStatistics.reset();
@@ -865,14 +895,19 @@ class Rank {
865
895
  for (const t of this.teams) {
866
896
  this.rankStatistics.teamSolvedNum[t.solvedProblemNum]++;
867
897
  }
898
+ if (this.teams.length > 0) {
899
+ this.rankStatistics.maxSolvedProblems = this.teams[0].solvedProblemNum;
900
+ }
868
901
  })();
869
902
  return this;
870
903
  }
871
904
  buildTeamRank() {
872
905
  let rank = 1;
906
+ let originalRank = 1;
873
907
  let preTeam = null;
874
908
  for (const t of this.teams) {
875
909
  t.rank = rank++;
910
+ t.originalRank = originalRank++;
876
911
  if (preTeam !== null) {
877
912
  if (t.isEqualRank(preTeam)) {
878
913
  t.rank = preTeam.rank;
@@ -903,6 +938,23 @@ class Rank {
903
938
  preTeam = t;
904
939
  }
905
940
  }
941
+ buildOrganizations() {
942
+ if (!this.contest.organization) {
943
+ return [];
944
+ }
945
+ const res = new Array();
946
+ const se = /* @__PURE__ */ new Set();
947
+ this.teams.forEach((t) => {
948
+ const org = t.organization;
949
+ if (se.has(org)) {
950
+ return;
951
+ }
952
+ res.push(org);
953
+ se.add(org);
954
+ });
955
+ res.sort();
956
+ return res;
957
+ }
906
958
  filterTeamByOrg(team) {
907
959
  const o = this.options;
908
960
  if (o.enableFilterTeamsByGroup) {
package/dist/index.d.ts CHANGED
@@ -139,6 +139,7 @@ declare function getImageSource(image: Image): string;
139
139
 
140
140
  declare class RankStatistics {
141
141
  teamSolvedNum: Array<number>;
142
+ maxSolvedProblems: number;
142
143
  constructor();
143
144
  reset(): void;
144
145
  }
@@ -159,6 +160,7 @@ declare class Team {
159
160
  coach?: string | Array<string>;
160
161
  members?: string | Array<string>;
161
162
  rank: number;
163
+ originalRank: number;
162
164
  organizationRank: number;
163
165
  solvedProblemNum: number;
164
166
  attemptedProblemNum: number;
@@ -182,17 +184,27 @@ type Teams = Array<Team>;
182
184
  declare function createTeam(teamJSON: Team$1): Team;
183
185
  declare function createTeams(teamsJSON: Teams$1): Teams;
184
186
 
187
+ interface SelectOptionItem {
188
+ value: string;
189
+ text: string;
190
+ }
185
191
  declare class RankOptions {
186
192
  enableFilterSubmissionsByTimestamp: boolean;
187
193
  width: number;
188
194
  timestamp: number;
189
195
  enableFilterTeamsByGroup: boolean;
190
196
  group: string;
197
+ filterOrganizations: Array<SelectOptionItem>;
198
+ filterOrganizationMap: Map<string, SelectOptionItem>;
199
+ filterTeams: Array<SelectOptionItem>;
200
+ filterTeamMap: Map<string, SelectOptionItem>;
191
201
  constructor();
192
202
  setWidth(width: number, contest: Contest): void;
193
203
  disableFilterSubmissionByTimestamp(): void;
194
204
  setGroup(group: string): void;
195
205
  disableFilterTeamsByGroup(): void;
206
+ setFilterOrganizations(filterOrganizations: Array<SelectOptionItem>): void;
207
+ setFilterTeams(filterTeams: Array<SelectOptionItem>): void;
196
208
  }
197
209
  declare class Rank {
198
210
  readonly contest: Contest;
@@ -200,12 +212,15 @@ declare class Rank {
200
212
  teamsMap: Map<string, Team>;
201
213
  submissions: Submissions;
202
214
  submissionsMap: Map<string, Submission>;
215
+ organizations: Array<string>;
216
+ originTeams: Teams;
203
217
  rankStatistics: RankStatistics;
204
218
  options: RankOptions;
205
219
  constructor(contest: Contest, teams: Teams, submissions: Submissions);
206
220
  buildRank(): this;
207
221
  buildTeamRank(): void;
208
222
  buildOrgRank(): void;
223
+ buildOrganizations(): string[];
209
224
  filterTeamByOrg(team: Team): boolean;
210
225
  getSubmissions(): Submissions;
211
226
  }
@@ -234,4 +249,4 @@ declare function isRejected(status: SubmissionStatus): boolean;
234
249
  declare function isPending(status: SubmissionStatus): boolean;
235
250
  declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
236
251
 
237
- export { Contest, ContestIndex, ContestIndexConfig, ContestIndexList, PlaceChartPointData, Problem, ProblemStatistics, Problems, Rank, RankOptions, RankStatistics, Resolver, 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 };
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 };
package/dist/index.mjs CHANGED
@@ -388,9 +388,11 @@ function getImageSource(image) {
388
388
  class RankStatistics {
389
389
  constructor() {
390
390
  this.teamSolvedNum = [];
391
+ this.maxSolvedProblems = 0;
391
392
  }
392
393
  reset() {
393
394
  this.teamSolvedNum = [];
395
+ this.maxSolvedProblems = 0;
394
396
  }
395
397
  }
396
398
 
@@ -409,6 +411,7 @@ class Team {
409
411
  this.group = [];
410
412
  this.tag = [];
411
413
  this.rank = 0;
414
+ this.originalRank = 0;
412
415
  this.organizationRank = -1;
413
416
  this.solvedProblemNum = 0;
414
417
  this.attemptedProblemNum = 0;
@@ -422,6 +425,7 @@ class Team {
422
425
  }
423
426
  reset() {
424
427
  this.rank = 0;
428
+ this.originalRank = 0;
425
429
  this.organizationRank = -1;
426
430
  this.solvedProblemNum = 0;
427
431
  this.attemptedProblemNum = 0;
@@ -710,6 +714,10 @@ class RankOptions {
710
714
  this.timestamp = 0;
711
715
  this.enableFilterTeamsByGroup = false;
712
716
  this.group = "";
717
+ this.filterOrganizations = [];
718
+ this.filterOrganizationMap = /* @__PURE__ */ new Map();
719
+ this.filterTeams = [];
720
+ this.filterTeamMap = /* @__PURE__ */ new Map();
713
721
  }
714
722
  setWidth(width, contest) {
715
723
  this.width = width;
@@ -729,6 +737,22 @@ class RankOptions {
729
737
  disableFilterTeamsByGroup() {
730
738
  this.enableFilterTeamsByGroup = false;
731
739
  }
740
+ setFilterOrganizations(filterOrganizations) {
741
+ const m = /* @__PURE__ */ new Map();
742
+ filterOrganizations.forEach((item) => {
743
+ m.set(item.value, item);
744
+ });
745
+ this.filterOrganizations = filterOrganizations;
746
+ this.filterOrganizationMap = m;
747
+ }
748
+ setFilterTeams(filterTeams) {
749
+ const m = /* @__PURE__ */ new Map();
750
+ filterTeams.forEach((item) => {
751
+ m.set(item.value, item);
752
+ });
753
+ this.filterTeams = filterTeams;
754
+ this.filterTeamMap = m;
755
+ }
732
756
  }
733
757
  class Rank {
734
758
  constructor(contest, teams, submissions) {
@@ -737,6 +761,9 @@ class Rank {
737
761
  this.teamsMap = new Map(this.teams.map((t) => [t.id, t]));
738
762
  this.submissions = _.cloneDeep(submissions).sort(Submission.compare);
739
763
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
764
+ this.organizations = this.buildOrganizations();
765
+ this.originTeams = this.teams.map((t) => t);
766
+ this.originTeams.sort(Team.compare);
740
767
  this.rankStatistics = new RankStatistics();
741
768
  this.options = new RankOptions();
742
769
  }
@@ -840,8 +867,11 @@ class Rank {
840
867
  }
841
868
  preSubmissionTimestampToMinute = s.timestampToMinute;
842
869
  }
843
- this.teams.forEach((t) => t.postProcessPlaceChartPoints());
870
+ this.teams.forEach((t) => t.calcSolvedData());
871
+ this.teams.sort(Team.compare);
872
+ this.buildTeamRank();
844
873
  this.buildOrgRank();
874
+ this.teams.forEach((t) => t.postProcessPlaceChartPoints());
845
875
  })();
846
876
  (() => {
847
877
  this.rankStatistics.reset();
@@ -849,14 +879,19 @@ class Rank {
849
879
  for (const t of this.teams) {
850
880
  this.rankStatistics.teamSolvedNum[t.solvedProblemNum]++;
851
881
  }
882
+ if (this.teams.length > 0) {
883
+ this.rankStatistics.maxSolvedProblems = this.teams[0].solvedProblemNum;
884
+ }
852
885
  })();
853
886
  return this;
854
887
  }
855
888
  buildTeamRank() {
856
889
  let rank = 1;
890
+ let originalRank = 1;
857
891
  let preTeam = null;
858
892
  for (const t of this.teams) {
859
893
  t.rank = rank++;
894
+ t.originalRank = originalRank++;
860
895
  if (preTeam !== null) {
861
896
  if (t.isEqualRank(preTeam)) {
862
897
  t.rank = preTeam.rank;
@@ -887,6 +922,23 @@ class Rank {
887
922
  preTeam = t;
888
923
  }
889
924
  }
925
+ buildOrganizations() {
926
+ if (!this.contest.organization) {
927
+ return [];
928
+ }
929
+ const res = new Array();
930
+ const se = /* @__PURE__ */ new Set();
931
+ this.teams.forEach((t) => {
932
+ const org = t.organization;
933
+ if (se.has(org)) {
934
+ return;
935
+ }
936
+ res.push(org);
937
+ se.add(org);
938
+ });
939
+ res.sort();
940
+ return res;
941
+ }
890
942
  filterTeamByOrg(team) {
891
943
  const o = this.options;
892
944
  if (o.enableFilterTeamsByGroup) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcpcio/core",
3
- "version": "0.5.3",
3
+ "version": "0.6.1",
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.5.3"
45
+ "@xcpcio/types": "0.6.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@babel/types": "^7.22.4",
@@ -1,11 +1,14 @@
1
1
  export class RankStatistics {
2
2
  teamSolvedNum: Array<number>;
3
+ maxSolvedProblems: number;
3
4
 
4
5
  constructor() {
5
6
  this.teamSolvedNum = [];
7
+ this.maxSolvedProblems = 0;
6
8
  }
7
9
 
8
10
  reset() {
9
11
  this.teamSolvedNum = [];
12
+ this.maxSolvedProblems = 0;
10
13
  }
11
14
  }
package/src/rank.ts CHANGED
@@ -8,6 +8,11 @@ import { Submission } from "./submission";
8
8
  import { TeamProblemStatistics } from "./problem";
9
9
  import { RankStatistics } from "./rank-statistics";
10
10
 
11
+ export interface SelectOptionItem {
12
+ value: string;
13
+ text: string;
14
+ }
15
+
11
16
  export class RankOptions {
12
17
  enableFilterSubmissionsByTimestamp: boolean;
13
18
  width: number;
@@ -16,6 +21,11 @@ export class RankOptions {
16
21
  enableFilterTeamsByGroup: boolean;
17
22
  group: string;
18
23
 
24
+ filterOrganizations: Array<SelectOptionItem>;
25
+ filterOrganizationMap: Map<string, SelectOptionItem>;
26
+ filterTeams: Array<SelectOptionItem>;
27
+ filterTeamMap: Map<string, SelectOptionItem>;
28
+
19
29
  constructor() {
20
30
  this.enableFilterSubmissionsByTimestamp = false;
21
31
  this.width = 0;
@@ -23,6 +33,12 @@ export class RankOptions {
23
33
 
24
34
  this.enableFilterTeamsByGroup = false;
25
35
  this.group = "";
36
+
37
+ this.filterOrganizations = [];
38
+ this.filterOrganizationMap = new Map<string, SelectOptionItem>();
39
+
40
+ this.filterTeams = [];
41
+ this.filterTeamMap = new Map<string, SelectOptionItem>();
26
42
  }
27
43
 
28
44
  setWidth(width: number, contest: Contest) {
@@ -47,6 +63,26 @@ export class RankOptions {
47
63
  disableFilterTeamsByGroup() {
48
64
  this.enableFilterTeamsByGroup = false;
49
65
  }
66
+
67
+ setFilterOrganizations(filterOrganizations: Array<SelectOptionItem>) {
68
+ const m = new Map<string, SelectOptionItem>();
69
+ filterOrganizations.forEach((item) => {
70
+ m.set(item.value, item);
71
+ });
72
+
73
+ this.filterOrganizations = filterOrganizations;
74
+ this.filterOrganizationMap = m;
75
+ }
76
+
77
+ setFilterTeams(filterTeams: Array<SelectOptionItem>) {
78
+ const m = new Map<string, SelectOptionItem>();
79
+ filterTeams.forEach((item) => {
80
+ m.set(item.value, item);
81
+ });
82
+
83
+ this.filterTeams = filterTeams;
84
+ this.filterTeamMap = m;
85
+ }
50
86
  }
51
87
 
52
88
  export class Rank {
@@ -58,6 +94,9 @@ export class Rank {
58
94
  submissions: Submissions;
59
95
  submissionsMap: Map<string, Submission>;
60
96
 
97
+ organizations: Array<string>;
98
+ originTeams: Teams;
99
+
61
100
  rankStatistics: RankStatistics;
62
101
 
63
102
  options: RankOptions;
@@ -71,6 +110,10 @@ export class Rank {
71
110
  this.submissions = _.cloneDeep(submissions).sort(Submission.compare);
72
111
  this.submissionsMap = new Map(this.submissions.map(s => [s.id, s]));
73
112
 
113
+ this.organizations = this.buildOrganizations();
114
+ this.originTeams = this.teams.map(t => t);
115
+ this.originTeams.sort(Team.compare);
116
+
74
117
  this.rankStatistics = new RankStatistics();
75
118
 
76
119
  this.options = new RankOptions();
@@ -208,8 +251,12 @@ export class Rank {
208
251
  preSubmissionTimestampToMinute = s.timestampToMinute;
209
252
  }
210
253
 
211
- this.teams.forEach(t => t.postProcessPlaceChartPoints());
254
+ this.teams.forEach(t => t.calcSolvedData());
255
+ this.teams.sort(Team.compare);
256
+ this.buildTeamRank();
212
257
  this.buildOrgRank();
258
+
259
+ this.teams.forEach(t => t.postProcessPlaceChartPoints());
213
260
  })();
214
261
 
215
262
  (() => {
@@ -219,6 +266,10 @@ export class Rank {
219
266
  for (const t of this.teams) {
220
267
  this.rankStatistics.teamSolvedNum[t.solvedProblemNum]++;
221
268
  }
269
+
270
+ if (this.teams.length > 0) {
271
+ this.rankStatistics.maxSolvedProblems = this.teams[0].solvedProblemNum;
272
+ }
222
273
  })();
223
274
 
224
275
  return this;
@@ -226,9 +277,11 @@ export class Rank {
226
277
 
227
278
  buildTeamRank() {
228
279
  let rank = 1;
280
+ let originalRank = 1;
229
281
  let preTeam = null;
230
282
  for (const t of this.teams) {
231
283
  t.rank = rank++;
284
+ t.originalRank = originalRank++;
232
285
 
233
286
  if (preTeam !== null) {
234
287
  if (t.isEqualRank(preTeam)) {
@@ -269,6 +322,29 @@ export class Rank {
269
322
  }
270
323
  }
271
324
 
325
+ buildOrganizations() {
326
+ if (!this.contest.organization) {
327
+ return [];
328
+ }
329
+
330
+ const res = new Array<string>();
331
+ const se = new Set<string>();
332
+
333
+ this.teams.forEach((t) => {
334
+ const org = t.organization;
335
+ if (se.has(org)) {
336
+ return;
337
+ }
338
+
339
+ res.push(org);
340
+ se.add(org);
341
+ });
342
+
343
+ res.sort();
344
+
345
+ return res;
346
+ }
347
+
272
348
  filterTeamByOrg(team: Team) {
273
349
  const o = this.options;
274
350
 
package/src/team.ts CHANGED
@@ -30,6 +30,7 @@ export class Team {
30
30
  members?: string | Array<string>;
31
31
 
32
32
  rank: number;
33
+ originalRank: number;
33
34
  organizationRank: number;
34
35
 
35
36
  solvedProblemNum: number;
@@ -57,6 +58,7 @@ export class Team {
57
58
  this.tag = [];
58
59
 
59
60
  this.rank = 0;
61
+ this.originalRank = 0;
60
62
  this.organizationRank = -1;
61
63
 
62
64
  this.solvedProblemNum = 0;
@@ -77,6 +79,7 @@ export class Team {
77
79
 
78
80
  reset() {
79
81
  this.rank = 0;
82
+ this.originalRank = 0;
80
83
  this.organizationRank = -1;
81
84
 
82
85
  this.solvedProblemNum = 0;