tods-competition-factory 1.8.16 → 1.8.17

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.mjs CHANGED
@@ -2382,7 +2382,7 @@ const matchUpFormatCode = {
2382
2382
  };
2383
2383
 
2384
2384
  function factoryVersion() {
2385
- return "1.8.16";
2385
+ return "1.8.17";
2386
2386
  }
2387
2387
 
2388
2388
  function getObjectTieFormat(obj) {
@@ -4603,8 +4603,8 @@ function findPolicy({
4603
4603
  }
4604
4604
 
4605
4605
  function getMatchUpCompetitiveProfile({
4606
- profileBands,
4607
4606
  tournamentRecord,
4607
+ profileBands,
4608
4608
  matchUp
4609
4609
  }) {
4610
4610
  if (!matchUp)
@@ -54617,6 +54617,267 @@ function getEntryStatusReports({
54617
54617
  };
54618
54618
  }
54619
54619
 
54620
+ function getParticipantStats({
54621
+ withCompetitiveProfiles,
54622
+ opponentParticipantId,
54623
+ withIndividualStats,
54624
+ teamParticipantId,
54625
+ tournamentRecord,
54626
+ tallyPolicy,
54627
+ matchUps
54628
+ }) {
54629
+ if (!tournamentRecord)
54630
+ return { error: MISSING_TOURNAMENT_RECORD };
54631
+ if (matchUps && !Array.isArray(matchUps))
54632
+ return { error: INVALID_MATCHUP };
54633
+ matchUps = matchUps || allTournamentMatchUps({ tournamentRecord }).matchUps;
54634
+ if (!matchUps?.length)
54635
+ return { error: MISSING_MATCHUPS };
54636
+ const teamParticipantIds = [];
54637
+ if (opponentParticipantId)
54638
+ teamParticipantIds.push(opponentParticipantId);
54639
+ if (teamParticipantId)
54640
+ teamParticipantIds.push(teamParticipantId);
54641
+ const participantFilters = !teamParticipantIds.length ? { participantTypes: [TEAM_PARTICIPANT] } : { participantIds: teamParticipantIds };
54642
+ const teamParticipants = getParticipants$1({ participantFilters, tournamentRecord }).participants ?? [];
54643
+ if (!teamParticipants.every(
54644
+ ({ participantType }) => participantType === TEAM_PARTICIPANT
54645
+ )) {
54646
+ return { error: INVALID_PARTICIPANT_IDS };
54647
+ }
54648
+ if (!teamParticipantIds.length)
54649
+ teamParticipantIds.push(...teamParticipants.map(extractAttributes("participantId")));
54650
+ const participantStats = /* @__PURE__ */ new Map();
54651
+ const participantNameMap = /* @__PURE__ */ new Map();
54652
+ const participating = /* @__PURE__ */ new Map();
54653
+ const teamMap = /* @__PURE__ */ new Map();
54654
+ const initStats = (participantId, participantName = "") => participantStats.get(participantId) || participantStats.set(participantId, {
54655
+ participantName,
54656
+ participantId,
54657
+ competitorIds: [],
54658
+ competitiveness: {},
54659
+ matchUpStatuses: {},
54660
+ tiebreaks: [0, 0],
54661
+ matchUps: [0, 0],
54662
+ points: [0, 0],
54663
+ games: [0, 0],
54664
+ sets: [0, 0]
54665
+ }) && participantStats.get(participantId);
54666
+ for (const teamParticipant of teamParticipants) {
54667
+ const { participantId, individualParticipantIds } = teamParticipant;
54668
+ teamMap.set(participantId, individualParticipantIds ?? []);
54669
+ initStats(participantId, teamParticipant.participantName);
54670
+ }
54671
+ if (teamParticipantId && !teamMap.get(teamParticipantId))
54672
+ return decorateResult({
54673
+ result: { error: PARTICIPANT_NOT_FOUND },
54674
+ context: { teamParticipantId }
54675
+ });
54676
+ if (opponentParticipantId && !teamMap.get(opponentParticipantId))
54677
+ return decorateResult({
54678
+ result: { error: PARTICIPANT_NOT_FOUND },
54679
+ context: { opponentParticipantId }
54680
+ });
54681
+ const relevantMatchUps = [];
54682
+ const getSideParticipantIds = (sides) => {
54683
+ const sideParticipantIds = [[], []];
54684
+ for (const side of sides) {
54685
+ if (side.participant?.participantName)
54686
+ participantNameMap.set(
54687
+ side.participant.participantId,
54688
+ side.participant.participantName
54689
+ );
54690
+ }
54691
+ const getCompetitorIds = ({ side, individualParticipantIds }) => {
54692
+ return side.participantId && (!individualParticipantIds?.length || individualParticipantIds.includes(side.participantId)) && [
54693
+ side.participantId
54694
+ ] || side.participant?.individualParticipantIds?.length && (!individualParticipantIds?.length || intersection(
54695
+ individualParticipantIds,
54696
+ side.participant?.individualParticipantIds
54697
+ ).length === side.participant?.individualParticipantIds?.length) && side.participant.individualParticipantIds;
54698
+ };
54699
+ if (teamMap.size) {
54700
+ const processSides = (thisTeamId, individualParticipantIds) => {
54701
+ for (const side of sides) {
54702
+ if (!side.participant)
54703
+ continue;
54704
+ const competitorIds = getCompetitorIds({
54705
+ individualParticipantIds,
54706
+ side
54707
+ });
54708
+ if (competitorIds?.length) {
54709
+ const sideNumber = side.sideNumber;
54710
+ if (!sideNumber)
54711
+ continue;
54712
+ const ids = [thisTeamId];
54713
+ if (withIndividualStats)
54714
+ ids.push(...competitorIds);
54715
+ sideParticipantIds[sideNumber - 1] = ids;
54716
+ const stats = participantStats.get(thisTeamId);
54717
+ for (const id of competitorIds.filter(Boolean)) {
54718
+ if (stats && !stats.competitorIds.includes(id))
54719
+ stats.competitorIds.push(id);
54720
+ }
54721
+ }
54722
+ }
54723
+ };
54724
+ if (teamParticipantId) {
54725
+ const processForTeam = !opponentParticipantId || sides.every((side) => {
54726
+ side.participant && (getCompetitorIds({
54727
+ side,
54728
+ individualParticipantIds: teamMap.get(teamParticipantId)
54729
+ }) || getCompetitorIds({
54730
+ side,
54731
+ individualParticipantIds: teamMap.get(opponentParticipantId)
54732
+ }));
54733
+ });
54734
+ if (processForTeam)
54735
+ processSides(teamParticipantId, teamMap.get(teamParticipantId));
54736
+ } else {
54737
+ for (const [thisTeamId, individualParticipantIds] of teamMap) {
54738
+ processSides(thisTeamId, individualParticipantIds);
54739
+ }
54740
+ }
54741
+ } else if (withIndividualStats) {
54742
+ for (const side of sides) {
54743
+ if (!side.participant)
54744
+ continue;
54745
+ const competitorIds = getCompetitorIds({
54746
+ individualParticipantIds: [],
54747
+ side
54748
+ });
54749
+ const sideNumber = side.sideNumber;
54750
+ if (!sideNumber)
54751
+ continue;
54752
+ sideParticipantIds[sideNumber - 1] = competitorIds;
54753
+ }
54754
+ }
54755
+ return sideParticipantIds;
54756
+ };
54757
+ for (const matchUp of matchUps) {
54758
+ if (!isObject(matchUp))
54759
+ return { error: INVALID_MATCHUP };
54760
+ const {
54761
+ matchUpStatus,
54762
+ matchUpFormat,
54763
+ matchUpType,
54764
+ winningSide,
54765
+ score,
54766
+ sides
54767
+ } = matchUp;
54768
+ if (!sides || !score || matchUpType === TEAM_MATCHUP || matchUpStatus === BYE)
54769
+ continue;
54770
+ const sideParticipantIds = getSideParticipantIds(sides);
54771
+ if (!sideParticipantIds.filter(Boolean).length)
54772
+ continue;
54773
+ const competitiveness = withCompetitiveProfiles && winningSide && getMatchUpCompetitiveProfile({ matchUp })?.competitiveness;
54774
+ relevantMatchUps.push(matchUp);
54775
+ const setsTally = countSets({
54776
+ matchUpStatus,
54777
+ matchUpFormat,
54778
+ tallyPolicy,
54779
+ winningSide,
54780
+ score
54781
+ });
54782
+ const gamesTally = countGames({
54783
+ matchUpStatus,
54784
+ matchUpFormat,
54785
+ tallyPolicy,
54786
+ winningSide,
54787
+ score
54788
+ });
54789
+ const { pointsTally, tiebreaksTally } = countPoints({
54790
+ matchUpFormat,
54791
+ score
54792
+ });
54793
+ sideParticipantIds.forEach((ids, index) => {
54794
+ for (const id of ids) {
54795
+ const stats = initStats(id, participantNameMap.get(id));
54796
+ if (stats) {
54797
+ const teamSumTally = (stat, tally) => tally.forEach((t, i) => stats[stat][i] += t);
54798
+ const tiebreaks = index ? [...tiebreaksTally].reverse() : tiebreaksTally;
54799
+ const points = index ? [...pointsTally].reverse() : pointsTally;
54800
+ const games = index ? [...gamesTally].reverse() : gamesTally;
54801
+ const sets = index ? [...setsTally].reverse() : setsTally;
54802
+ teamSumTally("tiebreaks", tiebreaks);
54803
+ teamSumTally("points", points);
54804
+ teamSumTally("games", games);
54805
+ teamSumTally("sets", sets);
54806
+ if (winningSide) {
54807
+ const tallyIndex = winningSide - 1 === index ? 0 : 1;
54808
+ stats.matchUps[tallyIndex] += 1;
54809
+ }
54810
+ if (competitiveness) {
54811
+ const attr = competitiveness.toLowerCase();
54812
+ if (!stats.competitiveness[attr])
54813
+ stats.competitiveness[attr] = [0, 0];
54814
+ stats.competitiveness[attr][index] += 1;
54815
+ }
54816
+ if (matchUpStatus) {
54817
+ const attr = matchUpStatus.toLowerCase();
54818
+ if (!stats.matchUpStatuses[attr])
54819
+ stats.matchUpStatuses[attr] = 0;
54820
+ stats.matchUpStatuses[attr] += 1;
54821
+ }
54822
+ }
54823
+ }
54824
+ });
54825
+ }
54826
+ const statsattributes = ["tiebreaks", "matchUps", "points", "games", "sets"];
54827
+ const competitivenessAttributes = ["competitive", "routine", "decisive"];
54828
+ const ratio = /* @__PURE__ */ new Map();
54829
+ const add = (a, b) => (a ?? 0) + (b ?? 0);
54830
+ for (const [participantId, stats] of participantStats.entries()) {
54831
+ for (const attr of statsattributes) {
54832
+ const total = stats[attr].reduce(add);
54833
+ if (total) {
54834
+ const value = stats[attr][0] / total;
54835
+ const accessor = `${attr}Ratio`;
54836
+ const fixedValue = parseFloat(value.toFixed(2));
54837
+ stats[accessor] = fixedValue;
54838
+ participating.set(participantId, true);
54839
+ if (!ratio.has(accessor))
54840
+ ratio.set(accessor, []);
54841
+ ratio.get(accessor)?.push(fixedValue);
54842
+ }
54843
+ }
54844
+ for (const attr of competitivenessAttributes) {
54845
+ const total = stats.competitiveness?.[attr]?.reduce(add);
54846
+ if (total) {
54847
+ const value = stats.competitiveness[attr][0] / total;
54848
+ const accessor = `${attr}Ratio`;
54849
+ const fixedValue = parseFloat(value.toFixed(2));
54850
+ stats[accessor] = fixedValue;
54851
+ }
54852
+ }
54853
+ }
54854
+ if (!teamParticipantId) {
54855
+ const highLowSort = (a, b) => b - a;
54856
+ for (const stats of participantStats.values()) {
54857
+ for (const attr of statsattributes) {
54858
+ const accessor = `${attr}Ratio`;
54859
+ if (typeof stats[accessor] === "number") {
54860
+ const index = ratio.get(accessor)?.sort(highLowSort).indexOf(stats[accessor]);
54861
+ if (typeof index === "number" && index >= 0) {
54862
+ const rankAccessor = `${attr}Rank`;
54863
+ stats[rankAccessor] = index + 1;
54864
+ }
54865
+ }
54866
+ }
54867
+ }
54868
+ }
54869
+ const result = { relevantMatchUps, ...SUCCESS };
54870
+ if (teamParticipantId) {
54871
+ result.teamStats = participantStats.get(teamParticipantId);
54872
+ if (opponentParticipantId)
54873
+ result.opponentStats = participantStats.get(opponentParticipantId);
54874
+ } else {
54875
+ result.participatingTeamsCount = participating.size;
54876
+ }
54877
+ result.allParticipantStats = [...participantStats.values()];
54878
+ return result;
54879
+ }
54880
+
54620
54881
  function getAvgWTN({
54621
54882
  eventType,
54622
54883
  matchUps,
@@ -54867,196 +55128,10 @@ function getPositionManipulations({ extensions }) {
54867
55128
  return extensions?.find(({ name }) => name === AUDIT_POSITION_ACTIONS)?.value?.slice(1);
54868
55129
  }
54869
55130
 
54870
- function getTeamStats({
54871
- opponentParticipantId,
54872
- teamParticipantId,
54873
- tournamentRecord,
54874
- tallyPolicy,
54875
- matchUps
54876
- }) {
54877
- if (!tournamentRecord)
54878
- return { error: MISSING_TOURNAMENT_RECORD };
54879
- if (matchUps && !Array.isArray(matchUps))
54880
- return { error: INVALID_MATCHUP };
54881
- matchUps = matchUps || allTournamentMatchUps({ tournamentRecord }).matchUps;
54882
- if (!matchUps?.length)
54883
- return { error: MISSING_MATCHUPS };
54884
- const teamParticipantIds = [];
54885
- if (opponentParticipantId)
54886
- teamParticipantIds.push(opponentParticipantId);
54887
- if (teamParticipantId)
54888
- teamParticipantIds.push(teamParticipantId);
54889
- const participantFilters = !teamParticipantIds.length ? { participantTypes: [TEAM_PARTICIPANT] } : { participantIds: teamParticipantIds };
54890
- const teamParticipants = getParticipants$1({ participantFilters, tournamentRecord }).participants ?? [];
54891
- if (!teamParticipants.every(
54892
- ({ participantType }) => participantType === TEAM_PARTICIPANT
54893
- )) {
54894
- return { error: INVALID_PARTICIPANT_IDS };
54895
- }
54896
- if (!teamParticipantIds.length)
54897
- teamParticipantIds.push(...teamParticipants.map(extractAttributes("participantId")));
54898
- const teamStats = /* @__PURE__ */ new Map();
54899
- const teamMap = /* @__PURE__ */ new Map();
54900
- for (const teamParticipant of teamParticipants) {
54901
- const { participantId, individualParticipantIds } = teamParticipant;
54902
- teamMap.set(participantId, individualParticipantIds ?? []);
54903
- teamStats.set(participantId, {
54904
- participantName: teamParticipant.participantName ?? "",
54905
- matchUpStatuses: {},
54906
- competitorIds: [],
54907
- tiebreaks: [0, 0],
54908
- matchUps: [0, 0],
54909
- points: [0, 0],
54910
- participantId,
54911
- games: [0, 0],
54912
- sets: [0, 0]
54913
- });
54914
- }
54915
- if (teamParticipantId && !teamMap.get(teamParticipantId))
54916
- return decorateResult({
54917
- result: { error: PARTICIPANT_NOT_FOUND },
54918
- context: { teamParticipantId }
54919
- });
54920
- if (opponentParticipantId && !teamMap.get(opponentParticipantId))
54921
- return decorateResult({
54922
- result: { error: PARTICIPANT_NOT_FOUND },
54923
- context: { opponentParticipantId }
54924
- });
54925
- const relevantMatchUps = [];
54926
- const getTeamParticipantIds = (sides) => {
54927
- const sideTeamParticipantIds = [];
54928
- const isTeamSide = (side, individualParticipantIds) => {
54929
- return !!(side.participantId && individualParticipantIds.includes(side.participantId) || side.participant?.individualParticipantIds?.length && intersection(
54930
- individualParticipantIds,
54931
- side.participant?.individualParticipantIds
54932
- ).length === side.participant?.individualParticipantIds?.length);
54933
- };
54934
- for (const [teamParticipantId2, individualParticipantIds] of teamMap) {
54935
- for (const side of sides) {
54936
- if (!side.participant)
54937
- continue;
54938
- if (isTeamSide(side, individualParticipantIds)) {
54939
- const sideNumber = side.sideNumber;
54940
- if (!sideNumber)
54941
- continue;
54942
- sideTeamParticipantIds[sideNumber - 1] = teamParticipantId2;
54943
- const competitorIds = side.participant?.individualParticipantIds?.length ? side.participant.individualParticipantIds : [side.participant.participantId];
54944
- const stats = teamStats.get(teamParticipantId2);
54945
- for (const id of competitorIds) {
54946
- if (stats && !stats.competitorIds.includes(id))
54947
- stats.competitorIds.push(id);
54948
- }
54949
- }
54950
- }
54951
- }
54952
- return sideTeamParticipantIds;
54953
- };
54954
- for (const matchUp of matchUps) {
54955
- if (!isObject(matchUp))
54956
- return { error: INVALID_MATCHUP };
54957
- const {
54958
- matchUpStatus,
54959
- matchUpFormat,
54960
- matchUpType,
54961
- winningSide,
54962
- score,
54963
- sides
54964
- } = matchUp;
54965
- if (!sides || !score || matchUpType === TEAM_MATCHUP || matchUpStatus === BYE)
54966
- continue;
54967
- const teamParticipantIds2 = getTeamParticipantIds(sides);
54968
- if (!teamParticipantIds2.filter(Boolean).length)
54969
- continue;
54970
- relevantMatchUps.push(matchUp);
54971
- const setsTally = countSets({
54972
- matchUpStatus,
54973
- matchUpFormat,
54974
- tallyPolicy,
54975
- winningSide,
54976
- score
54977
- });
54978
- const gamesTally = countGames({
54979
- matchUpStatus,
54980
- matchUpFormat,
54981
- tallyPolicy,
54982
- winningSide,
54983
- score
54984
- });
54985
- const { pointsTally, tiebreaksTally } = countPoints({
54986
- matchUpFormat,
54987
- score
54988
- });
54989
- teamParticipantIds2.forEach((teamParticipantId2, index) => {
54990
- if (teamParticipantId2) {
54991
- const stats = teamStats.get(teamParticipantId2);
54992
- if (stats) {
54993
- const teamSumTally = (stat, tally) => tally.forEach((t, i) => stats[stat][i] += t);
54994
- const tiebreaks = index ? [...tiebreaksTally].reverse() : tiebreaksTally;
54995
- const points = index ? [...pointsTally].reverse() : pointsTally;
54996
- const games = index ? [...gamesTally].reverse() : gamesTally;
54997
- const sets = index ? [...setsTally].reverse() : setsTally;
54998
- teamSumTally("tiebreaks", tiebreaks);
54999
- teamSumTally("points", points);
55000
- teamSumTally("games", games);
55001
- teamSumTally("sets", sets);
55002
- if (winningSide) {
55003
- const tallyIndex = winningSide - 1 === index ? 0 : 1;
55004
- stats.matchUps[tallyIndex] += 1;
55005
- }
55006
- if (matchUpStatus) {
55007
- if (!stats.matchUpStatuses[matchUpStatus])
55008
- stats.matchUpStatuses[matchUpStatus] = 0;
55009
- stats.matchUpStatuses[matchUpStatus] += 1;
55010
- }
55011
- }
55012
- }
55013
- });
55014
- }
55015
- const attrs = ["tiebreaks", "matchUps", "points", "games", "sets"];
55016
- const ratio = /* @__PURE__ */ new Map();
55017
- const add = (a, b) => (a ?? 0) + (b ?? 0);
55018
- for (const stats of teamStats.values()) {
55019
- for (const attr of attrs) {
55020
- const total = stats[attr].reduce(add);
55021
- if (total) {
55022
- const value = stats[attr][0] / total;
55023
- const accessor = `${attr}Ratio`;
55024
- const fixedValue = parseFloat(value.toFixed(2));
55025
- stats[accessor] = fixedValue;
55026
- if (!ratio.has(accessor))
55027
- ratio.set(accessor, []);
55028
- ratio.get(accessor)?.push(fixedValue);
55029
- }
55030
- }
55031
- }
55032
- const highLowSort = (a, b) => b - a;
55033
- for (const stats of teamStats.values()) {
55034
- for (const attr of attrs) {
55035
- const accessor = `${attr}Ratio`;
55036
- if (typeof stats[accessor] === "number") {
55037
- const index = ratio.get(accessor)?.sort(highLowSort).indexOf(stats[accessor]);
55038
- if (typeof index === "number" && index >= 0) {
55039
- const rankAccessor = `${attr}Rank`;
55040
- stats[rankAccessor] = index + 1;
55041
- }
55042
- }
55043
- }
55044
- }
55045
- const result = { relevantMatchUps, ...SUCCESS };
55046
- if (teamParticipantId) {
55047
- result.teamStats = teamStats.get(teamParticipantId);
55048
- if (opponentParticipantId)
55049
- result.opponentStats = teamStats.get(opponentParticipantId);
55050
- } else {
55051
- result.allTeamStats = [...teamStats.values()];
55052
- }
55053
- return result;
55054
- }
55055
-
55056
55131
  const reportGovernor = {
55057
55132
  getStructureReports,
55058
55133
  getEntryStatusReports,
55059
- getTeamStats
55134
+ getParticipantStats
55060
55135
  };
55061
55136
 
55062
55137
  function setDrawParticipantRepresentativeIds({