@xcpcio/core 0.72.0 → 0.74.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 CHANGED
@@ -131,6 +131,9 @@ class I18nText {
131
131
  }
132
132
  return result;
133
133
  }
134
+ valueOf() {
135
+ return this.getOrDefault();
136
+ }
134
137
  }
135
138
 
136
139
  function calcDirt(attemptedNum, solvedNum) {
@@ -659,14 +662,16 @@ class PlaceChartPointData {
659
662
  class Team {
660
663
  id;
661
664
  name;
665
+ organizationId;
666
+ organizationName;
662
667
  organization;
668
+ isFirstRankOfOrganization;
663
669
  group;
664
670
  tag;
665
671
  coaches;
666
672
  members;
667
673
  rank;
668
674
  originalRank;
669
- organizationRank;
670
675
  solvedProblemNum;
671
676
  attemptedProblemNum;
672
677
  lastSolvedProblem;
@@ -686,14 +691,13 @@ class Team {
686
691
  constructor() {
687
692
  this.id = "";
688
693
  this.name = new I18nText();
689
- this.organization = "";
694
+ this.isFirstRankOfOrganization = false;
690
695
  this.group = [];
691
696
  this.tag = [];
692
697
  this.coaches = [];
693
698
  this.members = [];
694
699
  this.rank = 0;
695
700
  this.originalRank = 0;
696
- this.organizationRank = -1;
697
701
  this.solvedProblemNum = 0;
698
702
  this.attemptedProblemNum = 0;
699
703
  this.lastSolvedProblem = null;
@@ -708,9 +712,9 @@ class Team {
708
712
  this.se = 0;
709
713
  }
710
714
  reset() {
715
+ this.isFirstRankOfOrganization = false;
711
716
  this.rank = 0;
712
717
  this.originalRank = 0;
713
- this.organizationRank = -1;
714
718
  this.solvedProblemNum = 0;
715
719
  this.attemptedProblemNum = 0;
716
720
  this.lastSolvedProblem = null;
@@ -834,7 +838,12 @@ function createTeam(teamJSON) {
834
838
  const t = new Team();
835
839
  t.id = teamJSON.id ?? teamJSON.team_id ?? "";
836
840
  t.name = I18nText.fromIText(teamJSON.name ?? teamJSON.team_name ?? "");
837
- t.organization = teamJSON.organization ?? "";
841
+ if (teamJSON.organization) {
842
+ t.organizationId = teamJSON.organization;
843
+ t.organizationName = teamJSON.organization;
844
+ } else {
845
+ t.organizationId = teamJSON.organization_id;
846
+ }
838
847
  t.group = ___default.cloneDeep(teamJSON.group ?? []);
839
848
  t.tag = ___default.cloneDeep(teamJSON.tag ?? []);
840
849
  t.members = createPersons(teamJSON.members);
@@ -1420,7 +1429,7 @@ class CodeforcesGymGhostDATConverter {
1420
1429
  rank.teams.forEach((team) => {
1421
1430
  let name = team.name.getOrDefault();
1422
1431
  if (team.organization) {
1423
- name = `${team.organization} - ${name}`;
1432
+ name = `${team.organization.name.getOrDefault()} - ${name}`;
1424
1433
  }
1425
1434
  if (team.members) {
1426
1435
  name = `${name} - ${team.membersToString()}`;
@@ -1621,12 +1630,12 @@ class GeneralExcelConverter {
1621
1630
  const arr = [];
1622
1631
  arr.push(team.rank.toString());
1623
1632
  if (team.organization) {
1624
- if (team.organizationRank !== -1) {
1625
- arr.push(team.organizationRank.toString());
1633
+ if (team.isFirstRankOfOrganization) {
1634
+ arr.push(team.organization.rank.toString());
1626
1635
  } else {
1627
1636
  arr.push("");
1628
1637
  }
1629
- arr.push(team.organization);
1638
+ arr.push(team.organization.name.getOrDefault());
1630
1639
  }
1631
1640
  arr.push(team.name.getOrDefault(), team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
1632
1641
  for (const p of team.problemStatistics) {
@@ -1697,7 +1706,7 @@ class ICPCStandingsCsvConverter {
1697
1706
  siteCitation: rank.contest.name.getOrDefault(),
1698
1707
  citation: ordinal__default(team.rank),
1699
1708
  teamName: team.name.getOrDefault(),
1700
- institution: team.organization
1709
+ institution: team.organization?.name.getOrDefault() ?? ""
1701
1710
  };
1702
1711
  resList.push(res);
1703
1712
  }
@@ -1744,6 +1753,42 @@ function getImageSource(image, asset_host) {
1744
1753
  return "";
1745
1754
  }
1746
1755
 
1756
+ class Organization {
1757
+ id;
1758
+ name;
1759
+ logo;
1760
+ // Teams belonging to this organization
1761
+ teams;
1762
+ rank;
1763
+ constructor() {
1764
+ this.id = "";
1765
+ this.name = new I18nText();
1766
+ this.teams = [];
1767
+ this.rank = -1;
1768
+ }
1769
+ reset() {
1770
+ this.rank = -1;
1771
+ }
1772
+ static compare(lhs, rhs) {
1773
+ if (lhs.id < rhs.id) {
1774
+ return -1;
1775
+ } else if (lhs.id > rhs.id) {
1776
+ return 1;
1777
+ }
1778
+ return 0;
1779
+ }
1780
+ }
1781
+ function createOrganization(orgJSON) {
1782
+ const org = new Organization();
1783
+ org.id = orgJSON.id;
1784
+ org.name = I18nText.fromIText(orgJSON.name);
1785
+ org.logo = orgJSON.logo;
1786
+ return org;
1787
+ }
1788
+ function createOrganizations(orgsJSON) {
1789
+ return orgsJSON.map((org) => createOrganization(org));
1790
+ }
1791
+
1747
1792
  class RankStatistics {
1748
1793
  teamSolvedNum;
1749
1794
  teamSolvedNumIndex;
@@ -1868,6 +1913,7 @@ class Rank {
1868
1913
  submissions;
1869
1914
  submissionsMap;
1870
1915
  organizations;
1916
+ organizationsMap;
1871
1917
  originTeams;
1872
1918
  rankStatistics;
1873
1919
  options;
@@ -1893,7 +1939,9 @@ class Rank {
1893
1939
  });
1894
1940
  }
1895
1941
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
1896
- this.organizations = this.buildOrganizations();
1942
+ this.organizationsMap = this.buildOrganizationsMap();
1943
+ this.organizations = [...this.organizationsMap.values()];
1944
+ this.organizations.sort(Organization.compare);
1897
1945
  this.originTeams = this.teams.map((t) => t);
1898
1946
  this.originTeams.sort(Team.compare);
1899
1947
  this.rankStatistics = new RankStatistics();
@@ -1916,6 +1964,31 @@ class Rank {
1916
1964
  this.statuses = [...se].sort();
1917
1965
  }
1918
1966
  }
1967
+ buildOrganizationsMap() {
1968
+ if (!this.contest.organization) {
1969
+ return /* @__PURE__ */ new Map();
1970
+ }
1971
+ const res = /* @__PURE__ */ new Map();
1972
+ this.teams.forEach((t) => {
1973
+ if (!t.organizationId) {
1974
+ return;
1975
+ }
1976
+ if (res.has(t.organizationId)) {
1977
+ const org2 = res.get(t.organizationId);
1978
+ org2?.teams.push(t);
1979
+ t.organization = org2;
1980
+ return;
1981
+ }
1982
+ const org = new Organization();
1983
+ org.id = t.organizationId;
1984
+ org.name = new I18nText();
1985
+ org.name.fallback = t.organizationName;
1986
+ org.teams.push(t);
1987
+ t.organization = org;
1988
+ res.set(org.id, org);
1989
+ });
1990
+ return res;
1991
+ }
1919
1992
  cleanRank() {
1920
1993
  (() => {
1921
1994
  this.teams = [];
@@ -1926,6 +1999,9 @@ class Rank {
1926
1999
  this.teams.push(v);
1927
2000
  }
1928
2001
  })();
2002
+ for (const o of this.organizations) {
2003
+ o.reset();
2004
+ }
1929
2005
  for (const t of this.teams) {
1930
2006
  t.reset();
1931
2007
  t.problemStatistics = this.contest.problems.map((p) => {
@@ -2080,39 +2156,21 @@ class Rank {
2080
2156
  }
2081
2157
  let rank = 1;
2082
2158
  let preTeam = null;
2083
- const se = /* @__PURE__ */ new Set();
2084
2159
  for (const t of this.teams) {
2085
2160
  const org = t.organization;
2086
- if (se.has(org)) {
2161
+ if (!org || org.rank > -1) {
2087
2162
  continue;
2088
2163
  }
2089
- se.add(org);
2090
- t.organizationRank = rank++;
2091
- if (preTeam !== null) {
2164
+ org.rank = rank++;
2165
+ t.isFirstRankOfOrganization = true;
2166
+ if (preTeam) {
2092
2167
  if (t.isEqualRank(preTeam)) {
2093
- t.organizationRank = preTeam.organizationRank;
2168
+ org.rank = preTeam.organization.rank;
2094
2169
  }
2095
2170
  }
2096
2171
  preTeam = t;
2097
2172
  }
2098
2173
  }
2099
- buildOrganizations() {
2100
- if (!this.contest.organization) {
2101
- return [];
2102
- }
2103
- const res = new Array();
2104
- const se = /* @__PURE__ */ new Set();
2105
- this.teams.forEach((t) => {
2106
- const org = t.organization;
2107
- if (se.has(org)) {
2108
- return;
2109
- }
2110
- res.push(org);
2111
- se.add(org);
2112
- });
2113
- res.sort();
2114
- return res;
2115
- }
2116
2174
  buildAwards() {
2117
2175
  if (this.contest.medal === "ccpc") {
2118
2176
  this.contest.awards = /* @__PURE__ */ new Map();
@@ -2448,7 +2506,7 @@ class Rating {
2448
2506
  u = new RatingUser();
2449
2507
  u.id = id;
2450
2508
  u.name = t.name;
2451
- u.organization = t.organization;
2509
+ u.organization = t.organizationName ?? "";
2452
2510
  u.members = t.members;
2453
2511
  u.coaches = t.coaches;
2454
2512
  u.rank = t.rank;
@@ -2468,7 +2526,7 @@ class Rating {
2468
2526
  h.rank = t.rank;
2469
2527
  h.rating = u.rating;
2470
2528
  h.teamName = t.name;
2471
- h.organization = t.organization;
2529
+ h.organization = t.organizationName ?? "";
2472
2530
  h.members = t.members;
2473
2531
  h.coaches = t.coaches;
2474
2532
  h.contestID = rank.contest.id;
@@ -2489,7 +2547,7 @@ class Rating {
2489
2547
  if (persons.length > 0) {
2490
2548
  return persons.map((person) => person.name.getOrDefault().trim()).sort().join("|");
2491
2549
  }
2492
- return `${t.organization}-${t.name}`;
2550
+ return `${t.organizationName ?? ""}-${t.name}`;
2493
2551
  }
2494
2552
  toJSON() {
2495
2553
  return {
@@ -2852,6 +2910,7 @@ exports.GiantsType = GiantsType;
2852
2910
  exports.I18nText = I18nText;
2853
2911
  exports.ICPCStandingsCsvConverter = ICPCStandingsCsvConverter;
2854
2912
  exports.MedalType = MedalType;
2913
+ exports.Organization = Organization;
2855
2914
  exports.Person = Person;
2856
2915
  exports.PlaceChartPointData = PlaceChartPointData;
2857
2916
  exports.Problem = Problem;
@@ -2876,6 +2935,8 @@ exports.createContest = createContest;
2876
2935
  exports.createContestIndex = createContestIndex;
2877
2936
  exports.createContestIndexList = createContestIndexList;
2878
2937
  exports.createDayJS = createDayJS;
2938
+ exports.createOrganization = createOrganization;
2939
+ exports.createOrganizations = createOrganizations;
2879
2940
  exports.createPersons = createPersons;
2880
2941
  exports.createProblem = createProblem;
2881
2942
  exports.createProblems = createProblems;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
1
+ import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Organization as Organization$1, Organizations as Organizations$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
2
2
  import dayjs from 'dayjs';
3
3
  export { default as dayjs } from 'dayjs';
4
4
  import * as XLSX from 'xlsx-js-style';
@@ -35,6 +35,7 @@ declare class I18nText {
35
35
  static fromI18NStringSet(stringSet: I18NStringSet): I18nText;
36
36
  static fromIText(text: Text): I18nText;
37
37
  toI18NStringSet(): I18NStringSet;
38
+ valueOf(): string;
38
39
  }
39
40
 
40
41
  declare class ContestOptions {
@@ -192,6 +193,20 @@ declare class TeamProblemStatistics {
192
193
  get penaltyInSecond(): number;
193
194
  }
194
195
 
196
+ declare class Organization {
197
+ id: string;
198
+ name: I18nText;
199
+ logo?: Image;
200
+ teams: Teams;
201
+ rank: number;
202
+ constructor();
203
+ reset(): void;
204
+ static compare(lhs: Organization, rhs: Organization): number;
205
+ }
206
+ type Organizations = Array<Organization>;
207
+ declare function createOrganization(orgJSON: Organization$1): Organization;
208
+ declare function createOrganizations(orgsJSON: Organizations$1): Organizations;
209
+
195
210
  declare class Person {
196
211
  name: I18nText;
197
212
  cfID?: string;
@@ -212,14 +227,16 @@ declare class PlaceChartPointData {
212
227
  declare class Team {
213
228
  id: string;
214
229
  name: I18nText;
215
- organization: string;
230
+ organizationId?: string;
231
+ organizationName?: string;
232
+ organization?: Organization;
233
+ isFirstRankOfOrganization: boolean;
216
234
  group: Array<string>;
217
235
  tag: Array<string>;
218
236
  coaches: Persons;
219
237
  members: Persons;
220
238
  rank: number;
221
239
  originalRank: number;
222
- organizationRank: number;
223
240
  solvedProblemNum: number;
224
241
  attemptedProblemNum: number;
225
242
  lastSolvedProblem: Problem | null;
@@ -363,7 +380,8 @@ declare class Rank {
363
380
  teamsMap: Map<string, Team>;
364
381
  submissions: Submissions;
365
382
  submissionsMap: Map<string, Submission>;
366
- organizations: Array<string>;
383
+ organizations: Organizations;
384
+ organizationsMap: Map<string, Organization>;
367
385
  originTeams: Teams;
368
386
  rankStatistics: RankStatistics;
369
387
  options: RankOptions;
@@ -371,11 +389,11 @@ declare class Rank {
371
389
  languages: Array<string>;
372
390
  statuses: Array<SubmissionStatus>;
373
391
  constructor(contest: Contest, teams: Teams, submissions: Submissions);
392
+ buildOrganizationsMap(): Map<string, Organization>;
374
393
  cleanRank(): void;
375
394
  buildRank(): this;
376
395
  buildTeamRank(): void;
377
396
  buildOrgRank(): void;
378
- buildOrganizations(): string[];
379
397
  buildAwards(): void;
380
398
  filterTeamByOrg(team: Team): boolean;
381
399
  getSubmissions(): Submissions;
@@ -535,5 +553,5 @@ declare function isRejected(status: SubmissionStatus): boolean;
535
553
  declare function isPending(status: SubmissionStatus): boolean;
536
554
  declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
537
555
 
538
- export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
539
- export type { Awards, Balloons, ContestIndexList, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
556
+ export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Organization, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createOrganization, createOrganizations, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
557
+ export type { Awards, Balloons, ContestIndexList, Organizations, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
1
+ import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Organization as Organization$1, Organizations as Organizations$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
2
2
  import dayjs from 'dayjs';
3
3
  export { default as dayjs } from 'dayjs';
4
4
  import * as XLSX from 'xlsx-js-style';
@@ -35,6 +35,7 @@ declare class I18nText {
35
35
  static fromI18NStringSet(stringSet: I18NStringSet): I18nText;
36
36
  static fromIText(text: Text): I18nText;
37
37
  toI18NStringSet(): I18NStringSet;
38
+ valueOf(): string;
38
39
  }
39
40
 
40
41
  declare class ContestOptions {
@@ -192,6 +193,20 @@ declare class TeamProblemStatistics {
192
193
  get penaltyInSecond(): number;
193
194
  }
194
195
 
196
+ declare class Organization {
197
+ id: string;
198
+ name: I18nText;
199
+ logo?: Image;
200
+ teams: Teams;
201
+ rank: number;
202
+ constructor();
203
+ reset(): void;
204
+ static compare(lhs: Organization, rhs: Organization): number;
205
+ }
206
+ type Organizations = Array<Organization>;
207
+ declare function createOrganization(orgJSON: Organization$1): Organization;
208
+ declare function createOrganizations(orgsJSON: Organizations$1): Organizations;
209
+
195
210
  declare class Person {
196
211
  name: I18nText;
197
212
  cfID?: string;
@@ -212,14 +227,16 @@ declare class PlaceChartPointData {
212
227
  declare class Team {
213
228
  id: string;
214
229
  name: I18nText;
215
- organization: string;
230
+ organizationId?: string;
231
+ organizationName?: string;
232
+ organization?: Organization;
233
+ isFirstRankOfOrganization: boolean;
216
234
  group: Array<string>;
217
235
  tag: Array<string>;
218
236
  coaches: Persons;
219
237
  members: Persons;
220
238
  rank: number;
221
239
  originalRank: number;
222
- organizationRank: number;
223
240
  solvedProblemNum: number;
224
241
  attemptedProblemNum: number;
225
242
  lastSolvedProblem: Problem | null;
@@ -363,7 +380,8 @@ declare class Rank {
363
380
  teamsMap: Map<string, Team>;
364
381
  submissions: Submissions;
365
382
  submissionsMap: Map<string, Submission>;
366
- organizations: Array<string>;
383
+ organizations: Organizations;
384
+ organizationsMap: Map<string, Organization>;
367
385
  originTeams: Teams;
368
386
  rankStatistics: RankStatistics;
369
387
  options: RankOptions;
@@ -371,11 +389,11 @@ declare class Rank {
371
389
  languages: Array<string>;
372
390
  statuses: Array<SubmissionStatus>;
373
391
  constructor(contest: Contest, teams: Teams, submissions: Submissions);
392
+ buildOrganizationsMap(): Map<string, Organization>;
374
393
  cleanRank(): void;
375
394
  buildRank(): this;
376
395
  buildTeamRank(): void;
377
396
  buildOrgRank(): void;
378
- buildOrganizations(): string[];
379
397
  buildAwards(): void;
380
398
  filterTeamByOrg(team: Team): boolean;
381
399
  getSubmissions(): Submissions;
@@ -535,5 +553,5 @@ declare function isRejected(status: SubmissionStatus): boolean;
535
553
  declare function isPending(status: SubmissionStatus): boolean;
536
554
  declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
537
555
 
538
- export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
539
- export type { Awards, Balloons, ContestIndexList, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
556
+ export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Organization, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createOrganization, createOrganizations, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
557
+ export type { Awards, Balloons, ContestIndexList, Organizations, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
1
+ import { Lang, I18NStringSet, Text, CalculationOfPenalty, TimeUnit, Image, StatusTimeDisplay, MedalPreset, BannerMode, ContestState, Contest as Contest$1, SubmissionReaction, SubmissionStatus, Submission as Submission$1, Submissions as Submissions$1, BalloonColor, Problem as Problem$1, Problems as Problems$1, Organization as Organization$1, Organizations as Organizations$1, Person as Person$1, Persons as Persons$1, Team as Team$1, Teams as Teams$1, ContestIndex as ContestIndex$1, IRatingHistory, IRatingUser, IRating } from '@xcpcio/types';
2
2
  import dayjs from 'dayjs';
3
3
  export { default as dayjs } from 'dayjs';
4
4
  import * as XLSX from 'xlsx-js-style';
@@ -35,6 +35,7 @@ declare class I18nText {
35
35
  static fromI18NStringSet(stringSet: I18NStringSet): I18nText;
36
36
  static fromIText(text: Text): I18nText;
37
37
  toI18NStringSet(): I18NStringSet;
38
+ valueOf(): string;
38
39
  }
39
40
 
40
41
  declare class ContestOptions {
@@ -192,6 +193,20 @@ declare class TeamProblemStatistics {
192
193
  get penaltyInSecond(): number;
193
194
  }
194
195
 
196
+ declare class Organization {
197
+ id: string;
198
+ name: I18nText;
199
+ logo?: Image;
200
+ teams: Teams;
201
+ rank: number;
202
+ constructor();
203
+ reset(): void;
204
+ static compare(lhs: Organization, rhs: Organization): number;
205
+ }
206
+ type Organizations = Array<Organization>;
207
+ declare function createOrganization(orgJSON: Organization$1): Organization;
208
+ declare function createOrganizations(orgsJSON: Organizations$1): Organizations;
209
+
195
210
  declare class Person {
196
211
  name: I18nText;
197
212
  cfID?: string;
@@ -212,14 +227,16 @@ declare class PlaceChartPointData {
212
227
  declare class Team {
213
228
  id: string;
214
229
  name: I18nText;
215
- organization: string;
230
+ organizationId?: string;
231
+ organizationName?: string;
232
+ organization?: Organization;
233
+ isFirstRankOfOrganization: boolean;
216
234
  group: Array<string>;
217
235
  tag: Array<string>;
218
236
  coaches: Persons;
219
237
  members: Persons;
220
238
  rank: number;
221
239
  originalRank: number;
222
- organizationRank: number;
223
240
  solvedProblemNum: number;
224
241
  attemptedProblemNum: number;
225
242
  lastSolvedProblem: Problem | null;
@@ -363,7 +380,8 @@ declare class Rank {
363
380
  teamsMap: Map<string, Team>;
364
381
  submissions: Submissions;
365
382
  submissionsMap: Map<string, Submission>;
366
- organizations: Array<string>;
383
+ organizations: Organizations;
384
+ organizationsMap: Map<string, Organization>;
367
385
  originTeams: Teams;
368
386
  rankStatistics: RankStatistics;
369
387
  options: RankOptions;
@@ -371,11 +389,11 @@ declare class Rank {
371
389
  languages: Array<string>;
372
390
  statuses: Array<SubmissionStatus>;
373
391
  constructor(contest: Contest, teams: Teams, submissions: Submissions);
392
+ buildOrganizationsMap(): Map<string, Organization>;
374
393
  cleanRank(): void;
375
394
  buildRank(): this;
376
395
  buildTeamRank(): void;
377
396
  buildOrgRank(): void;
378
- buildOrganizations(): string[];
379
397
  buildAwards(): void;
380
398
  filterTeamByOrg(team: Team): boolean;
381
399
  getSubmissions(): Submissions;
@@ -535,5 +553,5 @@ declare function isRejected(status: SubmissionStatus): boolean;
535
553
  declare function isPending(status: SubmissionStatus): boolean;
536
554
  declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
537
555
 
538
- export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
539
- export type { Awards, Balloons, ContestIndexList, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
556
+ export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Organization, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createOrganization, createOrganizations, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
557
+ export type { Awards, Balloons, ContestIndexList, Organizations, Persons, Problems, Ranks, RatingHistories, RatingUserMap, RatingUsers, SelectOptionItem, Submissions, Teams };
package/dist/index.mjs CHANGED
@@ -100,6 +100,9 @@ class I18nText {
100
100
  }
101
101
  return result;
102
102
  }
103
+ valueOf() {
104
+ return this.getOrDefault();
105
+ }
103
106
  }
104
107
 
105
108
  function calcDirt(attemptedNum, solvedNum) {
@@ -628,14 +631,16 @@ class PlaceChartPointData {
628
631
  class Team {
629
632
  id;
630
633
  name;
634
+ organizationId;
635
+ organizationName;
631
636
  organization;
637
+ isFirstRankOfOrganization;
632
638
  group;
633
639
  tag;
634
640
  coaches;
635
641
  members;
636
642
  rank;
637
643
  originalRank;
638
- organizationRank;
639
644
  solvedProblemNum;
640
645
  attemptedProblemNum;
641
646
  lastSolvedProblem;
@@ -655,14 +660,13 @@ class Team {
655
660
  constructor() {
656
661
  this.id = "";
657
662
  this.name = new I18nText();
658
- this.organization = "";
663
+ this.isFirstRankOfOrganization = false;
659
664
  this.group = [];
660
665
  this.tag = [];
661
666
  this.coaches = [];
662
667
  this.members = [];
663
668
  this.rank = 0;
664
669
  this.originalRank = 0;
665
- this.organizationRank = -1;
666
670
  this.solvedProblemNum = 0;
667
671
  this.attemptedProblemNum = 0;
668
672
  this.lastSolvedProblem = null;
@@ -677,9 +681,9 @@ class Team {
677
681
  this.se = 0;
678
682
  }
679
683
  reset() {
684
+ this.isFirstRankOfOrganization = false;
680
685
  this.rank = 0;
681
686
  this.originalRank = 0;
682
- this.organizationRank = -1;
683
687
  this.solvedProblemNum = 0;
684
688
  this.attemptedProblemNum = 0;
685
689
  this.lastSolvedProblem = null;
@@ -803,7 +807,12 @@ function createTeam(teamJSON) {
803
807
  const t = new Team();
804
808
  t.id = teamJSON.id ?? teamJSON.team_id ?? "";
805
809
  t.name = I18nText.fromIText(teamJSON.name ?? teamJSON.team_name ?? "");
806
- t.organization = teamJSON.organization ?? "";
810
+ if (teamJSON.organization) {
811
+ t.organizationId = teamJSON.organization;
812
+ t.organizationName = teamJSON.organization;
813
+ } else {
814
+ t.organizationId = teamJSON.organization_id;
815
+ }
807
816
  t.group = _.cloneDeep(teamJSON.group ?? []);
808
817
  t.tag = _.cloneDeep(teamJSON.tag ?? []);
809
818
  t.members = createPersons(teamJSON.members);
@@ -1389,7 +1398,7 @@ class CodeforcesGymGhostDATConverter {
1389
1398
  rank.teams.forEach((team) => {
1390
1399
  let name = team.name.getOrDefault();
1391
1400
  if (team.organization) {
1392
- name = `${team.organization} - ${name}`;
1401
+ name = `${team.organization.name.getOrDefault()} - ${name}`;
1393
1402
  }
1394
1403
  if (team.members) {
1395
1404
  name = `${name} - ${team.membersToString()}`;
@@ -1590,12 +1599,12 @@ class GeneralExcelConverter {
1590
1599
  const arr = [];
1591
1600
  arr.push(team.rank.toString());
1592
1601
  if (team.organization) {
1593
- if (team.organizationRank !== -1) {
1594
- arr.push(team.organizationRank.toString());
1602
+ if (team.isFirstRankOfOrganization) {
1603
+ arr.push(team.organization.rank.toString());
1595
1604
  } else {
1596
1605
  arr.push("");
1597
1606
  }
1598
- arr.push(team.organization);
1607
+ arr.push(team.organization.name.getOrDefault());
1599
1608
  }
1600
1609
  arr.push(team.name.getOrDefault(), team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
1601
1610
  for (const p of team.problemStatistics) {
@@ -1666,7 +1675,7 @@ class ICPCStandingsCsvConverter {
1666
1675
  siteCitation: rank.contest.name.getOrDefault(),
1667
1676
  citation: ordinal(team.rank),
1668
1677
  teamName: team.name.getOrDefault(),
1669
- institution: team.organization
1678
+ institution: team.organization?.name.getOrDefault() ?? ""
1670
1679
  };
1671
1680
  resList.push(res);
1672
1681
  }
@@ -1713,6 +1722,42 @@ function getImageSource(image, asset_host) {
1713
1722
  return "";
1714
1723
  }
1715
1724
 
1725
+ class Organization {
1726
+ id;
1727
+ name;
1728
+ logo;
1729
+ // Teams belonging to this organization
1730
+ teams;
1731
+ rank;
1732
+ constructor() {
1733
+ this.id = "";
1734
+ this.name = new I18nText();
1735
+ this.teams = [];
1736
+ this.rank = -1;
1737
+ }
1738
+ reset() {
1739
+ this.rank = -1;
1740
+ }
1741
+ static compare(lhs, rhs) {
1742
+ if (lhs.id < rhs.id) {
1743
+ return -1;
1744
+ } else if (lhs.id > rhs.id) {
1745
+ return 1;
1746
+ }
1747
+ return 0;
1748
+ }
1749
+ }
1750
+ function createOrganization(orgJSON) {
1751
+ const org = new Organization();
1752
+ org.id = orgJSON.id;
1753
+ org.name = I18nText.fromIText(orgJSON.name);
1754
+ org.logo = orgJSON.logo;
1755
+ return org;
1756
+ }
1757
+ function createOrganizations(orgsJSON) {
1758
+ return orgsJSON.map((org) => createOrganization(org));
1759
+ }
1760
+
1716
1761
  class RankStatistics {
1717
1762
  teamSolvedNum;
1718
1763
  teamSolvedNumIndex;
@@ -1837,6 +1882,7 @@ class Rank {
1837
1882
  submissions;
1838
1883
  submissionsMap;
1839
1884
  organizations;
1885
+ organizationsMap;
1840
1886
  originTeams;
1841
1887
  rankStatistics;
1842
1888
  options;
@@ -1862,7 +1908,9 @@ class Rank {
1862
1908
  });
1863
1909
  }
1864
1910
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
1865
- this.organizations = this.buildOrganizations();
1911
+ this.organizationsMap = this.buildOrganizationsMap();
1912
+ this.organizations = [...this.organizationsMap.values()];
1913
+ this.organizations.sort(Organization.compare);
1866
1914
  this.originTeams = this.teams.map((t) => t);
1867
1915
  this.originTeams.sort(Team.compare);
1868
1916
  this.rankStatistics = new RankStatistics();
@@ -1885,6 +1933,31 @@ class Rank {
1885
1933
  this.statuses = [...se].sort();
1886
1934
  }
1887
1935
  }
1936
+ buildOrganizationsMap() {
1937
+ if (!this.contest.organization) {
1938
+ return /* @__PURE__ */ new Map();
1939
+ }
1940
+ const res = /* @__PURE__ */ new Map();
1941
+ this.teams.forEach((t) => {
1942
+ if (!t.organizationId) {
1943
+ return;
1944
+ }
1945
+ if (res.has(t.organizationId)) {
1946
+ const org2 = res.get(t.organizationId);
1947
+ org2?.teams.push(t);
1948
+ t.organization = org2;
1949
+ return;
1950
+ }
1951
+ const org = new Organization();
1952
+ org.id = t.organizationId;
1953
+ org.name = new I18nText();
1954
+ org.name.fallback = t.organizationName;
1955
+ org.teams.push(t);
1956
+ t.organization = org;
1957
+ res.set(org.id, org);
1958
+ });
1959
+ return res;
1960
+ }
1888
1961
  cleanRank() {
1889
1962
  (() => {
1890
1963
  this.teams = [];
@@ -1895,6 +1968,9 @@ class Rank {
1895
1968
  this.teams.push(v);
1896
1969
  }
1897
1970
  })();
1971
+ for (const o of this.organizations) {
1972
+ o.reset();
1973
+ }
1898
1974
  for (const t of this.teams) {
1899
1975
  t.reset();
1900
1976
  t.problemStatistics = this.contest.problems.map((p) => {
@@ -2049,39 +2125,21 @@ class Rank {
2049
2125
  }
2050
2126
  let rank = 1;
2051
2127
  let preTeam = null;
2052
- const se = /* @__PURE__ */ new Set();
2053
2128
  for (const t of this.teams) {
2054
2129
  const org = t.organization;
2055
- if (se.has(org)) {
2130
+ if (!org || org.rank > -1) {
2056
2131
  continue;
2057
2132
  }
2058
- se.add(org);
2059
- t.organizationRank = rank++;
2060
- if (preTeam !== null) {
2133
+ org.rank = rank++;
2134
+ t.isFirstRankOfOrganization = true;
2135
+ if (preTeam) {
2061
2136
  if (t.isEqualRank(preTeam)) {
2062
- t.organizationRank = preTeam.organizationRank;
2137
+ org.rank = preTeam.organization.rank;
2063
2138
  }
2064
2139
  }
2065
2140
  preTeam = t;
2066
2141
  }
2067
2142
  }
2068
- buildOrganizations() {
2069
- if (!this.contest.organization) {
2070
- return [];
2071
- }
2072
- const res = new Array();
2073
- const se = /* @__PURE__ */ new Set();
2074
- this.teams.forEach((t) => {
2075
- const org = t.organization;
2076
- if (se.has(org)) {
2077
- return;
2078
- }
2079
- res.push(org);
2080
- se.add(org);
2081
- });
2082
- res.sort();
2083
- return res;
2084
- }
2085
2143
  buildAwards() {
2086
2144
  if (this.contest.medal === "ccpc") {
2087
2145
  this.contest.awards = /* @__PURE__ */ new Map();
@@ -2417,7 +2475,7 @@ class Rating {
2417
2475
  u = new RatingUser();
2418
2476
  u.id = id;
2419
2477
  u.name = t.name;
2420
- u.organization = t.organization;
2478
+ u.organization = t.organizationName ?? "";
2421
2479
  u.members = t.members;
2422
2480
  u.coaches = t.coaches;
2423
2481
  u.rank = t.rank;
@@ -2437,7 +2495,7 @@ class Rating {
2437
2495
  h.rank = t.rank;
2438
2496
  h.rating = u.rating;
2439
2497
  h.teamName = t.name;
2440
- h.organization = t.organization;
2498
+ h.organization = t.organizationName ?? "";
2441
2499
  h.members = t.members;
2442
2500
  h.coaches = t.coaches;
2443
2501
  h.contestID = rank.contest.id;
@@ -2458,7 +2516,7 @@ class Rating {
2458
2516
  if (persons.length > 0) {
2459
2517
  return persons.map((person) => person.name.getOrDefault().trim()).sort().join("|");
2460
2518
  }
2461
- return `${t.organization}-${t.name}`;
2519
+ return `${t.organizationName ?? ""}-${t.name}`;
2462
2520
  }
2463
2521
  toJSON() {
2464
2522
  return {
@@ -2806,4 +2864,4 @@ class ResolverVue extends Resolver {
2806
2864
  }
2807
2865
  }
2808
2866
 
2809
- export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
2867
+ export { Award, Balloon, BattleOfGiants, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, Giants, GiantsType, I18nText, ICPCStandingsCsvConverter, MedalType, Organization, Person, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Rating, RatingCalculator, RatingHistory, RatingLevel, RatingLevelToString, RatingUser, RatingUtility, Resolver, ResolverVue, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createOrganization, createOrganizations, createPersons, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, getWhiteOrBlackColorV1, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xcpcio/core",
3
3
  "type": "module",
4
- "version": "0.72.0",
4
+ "version": "0.74.0",
5
5
  "description": "The core library for XCPCIO",
6
6
  "author": "Dup4 <hi@dup4.com>",
7
7
  "license": "MIT",
@@ -42,7 +42,7 @@
42
42
  "papaparse": "^5.5.3",
43
43
  "string-width": "^8.1.0",
44
44
  "xlsx-js-style": "^1.2.0",
45
- "@xcpcio/types": "0.72.0"
45
+ "@xcpcio/types": "0.74.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@babel/types": "^7.28.5",