tods-competition-factory 1.8.9 → 1.8.11

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
@@ -913,10 +913,6 @@ const INVALID_SCALE_ITEM = {
913
913
  message: "Invalid scaleItem",
914
914
  code: "ERR_INVALID_SCALE_ITEM"
915
915
  };
916
- const SCALE_ITEM_NOT_FOUND = {
917
- message: "No scaleItem found",
918
- code: "ERR_NOT_FOUND_SCALE_ITEM"
919
- };
920
916
  const MODIFICATIONS_FAILED = {
921
917
  message: "Modifications failed",
922
918
  code: "ERR_FAILURE_MODIFICATIONS"
@@ -1174,7 +1170,6 @@ const errorConditionConstants = {
1174
1170
  PENALTY_NOT_FOUND,
1175
1171
  POLICY_NOT_ATTACHED,
1176
1172
  POLICY_NOT_FOUND,
1177
- SCALE_ITEM_NOT_FOUND,
1178
1173
  SCHEDULE_NOT_CLEARED,
1179
1174
  SCHEDULED_MATCHUPS,
1180
1175
  SEEDSCOUNT_GREATER_THAN_DRAW_SIZE,
@@ -2380,7 +2375,7 @@ const matchUpFormatCode = {
2380
2375
  };
2381
2376
 
2382
2377
  function factoryVersion() {
2383
- return "1.8.9";
2378
+ return "1.8.11";
2384
2379
  }
2385
2380
 
2386
2381
  function getObjectTieFormat(obj) {
@@ -4470,7 +4465,7 @@ function getPolicyDefinitions({
4470
4465
  if (policy)
4471
4466
  policyDefinitions[policyType] = policy;
4472
4467
  }
4473
- return Object.keys(policyDefinitions).length ? { policyDefinitions } : { error: POLICY_NOT_FOUND };
4468
+ return Object.keys(policyDefinitions).length ? { policyDefinitions } : { info: POLICY_NOT_FOUND.message };
4474
4469
  }
4475
4470
 
4476
4471
  const WALKOVER$1 = "WALKOVER";
@@ -4587,7 +4582,7 @@ function findPolicy({
4587
4582
  structure,
4588
4583
  event
4589
4584
  });
4590
- return appliedPolicies?.[policyType] ? { policy: appliedPolicies[policyType] } : { error: POLICY_NOT_FOUND };
4585
+ return appliedPolicies?.[policyType] ? { policy: appliedPolicies[policyType] } : { info: POLICY_NOT_FOUND?.message };
4591
4586
  }
4592
4587
 
4593
4588
  function getMatchUpCompetitiveProfile({
@@ -15080,7 +15075,7 @@ const POLICY_PRIVACY_DEFAULT = {
15080
15075
  const ADULT = "ADULT";
15081
15076
  const JUNIOR = "JUNIOR";
15082
15077
  const WHEELCHAIR = "WHEELCHAIR";
15083
- const POLICY_SCHEDULING_USTA = {
15078
+ const POLICY_SCHEDULING_DEFAULT = {
15084
15079
  [POLICY_TYPE_SCHEDULING]: {
15085
15080
  defaultTimes: {
15086
15081
  averageTimes: [{ categoryNames: [], minutes: { default: 90 } }],
@@ -15427,7 +15422,7 @@ const policies = {
15427
15422
  POLICY_POSITION_ACTIONS_UNRESTRICTED,
15428
15423
  POLICY_PRIVACY_DEFAULT,
15429
15424
  POLICY_ROUND_NAMING_DEFAULT,
15430
- POLICY_SCHEDULING_USTA,
15425
+ POLICY_SCHEDULING_DEFAULT,
15431
15426
  POLICY_SCORING_DEFAULT,
15432
15427
  POLICY_SCORING_USTA,
15433
15428
  POLICY_SEEDING_ITF,
@@ -26700,7 +26695,7 @@ function participantScaleItem({
26700
26695
  return { error: INVALID_VALUES };
26701
26696
  if (!participant.timeItems)
26702
26697
  participant.timeItems = [];
26703
- if (participant && Array.isArray(participant.timeItems)) {
26698
+ if (Array.isArray(participant.timeItems)) {
26704
26699
  const { accessor, scaleType, eventType, scaleName } = scaleAttributes;
26705
26700
  const filterType = [SCALE$1, scaleType, eventType, scaleName].join(".");
26706
26701
  const filteredTimeItems = participant.timeItems.filter((timeItem2) => timeItem2?.itemType === filterType).filter((timeItem2) => !requireTimeStamp || timeItem2?.itemDate).sort(
@@ -26720,12 +26715,10 @@ function participantScaleItem({
26720
26715
  scaleName: scaleName2,
26721
26716
  scaleType: scaleType2
26722
26717
  };
26723
- return { scaleItem };
26724
- } else {
26725
- return { error: SCALE_ITEM_NOT_FOUND };
26718
+ return { ...SUCCESS, scaleItem };
26726
26719
  }
26727
26720
  }
26728
- return { error: MISSING_PARTICIPANT };
26721
+ return { ...SUCCESS, scaleItem: void 0 };
26729
26722
  }
26730
26723
 
26731
26724
  function getEventSeedAssignments({
@@ -26932,7 +26925,7 @@ function addStructureParticipation({
26932
26925
 
26933
26926
  function processSides(params) {
26934
26927
  const {
26935
- withScheduleTimes,
26928
+ withScheduleItems,
26936
26929
  scheduleAnalysis,
26937
26930
  withTeamMatchUps,
26938
26931
  participantMap,
@@ -27042,7 +27035,7 @@ function processSides(params) {
27042
27035
  stage
27043
27036
  });
27044
27037
  }
27045
- if (scheduleAnalysis || withScheduleTimes) {
27038
+ if (scheduleAnalysis || withScheduleItems) {
27046
27039
  addScheduleItem({
27047
27040
  participantMap,
27048
27041
  participantId: participantId2,
@@ -27188,7 +27181,6 @@ function getParticipantEntries(params) {
27188
27181
  participantMap,
27189
27182
  withPotentialMatchUps,
27190
27183
  withRankingProfile,
27191
- withScheduleTimes,
27192
27184
  withScheduleItems,
27193
27185
  scheduleAnalysis,
27194
27186
  withTeamMatchUps,
@@ -27199,8 +27191,6 @@ function getParticipantEntries(params) {
27199
27191
  withEvents,
27200
27192
  withDraws
27201
27193
  } = params;
27202
- if (withScheduleItems)
27203
- console.log({ withScheduleItems });
27204
27194
  const targetParticipantIds = participantFilters?.participantIds;
27205
27195
  const getRelevantParticipantIds = (participantId) => {
27206
27196
  const relevantParticipantIds = [participantId];
@@ -27218,7 +27208,7 @@ function getParticipantEntries(params) {
27218
27208
  withDraws: withDraws || withRankingProfile,
27219
27209
  withPotentialMatchUps,
27220
27210
  withRankingProfile,
27221
- withScheduleTimes,
27211
+ withScheduleItems,
27222
27212
  scheduleAnalysis,
27223
27213
  withTeamMatchUps,
27224
27214
  withStatistics,
@@ -27538,7 +27528,7 @@ function getParticipantEntries(params) {
27538
27528
  matchUpType: matchUpType2
27539
27529
  });
27540
27530
  }
27541
- if (Array.isArray(potentialParticipants) && (nextMatchUps || !!scheduleAnalysis || withScheduleTimes)) {
27531
+ if (Array.isArray(potentialParticipants) && (nextMatchUps || !!scheduleAnalysis || withScheduleItems)) {
27542
27532
  const potentialParticipantIds = potentialParticipants.flat().map(extractAttributes("participantId")).filter(Boolean);
27543
27533
  potentialParticipantIds?.forEach((participantId) => {
27544
27534
  const relevantParticipantIds = getRelevantParticipantIds(participantId);
@@ -27553,7 +27543,7 @@ function getParticipantEntries(params) {
27553
27543
  drawId
27554
27544
  });
27555
27545
  });
27556
- if (!!scheduleAnalysis || withScheduleTimes) {
27546
+ if (!!scheduleAnalysis || withScheduleItems) {
27557
27547
  addScheduleItem({
27558
27548
  potential: true,
27559
27549
  participantMap,
@@ -27662,13 +27652,18 @@ function getParticipantEntries(params) {
27662
27652
  const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
27663
27653
  const sameDraw = scheduleItem.drawId === consideredItem.drawId;
27664
27654
  const bothPotential = potentialMatchUps[scheduleItem.matchUpId] && potentialMatchUps[consideredItem.matchUpId];
27665
- const nextMinutes = timeStringMinutes(consideredItem.scheduledTime);
27666
- const minutesDifference = Math.abs(nextMinutes - scheduledMinutes);
27667
- const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredItem.scheduledTime);
27668
- if (timeOverlap && !(bothPotential && sameDraw)) {
27655
+ const consideredMinutes = timeStringMinutes(
27656
+ consideredItem.scheduledTime
27657
+ );
27658
+ const minutesDifference = Math.abs(
27659
+ consideredMinutes - scheduledMinutes
27660
+ );
27661
+ const itemIsPrior = consideredMinutes > scheduledMinutes;
27662
+ const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : itemIsPrior && timeStringMinutes(consideredItem.scheduledTime) < timeStringMinutes(notBeforeTime);
27663
+ if (timeOverlap && !(bothPotential && sameDraw) && itemIsPrior) {
27669
27664
  participantAggregator.scheduleConflicts.push({
27670
- priorScheduledMatchUpId: consideredItem.matchUpId,
27671
- matchUpIdWithConflict: scheduleItem.matchUpId
27665
+ priorScheduledMatchUpId: scheduleItem.matchUpId,
27666
+ matchUpIdWithConflict: consideredItem.matchUpId
27672
27667
  });
27673
27668
  }
27674
27669
  }
@@ -27884,6 +27879,7 @@ function getParticipants$1(params) {
27884
27879
  ({
27885
27880
  potentialMatchUps,
27886
27881
  scheduleConflicts,
27882
+ scheduleItems,
27887
27883
  participant,
27888
27884
  statistics,
27889
27885
  opponents,
@@ -27909,7 +27905,8 @@ function getParticipants$1(params) {
27909
27905
  matchUps: withMatchUps || withRankingProfile ? Object.values(matchUps2) : void 0,
27910
27906
  opponents: withOpponents ? participantOpponents : void 0,
27911
27907
  potentialMatchUps: nextMatchUps ? Object.values(potentialMatchUps) : void 0,
27912
- statistics: withStatistics ? Object.values(statistics) : void 0
27908
+ statistics: withStatistics ? Object.values(statistics) : void 0,
27909
+ scheduleItems: withScheduleItems ? scheduleItems : void 0
27913
27910
  },
27914
27911
  false,
27915
27912
  false,
@@ -27940,1465 +27937,372 @@ function getParticipants$1(params) {
27940
27937
  };
27941
27938
  }
27942
27939
 
27943
- function getDerivedPositionAssignments({
27944
- derivedDrawInfo,
27940
+ function deepMerge(existing, incoming, arrayMerge) {
27941
+ if (!existing && incoming)
27942
+ return incoming;
27943
+ if (existing && !incoming)
27944
+ return existing;
27945
+ if (typeof existing !== "object" || typeof incoming !== "object")
27946
+ return existing;
27947
+ const keys = unique(Object.keys(existing).concat(Object.keys(incoming)));
27948
+ return keys.reduce((merged, key) => {
27949
+ if (!incoming[key]) {
27950
+ merged[key] = existing[key];
27951
+ } else if (!existing[key]) {
27952
+ merged[key] = incoming[key];
27953
+ } else if (typeof existing[key] !== typeof incoming[key]) {
27954
+ merged[key] = incoming[key];
27955
+ } else if (Array.isArray(existing[key])) {
27956
+ if (arrayMerge === true || Array.isArray(arrayMerge) && arrayMerge.includes(key)) {
27957
+ const mergedArrays = unique(
27958
+ existing[key].map((e) => JSON.stringify(e)).concat(incoming[key].map((i) => JSON.stringify(i)))
27959
+ ).map((u) => JSON.parse(u));
27960
+ merged[key] = mergedArrays;
27961
+ } else {
27962
+ merged[key] = incoming[key];
27963
+ }
27964
+ } else if (typeof existing[key] === "object") {
27965
+ merged[key] = deepMerge(existing[key], incoming[key], arrayMerge);
27966
+ } else {
27967
+ merged[key] = incoming[key];
27968
+ }
27969
+ return merged;
27970
+ }, {});
27971
+ }
27972
+
27973
+ function getParticipants(params) {
27974
+ const { tournamentRecords } = params || {};
27975
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length) {
27976
+ return { error: MISSING_TOURNAMENT_RECORDS };
27977
+ }
27978
+ const participantMap = {};
27979
+ const participants = [];
27980
+ const derivedEventInfo = {};
27981
+ const derivedDrawInfo = {};
27982
+ const matchUps = [];
27983
+ const mappedMatchUps = {};
27984
+ const participantIdsWithConflicts = [];
27985
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
27986
+ const {
27987
+ participantIdsWithConflicts: idsWithConflicts,
27988
+ mappedMatchUps: tournamentMappedMatchUps,
27989
+ participantMap: tournamentParticipantMap,
27990
+ participants: tournamentParticipants,
27991
+ matchUps: tournamentMatchUps,
27992
+ derivedEventInfo: eventInfo,
27993
+ derivedDrawInfo: drawInfo
27994
+ } = getParticipants$1({ tournamentRecord, ...params });
27995
+ Object.assign(mappedMatchUps, tournamentMappedMatchUps);
27996
+ Object.assign(participantMap, tournamentParticipantMap);
27997
+ Object.assign(derivedEventInfo, eventInfo);
27998
+ Object.assign(derivedDrawInfo, drawInfo);
27999
+ participants.push(...tournamentParticipants ?? []);
28000
+ matchUps.push(...tournamentMatchUps ?? []);
28001
+ idsWithConflicts?.forEach((participantId) => {
28002
+ if (!participantIdsWithConflicts.includes(participantId))
28003
+ participantIdsWithConflicts.push(participantId);
28004
+ });
28005
+ }
28006
+ return {
28007
+ participantIdsWithConflicts,
28008
+ derivedEventInfo,
28009
+ derivedDrawInfo,
28010
+ participantMap,
28011
+ mappedMatchUps,
28012
+ participants,
28013
+ ...SUCCESS,
28014
+ matchUps
28015
+ };
28016
+ }
28017
+ function getCompetitionParticipants(params) {
28018
+ const { tournamentRecords } = params || {};
28019
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28020
+ return { error: MISSING_TOURNAMENT_RECORDS };
28021
+ let competitionParticipants = [];
28022
+ const participantIdsWithConflicts = [];
28023
+ const competitionParticipantIds = [];
28024
+ const mappedMatchUps = {};
28025
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28026
+ const {
28027
+ participants,
28028
+ participantIdsWithConflicts: idsWithConflicts,
28029
+ mappedMatchUps: matchUpsMap
28030
+ } = getParticipants$1({
28031
+ tournamentRecord,
28032
+ ...params
28033
+ });
28034
+ if (matchUpsMap)
28035
+ Object.assign(mappedMatchUps, matchUpsMap);
28036
+ for (const tournamentParticipant of participants ?? []) {
28037
+ const { participantId } = tournamentParticipant;
28038
+ if (!competitionParticipantIds.includes(participantId)) {
28039
+ competitionParticipantIds.push(participantId);
28040
+ competitionParticipants.push(tournamentParticipant);
28041
+ } else {
28042
+ competitionParticipants = competitionParticipants.map(
28043
+ (participant) => participant.participantId !== participantId ? participant : deepMerge(participant, tournamentParticipant, true)
28044
+ );
28045
+ }
28046
+ }
28047
+ idsWithConflicts?.forEach((participantId) => {
28048
+ if (!participantIdsWithConflicts.includes(participantId))
28049
+ participantIdsWithConflicts.push(participantId);
28050
+ });
28051
+ }
28052
+ return {
28053
+ competitionParticipants,
28054
+ participantIdsWithConflicts,
28055
+ mappedMatchUps,
28056
+ ...SUCCESS
28057
+ };
28058
+ }
28059
+ function publicFindParticipant({
28060
+ tournamentRecords,
28061
+ policyDefinitions,
28062
+ contextProfile,
27945
28063
  participantId,
27946
- drawId
28064
+ personId
27947
28065
  }) {
27948
- const mainPositionAssignment = derivedDrawInfo[drawId]?.mainPositionAssignments?.find(
27949
- (assignment) => assignment.participantId === participantId
27950
- );
27951
- const qualifyingPositionAssignment = derivedDrawInfo[drawId]?.qualifyingPositionAssignments?.find(
27952
- (assignment) => assignment.participantId === participantId
28066
+ if (!tournamentRecords)
28067
+ return { error: MISSING_TOURNAMENT_RECORDS };
28068
+ if (typeof participantId !== "string" && typeof personId !== "string")
28069
+ return { error: MISSING_VALUE, stack: "publicFindParticipant" };
28070
+ let participant, tournamentId;
28071
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28072
+ tournamentId = tournamentRecord.tournamentId;
28073
+ const participants = getParticipants$1({
28074
+ policyDefinitions,
28075
+ tournamentRecord
28076
+ }).participants ?? [];
28077
+ participant = findParticipant({
28078
+ tournamentParticipants: participants,
28079
+ internalUse: true,
28080
+ policyDefinitions,
28081
+ contextProfile,
28082
+ participantId,
28083
+ personId
28084
+ });
28085
+ if (participant)
28086
+ break;
28087
+ }
28088
+ return { participant, tournamentId, ...SUCCESS };
28089
+ }
28090
+
28091
+ const penaltyTemplate = ({ penaltyId = UUID() } = {}) => ({
28092
+ refereeParticipantId: void 0,
28093
+ penaltyCode: void 0,
28094
+ penaltyType: void 0,
28095
+ extensions: void 0,
28096
+ matchUpId: void 0,
28097
+ createdAt: void 0,
28098
+ issuedAt: void 0,
28099
+ notes: void 0,
28100
+ penaltyId
28101
+ });
28102
+
28103
+ function addPenalty$1({
28104
+ refereeParticipantId,
28105
+ tournamentRecord,
28106
+ participantIds,
28107
+ penaltyCode,
28108
+ penaltyType,
28109
+ extensions,
28110
+ penaltyId,
28111
+ matchUpId,
28112
+ issuedAt,
28113
+ notes
28114
+ }) {
28115
+ if (!tournamentRecord)
28116
+ return { error: MISSING_TOURNAMENT_RECORD };
28117
+ if (!participantIds)
28118
+ return { error: MISSING_PARTICIPANT_ID };
28119
+ if (!penaltyType)
28120
+ return { error: MISSING_PENALTY_TYPE };
28121
+ const participants = tournamentRecord?.participants || [];
28122
+ const relevantParticipants = participants.filter(
28123
+ (participant) => participantIds.includes(participant.participantId)
27953
28124
  );
27954
- const positionAssignments = {};
27955
- if (mainPositionAssignment) {
27956
- const { participantId: participantId2, ...props } = mainPositionAssignment;
27957
- if (participantId2)
27958
- positionAssignments[MAIN] = { ...props };
28125
+ if (!relevantParticipants.length)
28126
+ return { error: PARTICIPANT_NOT_FOUND };
28127
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
28128
+ const penaltyItem = Object.assign(penaltyTemplate({ penaltyId }), {
28129
+ refereeParticipantId,
28130
+ penaltyCode,
28131
+ penaltyType,
28132
+ matchUpId,
28133
+ notes,
28134
+ issuedAt,
28135
+ createdAt
28136
+ });
28137
+ if (Array.isArray(extensions)) {
28138
+ extensions.forEach(
28139
+ (extension) => addExtension$1({ element: penaltyItem, extension })
28140
+ );
27959
28141
  }
27960
- if (qualifyingPositionAssignment) {
27961
- const { participantId: participantId2, ...props } = qualifyingPositionAssignment;
27962
- if (participantId2)
27963
- positionAssignments[QUALIFYING] = { ...props };
28142
+ relevantParticipants.forEach((participant) => {
28143
+ if (!participant.penalties)
28144
+ participant.penalties = [];
28145
+ participant.penalties.push(penaltyItem);
28146
+ });
28147
+ addNotice({
28148
+ topic: MODIFY_PARTICIPANTS,
28149
+ payload: {
28150
+ tournamentId: tournamentRecord.tournamentId,
28151
+ participants: relevantParticipants
28152
+ }
28153
+ });
28154
+ return { ...SUCCESS, penaltyId: penaltyItem.penaltyId };
28155
+ }
28156
+ function removePenalty$1({
28157
+ tournamentRecord,
28158
+ penaltyId
28159
+ }) {
28160
+ if (!tournamentRecord)
28161
+ return { error: MISSING_TOURNAMENT_RECORD };
28162
+ if (!penaltyId)
28163
+ return { error: MISSING_PENALTY_ID };
28164
+ const participants = tournamentRecord?.participants || [];
28165
+ const modifiedParticipants = [];
28166
+ let penaltyRemoved = false;
28167
+ let removedPenalty;
28168
+ participants.forEach((participant) => {
28169
+ let participantModified = false;
28170
+ participant.penalties = (participant.penalties || []).filter((penalty) => {
28171
+ if (penalty.penaltyId === penaltyId) {
28172
+ participantModified = true;
28173
+ if (!penaltyRemoved) {
28174
+ removedPenalty = penalty;
28175
+ penaltyRemoved = true;
28176
+ }
28177
+ }
28178
+ if (participantModified)
28179
+ modifiedParticipants.push(participant);
28180
+ return penalty.penaltyId !== penaltyId;
28181
+ });
28182
+ });
28183
+ if (removedPenalty) {
28184
+ addNotice({
28185
+ topic: MODIFY_PARTICIPANTS,
28186
+ payload: {
28187
+ tournamentId: tournamentRecord.tournamentId,
28188
+ participants: modifiedParticipants
28189
+ }
28190
+ });
27964
28191
  }
27965
- return Object.keys(positionAssignments).length ? positionAssignments : void 0;
28192
+ return removedPenalty ? { ...SUCCESS, penalty: removedPenalty } : { error: PENALTY_NOT_FOUND };
27966
28193
  }
27967
-
27968
- function getRelevantParticipantIdsMap({
27969
- processParticipantId,
27970
- // optional method which is passed each participantId
27971
- tournamentRecords,
28194
+ function getTournamentPenalties({
27972
28195
  tournamentRecord
27973
28196
  }) {
27974
- if (typeof tournamentRecord !== "object" && typeof tournamentRecords !== "object")
28197
+ if (!tournamentRecord)
27975
28198
  return { error: MISSING_TOURNAMENT_RECORD };
27976
- const allParticipants = tournamentRecords ? Object.values(tournamentRecords).map((tournamentRecord2) => tournamentRecord2?.participants || []).flat() : tournamentRecord?.participants || [];
27977
- const relevantParticipantIdsMap = Object.assign(
27978
- {},
27979
- ...allParticipants.map(
27980
- ({ participantId, participantType, individualParticipantIds }) => {
27981
- typeof processParticipantId === "function" && processParticipantId(participantId);
27982
- const individualParticipantIdObjects = (individualParticipantIds || []).map((relevantParticipantId) => ({
27983
- participantType: INDIVIDUAL,
27984
- relevantParticipantId
27985
- }));
27986
- return {
27987
- [participantId]: individualParticipantIdObjects.concat({
27988
- relevantParticipantId: participantId,
27989
- participantType
27990
- })
28199
+ const participants = tournamentRecord?.participants || [];
28200
+ const allPenalties = participants.reduce((penalties, participant) => {
28201
+ const { participantId } = participant;
28202
+ (participant.penalties || []).forEach((penalty) => {
28203
+ const { penaltyId } = penalty || {};
28204
+ if (penalties[penaltyId]) {
28205
+ penalties[penaltyId].participants.push(participantId);
28206
+ } else {
28207
+ penalties[penaltyId] = {
28208
+ ...penalty,
28209
+ participantIds: [participantId]
27991
28210
  };
27992
28211
  }
27993
- )
27994
- );
27995
- return { relevantParticipantIdsMap };
28212
+ });
28213
+ return penalties;
28214
+ }, {});
28215
+ return { penalties: Object.values(allPenalties) };
27996
28216
  }
27997
-
27998
- function getDerivedSeedAssignments({
27999
- derivedDrawInfo,
28000
- participantId,
28001
- drawId
28217
+ function modifyPenalty$1({
28218
+ tournamentRecord,
28219
+ modifications,
28220
+ penaltyId
28002
28221
  }) {
28003
- const mainSeedAssignment = derivedDrawInfo[drawId]?.mainSeedAssignments?.find(
28004
- (assignment) => assignment.participantId === participantId
28222
+ if (!tournamentRecord)
28223
+ return { error: MISSING_TOURNAMENT_RECORD };
28224
+ if (!modifications)
28225
+ return { error: INVALID_VALUES, modifications };
28226
+ if (!penaltyId)
28227
+ return { error: MISSING_PENALTY_ID };
28228
+ const participants = tournamentRecord?.participants || [];
28229
+ const validAttributes = Object.keys(penaltyTemplate()).filter(
28230
+ (attribute) => attribute !== "penaltyId"
28005
28231
  );
28006
- const qualifyingSeedAssignment = derivedDrawInfo[drawId]?.qualifyingSeedAssignments?.find(
28007
- (assignment) => assignment.participantId === participantId
28232
+ const validModificationAttributes = Object.keys(modifications).filter(
28233
+ (attribute) => validAttributes.includes(attribute)
28008
28234
  );
28009
- const seedAssignments = {};
28010
- if (mainSeedAssignment) {
28011
- const { participantId: participantId2, ...props } = mainSeedAssignment;
28012
- if (participantId2)
28013
- seedAssignments[MAIN] = { ...props };
28014
- }
28015
- if (qualifyingSeedAssignment) {
28016
- const { participantId: participantId2, ...props } = qualifyingSeedAssignment;
28017
- if (participantId2)
28018
- seedAssignments[QUALIFYING] = { ...props };
28235
+ if (!validModificationAttributes.length)
28236
+ return { error: NO_VALID_ATTRIBUTES };
28237
+ let updatedPenalty;
28238
+ const modifiedParticipants = [];
28239
+ participants.forEach((participant) => {
28240
+ let participantModified = false;
28241
+ participant.penalties = (participant.penalties || []).map((penalty) => {
28242
+ if (penalty.penaltyId === penaltyId) {
28243
+ participantModified = true;
28244
+ validModificationAttributes.forEach(
28245
+ (attribute) => Object.assign(penalty, { [attribute]: modifications[attribute] })
28246
+ );
28247
+ if (!updatedPenalty)
28248
+ updatedPenalty = penalty;
28249
+ }
28250
+ return penalty;
28251
+ });
28252
+ if (participantModified)
28253
+ modifiedParticipants.push(participant);
28254
+ });
28255
+ if (updatedPenalty) {
28256
+ addNotice({
28257
+ topic: MODIFY_PARTICIPANTS,
28258
+ payload: {
28259
+ tournamentId: tournamentRecord.tournamentId,
28260
+ participants: modifiedParticipants
28261
+ }
28262
+ });
28019
28263
  }
28020
- return Object.keys(seedAssignments).length ? seedAssignments : void 0;
28264
+ return updatedPenalty ? { ...SUCCESS, penalty: updatedPenalty } : { error: PENALTY_NOT_FOUND };
28021
28265
  }
28022
28266
 
28023
- const hasSchedule = ({
28024
- scheduleAttributes = ["scheduledDate", "scheduledTime"],
28025
- schedule = {}
28026
- }) => {
28027
- const matchUpScheduleKeys = Object.keys(schedule).filter((key) => scheduleAttributes.includes(key)).filter((key) => schedule[key]);
28028
- return !!matchUpScheduleKeys.length;
28029
- };
28030
-
28031
- function participantScheduledMatchUps({
28032
- scheduleAttributes = ["scheduledDate", "scheduledTime"],
28033
- matchUps = []
28034
- }) {
28035
- if (!validMatchUps(matchUps))
28036
- return { error: MISSING_MATCHUPS };
28037
- if (!Array.isArray(scheduleAttributes))
28038
- return { error: INVALID_VALUES };
28039
- const scheduledMatchUps = matchUps.filter(Boolean).filter(({ schedule }) => hasSchedule({ schedule, scheduleAttributes })).reduce((dateMatchUps, matchUp) => {
28040
- const { schedule } = matchUp;
28041
- const date = extractDate(schedule?.scheduledDate);
28042
- const time = extractTime(schedule?.scheduledTime);
28043
- if (date && time) {
28044
- if (dateMatchUps[date]) {
28045
- dateMatchUps[date].push(matchUp);
28046
- } else {
28047
- dateMatchUps[date] = [matchUp];
28048
- }
28267
+ function addPenalty(params) {
28268
+ const { tournamentRecords, participantIds } = params;
28269
+ let penaltyId;
28270
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28271
+ const participants = getParticipants$1({
28272
+ tournamentRecord
28273
+ }).participants ?? [];
28274
+ const tournamentParticipantIds = participants?.map(extractAttributes("participantId")).filter((participantId) => participantIds.includes(participantId));
28275
+ if (tournamentParticipantIds.length) {
28276
+ const result = addPenalty$1({
28277
+ ...params,
28278
+ penaltyId: params.penaltyId || penaltyId,
28279
+ tournamentRecord,
28280
+ participantIds: tournamentParticipantIds
28281
+ });
28282
+ penaltyId = result.penaltyId;
28049
28283
  }
28050
- return dateMatchUps;
28051
- }, {});
28052
- const dates = Object.keys(scheduledMatchUps);
28053
- dates.forEach((date) => {
28054
- scheduledMatchUps[date].sort(
28055
- (a, b) => timeSort(
28056
- extractTime(a.schedule?.scheduledTime),
28057
- extractTime(b.schedule?.scheduledTime)
28058
- )
28059
- );
28060
- });
28061
- return { scheduledMatchUps };
28284
+ }
28285
+ return penaltyId ? { ...SUCCESS, penaltyId } : { error: PARTICIPANT_NOT_FOUND };
28062
28286
  }
28063
-
28064
- function annotateParticipant(params) {
28065
- const {
28066
- withScaleValues = true,
28067
- eventsPublishStatuses,
28068
- withEvents = true,
28069
- withDraws = true,
28070
- participantIdMap,
28071
- scheduleAnalysis,
28072
- derivedDrawInfo,
28073
- usePublishState,
28074
- withStatistics,
28075
- withOpponents,
28076
- withMatchUps,
28077
- withSeeding,
28078
- participant,
28079
- withISO2,
28080
- withIOC
28081
- } = params;
28082
- const scheduleConflicts = [];
28083
- const scheduleItems = [];
28084
- if (withIOC || withISO2)
28085
- addNationalityCode({ participant, withIOC, withISO2 });
28086
- if (withScaleValues) {
28087
- const { ratings, rankings } = getScaleValues({ participant });
28088
- participant.rankings = rankings;
28089
- participant.ratings = ratings;
28287
+ function modifyPenalty(params) {
28288
+ const { tournamentRecords } = params;
28289
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28290
+ return { error: MISSING_TOURNAMENT_RECORDS };
28291
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28292
+ const result = modifyPenalty$1({ tournamentRecord, ...params });
28293
+ if (result.error && result.error !== PENALTY_NOT_FOUND)
28294
+ return result;
28090
28295
  }
28091
- const participantId = participant?.participantId;
28092
- if (!participantId || !participantIdMap[participantId])
28093
- return {};
28094
- const {
28095
- potentialMatchUps,
28096
- opponents,
28097
- matchUps,
28098
- events,
28099
- losses,
28100
- draws,
28101
- wins
28102
- } = participantIdMap[participantId];
28103
- const denominator = wins + losses;
28104
- const numerator = wins;
28105
- const statValue = denominator && numerator / denominator;
28106
- const winRatioStat = {
28107
- statCode: WIN_RATIO$1,
28108
- denominator,
28109
- numerator,
28110
- statValue
28111
- };
28112
- const participantDraws = Object.values(draws);
28113
- const participantEvents = Object.values(events);
28114
- if (withDraws && participantDraws) {
28115
- participant.draws = participantDraws;
28116
- for (const participantDraw of participantDraws) {
28117
- const publishedSeeding = eventsPublishStatuses[participantDraw.eventId]?.publishedSeeding;
28118
- const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(participantDraw.drawId));
28119
- if (seedingPublished) {
28120
- const seedAssignments = getDerivedSeedAssignments({
28121
- drawId: participantDraw.drawId,
28122
- derivedDrawInfo,
28123
- participantId
28124
- });
28125
- if (seedAssignments) {
28126
- participantDraw.seedAssignments = seedAssignments;
28127
- }
28128
- }
28129
- }
28130
- }
28131
- if (withEvents && participantEvents) {
28132
- participant.events = participantEvents;
28133
- if (withSeeding) {
28134
- const seedingScales = Object.assign(
28135
- {},
28136
- ...(participant.timeItems || []).filter(({ itemType }) => itemType.split(".")[1] === SEEDING$1).map(({ itemType: seedingScaleName, itemValue: seedValue }) => ({
28137
- [seedingScaleName]: seedValue
28138
- }))
28139
- );
28140
- for (const participantEvent of participantEvents) {
28141
- const getScaleAccessor = (scaleName) => [SCALE$1, SEEDING$1, participantEvent.eventType, scaleName].join(".");
28142
- const publishedSeeding = eventsPublishStatuses[participantEvent.eventId]?.publishedSeeding;
28143
- const eventSeedingScaleNames = (publishedSeeding?.stageSeedingScaleNames && Object.values(publishedSeeding?.stageSeedingScaleNames) || Array.isArray(publishedSeeding?.seedingScaleNames) && publishedSeeding.seedingScaleNames || []).map(getScaleAccessor);
28144
- const publishedEventSeedingScaleNames = intersection(
28145
- Object.keys(seedingScales),
28146
- eventSeedingScaleNames
28147
- );
28148
- const eventSeedingPublished = !!(!usePublishState || !Object.keys(seedingScales).length && !publishedSeeding?.drawIds?.length || publishedEventSeedingScaleNames.length);
28149
- if (eventSeedingPublished && publishedEventSeedingScaleNames.length) {
28150
- if (publishedSeeding?.stageSeedingScaleNames) {
28151
- const scaleValues = Object.keys(
28152
- publishedSeeding.stageSeedingScaleNames
28153
- ).map((key) => {
28154
- const accessor = getScaleAccessor(
28155
- publishedSeeding.stageSeedingScaleNames[key]
28156
- );
28157
- const scaleValue = seedingScales[accessor];
28158
- return [key, scaleValue];
28159
- }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
28160
- const seedAssignments = Object.assign({}, ...scaleValues);
28161
- participantEvent.seedAssignments = seedAssignments;
28162
- } else if (publishedEventSeedingScaleNames) {
28163
- const seedValues = publishedEventSeedingScaleNames.map(
28164
- (scaleName) => seedingScales[scaleName]
28165
- );
28166
- participantEvent.seedValue = seedValues.pop();
28167
- }
28168
- } else if (!usePublishState && typeof withSeeding === "object") {
28169
- const scaleValues = Object.keys(withSeeding).map((key) => {
28170
- const accessor = getScaleAccessor(withSeeding[key]);
28171
- const scaleValue = seedingScales[accessor];
28172
- return [key, scaleValue];
28173
- }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
28174
- const seedAssignments = Object.assign({}, ...scaleValues);
28175
- participantEvent.seedAssignments = seedAssignments;
28176
- } else {
28177
- const { categoryName, ageCategoryCode } = participantEvent.category || {};
28178
- let scaleItem;
28179
- for (const scaleName of [
28180
- participantEvent.eventId,
28181
- ageCategoryCode,
28182
- categoryName
28183
- ]) {
28184
- const scaleAttributes = {
28185
- eventType: participantEvent.eventType,
28186
- scaleType: SEEDING$1,
28187
- scaleName
28188
- };
28189
- const result = participantScaleItem({
28190
- scaleAttributes,
28191
- participant
28192
- });
28193
- if (result.scaleItem) {
28194
- scaleItem = result.scaleItem;
28195
- break;
28196
- }
28197
- }
28198
- if (scaleItem) {
28199
- const seedValue = scaleItem.scaleValue;
28200
- const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(
28201
- participantEvent.drawId
28202
- ));
28203
- if (seedingPublished) {
28204
- participantEvent.seedValue = seedValue;
28205
- }
28206
- }
28207
- }
28208
- if (participantEvent.drawIds?.length) {
28209
- for (const flightDrawId of participantEvent.drawIds || []) {
28210
- const drawSeedPublishingDisabled = publishedSeeding?.drawIds?.length && !publishedSeeding?.drawIds?.includes(flightDrawId);
28211
- if (eventSeedingPublished && !drawSeedPublishingDisabled) {
28212
- const seedAssignments = getDerivedSeedAssignments({
28213
- drawId: flightDrawId,
28214
- derivedDrawInfo,
28215
- participantId
28216
- });
28217
- if (seedAssignments && participantEvent.seedAssignments) {
28218
- for (const key of Object.keys(
28219
- participantEvent.seedAssignments
28220
- )) {
28221
- participantEvent.seedAssignments[key] = seedAssignments[key];
28222
- }
28223
- } else {
28224
- participantEvent.seedAssignments = seedAssignments;
28225
- }
28226
- }
28227
- }
28228
- }
28229
- }
28230
- }
28231
- }
28232
- const participantOpponents = Object.values(opponents).flat();
28233
- if (withOpponents && participantOpponents?.length) {
28234
- participant.opponents = participantOpponents;
28235
- participantDraws?.forEach((draw) => {
28236
- draw.opponents = participantOpponents.filter(
28237
- (opponent) => opponent.drawId === draw.drawId
28238
- );
28239
- });
28240
- }
28241
- const participantPotentialMatchUps = Object.values(potentialMatchUps);
28242
- const participantMatchUps = Object.values(matchUps);
28243
- if (withMatchUps) {
28244
- participant.potentialMatchUps = participantPotentialMatchUps;
28245
- participant.matchUps = participantMatchUps;
28246
- }
28247
- const allParticipantMatchUps = participantMatchUps.concat(
28248
- participantPotentialMatchUps
28249
- );
28250
- const scheduledMatchUps = participantScheduledMatchUps({
28251
- matchUps: allParticipantMatchUps
28252
- })?.scheduledMatchUps || [];
28253
- const { scheduledMinutesDifference } = scheduleAnalysis || {};
28254
- const dates = Object.keys(scheduledMatchUps);
28255
- dates.forEach((date) => {
28256
- scheduledMatchUps[date].filter(Boolean).forEach((matchUp, i) => {
28257
- const {
28258
- schedule: {
28259
- scheduledTime,
28260
- timeAfterRecovery,
28261
- typeChangeTimeAfterRecovery
28262
- },
28263
- matchUpStatus,
28264
- roundPosition,
28265
- structureName,
28266
- matchUpType,
28267
- roundNumber,
28268
- matchUpId,
28269
- drawId,
28270
- score
28271
- } = matchUp;
28272
- scheduleItems.push({
28273
- ...matchUp.schedule,
28274
- scheduledTime: extractTime(matchUp.schedule?.scheduledTime),
28275
- roundPosition,
28276
- structureName,
28277
- matchUpType,
28278
- roundNumber,
28279
- matchUpId,
28280
- drawId
28281
- });
28282
- const ignoreMatchUp = matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(matchUpStatus) && !scoreHasValue({ score });
28283
- if (scheduledTime && !ignoreMatchUp) {
28284
- const scheduledMinutes = timeStringMinutes(scheduledTime);
28285
- const matchUpsToConsider = scheduledMatchUps[date].slice(i + 1);
28286
- for (const consideredMatchUp of matchUpsToConsider) {
28287
- const ignoreMatchUp2 = consideredMatchUp.matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(consideredMatchUp.matchUpStatus) && !scoreHasValue(consideredMatchUp);
28288
- if (!ignoreMatchUp2 && consideredMatchUp.schedule?.scheduledTime) {
28289
- const typeChange = matchUp.matchUpType !== consideredMatchUp.matchUpType;
28290
- const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
28291
- const sameDraw = matchUp.drawId === consideredMatchUp.drawId;
28292
- const bothPotential = matchUp.potential && consideredMatchUp.potential;
28293
- const nextMinutes = timeStringMinutes(
28294
- consideredMatchUp.schedule?.scheduledTime
28295
- );
28296
- const minutesDifference = nextMinutes - scheduledMinutes;
28297
- const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredMatchUp.schedule?.scheduledTime);
28298
- if (timeOverlap && !(bothPotential && sameDraw)) {
28299
- scheduleConflicts.push({
28300
- priorScheduledMatchUpId: consideredMatchUp.matchUpId,
28301
- matchUpIdWithConflict: matchUpId
28302
- });
28303
- }
28304
- }
28305
- }
28306
- }
28307
- });
28308
- });
28309
- if (withStatistics)
28310
- participant.statistics = [winRatioStat];
28311
- return { scheduleConflicts, scheduleItems };
28312
- }
28313
-
28314
- function getDrawDetails({
28315
- eventEntries,
28316
- sortConfig,
28317
- event
28318
- }) {
28319
- const derivedInfo = {};
28320
- const drawDetails = Object.assign(
28321
- {},
28322
- ...(event.drawDefinitions ?? []).map((drawDefinition) => {
28323
- const entriesMap = Object.assign(
28324
- {},
28325
- ...(eventEntries ?? []).filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry })),
28326
- ...drawDefinition.entries.filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry }))
28327
- );
28328
- const drawEntries = Object.values(entriesMap);
28329
- const mainStructure = getDrawStructures({
28330
- stageSequence: 1,
28331
- drawDefinition,
28332
- stage: MAIN
28333
- })?.structures?.[0];
28334
- const mainPositionAssignments = mainStructure && getPositionAssignments$1({
28335
- structure: mainStructure
28336
- })?.positionAssignments;
28337
- const drawSize = mainPositionAssignments?.length;
28338
- const qualifyingStructure = getDrawStructures({
28339
- stageSequence: 1,
28340
- stage: QUALIFYING,
28341
- drawDefinition
28342
- })?.structures?.[0];
28343
- const qualifyingPositionAssignments = mainStructure && getPositionAssignments$1({
28344
- structure: qualifyingStructure
28345
- })?.positionAssignments;
28346
- const qualifyingDrawSize = qualifyingPositionAssignments?.length;
28347
- const mainSeedAssignments = mainStructure?.seedAssignments;
28348
- const qualifyingSeedAssignments = qualifyingStructure?.seedAssignments;
28349
- const orderedStructureIds = (drawDefinition.structures || []).sort((a, b) => structureSort(a, b, sortConfig)).map(({ structureId, structures }) => {
28350
- return [
28351
- structureId,
28352
- ...(structures || []).map(({ structureId: structureId2 }) => structureId2)
28353
- ];
28354
- }).flat(Infinity);
28355
- const flightNumber = event?._flightProfile?.flights?.find(
28356
- (flight) => flight.drawId === drawDefinition.drawId
28357
- )?.flightNumber;
28358
- derivedInfo[drawDefinition.drawId] = {
28359
- qualifyingPositionAssignments,
28360
- qualifyingSeedAssignments,
28361
- mainPositionAssignments,
28362
- mainSeedAssignments,
28363
- orderedStructureIds,
28364
- qualifyingDrawSize,
28365
- flightNumber,
28366
- drawSize
28367
- };
28368
- return {
28369
- [drawDefinition.drawId]: {
28370
- drawType: drawDefinition.drawType,
28371
- drawEntries
28372
- }
28373
- };
28374
- })
28375
- );
28376
- return { derivedInfo, drawDetails };
28377
- }
28378
-
28379
- function processMatchUp({
28380
- relevantParticipantIdsMap,
28381
- participantFilters,
28382
- participantIdMap,
28383
- derivedDrawInfo,
28384
- eventDrawsCount,
28385
- drawDetails,
28386
- eventType,
28387
- matchUp
28388
- }) {
28389
- const {
28390
- collectionId,
28391
- collectionPosition,
28392
- drawId,
28393
- drawName,
28394
- eventId,
28395
- eventName,
28396
- finishingRound,
28397
- finishingPositionRange,
28398
- processCodes,
28399
- loserTo,
28400
- matchUpId,
28401
- matchUpType,
28402
- matchUpFormat,
28403
- matchUpStatus,
28404
- matchUpStatusCodes,
28405
- matchUpTieId,
28406
- roundName,
28407
- roundNumber,
28408
- roundPosition,
28409
- score,
28410
- sides,
28411
- stage,
28412
- stageSequence,
28413
- schedule,
28414
- structureName,
28415
- structureId,
28416
- tieFormat,
28417
- tieMatchUps,
28418
- tournamentId,
28419
- winnerTo,
28420
- winningSide
28421
- } = matchUp;
28422
- const targetParticipantIds = participantFilters?.participantIds;
28423
- const getRelevantParticipantIds = (participantId) => {
28424
- const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
28425
- relevantParticipantIds.push(participantId);
28426
- return relevantParticipantIds.some(
28427
- (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
28428
- ) ? relevantParticipantIds : [];
28429
- };
28430
- const { winner, loser } = finishingPositionRange || {};
28431
- const doublesTieParticipants = tieMatchUps?.length && tieMatchUps.filter(({ matchUpType: matchUpType2 }) => matchUpType2 === DOUBLES_MATCHUP).map(
28432
- ({ sides: sides2 }) => sides2.map(
28433
- ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
28434
- sideNumber,
28435
- participantId,
28436
- participant
28437
- }
28438
- )
28439
- ).flat().filter(Boolean) || [];
28440
- if (eventType === TEAM_EVENT && matchUpType === DOUBLES_MATCHUP) {
28441
- const participants = (matchUp.sides?.filter(Boolean) || []).map(
28442
- ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
28443
- sideNumber,
28444
- participantId,
28445
- participant
28446
- }
28447
- ).filter(Boolean);
28448
- doublesTieParticipants.push(...participants);
28449
- }
28450
- sides?.forEach((params) => {
28451
- const { participantId, sideNumber } = params;
28452
- if (!participantId)
28453
- return;
28454
- const { drawType, drawEntries } = drawDetails[drawId];
28455
- const participantScore = sideNumber === 1 ? score?.scoreStringSide1 : score?.scoreStringSide2;
28456
- const participantWon = winningSide && sideNumber === winningSide;
28457
- const opponent = matchUp.sides.find(
28458
- (side) => side.sideNumber === 3 - sideNumber
28459
- );
28460
- const opponentParticipantId = opponent?.participantId;
28461
- const relevantOpponents = opponentParticipantId && relevantParticipantIdsMap[opponentParticipantId] || [];
28462
- const finishingPositionRange2 = participantWon ? winner : loser;
28463
- const drawEntry = drawEntries.find(
28464
- (entry) => entry.participantId === participantId
28465
- );
28466
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28467
- const addedPairParticipantIds = [];
28468
- doublesTieParticipants?.filter((participant) => participant.sideNumber === sideNumber).forEach((p) => {
28469
- const participantId2 = p.participantId;
28470
- if (participantId2 && !addedPairParticipantIds.includes(participantId2)) {
28471
- relevantParticipantIds.push({
28472
- relevantParticipantId: participantId2,
28473
- participantType: PAIR
28474
- });
28475
- addedPairParticipantIds.push(participantId2);
28476
- }
28477
- });
28478
- const filteredRelevantParticipantIds = relevantParticipantIds.filter(
28479
- (opponent2) => {
28480
- return eventType !== TEAM_EVENT || eventType === TEAM_EVENT && [DOUBLES_MATCHUP, TEAM_MATCHUP].includes(matchUpType) && [PAIR, TEAM_PARTICIPANT].includes(opponent2.participantType) || eventType === TEAM_EVENT && [SINGLES_MATCHUP, DOUBLES_MATCHUP].includes(matchUpType) && [INDIVIDUAL].includes(opponent2.participantType);
28481
- }
28482
- );
28483
- filteredRelevantParticipantIds?.forEach(
28484
- ({ relevantParticipantId, participantType }) => {
28485
- const { entryStage, entryStatus, entryPosition } = drawEntry || {};
28486
- if (!participantIdMap[relevantParticipantId])
28487
- return;
28488
- if (!participantIdMap[relevantParticipantId].draws[drawId]) {
28489
- const positionAssignments = getDerivedPositionAssignments({
28490
- participantId: relevantParticipantId,
28491
- derivedDrawInfo,
28492
- drawId
28493
- });
28494
- const seedAssignments = getDerivedSeedAssignments({
28495
- participantId: relevantParticipantId,
28496
- derivedDrawInfo,
28497
- drawId
28498
- });
28499
- participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
28500
- qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
28501
- drawSize: derivedDrawInfo[drawId]?.drawSize,
28502
- partnerParticipantIds: [],
28503
- positionAssignments,
28504
- seedAssignments,
28505
- entryPosition,
28506
- entryStatus,
28507
- entryStage,
28508
- drawName,
28509
- drawType,
28510
- eventId,
28511
- drawId
28512
- });
28513
- }
28514
- if (!participantIdMap[relevantParticipantId].events[eventId]) {
28515
- participantIdMap[relevantParticipantId].events[eventId] = {
28516
- partnerParticipantIds: [],
28517
- drawIds: [],
28518
- eventName,
28519
- eventId
28520
- };
28521
- }
28522
- const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
28523
- if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
28524
- participantIdMap[relevantParticipantId].events[eventId].drawIds.push(
28525
- drawId
28526
- );
28527
- }
28528
- let partnerParticipantId;
28529
- if (participantType === INDIVIDUAL && matchUpType === DOUBLES_MATCHUP) {
28530
- const relevantParticipantInfo = filteredRelevantParticipantIds.find(
28531
- (participantInfo) => {
28532
- return participantInfo.relevantParticipantId !== relevantParticipantId && participantInfo.participantType === INDIVIDUAL;
28533
- }
28534
- );
28535
- partnerParticipantId = relevantParticipantInfo?.relevantParticipantId;
28536
- }
28537
- const filteredRelevantOpponents = relevantOpponents?.filter(
28538
- (opponent2) => matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT && opponent2.participantType === TEAM_PARTICIPANT || matchUpType === SINGLES_MATCHUP && opponent2.participantType === INDIVIDUAL || matchUpType === DOUBLES_MATCHUP && (participantType === INDIVIDUAL ? [INDIVIDUAL, PAIR].includes(opponent2.participantType) : (
28539
- // for PAIR participants only show PAIR opponenents
28540
- opponent2.participantType === PAIR
28541
- ))
28542
- ) || [];
28543
- filteredRelevantOpponents.forEach(
28544
- ({
28545
- relevantParticipantId: opponentParticipantId2,
28546
- participantType: opponentParticipantType
28547
- }) => {
28548
- if (!participantIdMap[relevantParticipantId].opponents) {
28549
- participantIdMap[relevantParticipantId].opponents = {};
28550
- }
28551
- participantIdMap[relevantParticipantId].opponents[opponentParticipantId2] = {
28552
- eventId,
28553
- drawId,
28554
- matchUpId,
28555
- participantType: opponentParticipantType,
28556
- participantId: opponentParticipantId2
28557
- };
28558
- }
28559
- );
28560
- const opponentParticipantInfo = filteredRelevantOpponents.map(
28561
- ({ relevantParticipantId: relevantParticipantId2, participantType: participantType2 }) => ({
28562
- participantId: relevantParticipantId2,
28563
- participantType: participantType2
28564
- })
28565
- );
28566
- const includeMatchUp = matchUpType !== TEAM_MATCHUP && [INDIVIDUAL, PAIR].includes(participantType) || matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT;
28567
- if (includeMatchUp)
28568
- participantIdMap[relevantParticipantId].matchUps[matchUpId] = definedAttributes({
28569
- collectionId,
28570
- collectionPosition,
28571
- drawId,
28572
- eventId,
28573
- eventType,
28574
- eventDrawsCount,
28575
- finishingRound,
28576
- finishingPositionRange: finishingPositionRange2,
28577
- loserTo,
28578
- matchUpId,
28579
- matchUpType,
28580
- matchUpFormat,
28581
- matchUpStatus,
28582
- matchUpStatusCodes,
28583
- matchUpTieId,
28584
- opponentParticipantInfo,
28585
- participantWon,
28586
- partnerParticipantId,
28587
- perspectiveScoreString: participantScore,
28588
- processCodes,
28589
- roundName,
28590
- roundNumber,
28591
- roundPosition,
28592
- schedule,
28593
- score,
28594
- sides,
28595
- stage,
28596
- stageSequence,
28597
- structureName,
28598
- structureId,
28599
- tieFormat,
28600
- tournamentId,
28601
- winnerTo,
28602
- winningSide
28603
- });
28604
- if (partnerParticipantId) {
28605
- participantIdMap[relevantParticipantId].events[eventId].partnerParticipantIds.push(partnerParticipantId);
28606
- participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantIds.push(partnerParticipantId);
28607
- participantIdMap[relevantParticipantId].events[eventId].partnerParticipantId = partnerParticipantId;
28608
- participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantId = partnerParticipantId;
28609
- }
28610
- if (winningSide) {
28611
- if (participantWon) {
28612
- participantIdMap[relevantParticipantId].wins++;
28613
- } else {
28614
- participantIdMap[relevantParticipantId].losses++;
28615
- }
28616
- }
28617
- }
28618
- );
28619
- });
28620
- if (Array.isArray(matchUp.potentialParticipants)) {
28621
- const potentialParticipantIds = getParticipantIds(
28622
- matchUp.potentialParticipants.flat()
28623
- );
28624
- potentialParticipantIds?.forEach((participantId) => {
28625
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28626
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28627
- participantIdMap[relevantParticipantId].potentialMatchUps[matchUpId] = definedAttributes({
28628
- drawId,
28629
- eventId,
28630
- eventType,
28631
- matchUpId,
28632
- matchUpType,
28633
- matchUpFormat,
28634
- roundName,
28635
- roundNumber,
28636
- roundPosition,
28637
- schedule,
28638
- tieFormat,
28639
- structureName,
28640
- tournamentId,
28641
- potential: true
28642
- });
28643
- });
28644
- });
28645
- }
28646
- }
28647
-
28648
- function addParticipantContext(params) {
28649
- const participantIdsWithConflicts = [];
28650
- const eventsPublishStatuses = {};
28651
- const derivedDrawInfo = {};
28652
- const participantIdMap = {};
28653
- const initializeParticipantId = (participantId) => {
28654
- if (!participantIdMap[participantId])
28655
- participantIdMap[participantId] = {
28656
- groupParticipantIds: [],
28657
- teamParticipantIds: [],
28658
- pairParticipantIds: [],
28659
- potentialMatchUps: {},
28660
- scheduleItems: [],
28661
- opponents: {},
28662
- matchUps: {},
28663
- events: {},
28664
- groups: [],
28665
- teams: [],
28666
- draws: {},
28667
- losses: 0,
28668
- wins: 0
28669
- };
28670
- };
28671
- const { tournamentRecord, participantFilters, allTournamentParticipants } = params;
28672
- const { relevantParticipantIdsMap } = getRelevantParticipantIdsMap({
28673
- processParticipantId: initializeParticipantId,
28674
- tournamentRecord
28675
- });
28676
- const targetParticipantIds = participantFilters?.participantIds;
28677
- const getRelevantParticipantIds = (participantId) => {
28678
- const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
28679
- relevantParticipantIds.push(participantId);
28680
- return relevantParticipantIds.some(
28681
- (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
28682
- ) ? relevantParticipantIds : [];
28683
- };
28684
- params.withGroupings && allTournamentParticipants.forEach((participant) => {
28685
- if (participant.participantType === GROUP) {
28686
- const groupParticipantId = participant.participantId;
28687
- participant?.individualParticipantIds?.forEach((participantId) => {
28688
- if (!participantIdMap[participantId].groupParticipantIds.includes(
28689
- groupParticipantId
28690
- )) {
28691
- participantIdMap[participantId].groupParticipantIds.push(
28692
- groupParticipantId
28693
- );
28694
- participantIdMap[participantId].groups.push({
28695
- participantRoleResponsibilities: participant.participantRoleResponsibilities,
28696
- participantOtherName: participant.participantOtherName,
28697
- participantName: participant.participantName,
28698
- participantId: participant.participantId
28699
- });
28700
- }
28701
- });
28702
- }
28703
- if (participant.participantType === TEAM$2) {
28704
- const teamParticipantId = participant.participantId;
28705
- participant?.individualParticipantIds?.forEach((participantId) => {
28706
- if (!participantIdMap[participantId]?.teamParticipantIds?.includes(
28707
- teamParticipantId
28708
- )) {
28709
- participantIdMap[participantId]?.teamParticipantIds.push(
28710
- teamParticipantId
28711
- );
28712
- participantIdMap[participantId]?.teams.push({
28713
- participantRoleResponsibilities: participant.participantRoleResponsibilities,
28714
- participantOtherName: participant.participantOtherName,
28715
- participantName: participant.participantName,
28716
- participantId: participant.participantId,
28717
- teamId: participant.teamId
28718
- });
28719
- }
28720
- });
28721
- }
28722
- if (participant.participantType === PAIR) {
28723
- const pairParticipantId = participant.participantId;
28724
- participant?.individualParticipantIds?.forEach((participantId) => {
28725
- if (participantIdMap[participantId] && !participantIdMap[participantId].pairParticipantIds.includes(
28726
- pairParticipantId
28727
- )) {
28728
- participantIdMap[participantId].pairParticipantIds.push(
28729
- pairParticipantId
28730
- );
28731
- }
28732
- });
28733
- }
28734
- });
28735
- if (params.withMatchUps) {
28736
- getMatchUpDependencies({ tournamentRecord });
28737
- }
28738
- if (params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withSeeding || params.withEvents || params.withDraws) {
28739
- params.tournamentEvents?.forEach((rawEvent) => {
28740
- const event = makeDeepCopy(rawEvent, true, true);
28741
- const flightProfile = getFlightProfile({ event }).flightProfile;
28742
- const eventDrawsCount = flightProfile?.flights?.length || event.drawDefinitions?.length || 0;
28743
- (event.drawDefinitions || []).forEach((drawDefinition, i) => {
28744
- if (event?.eventType === TEAM$2) {
28745
- const { extension } = findExtension$2({
28746
- element: rawEvent.drawDefinitions[i],
28747
- // rawEvent because deepCopy has converted extensions
28748
- name: LINEUPS
28749
- });
28750
- if (extension)
28751
- drawDefinition.extensions = [extension];
28752
- }
28753
- });
28754
- const { eventId, eventName, eventType, category } = event;
28755
- const eventInfo = { eventId, eventName, eventType, category };
28756
- const extensionKeys = event && Object.keys(event).filter((key) => key.startsWith("_"));
28757
- extensionKeys?.forEach(
28758
- (extensionKey) => eventInfo[extensionKey] = event[extensionKey]
28759
- );
28760
- const eventEntries = event.entries || [];
28761
- const itemType = `${PUBLISH}.${STATUS$1}`;
28762
- const { timeItem } = getEventTimeItem({
28763
- itemType,
28764
- event
28765
- });
28766
- if (timeItem?.itemValue?.PUBLIC) {
28767
- const { drawIds: publishedDrawIds = [], seeding } = timeItem.itemValue.PUBLIC || {};
28768
- const publishedSeeding = {
28769
- published: void 0,
28770
- // seeding can be present for all entries in an event when no flights have been defined
28771
- seedingScaleNames: [],
28772
- drawIds: []
28773
- // seeding can be specific to drawIds
28774
- };
28775
- if (seeding)
28776
- Object.assign(publishedSeeding, timeItem.itemValue.PUBLIC.seeding);
28777
- eventsPublishStatuses[eventId] = {
28778
- publishedDrawIds,
28779
- publishedSeeding
28780
- };
28781
- }
28782
- const disallowedConstants = [
28783
- ...Object.values(extensionConstants)
28784
- ];
28785
- const disallowedKeys = disallowedConstants.map(
28786
- (constant) => `_${constant}`
28787
- );
28788
- const filteredEventInfo = eventInfo && Object.keys(eventInfo).filter((key) => !disallowedKeys.includes(key)).reduce((obj, key) => {
28789
- obj[key] = eventInfo[key];
28790
- return obj;
28791
- }, {});
28792
- eventEntries?.filter((entry) => entry?.participantId).forEach((entry) => {
28793
- const { participantId, entryStage, entryStatus, entryPosition } = entry;
28794
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28795
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28796
- if (!participantIdMap[relevantParticipantId])
28797
- initializeParticipantId(relevantParticipantId);
28798
- participantIdMap[relevantParticipantId].events[eventId] = {
28799
- ...filteredEventInfo,
28800
- partnerParticipantIds: [],
28801
- entryPosition,
28802
- entryStatus,
28803
- entryStage,
28804
- drawIds: [],
28805
- eventId
28806
- };
28807
- });
28808
- });
28809
- const addDrawData = ({ drawEntry, drawId }) => {
28810
- const { participantId, entryStage, entryStatus, entryPosition } = drawEntry;
28811
- const relevantParticipantIds = getRelevantParticipantIds(participantId);
28812
- relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
28813
- if (!participantIdMap[relevantParticipantId].events[eventId]) {
28814
- participantIdMap[relevantParticipantId].events[eventId] = {
28815
- ...filteredEventInfo,
28816
- partnerParticipantIds: [],
28817
- entryPosition,
28818
- entryStatus,
28819
- entryStage,
28820
- drawIds: [],
28821
- eventId
28822
- };
28823
- }
28824
- if (!participantIdMap[relevantParticipantId].draws[drawId]) {
28825
- const positionAssignments = getDerivedPositionAssignments({
28826
- participantId: relevantParticipantId,
28827
- derivedDrawInfo,
28828
- drawId
28829
- });
28830
- const seedAssignments = getDerivedSeedAssignments({
28831
- participantId: relevantParticipantId,
28832
- derivedDrawInfo,
28833
- drawId
28834
- });
28835
- participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
28836
- qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
28837
- drawSize: derivedDrawInfo[drawId]?.drawSize,
28838
- partnerParticipantIds: [],
28839
- positionAssignments,
28840
- eventDrawsCount,
28841
- seedAssignments,
28842
- entryPosition,
28843
- entryStatus,
28844
- entryStage,
28845
- eventId,
28846
- drawId
28847
- });
28848
- }
28849
- const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
28850
- if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
28851
- participantIdMap[relevantParticipantId].events[eventId].drawIds.push(drawId);
28852
- }
28853
- });
28854
- };
28855
- const drawIdsWithDefinitions = event.drawDefinitions?.map(({ drawId }) => drawId) || [];
28856
- eventInfo._flightProfile?.flights?.forEach((flight) => {
28857
- const { drawId, drawEntries } = flight;
28858
- if (!drawIdsWithDefinitions.includes(drawId)) {
28859
- drawEntries?.forEach(
28860
- (drawEntry) => addDrawData({ drawEntry, drawId })
28861
- );
28862
- }
28863
- });
28864
- const { drawDetails, derivedInfo } = getDrawDetails({
28865
- eventEntries,
28866
- event
28867
- });
28868
- Object.assign(derivedDrawInfo, derivedInfo);
28869
- if (event.eventType === TEAM$2 || // for TEAM events some individual attributes can only be derived by processing
28870
- params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withDraws) {
28871
- const matchUps = allEventMatchUps({
28872
- afterRecoveryTimes: params.scheduleAnalysis,
28873
- participants: allTournamentParticipants,
28874
- nextMatchUps: true,
28875
- tournamentRecord,
28876
- inContext: true,
28877
- event
28878
- })?.matchUps;
28879
- matchUps?.forEach(
28880
- (matchUp) => processMatchUp({
28881
- relevantParticipantIdsMap,
28882
- participantFilters,
28883
- participantIdMap,
28884
- derivedDrawInfo,
28885
- eventDrawsCount,
28886
- drawDetails,
28887
- eventType,
28888
- matchUp
28889
- })
28890
- );
28891
- }
28892
- });
28893
- }
28894
- params.tournamentParticipants?.forEach((participant) => {
28895
- const { scheduleConflicts, scheduleItems } = annotateParticipant({
28896
- ...params,
28897
- eventsPublishStatuses,
28898
- participantIdMap,
28899
- derivedDrawInfo,
28900
- participant
28901
- });
28902
- if (params.withSignInStatus) {
28903
- const { timeItem } = getTimeItem({
28904
- itemType: SIGN_IN_STATUS,
28905
- element: participant
28906
- });
28907
- participant.signedIn = timeItem?.itemValue === SIGNED_IN;
28908
- }
28909
- if (params.withScheduleItems) {
28910
- participant.scheduleItems = scheduleItems;
28911
- }
28912
- if (params.scheduleAnalysis) {
28913
- participant.scheduleConflicts = scheduleConflicts;
28914
- if (scheduleConflicts?.length && !participantIdsWithConflicts.includes(participant.participantId)) {
28915
- participantIdsWithConflicts.push(participant.participantId);
28916
- }
28917
- }
28918
- if (params.withGroupings !== false) {
28919
- const participantAttributes = participantIdMap[participant.participantId];
28920
- participant.groupParticipantIds = participantAttributes?.groupParticipantIds;
28921
- participant.pairParticipantIds = participantAttributes?.pairParticipantIds;
28922
- participant.teamParticipantIds = participantAttributes?.teamParticipantIds;
28923
- participant.groups = participantAttributes?.groups;
28924
- participant.teams = participantAttributes?.teams;
28925
- }
28926
- if (params.withTeamMatchUps) ;
28927
- });
28928
- return { participantIdsWithConflicts, eventsPublishStatuses };
28929
- }
28930
-
28931
- function getTournamentParticipants(params) {
28932
- const {
28933
- participantFilters = {},
28934
- convertExtensions,
28935
- policyDefinitions,
28936
- withScheduleItems,
28937
- scheduleAnalysis,
28938
- withSignInStatus,
28939
- withTeamMatchUps,
28940
- // not implemented
28941
- tournamentRecord,
28942
- usePublishState,
28943
- withScaleValues,
28944
- withStatistics,
28945
- withGroupings,
28946
- withOpponents,
28947
- withMatchUps,
28948
- withSeeding,
28949
- withEvents,
28950
- withDraws,
28951
- inContext,
28952
- withISO2,
28953
- withIOC
28954
- } = params;
28955
- if (!tournamentRecord)
28956
- return { error: MISSING_TOURNAMENT_RECORD };
28957
- if (!tournamentRecord.participants)
28958
- return { error: MISSING_PARTICIPANTS };
28959
- const allTournamentParticipants = tournamentRecord.participants.map(
28960
- // (participant) => makeDeepCopy(participant, convertExtensions, true)
28961
- (participant) => makeDeepCopy(participant, convertExtensions)
28962
- // removed until Mongo/Mongoose issues resolved
28963
- );
28964
- if (typeof participantFilters !== "object")
28965
- return { error: INVALID_OBJECT, participantFilters };
28966
- if (inContext) {
28967
- allTournamentParticipants?.forEach((participant) => {
28968
- if ([PAIR, TEAM, GROUP].includes(participant.participantType)) {
28969
- participant.individualParticipants = participant.individualParticipantIds?.map((participantId) => {
28970
- const targetParticipant = tournamentRecord.participants.find(
28971
- (p) => p.participantId === participantId
28972
- );
28973
- const individualParticipant = makeDeepCopy(
28974
- targetParticipant,
28975
- convertExtensions,
28976
- true
28977
- );
28978
- if (withScaleValues) {
28979
- const { ratings, rankings } = getScaleValues({
28980
- participant: individualParticipant
28981
- });
28982
- individualParticipant.ratings = ratings;
28983
- individualParticipant.rankings = rankings;
28984
- }
28985
- if (withIOC || withISO2)
28986
- addNationalityCode({
28987
- participant: individualParticipant,
28988
- withISO2,
28989
- withIOC
28990
- });
28991
- return individualParticipant;
28992
- });
28993
- }
28994
- });
28995
- }
28996
- let tournamentParticipants = participantFilters ? filterParticipants({
28997
- participants: allTournamentParticipants,
28998
- participantFilters,
28999
- tournamentRecord
29000
- }) : allTournamentParticipants;
29001
- let participantIdsWithConflicts, eventsPublishStatuses;
29002
- const addContext = withScheduleItems || withSignInStatus || scheduleAnalysis || withScaleValues || withStatistics || withGroupings || withOpponents || withMatchUps || withSeeding || withEvents || withDraws || withISO2 || withIOC;
29003
- if (addContext) {
29004
- const result = addParticipantContext({
29005
- tournamentEvents: tournamentRecord.events,
29006
- allTournamentParticipants,
29007
- tournamentParticipants,
29008
- participantFilters,
29009
- withScheduleItems,
29010
- withSignInStatus,
29011
- tournamentRecord,
29012
- scheduleAnalysis,
29013
- withTeamMatchUps,
29014
- usePublishState,
29015
- withScaleValues,
29016
- withStatistics,
29017
- withGroupings,
29018
- withOpponents,
29019
- withMatchUps,
29020
- withSeeding,
29021
- withEvents,
29022
- withDraws,
29023
- withISO2,
29024
- withIOC
29025
- });
29026
- participantIdsWithConflicts = result?.participantIdsWithConflicts;
29027
- eventsPublishStatuses = result?.eventsPublishStatuses;
29028
- }
29029
- const participantAttributes = policyDefinitions?.[POLICY_TYPE_PARTICIPANT];
29030
- if (participantAttributes?.participant) {
29031
- tournamentParticipants = tournamentParticipants.map(
29032
- (participant) => attributeFilter({
29033
- template: participantAttributes.participant,
29034
- source: participant
29035
- })
29036
- );
29037
- }
29038
- return {
29039
- participantIdsWithConflicts,
29040
- tournamentParticipants,
29041
- eventsPublishStatuses
29042
- };
29043
- }
29044
-
29045
- function deepMerge(existing, incoming, arrayMerge) {
29046
- if (!existing && incoming)
29047
- return incoming;
29048
- if (existing && !incoming)
29049
- return existing;
29050
- if (typeof existing !== "object" || typeof incoming !== "object")
29051
- return existing;
29052
- const keys = unique(Object.keys(existing).concat(Object.keys(incoming)));
29053
- return keys.reduce((merged, key) => {
29054
- if (!incoming[key]) {
29055
- merged[key] = existing[key];
29056
- } else if (!existing[key]) {
29057
- merged[key] = incoming[key];
29058
- } else if (typeof existing[key] !== typeof incoming[key]) {
29059
- merged[key] = incoming[key];
29060
- } else if (Array.isArray(existing[key])) {
29061
- if (arrayMerge === true || Array.isArray(arrayMerge) && arrayMerge.includes(key)) {
29062
- const mergedArrays = unique(
29063
- existing[key].map((e) => JSON.stringify(e)).concat(incoming[key].map((i) => JSON.stringify(i)))
29064
- ).map((u) => JSON.parse(u));
29065
- merged[key] = mergedArrays;
29066
- } else {
29067
- merged[key] = incoming[key];
29068
- }
29069
- } else if (typeof existing[key] === "object") {
29070
- merged[key] = deepMerge(existing[key], incoming[key], arrayMerge);
29071
- } else {
29072
- merged[key] = incoming[key];
29073
- }
29074
- return merged;
29075
- }, {});
29076
- }
29077
-
29078
- function getParticipants(params) {
29079
- const { tournamentRecords } = params || {};
29080
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length) {
29081
- return { error: MISSING_TOURNAMENT_RECORDS };
29082
- }
29083
- const participantMap = {};
29084
- const participants = [];
29085
- const derivedEventInfo = {};
29086
- const derivedDrawInfo = {};
29087
- const matchUps = [];
29088
- const mappedMatchUps = {};
29089
- const participantIdsWithConflicts = [];
29090
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29091
- const {
29092
- participantIdsWithConflicts: idsWithConflicts,
29093
- mappedMatchUps: tournamentMappedMatchUps,
29094
- participantMap: tournamentParticipantMap,
29095
- participants: tournamentParticipants,
29096
- matchUps: tournamentMatchUps,
29097
- derivedEventInfo: eventInfo,
29098
- derivedDrawInfo: drawInfo
29099
- } = getParticipants$1({ tournamentRecord, ...params });
29100
- Object.assign(mappedMatchUps, tournamentMappedMatchUps);
29101
- Object.assign(participantMap, tournamentParticipantMap);
29102
- Object.assign(derivedEventInfo, eventInfo);
29103
- Object.assign(derivedDrawInfo, drawInfo);
29104
- participants.push(...tournamentParticipants ?? []);
29105
- matchUps.push(...tournamentMatchUps ?? []);
29106
- idsWithConflicts?.forEach((participantId) => {
29107
- if (!participantIdsWithConflicts.includes(participantId))
29108
- participantIdsWithConflicts.push(participantId);
29109
- });
29110
- }
29111
- return {
29112
- participantIdsWithConflicts,
29113
- derivedEventInfo,
29114
- derivedDrawInfo,
29115
- participantMap,
29116
- mappedMatchUps,
29117
- participants,
29118
- ...SUCCESS,
29119
- matchUps
29120
- };
29121
- }
29122
- function getCompetitionParticipants(params) {
29123
- const { tournamentRecords } = params || {};
29124
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29125
- return { error: MISSING_TOURNAMENT_RECORDS };
29126
- let competitionParticipants = [];
29127
- const participantIdsWithConflicts = [];
29128
- const competitionParticipantIds = [];
29129
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29130
- const {
29131
- tournamentParticipants,
29132
- participantIdsWithConflicts: idsWithConflicts
29133
- } = getTournamentParticipants({
29134
- tournamentRecord,
29135
- ...params
29136
- });
29137
- for (const tournamentParticipant of tournamentParticipants) {
29138
- const { participantId } = tournamentParticipant;
29139
- if (!competitionParticipantIds.includes(participantId)) {
29140
- competitionParticipantIds.push(participantId);
29141
- competitionParticipants.push(tournamentParticipant);
29142
- } else {
29143
- competitionParticipants = competitionParticipants.map(
29144
- (participant) => participant.participantId !== participantId ? participant : deepMerge(participant, tournamentParticipant, true)
29145
- );
29146
- }
29147
- }
29148
- idsWithConflicts?.forEach((participantId) => {
29149
- if (!participantIdsWithConflicts.includes(participantId))
29150
- participantIdsWithConflicts.push(participantId);
29151
- });
29152
- }
29153
- return { competitionParticipants, participantIdsWithConflicts, ...SUCCESS };
29154
- }
29155
- function publicFindParticipant({
29156
- policyDefinitions,
29157
- tournamentRecords,
29158
- participantId,
29159
- inContext,
29160
- personId
29161
- }) {
29162
- if (!tournamentRecords)
29163
- return { error: MISSING_TOURNAMENT_RECORDS };
29164
- if (typeof participantId !== "string" && typeof personId !== "string")
29165
- return { error: MISSING_VALUE, stack: "publicFindParticipant" };
29166
- let participant, tournamentId;
29167
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29168
- tournamentId = tournamentRecord.tournamentId;
29169
- const { tournamentParticipants } = getTournamentParticipants({
29170
- policyDefinitions,
29171
- tournamentRecord,
29172
- inContext
29173
- });
29174
- participant = findParticipant({
29175
- tournamentParticipants,
29176
- internalUse: true,
29177
- policyDefinitions,
29178
- participantId,
29179
- personId
29180
- });
29181
- if (participant)
29182
- break;
29183
- }
29184
- return { participant, tournamentId, ...SUCCESS };
29185
- }
29186
-
29187
- const penaltyTemplate = ({ penaltyId = UUID() } = {}) => ({
29188
- refereeParticipantId: void 0,
29189
- penaltyCode: void 0,
29190
- penaltyType: void 0,
29191
- extensions: void 0,
29192
- matchUpId: void 0,
29193
- createdAt: void 0,
29194
- issuedAt: void 0,
29195
- notes: void 0,
29196
- penaltyId
29197
- });
29198
-
29199
- function addPenalty$1({
29200
- refereeParticipantId,
29201
- tournamentRecord,
29202
- participantIds,
29203
- penaltyCode,
29204
- penaltyType,
29205
- extensions,
29206
- penaltyId,
29207
- matchUpId,
29208
- issuedAt,
29209
- notes
29210
- }) {
29211
- if (!tournamentRecord)
29212
- return { error: MISSING_TOURNAMENT_RECORD };
29213
- if (!participantIds)
29214
- return { error: MISSING_PARTICIPANT_ID };
29215
- if (!penaltyType)
29216
- return { error: MISSING_PENALTY_TYPE };
29217
- const participants = tournamentRecord?.participants || [];
29218
- const relevantParticipants = participants.filter(
29219
- (participant) => participantIds.includes(participant.participantId)
29220
- );
29221
- if (!relevantParticipants.length)
29222
- return { error: PARTICIPANT_NOT_FOUND };
29223
- const createdAt = (/* @__PURE__ */ new Date()).toISOString();
29224
- const penaltyItem = Object.assign(penaltyTemplate({ penaltyId }), {
29225
- refereeParticipantId,
29226
- penaltyCode,
29227
- penaltyType,
29228
- matchUpId,
29229
- notes,
29230
- issuedAt,
29231
- createdAt
29232
- });
29233
- if (Array.isArray(extensions)) {
29234
- extensions.forEach(
29235
- (extension) => addExtension$1({ element: penaltyItem, extension })
29236
- );
29237
- }
29238
- relevantParticipants.forEach((participant) => {
29239
- if (!participant.penalties)
29240
- participant.penalties = [];
29241
- participant.penalties.push(penaltyItem);
29242
- });
29243
- addNotice({
29244
- topic: MODIFY_PARTICIPANTS,
29245
- payload: {
29246
- tournamentId: tournamentRecord.tournamentId,
29247
- participants: relevantParticipants
29248
- }
29249
- });
29250
- return { ...SUCCESS, penaltyId: penaltyItem.penaltyId };
29251
- }
29252
- function removePenalty$1({
29253
- tournamentRecord,
29254
- penaltyId
29255
- }) {
29256
- if (!tournamentRecord)
29257
- return { error: MISSING_TOURNAMENT_RECORD };
29258
- if (!penaltyId)
29259
- return { error: MISSING_PENALTY_ID };
29260
- const participants = tournamentRecord?.participants || [];
29261
- const modifiedParticipants = [];
29262
- let penaltyRemoved = false;
29263
- let removedPenalty;
29264
- participants.forEach((participant) => {
29265
- let participantModified = false;
29266
- participant.penalties = (participant.penalties || []).filter((penalty) => {
29267
- if (penalty.penaltyId === penaltyId) {
29268
- participantModified = true;
29269
- if (!penaltyRemoved) {
29270
- removedPenalty = penalty;
29271
- penaltyRemoved = true;
29272
- }
29273
- }
29274
- if (participantModified)
29275
- modifiedParticipants.push(participant);
29276
- return penalty.penaltyId !== penaltyId;
29277
- });
29278
- });
29279
- if (removedPenalty) {
29280
- addNotice({
29281
- topic: MODIFY_PARTICIPANTS,
29282
- payload: {
29283
- tournamentId: tournamentRecord.tournamentId,
29284
- participants: modifiedParticipants
29285
- }
29286
- });
29287
- }
29288
- return removedPenalty ? { ...SUCCESS, penalty: removedPenalty } : { error: PENALTY_NOT_FOUND };
29289
- }
29290
- function getTournamentPenalties({
29291
- tournamentRecord
29292
- }) {
29293
- if (!tournamentRecord)
29294
- return { error: MISSING_TOURNAMENT_RECORD };
29295
- const participants = tournamentRecord?.participants || [];
29296
- const allPenalties = participants.reduce((penalties, participant) => {
29297
- const { participantId } = participant;
29298
- (participant.penalties || []).forEach((penalty) => {
29299
- const { penaltyId } = penalty || {};
29300
- if (penalties[penaltyId]) {
29301
- penalties[penaltyId].participants.push(participantId);
29302
- } else {
29303
- penalties[penaltyId] = {
29304
- ...penalty,
29305
- participantIds: [participantId]
29306
- };
29307
- }
29308
- });
29309
- return penalties;
29310
- }, {});
29311
- return { penalties: Object.values(allPenalties) };
29312
- }
29313
- function modifyPenalty$1({
29314
- tournamentRecord,
29315
- modifications,
29316
- penaltyId
29317
- }) {
29318
- if (!tournamentRecord)
29319
- return { error: MISSING_TOURNAMENT_RECORD };
29320
- if (!modifications)
29321
- return { error: INVALID_VALUES, modifications };
29322
- if (!penaltyId)
29323
- return { error: MISSING_PENALTY_ID };
29324
- const participants = tournamentRecord?.participants || [];
29325
- const validAttributes = Object.keys(penaltyTemplate()).filter(
29326
- (attribute) => attribute !== "penaltyId"
29327
- );
29328
- const validModificationAttributes = Object.keys(modifications).filter(
29329
- (attribute) => validAttributes.includes(attribute)
29330
- );
29331
- if (!validModificationAttributes.length)
29332
- return { error: NO_VALID_ATTRIBUTES };
29333
- let updatedPenalty;
29334
- const modifiedParticipants = [];
29335
- participants.forEach((participant) => {
29336
- let participantModified = false;
29337
- participant.penalties = (participant.penalties || []).map((penalty) => {
29338
- if (penalty.penaltyId === penaltyId) {
29339
- participantModified = true;
29340
- validModificationAttributes.forEach(
29341
- (attribute) => Object.assign(penalty, { [attribute]: modifications[attribute] })
29342
- );
29343
- if (!updatedPenalty)
29344
- updatedPenalty = penalty;
29345
- }
29346
- return penalty;
29347
- });
29348
- if (participantModified)
29349
- modifiedParticipants.push(participant);
29350
- });
29351
- if (updatedPenalty) {
29352
- addNotice({
29353
- topic: MODIFY_PARTICIPANTS,
29354
- payload: {
29355
- tournamentId: tournamentRecord.tournamentId,
29356
- participants: modifiedParticipants
29357
- }
29358
- });
29359
- }
29360
- return updatedPenalty ? { ...SUCCESS, penalty: updatedPenalty } : { error: PENALTY_NOT_FOUND };
29361
- }
29362
-
29363
- function addPenalty(params) {
29364
- const { tournamentRecords, participantIds } = params;
29365
- let penaltyId;
29366
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29367
- const participants = getParticipants$1({
29368
- tournamentRecord
29369
- }).participants ?? [];
29370
- const tournamentParticipantIds = participants?.map(extractAttributes("participantId")).filter((participantId) => participantIds.includes(participantId));
29371
- if (tournamentParticipantIds.length) {
29372
- const result = addPenalty$1({
29373
- ...params,
29374
- penaltyId: params.penaltyId || penaltyId,
29375
- tournamentRecord,
29376
- participantIds: tournamentParticipantIds
29377
- });
29378
- penaltyId = result.penaltyId;
29379
- }
29380
- }
29381
- return penaltyId ? { ...SUCCESS, penaltyId } : { error: PARTICIPANT_NOT_FOUND };
29382
- }
29383
- function modifyPenalty(params) {
29384
- const { tournamentRecords } = params;
29385
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29386
- return { error: MISSING_TOURNAMENT_RECORDS };
29387
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29388
- const result = modifyPenalty$1({ tournamentRecord, ...params });
29389
- if (result.error && result.error !== PENALTY_NOT_FOUND)
29390
- return result;
29391
- }
29392
- return { ...SUCCESS };
29393
- }
29394
- function removePenalty(params) {
29395
- const { tournamentRecords } = params;
29396
- if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
29397
- return { error: MISSING_TOURNAMENT_RECORDS };
29398
- for (const tournamentRecord of Object.values(tournamentRecords)) {
29399
- const result = removePenalty$1({ tournamentRecord, ...params });
29400
- if (result.error && result.error !== PENALTY_NOT_FOUND)
29401
- return result;
28296
+ return { ...SUCCESS };
28297
+ }
28298
+ function removePenalty(params) {
28299
+ const { tournamentRecords } = params;
28300
+ if (typeof tournamentRecords !== "object" || !Object.keys(tournamentRecords).length)
28301
+ return { error: MISSING_TOURNAMENT_RECORDS };
28302
+ for (const tournamentRecord of Object.values(tournamentRecords)) {
28303
+ const result = removePenalty$1({ tournamentRecord, ...params });
28304
+ if (result.error && result.error !== PENALTY_NOT_FOUND)
28305
+ return result;
29402
28306
  }
29403
28307
  return { ...SUCCESS };
29404
28308
  }
@@ -31905,6 +30809,7 @@ function getEventMatchUpFormatTiming$1({
31905
30809
  if (!event)
31906
30810
  return { error: MISSING_EVENT };
31907
30811
  let matchUpFormatDefinitions = [];
30812
+ let info;
31908
30813
  if (!matchUpFormats?.length) {
31909
30814
  const { policy } = findPolicy({
31910
30815
  policyType: POLICY_TYPE_SCORING,
@@ -31918,20 +30823,19 @@ function getEventMatchUpFormatTiming$1({
31918
30823
  name: SCHEDULE_TIMING,
31919
30824
  event
31920
30825
  });
30826
+ let matchUpAverageTimes, matchUpRecoveryTimes;
31921
30827
  if (extension?.value) {
31922
- matchUpFormatDefinitions = unique(
31923
- [
31924
- ...(extension.value.matchUpAverageTimes || []).map(
31925
- (at) => at.matchUpFormatCodes
31926
- ),
31927
- ...(extension.value.matchUpRecoveryTimes || []).map(
31928
- (at) => at.matchUpFormatCodes
31929
- )
31930
- ].flat()
31931
- ).map((matchUpFormat) => ({ matchUpFormat }));
30828
+ ({ matchUpAverageTimes, matchUpRecoveryTimes } = extension.value);
31932
30829
  } else {
31933
- return { error: MISSING_SCORING_POLICY };
30830
+ ({ matchUpAverageTimes, matchUpRecoveryTimes } = POLICY_SCHEDULING_DEFAULT[POLICY_TYPE_SCHEDULING]);
31934
30831
  }
30832
+ matchUpFormatDefinitions = unique(
30833
+ [
30834
+ ...(matchUpAverageTimes || []).map((at) => at.matchUpFormatCodes),
30835
+ ...(matchUpRecoveryTimes || []).map((at) => at.matchUpFormatCodes)
30836
+ ].flat()
30837
+ ).map((matchUpFormat) => ({ matchUpFormat }));
30838
+ info = "default scheduling policy in use";
31935
30839
  }
31936
30840
  } else {
31937
30841
  const uniqueMatchUpFormats = [];
@@ -31946,7 +30850,7 @@ function getEventMatchUpFormatTiming$1({
31946
30850
  }).filter(Boolean);
31947
30851
  }
31948
30852
  const { eventType, eventId, category } = event;
31949
- const categoryName = category?.categoryName || category?.ageCategoryCode || eventId;
30853
+ const categoryName = category?.categoryName ?? category?.ageCategoryCode ?? eventId;
31950
30854
  if (!eventId)
31951
30855
  return { error: MISSING_EVENT };
31952
30856
  const eventMatchUpFormatTiming = matchUpFormatDefinitions.map(
@@ -31959,17 +30863,14 @@ function getEventMatchUpFormatTiming$1({
31959
30863
  eventType,
31960
30864
  event
31961
30865
  });
31962
- return Object.assign(
31963
- {},
31964
- {
31965
- ...timing,
31966
- description,
31967
- matchUpFormat
31968
- }
31969
- );
30866
+ return {
30867
+ matchUpFormat,
30868
+ description,
30869
+ ...timing
30870
+ };
31970
30871
  }
31971
30872
  );
31972
- return { eventMatchUpFormatTiming };
30873
+ return definedAttributes({ eventMatchUpFormatTiming, info });
31973
30874
  }
31974
30875
 
31975
30876
  function getEventMatchUpFormatTiming({
@@ -33233,6 +32134,14 @@ function modifyParticipantMatchUpsCount({
33233
32134
  });
33234
32135
  }
33235
32136
 
32137
+ const hasSchedule = ({
32138
+ scheduleAttributes = ["scheduledDate", "scheduledTime"],
32139
+ schedule = {}
32140
+ }) => {
32141
+ const matchUpScheduleKeys = Object.keys(schedule).filter((key) => scheduleAttributes.includes(key)).filter((key) => schedule[key]);
32142
+ return !!matchUpScheduleKeys.length;
32143
+ };
32144
+
33236
32145
  function processAlreadyScheduledMatchUps({
33237
32146
  matchUpPotentialParticipantIds,
33238
32147
  individualParticipantProfiles,
@@ -36924,14 +35833,12 @@ function getParticipantScaleItem$1({
36924
35833
  policyDefinitions,
36925
35834
  scaleAttributes,
36926
35835
  participantId,
36927
- inContext,
36928
35836
  personId
36929
35837
  }) {
36930
35838
  let result = publicFindParticipant({
36931
35839
  tournamentRecords,
36932
35840
  policyDefinitions,
36933
35841
  participantId,
36934
- inContext,
36935
35842
  personId
36936
35843
  });
36937
35844
  if (result.error)
@@ -50096,496 +49003,1590 @@ function clearHistory({ matchUp }) {
50096
49003
  return saveHistory({ matchUp });
50097
49004
  }
50098
49005
 
50099
- function addPoint({ matchUp, point }) {
50100
- if (!point)
50101
- return { error: MISSING_VALUE };
50102
- if (typeof point !== "object")
50103
- return { error: INVALID_VALUES, context: { point } };
50104
- const { history = [] } = getHistory({ matchUp });
50105
- history.push(point);
50106
- return saveHistory({ matchUp, history });
49006
+ function addPoint({ matchUp, point }) {
49007
+ if (!point)
49008
+ return { error: MISSING_VALUE };
49009
+ if (typeof point !== "object")
49010
+ return { error: INVALID_VALUES, context: { point } };
49011
+ const { history = [] } = getHistory({ matchUp });
49012
+ history.push(point);
49013
+ return saveHistory({ matchUp, history });
49014
+ }
49015
+
49016
+ function addGame({ matchUp, game }) {
49017
+ if (typeof game !== "object")
49018
+ return { error: INVALID_VALUES, context: { game } };
49019
+ const { history = [] } = getHistory({ matchUp });
49020
+ history.push(game);
49021
+ return saveHistory({ matchUp, history });
49022
+ }
49023
+
49024
+ function addShot({ matchUp, shot }) {
49025
+ if (typeof shot !== "object")
49026
+ return { error: MISSING_VALUE };
49027
+ const { history = [] } = getHistory({ matchUp });
49028
+ history.push(shot);
49029
+ return saveHistory({ matchUp, history });
49030
+ }
49031
+
49032
+ function addSet({ matchUp, set }) {
49033
+ if (typeof set !== "object")
49034
+ return { error: MISSING_VALUE };
49035
+ const { history = [] } = getHistory({ matchUp });
49036
+ history.push(set);
49037
+ return saveHistory({ matchUp, history });
49038
+ }
49039
+
49040
+ function redo({ matchUp }) {
49041
+ const { history = [], undoHistory = [] } = getHistory({ matchUp });
49042
+ if (undoHistory.length)
49043
+ history.push(undoHistory.pop());
49044
+ return saveHistory({ matchUp, history, undoHistory });
49045
+ }
49046
+
49047
+ function undo({ matchUp }) {
49048
+ const { history = [], undoHistory = [] } = getHistory({ matchUp });
49049
+ undoHistory.push(history.pop());
49050
+ return saveHistory({ matchUp, history, undoHistory });
49051
+ }
49052
+
49053
+ const umo = {
49054
+ scoreboard: () => {
49055
+ },
49056
+ addPoints: () => {
49057
+ },
49058
+ addPoint: () => {
49059
+ }
49060
+ };
49061
+
49062
+ const historyGovernor = {
49063
+ calculateHistoryScore,
49064
+ setServingSide,
49065
+ clearHistory,
49066
+ addPoint,
49067
+ addGame,
49068
+ addShot,
49069
+ addSet,
49070
+ redo,
49071
+ undo,
49072
+ umo
49073
+ };
49074
+
49075
+ function analyzeMatchUp(params) {
49076
+ const { matchUp, sideNumber, setNumber, isTiebreakValue, isPointValue } = params || {};
49077
+ let { matchUpFormat } = params || {};
49078
+ if (!matchUp)
49079
+ return { error: MISSING_MATCHUP };
49080
+ matchUpFormat = matchUpFormat || matchUp?.matchUpFormat;
49081
+ const matchUpScoringFormat = parse(matchUpFormat);
49082
+ const isCompletedMatchUp = !!matchUp?.winningSide;
49083
+ const sets = matchUp.score?.sets;
49084
+ const setsCount = sets?.length;
49085
+ const setIndex = setNumber && setNumber - 1;
49086
+ const isExistingSet = !!sets?.find(
49087
+ (set, index) => set.setNumber === setNumber && index === setIndex
49088
+ );
49089
+ const completedSets = sets?.filter((set) => set?.winningSide) || [];
49090
+ const completedSetsCount = completedSets?.length || 0;
49091
+ const setsFollowingCurrent = setNumber && sets?.slice(setNumber) || [];
49092
+ const isLastSetWithValues = !!(setsCount && setNumber && // EVERY: is this a candidate for .every?
49093
+ setsFollowingCurrent?.reduce((noValues, set) => {
49094
+ return (!set || !set.side1Score && !set.side2Score && !set.side1TiebreakScore && !set.side2TiebreakScore && !set.side1PointScore && !set.side2PointScore) && noValues;
49095
+ }, true));
49096
+ const setObject = setNumber <= setsCount && sets.find((set) => set.setNumber === setNumber);
49097
+ const specifiedSetAnalysis = setObject && analyzeSet({ setObject, matchUpScoringFormat });
49098
+ const {
49099
+ isCompletedSet,
49100
+ sideGameScores,
49101
+ // sidePointScores,
49102
+ sideTiebreakScores
49103
+ } = specifiedSetAnalysis || {};
49104
+ const isActiveSet = !!(setObject && !isCompletedSet && isLastSetWithValues || setNumber && setNumber === setsCount + 1 && !isCompletedMatchUp);
49105
+ const isValidSideNumber = [1, 2].includes(sideNumber);
49106
+ const sideIndex = isValidSideNumber ? sideNumber - 1 : 0;
49107
+ const existingValue = setObject && isValidSideNumber && (!isTiebreakValue && !isPointValue && sideGameScores[sideIndex] !== void 0 && sideGameScores[sideIndex] || isTiebreakValue && sideTiebreakScores[sideIndex] !== void 0 && sideTiebreakScores[sideIndex]);
49108
+ const hasExistingValue = !!existingValue;
49109
+ const completedSetsHaveValidOutcomes = completedSets?.map(
49110
+ (setObject2) => analyzeSet({ setObject: setObject2, matchUpScoringFormat }).isValidSetOutcome
49111
+ ).reduce((valid, validOutcome) => valid && validOutcome, true);
49112
+ const setsWinCounts = completedSets.reduce(
49113
+ (counts, set) => {
49114
+ const { winningSide } = set;
49115
+ const winningSideIndex = winningSide - 1;
49116
+ counts[winningSideIndex]++;
49117
+ return counts;
49118
+ },
49119
+ [0, 0]
49120
+ );
49121
+ const matchUpWinningSide = matchUp?.winningSide;
49122
+ const matchUpWinningSideIndex = matchUpWinningSide && matchUpWinningSide - 1;
49123
+ const matchUpLosingSideIndex = 1 - matchUpWinningSideIndex;
49124
+ const winningSideSetsCount = setsWinCounts[matchUpWinningSideIndex];
49125
+ const losingSideSetsCount = setsWinCounts[matchUpLosingSideIndex];
49126
+ const maxSetsCount = Math.max(...setsWinCounts);
49127
+ const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
49128
+ const { bestOf } = matchUpScoringFormat || {};
49129
+ const setsToWin = bestOf && Math.ceil(bestOf / 2) || 1;
49130
+ const calculatedWinningSide = maxSetsCount === setsToWin && maxSetsInstances === 1 && setsWinCounts.indexOf(maxSetsCount) + 1 || void 0;
49131
+ const validMatchUpWinningSide = winningSideSetsCount > losingSideSetsCount && matchUpWinningSide === calculatedWinningSide;
49132
+ const validMatchUpOutcome = calculatedWinningSide && completedSetsHaveValidOutcomes && validMatchUpWinningSide;
49133
+ return {
49134
+ completedSetsHaveValidOutcomes,
49135
+ validMatchUpWinningSide,
49136
+ calculatedWinningSide,
49137
+ matchUpScoringFormat,
49138
+ validMatchUpOutcome,
49139
+ isLastSetWithValues,
49140
+ completedSetsCount,
49141
+ isCompletedMatchUp,
49142
+ isValidSideNumber,
49143
+ hasExistingValue,
49144
+ existingValue,
49145
+ isExistingSet,
49146
+ isActiveSet,
49147
+ ...specifiedSetAnalysis
49148
+ };
49149
+ }
49150
+
49151
+ const queryGovernor$1 = {
49152
+ tallyParticipantResults,
49153
+ matchUpIsComplete,
49154
+ analyzeMatchUp,
49155
+ getMatchUpType,
49156
+ scoreHasValue,
49157
+ validMatchUps,
49158
+ validMatchUp
49159
+ };
49160
+
49161
+ let keyedMatchUps = {};
49162
+ let matchUpId;
49163
+ function setState$2(value, deepCopyOption = true) {
49164
+ if (!value)
49165
+ return { error: MISSING_VALUE };
49166
+ if (typeof value !== "object")
49167
+ return { error: INVALID_OBJECT };
49168
+ if (value.matchUpId) {
49169
+ matchUpId = value.matchUpId;
49170
+ keyedMatchUps[matchUpId] = deepCopyOption ? makeDeepCopy(value) : value;
49171
+ } else if (Array.isArray(value)) {
49172
+ for (const m of value.reverse()) {
49173
+ if (m.matchUpId) {
49174
+ keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
49175
+ if (!matchUpId)
49176
+ matchUpId = m.matchUpId;
49177
+ }
49178
+ }
49179
+ } else {
49180
+ for (const m of Object.values(value)) {
49181
+ if (m.matchUpId) {
49182
+ keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
49183
+ if (!matchUpId)
49184
+ matchUpId = m.matchUpId;
49185
+ }
49186
+ }
49187
+ }
49188
+ return deepCopyOption ? makeDeepCopy(value) : value;
49189
+ }
49190
+ function getMatchUp() {
49191
+ return keyedMatchUps[matchUpId];
49192
+ }
49193
+ function getMatchUps() {
49194
+ return Object.values(keyedMatchUps);
49195
+ }
49196
+ function reset() {
49197
+ matchUpId = void 0;
49198
+ keyedMatchUps = {};
49199
+ }
49200
+ function getState$2(params) {
49201
+ return makeDeepCopy(
49202
+ keyedMatchUps[matchUpId],
49203
+ params?.convertExtensions,
49204
+ false,
49205
+ params?.removeExtensions
49206
+ );
49207
+ }
49208
+
49209
+ const matchUpEngine = (() => {
49210
+ const engine = {
49211
+ getState: (params) => getState$2(params),
49212
+ version: () => factoryVersion(),
49213
+ reset: () => {
49214
+ reset();
49215
+ return { ...SUCCESS };
49216
+ },
49217
+ drawId: void 0,
49218
+ error: void 0,
49219
+ success: false,
49220
+ devContext: (contextCriteria) => {
49221
+ setDevContext(contextCriteria);
49222
+ return engine;
49223
+ },
49224
+ setState: (definition, deepCopyOption, deepCopyAttributes) => {
49225
+ setDeepCopy(deepCopyOption, deepCopyAttributes);
49226
+ const result = setState$2(definition);
49227
+ return processResult(result);
49228
+ }
49229
+ };
49230
+ function processResult(result) {
49231
+ if (result?.error) {
49232
+ engine.error = result.error;
49233
+ engine.success = false;
49234
+ } else {
49235
+ engine.error = void 0;
49236
+ engine.success = true;
49237
+ engine.drawId = result.drawId;
49238
+ }
49239
+ return engine;
49240
+ }
49241
+ importGovernors([
49242
+ tieFormatGovernor,
49243
+ historyGovernor,
49244
+ queryGovernor$1,
49245
+ scoreGovernor
49246
+ ]);
49247
+ return engine;
49248
+ function importGovernors(governors) {
49249
+ governors.forEach((governor) => {
49250
+ Object.keys(governor).forEach((methodName) => {
49251
+ engine[methodName] = (params) => {
49252
+ if (getDevContext()) {
49253
+ return invoke({ params, governor, methodName });
49254
+ } else {
49255
+ try {
49256
+ return invoke({ params, governor, methodName });
49257
+ } catch (err) {
49258
+ handleCaughtError({
49259
+ engineName: "matchUpEngine",
49260
+ methodName,
49261
+ params,
49262
+ err
49263
+ });
49264
+ }
49265
+ }
49266
+ };
49267
+ });
49268
+ });
49269
+ }
49270
+ function invoke({ params, governor, methodName }) {
49271
+ engine.error = void 0;
49272
+ engine.success = false;
49273
+ const matchUp = params?.matchUp || getMatchUp();
49274
+ const matchUps = params?.matchUps || getMatchUps();
49275
+ const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
49276
+ params = {
49277
+ ...params,
49278
+ matchUpId: matchUp?.matchUpId,
49279
+ matchUps,
49280
+ matchUp
49281
+ };
49282
+ const result = governor[methodName](params);
49283
+ if (result?.error) {
49284
+ if (snapshot)
49285
+ setState$2(snapshot);
49286
+ return { ...result, rolledBack: !!snapshot };
49287
+ }
49288
+ const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
49289
+ if (notify)
49290
+ notifySubscribers();
49291
+ if (notify || !result?.success || params?.doNotNotify)
49292
+ deleteNotices();
49293
+ return result;
49294
+ }
49295
+ })();
49296
+
49297
+ function matchUpEngineAsync(test) {
49298
+ const result = createInstanceState();
49299
+ if (result.error && !test)
49300
+ return result;
49301
+ const engine = {
49302
+ getState: (params) => getState$2(params),
49303
+ version: () => factoryVersion(),
49304
+ reset: () => {
49305
+ reset();
49306
+ return { ...SUCCESS };
49307
+ },
49308
+ drawId: void 0,
49309
+ error: void 0,
49310
+ success: false,
49311
+ devContext: (contextCriteria) => {
49312
+ setDevContext(contextCriteria);
49313
+ return engine;
49314
+ },
49315
+ setState: (definition, deepCopyOption, deepCopyAttributes) => {
49316
+ setDeepCopy(deepCopyOption, deepCopyAttributes);
49317
+ const result2 = setState$2(definition);
49318
+ return processResult(result2);
49319
+ }
49320
+ };
49321
+ function processResult(result2) {
49322
+ if (result2?.error) {
49323
+ engine.error = result2.error;
49324
+ engine.success = false;
49325
+ } else {
49326
+ engine.error = void 0;
49327
+ engine.success = true;
49328
+ engine.drawId = result2.drawId;
49329
+ }
49330
+ return engine;
49331
+ }
49332
+ importGovernors([
49333
+ tieFormatGovernor,
49334
+ historyGovernor,
49335
+ queryGovernor$1,
49336
+ scoreGovernor
49337
+ ]);
49338
+ return engine;
49339
+ async function importGovernors(governors) {
49340
+ for (const governor of governors) {
49341
+ const governorMethods = Object.keys(governor);
49342
+ for (const methodName of governorMethods) {
49343
+ engine[methodName] = async (params) => {
49344
+ if (getDevContext()) {
49345
+ return await invoke({ params, governor, methodName });
49346
+ } else {
49347
+ try {
49348
+ return await invoke({ params, governor, methodName });
49349
+ } catch (err) {
49350
+ handleCaughtError({
49351
+ engineName: "matchUpEngine",
49352
+ methodName,
49353
+ params,
49354
+ err
49355
+ });
49356
+ }
49357
+ }
49358
+ };
49359
+ }
49360
+ }
49361
+ }
49362
+ async function invoke({ params, governor, methodName }) {
49363
+ engine.success = false;
49364
+ engine.error = void 0;
49365
+ const matchUp = params?.matchUp || getMatchUp();
49366
+ const matchUps = params?.matchUps || getMatchUps();
49367
+ const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
49368
+ params = {
49369
+ ...params,
49370
+ matchUpId: matchUp?.matchUpId,
49371
+ matchUps,
49372
+ matchUp
49373
+ };
49374
+ const result2 = governor[methodName](params);
49375
+ if (result2?.error) {
49376
+ if (snapshot)
49377
+ setState$2(snapshot);
49378
+ return { ...result2, rolledBack: !!snapshot };
49379
+ }
49380
+ const notify = result2?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
49381
+ if (notify)
49382
+ await notifySubscribersAsync();
49383
+ if (notify || !result2?.success || params?.doNotNotify)
49384
+ deleteNotices();
49385
+ return result2;
49386
+ }
49387
+ }
49388
+
49389
+ function newTournamentRecord(params) {
49390
+ const attributes = params || {};
49391
+ if (!attributes.tournamentId)
49392
+ attributes.tournamentId = UUID();
49393
+ if (attributes.startDate && !isISODateString(attributes.startDate) && !validDateString.test(attributes.startDate)) {
49394
+ return { error: INVALID_DATE };
49395
+ }
49396
+ if (attributes.endDate && !isISODateString(attributes.endDate) && !validDateString.test(attributes.endDate)) {
49397
+ return { error: INVALID_DATE };
49398
+ }
49399
+ if (attributes.extensions) {
49400
+ attributes.extensions = attributes.extensions.filter(isValidExtension);
49401
+ }
49402
+ return { ...attributes };
49403
+ }
49404
+
49405
+ function setState$1(tournament, deepCopyOption) {
49406
+ if (typeof tournament !== "object")
49407
+ return { error: INVALID_OBJECT };
49408
+ const tournamentId = tournament.unifiedTournamentId?.tournamentId || tournament.tournamentId;
49409
+ if (!tournamentId)
49410
+ return { error: MISSING_TOURNAMENT_ID };
49411
+ const tournamentRecord = deepCopyOption !== false ? makeDeepCopy(tournament) : tournament;
49412
+ setTournamentRecords({ [tournamentId]: tournamentRecord });
49413
+ setTournamentId(tournamentId);
49414
+ return tournamentRecord;
49415
+ }
49416
+ function getState$1({
49417
+ convertExtensions = false,
49418
+ removeExtensions = false,
49419
+ tournamentId
49420
+ }) {
49421
+ if (typeof tournamentId !== "string")
49422
+ return {};
49423
+ const tournamentRecord = getTournamentRecord(tournamentId);
49424
+ return {
49425
+ tournamentRecord: makeDeepCopy(
49426
+ tournamentRecord,
49427
+ convertExtensions,
49428
+ false,
49429
+ removeExtensions
49430
+ )
49431
+ };
49432
+ }
49433
+ function paramsMiddleware$1(tournamentRecord, params, prefetch) {
49434
+ if (params) {
49435
+ const drawId = params.drawId || params.matchUp?.drawId;
49436
+ if (drawId) {
49437
+ const { event, drawDefinition } = findEvent({
49438
+ tournamentRecord,
49439
+ drawId
49440
+ });
49441
+ params = {
49442
+ ...params,
49443
+ event,
49444
+ drawDefinition
49445
+ };
49446
+ if (prefetch) {
49447
+ const matchUpsMap = getMatchUpsMap({ drawDefinition });
49448
+ const { matchUps: inContextDrawMatchUps } = getAllDrawMatchUps({
49449
+ inContext: true,
49450
+ drawDefinition,
49451
+ matchUpsMap
49452
+ });
49453
+ params.matchUpsMap = matchUpsMap;
49454
+ params.inContextDrawMatchUps = inContextDrawMatchUps;
49455
+ }
49456
+ }
49457
+ if (params.eventId && !params.event) {
49458
+ const { event } = findEvent({
49459
+ eventId: params.eventId,
49460
+ tournamentRecord
49461
+ });
49462
+ if (event) {
49463
+ params = { ...params, event };
49464
+ }
49465
+ }
49466
+ }
49467
+ return params;
49468
+ }
49469
+
49470
+ function getEligibleVoluntaryConsolationParticipants(params) {
49471
+ if (!params.tournamentRecord)
49472
+ return { error: MISSING_TOURNAMENT_RECORD };
49473
+ return getEligibleVoluntaryConsolationParticipants$1(params);
50107
49474
  }
50108
49475
 
50109
- function addGame({ matchUp, game }) {
50110
- if (typeof game !== "object")
50111
- return { error: INVALID_VALUES, context: { game } };
50112
- const { history = [] } = getHistory({ matchUp });
50113
- history.push(game);
50114
- return saveHistory({ matchUp, history });
49476
+ function getParticipantEventDetails({
49477
+ tournamentRecord,
49478
+ participantId
49479
+ }) {
49480
+ if (!tournamentRecord)
49481
+ return { error: MISSING_TOURNAMENT_RECORD };
49482
+ if (!participantId)
49483
+ return { error: MISSING_PARTICIPANT_ID };
49484
+ const relevantParticipantIds = [participantId].concat(
49485
+ (tournamentRecord.participants || []).filter(
49486
+ (participant) => participant?.participantType && [TEAM, PAIR].includes(participant.participantType) && participant.individualParticipantIds?.includes(participantId)
49487
+ ).map((participant) => participant.participantId)
49488
+ );
49489
+ const relevantEvents = (tournamentRecord.events || []).filter((event) => {
49490
+ const enteredParticipantIds = (event?.entries || []).map(
49491
+ (entry) => entry.participantId
49492
+ );
49493
+ return overlap(enteredParticipantIds, relevantParticipantIds);
49494
+ }).map((event) => ({ eventName: event.eventName, eventId: event.eventId }));
49495
+ return { eventDetails: relevantEvents };
50115
49496
  }
50116
49497
 
50117
- function addShot({ matchUp, shot }) {
50118
- if (typeof shot !== "object")
50119
- return { error: MISSING_VALUE };
50120
- const { history = [] } = getHistory({ matchUp });
50121
- history.push(shot);
50122
- return saveHistory({ matchUp, history });
49498
+ function getDerivedPositionAssignments({
49499
+ derivedDrawInfo,
49500
+ participantId,
49501
+ drawId
49502
+ }) {
49503
+ const mainPositionAssignment = derivedDrawInfo[drawId]?.mainPositionAssignments?.find(
49504
+ (assignment) => assignment.participantId === participantId
49505
+ );
49506
+ const qualifyingPositionAssignment = derivedDrawInfo[drawId]?.qualifyingPositionAssignments?.find(
49507
+ (assignment) => assignment.participantId === participantId
49508
+ );
49509
+ const positionAssignments = {};
49510
+ if (mainPositionAssignment) {
49511
+ const { participantId: participantId2, ...props } = mainPositionAssignment;
49512
+ if (participantId2)
49513
+ positionAssignments[MAIN] = { ...props };
49514
+ }
49515
+ if (qualifyingPositionAssignment) {
49516
+ const { participantId: participantId2, ...props } = qualifyingPositionAssignment;
49517
+ if (participantId2)
49518
+ positionAssignments[QUALIFYING] = { ...props };
49519
+ }
49520
+ return Object.keys(positionAssignments).length ? positionAssignments : void 0;
50123
49521
  }
50124
49522
 
50125
- function addSet({ matchUp, set }) {
50126
- if (typeof set !== "object")
50127
- return { error: MISSING_VALUE };
50128
- const { history = [] } = getHistory({ matchUp });
50129
- history.push(set);
50130
- return saveHistory({ matchUp, history });
49523
+ function getRelevantParticipantIdsMap({
49524
+ processParticipantId,
49525
+ // optional method which is passed each participantId
49526
+ tournamentRecords,
49527
+ tournamentRecord
49528
+ }) {
49529
+ if (typeof tournamentRecord !== "object" && typeof tournamentRecords !== "object")
49530
+ return { error: MISSING_TOURNAMENT_RECORD };
49531
+ const allParticipants = tournamentRecords ? Object.values(tournamentRecords).map((tournamentRecord2) => tournamentRecord2?.participants || []).flat() : tournamentRecord?.participants || [];
49532
+ const relevantParticipantIdsMap = Object.assign(
49533
+ {},
49534
+ ...allParticipants.map(
49535
+ ({ participantId, participantType, individualParticipantIds }) => {
49536
+ typeof processParticipantId === "function" && processParticipantId(participantId);
49537
+ const individualParticipantIdObjects = (individualParticipantIds || []).map((relevantParticipantId) => ({
49538
+ participantType: INDIVIDUAL,
49539
+ relevantParticipantId
49540
+ }));
49541
+ return {
49542
+ [participantId]: individualParticipantIdObjects.concat({
49543
+ relevantParticipantId: participantId,
49544
+ participantType
49545
+ })
49546
+ };
49547
+ }
49548
+ )
49549
+ );
49550
+ return { relevantParticipantIdsMap };
50131
49551
  }
50132
49552
 
50133
- function redo({ matchUp }) {
50134
- const { history = [], undoHistory = [] } = getHistory({ matchUp });
50135
- if (undoHistory.length)
50136
- history.push(undoHistory.pop());
50137
- return saveHistory({ matchUp, history, undoHistory });
49553
+ function getDerivedSeedAssignments({
49554
+ derivedDrawInfo,
49555
+ participantId,
49556
+ drawId
49557
+ }) {
49558
+ const mainSeedAssignment = derivedDrawInfo[drawId]?.mainSeedAssignments?.find(
49559
+ (assignment) => assignment.participantId === participantId
49560
+ );
49561
+ const qualifyingSeedAssignment = derivedDrawInfo[drawId]?.qualifyingSeedAssignments?.find(
49562
+ (assignment) => assignment.participantId === participantId
49563
+ );
49564
+ const seedAssignments = {};
49565
+ if (mainSeedAssignment) {
49566
+ const { participantId: participantId2, ...props } = mainSeedAssignment;
49567
+ if (participantId2)
49568
+ seedAssignments[MAIN] = { ...props };
49569
+ }
49570
+ if (qualifyingSeedAssignment) {
49571
+ const { participantId: participantId2, ...props } = qualifyingSeedAssignment;
49572
+ if (participantId2)
49573
+ seedAssignments[QUALIFYING] = { ...props };
49574
+ }
49575
+ return Object.keys(seedAssignments).length ? seedAssignments : void 0;
50138
49576
  }
50139
49577
 
50140
- function undo({ matchUp }) {
50141
- const { history = [], undoHistory = [] } = getHistory({ matchUp });
50142
- undoHistory.push(history.pop());
50143
- return saveHistory({ matchUp, history, undoHistory });
49578
+ function participantScheduledMatchUps({
49579
+ scheduleAttributes = ["scheduledDate", "scheduledTime"],
49580
+ matchUps = []
49581
+ }) {
49582
+ if (!validMatchUps(matchUps))
49583
+ return { error: MISSING_MATCHUPS };
49584
+ if (!Array.isArray(scheduleAttributes))
49585
+ return { error: INVALID_VALUES };
49586
+ const scheduledMatchUps = matchUps.filter(Boolean).filter(({ schedule }) => hasSchedule({ schedule, scheduleAttributes })).reduce((dateMatchUps, matchUp) => {
49587
+ const { schedule } = matchUp;
49588
+ const date = extractDate(schedule?.scheduledDate);
49589
+ const time = extractTime(schedule?.scheduledTime);
49590
+ if (date && time) {
49591
+ if (dateMatchUps[date]) {
49592
+ dateMatchUps[date].push(matchUp);
49593
+ } else {
49594
+ dateMatchUps[date] = [matchUp];
49595
+ }
49596
+ }
49597
+ return dateMatchUps;
49598
+ }, {});
49599
+ const dates = Object.keys(scheduledMatchUps);
49600
+ dates.forEach((date) => {
49601
+ scheduledMatchUps[date].sort(
49602
+ (a, b) => timeSort(
49603
+ extractTime(a.schedule?.scheduledTime),
49604
+ extractTime(b.schedule?.scheduledTime)
49605
+ )
49606
+ );
49607
+ });
49608
+ return { scheduledMatchUps };
50144
49609
  }
50145
49610
 
50146
- const umo = {
50147
- scoreboard: () => {
50148
- },
50149
- addPoints: () => {
50150
- },
50151
- addPoint: () => {
49611
+ function annotateParticipant(params) {
49612
+ const {
49613
+ withScaleValues = true,
49614
+ eventsPublishStatuses,
49615
+ withEvents = true,
49616
+ withDraws = true,
49617
+ participantIdMap,
49618
+ scheduleAnalysis,
49619
+ derivedDrawInfo,
49620
+ usePublishState,
49621
+ withStatistics,
49622
+ withOpponents,
49623
+ withMatchUps,
49624
+ withSeeding,
49625
+ participant,
49626
+ withISO2,
49627
+ withIOC
49628
+ } = params;
49629
+ const scheduleConflicts = [];
49630
+ const scheduleItems = [];
49631
+ if (withIOC || withISO2)
49632
+ addNationalityCode({ participant, withIOC, withISO2 });
49633
+ if (withScaleValues) {
49634
+ const { ratings, rankings } = getScaleValues({ participant });
49635
+ participant.rankings = rankings;
49636
+ participant.ratings = ratings;
50152
49637
  }
50153
- };
50154
-
50155
- const historyGovernor = {
50156
- calculateHistoryScore,
50157
- setServingSide,
50158
- clearHistory,
50159
- addPoint,
50160
- addGame,
50161
- addShot,
50162
- addSet,
50163
- redo,
50164
- undo,
50165
- umo
50166
- };
50167
-
50168
- function analyzeMatchUp(params) {
50169
- const { matchUp, sideNumber, setNumber, isTiebreakValue, isPointValue } = params || {};
50170
- let { matchUpFormat } = params || {};
50171
- if (!matchUp)
50172
- return { error: MISSING_MATCHUP };
50173
- matchUpFormat = matchUpFormat || matchUp?.matchUpFormat;
50174
- const matchUpScoringFormat = parse(matchUpFormat);
50175
- const isCompletedMatchUp = !!matchUp?.winningSide;
50176
- const sets = matchUp.score?.sets;
50177
- const setsCount = sets?.length;
50178
- const setIndex = setNumber && setNumber - 1;
50179
- const isExistingSet = !!sets?.find(
50180
- (set, index) => set.setNumber === setNumber && index === setIndex
50181
- );
50182
- const completedSets = sets?.filter((set) => set?.winningSide) || [];
50183
- const completedSetsCount = completedSets?.length || 0;
50184
- const setsFollowingCurrent = setNumber && sets?.slice(setNumber) || [];
50185
- const isLastSetWithValues = !!(setsCount && setNumber && // EVERY: is this a candidate for .every?
50186
- setsFollowingCurrent?.reduce((noValues, set) => {
50187
- return (!set || !set.side1Score && !set.side2Score && !set.side1TiebreakScore && !set.side2TiebreakScore && !set.side1PointScore && !set.side2PointScore) && noValues;
50188
- }, true));
50189
- const setObject = setNumber <= setsCount && sets.find((set) => set.setNumber === setNumber);
50190
- const specifiedSetAnalysis = setObject && analyzeSet({ setObject, matchUpScoringFormat });
49638
+ const participantId = participant?.participantId;
49639
+ if (!participantId || !participantIdMap[participantId])
49640
+ return {};
50191
49641
  const {
50192
- isCompletedSet,
50193
- sideGameScores,
50194
- // sidePointScores,
50195
- sideTiebreakScores
50196
- } = specifiedSetAnalysis || {};
50197
- const isActiveSet = !!(setObject && !isCompletedSet && isLastSetWithValues || setNumber && setNumber === setsCount + 1 && !isCompletedMatchUp);
50198
- const isValidSideNumber = [1, 2].includes(sideNumber);
50199
- const sideIndex = isValidSideNumber ? sideNumber - 1 : 0;
50200
- const existingValue = setObject && isValidSideNumber && (!isTiebreakValue && !isPointValue && sideGameScores[sideIndex] !== void 0 && sideGameScores[sideIndex] || isTiebreakValue && sideTiebreakScores[sideIndex] !== void 0 && sideTiebreakScores[sideIndex]);
50201
- const hasExistingValue = !!existingValue;
50202
- const completedSetsHaveValidOutcomes = completedSets?.map(
50203
- (setObject2) => analyzeSet({ setObject: setObject2, matchUpScoringFormat }).isValidSetOutcome
50204
- ).reduce((valid, validOutcome) => valid && validOutcome, true);
50205
- const setsWinCounts = completedSets.reduce(
50206
- (counts, set) => {
50207
- const { winningSide } = set;
50208
- const winningSideIndex = winningSide - 1;
50209
- counts[winningSideIndex]++;
50210
- return counts;
50211
- },
50212
- [0, 0]
50213
- );
50214
- const matchUpWinningSide = matchUp?.winningSide;
50215
- const matchUpWinningSideIndex = matchUpWinningSide && matchUpWinningSide - 1;
50216
- const matchUpLosingSideIndex = 1 - matchUpWinningSideIndex;
50217
- const winningSideSetsCount = setsWinCounts[matchUpWinningSideIndex];
50218
- const losingSideSetsCount = setsWinCounts[matchUpLosingSideIndex];
50219
- const maxSetsCount = Math.max(...setsWinCounts);
50220
- const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
50221
- const { bestOf } = matchUpScoringFormat || {};
50222
- const setsToWin = bestOf && Math.ceil(bestOf / 2) || 1;
50223
- const calculatedWinningSide = maxSetsCount === setsToWin && maxSetsInstances === 1 && setsWinCounts.indexOf(maxSetsCount) + 1 || void 0;
50224
- const validMatchUpWinningSide = winningSideSetsCount > losingSideSetsCount && matchUpWinningSide === calculatedWinningSide;
50225
- const validMatchUpOutcome = calculatedWinningSide && completedSetsHaveValidOutcomes && validMatchUpWinningSide;
50226
- return {
50227
- completedSetsHaveValidOutcomes,
50228
- validMatchUpWinningSide,
50229
- calculatedWinningSide,
50230
- matchUpScoringFormat,
50231
- validMatchUpOutcome,
50232
- isLastSetWithValues,
50233
- completedSetsCount,
50234
- isCompletedMatchUp,
50235
- isValidSideNumber,
50236
- hasExistingValue,
50237
- existingValue,
50238
- isExistingSet,
50239
- isActiveSet,
50240
- ...specifiedSetAnalysis
49642
+ potentialMatchUps,
49643
+ opponents,
49644
+ matchUps,
49645
+ events,
49646
+ losses,
49647
+ draws,
49648
+ wins
49649
+ } = participantIdMap[participantId];
49650
+ const denominator = wins + losses;
49651
+ const numerator = wins;
49652
+ const statValue = denominator && numerator / denominator;
49653
+ const winRatioStat = {
49654
+ statCode: WIN_RATIO$1,
49655
+ denominator,
49656
+ numerator,
49657
+ statValue
50241
49658
  };
50242
- }
50243
-
50244
- const queryGovernor$1 = {
50245
- tallyParticipantResults,
50246
- matchUpIsComplete,
50247
- analyzeMatchUp,
50248
- getMatchUpType,
50249
- scoreHasValue,
50250
- validMatchUps,
50251
- validMatchUp
50252
- };
50253
-
50254
- let keyedMatchUps = {};
50255
- let matchUpId;
50256
- function setState$2(value, deepCopyOption = true) {
50257
- if (!value)
50258
- return { error: MISSING_VALUE };
50259
- if (typeof value !== "object")
50260
- return { error: INVALID_OBJECT };
50261
- if (value.matchUpId) {
50262
- matchUpId = value.matchUpId;
50263
- keyedMatchUps[matchUpId] = deepCopyOption ? makeDeepCopy(value) : value;
50264
- } else if (Array.isArray(value)) {
50265
- for (const m of value.reverse()) {
50266
- if (m.matchUpId) {
50267
- keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
50268
- if (!matchUpId)
50269
- matchUpId = m.matchUpId;
49659
+ const participantDraws = Object.values(draws);
49660
+ const participantEvents = Object.values(events);
49661
+ if (withDraws && participantDraws) {
49662
+ participant.draws = participantDraws;
49663
+ for (const participantDraw of participantDraws) {
49664
+ const publishedSeeding = eventsPublishStatuses[participantDraw.eventId]?.publishedSeeding;
49665
+ const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(participantDraw.drawId));
49666
+ if (seedingPublished) {
49667
+ const seedAssignments = getDerivedSeedAssignments({
49668
+ drawId: participantDraw.drawId,
49669
+ derivedDrawInfo,
49670
+ participantId
49671
+ });
49672
+ if (seedAssignments) {
49673
+ participantDraw.seedAssignments = seedAssignments;
49674
+ }
50270
49675
  }
50271
49676
  }
50272
- } else {
50273
- for (const m of Object.values(value)) {
50274
- if (m.matchUpId) {
50275
- keyedMatchUps[m.matchUpId] = deepCopyOption ? makeDeepCopy(m) : m;
50276
- if (!matchUpId)
50277
- matchUpId = m.matchUpId;
49677
+ }
49678
+ if (withEvents && participantEvents) {
49679
+ participant.events = participantEvents;
49680
+ if (withSeeding) {
49681
+ const seedingScales = Object.assign(
49682
+ {},
49683
+ ...(participant.timeItems || []).filter(({ itemType }) => itemType.split(".")[1] === SEEDING$1).map(({ itemType: seedingScaleName, itemValue: seedValue }) => ({
49684
+ [seedingScaleName]: seedValue
49685
+ }))
49686
+ );
49687
+ for (const participantEvent of participantEvents) {
49688
+ const getScaleAccessor = (scaleName) => [SCALE$1, SEEDING$1, participantEvent.eventType, scaleName].join(".");
49689
+ const publishedSeeding = eventsPublishStatuses[participantEvent.eventId]?.publishedSeeding;
49690
+ const eventSeedingScaleNames = (publishedSeeding?.stageSeedingScaleNames && Object.values(publishedSeeding?.stageSeedingScaleNames) || Array.isArray(publishedSeeding?.seedingScaleNames) && publishedSeeding.seedingScaleNames || []).map(getScaleAccessor);
49691
+ const publishedEventSeedingScaleNames = intersection(
49692
+ Object.keys(seedingScales),
49693
+ eventSeedingScaleNames
49694
+ );
49695
+ const eventSeedingPublished = !!(!usePublishState || !Object.keys(seedingScales).length && !publishedSeeding?.drawIds?.length || publishedEventSeedingScaleNames.length);
49696
+ if (eventSeedingPublished && publishedEventSeedingScaleNames.length) {
49697
+ if (publishedSeeding?.stageSeedingScaleNames) {
49698
+ const scaleValues = Object.keys(
49699
+ publishedSeeding.stageSeedingScaleNames
49700
+ ).map((key) => {
49701
+ const accessor = getScaleAccessor(
49702
+ publishedSeeding.stageSeedingScaleNames[key]
49703
+ );
49704
+ const scaleValue = seedingScales[accessor];
49705
+ return [key, scaleValue];
49706
+ }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
49707
+ const seedAssignments = Object.assign({}, ...scaleValues);
49708
+ participantEvent.seedAssignments = seedAssignments;
49709
+ } else if (publishedEventSeedingScaleNames) {
49710
+ const seedValues = publishedEventSeedingScaleNames.map(
49711
+ (scaleName) => seedingScales[scaleName]
49712
+ );
49713
+ participantEvent.seedValue = seedValues.pop();
49714
+ }
49715
+ } else if (!usePublishState && typeof withSeeding === "object") {
49716
+ const scaleValues = Object.keys(withSeeding).map((key) => {
49717
+ const accessor = getScaleAccessor(withSeeding[key]);
49718
+ const scaleValue = seedingScales[accessor];
49719
+ return [key, scaleValue];
49720
+ }).filter((pair) => pair[1]).map((pair) => ({ [pair[0]]: { seedValue: pair[1] } }));
49721
+ const seedAssignments = Object.assign({}, ...scaleValues);
49722
+ participantEvent.seedAssignments = seedAssignments;
49723
+ } else {
49724
+ const { categoryName, ageCategoryCode } = participantEvent.category || {};
49725
+ let scaleItem;
49726
+ for (const scaleName of [
49727
+ participantEvent.eventId,
49728
+ ageCategoryCode,
49729
+ categoryName
49730
+ ]) {
49731
+ const scaleAttributes = {
49732
+ eventType: participantEvent.eventType,
49733
+ scaleType: SEEDING$1,
49734
+ scaleName
49735
+ };
49736
+ const result = participantScaleItem({
49737
+ scaleAttributes,
49738
+ participant
49739
+ });
49740
+ if (result.scaleItem) {
49741
+ scaleItem = result.scaleItem;
49742
+ break;
49743
+ }
49744
+ }
49745
+ if (scaleItem) {
49746
+ const seedValue = scaleItem.scaleValue;
49747
+ const seedingPublished = !usePublishState || publishedSeeding?.published && (publishedSeeding?.drawIds?.length === 0 || publishedSeeding?.drawIds?.includes(
49748
+ participantEvent.drawId
49749
+ ));
49750
+ if (seedingPublished) {
49751
+ participantEvent.seedValue = seedValue;
49752
+ }
49753
+ }
49754
+ }
49755
+ if (participantEvent.drawIds?.length) {
49756
+ for (const flightDrawId of participantEvent.drawIds || []) {
49757
+ const drawSeedPublishingDisabled = publishedSeeding?.drawIds?.length && !publishedSeeding?.drawIds?.includes(flightDrawId);
49758
+ if (eventSeedingPublished && !drawSeedPublishingDisabled) {
49759
+ const seedAssignments = getDerivedSeedAssignments({
49760
+ drawId: flightDrawId,
49761
+ derivedDrawInfo,
49762
+ participantId
49763
+ });
49764
+ if (seedAssignments && participantEvent.seedAssignments) {
49765
+ for (const key of Object.keys(
49766
+ participantEvent.seedAssignments
49767
+ )) {
49768
+ participantEvent.seedAssignments[key] = seedAssignments[key];
49769
+ }
49770
+ } else {
49771
+ participantEvent.seedAssignments = seedAssignments;
49772
+ }
49773
+ }
49774
+ }
49775
+ }
49776
+ }
49777
+ }
49778
+ }
49779
+ const participantOpponents = Object.values(opponents).flat();
49780
+ if (withOpponents && participantOpponents?.length) {
49781
+ participant.opponents = participantOpponents;
49782
+ participantDraws?.forEach((draw) => {
49783
+ draw.opponents = participantOpponents.filter(
49784
+ (opponent) => opponent.drawId === draw.drawId
49785
+ );
49786
+ });
49787
+ }
49788
+ const participantPotentialMatchUps = Object.values(potentialMatchUps);
49789
+ const participantMatchUps = Object.values(matchUps);
49790
+ if (withMatchUps) {
49791
+ participant.potentialMatchUps = participantPotentialMatchUps;
49792
+ participant.matchUps = participantMatchUps;
49793
+ }
49794
+ const allParticipantMatchUps = participantMatchUps.concat(
49795
+ participantPotentialMatchUps
49796
+ );
49797
+ const scheduledMatchUps = participantScheduledMatchUps({
49798
+ matchUps: allParticipantMatchUps
49799
+ })?.scheduledMatchUps || [];
49800
+ const { scheduledMinutesDifference } = scheduleAnalysis || {};
49801
+ const dates = Object.keys(scheduledMatchUps);
49802
+ dates.forEach((date) => {
49803
+ scheduledMatchUps[date].filter(Boolean).forEach((matchUp, i) => {
49804
+ const {
49805
+ schedule: {
49806
+ scheduledTime,
49807
+ timeAfterRecovery,
49808
+ typeChangeTimeAfterRecovery
49809
+ },
49810
+ matchUpStatus,
49811
+ roundPosition,
49812
+ structureName,
49813
+ matchUpType,
49814
+ roundNumber,
49815
+ matchUpId,
49816
+ drawId,
49817
+ score
49818
+ } = matchUp;
49819
+ scheduleItems.push({
49820
+ ...matchUp.schedule,
49821
+ scheduledTime: extractTime(matchUp.schedule?.scheduledTime),
49822
+ roundPosition,
49823
+ structureName,
49824
+ matchUpType,
49825
+ roundNumber,
49826
+ matchUpId,
49827
+ drawId
49828
+ });
49829
+ const ignoreMatchUp = matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(matchUpStatus) && !scoreHasValue({ score });
49830
+ if (scheduledTime && !ignoreMatchUp) {
49831
+ const scheduledMinutes = timeStringMinutes(scheduledTime);
49832
+ const matchUpsToConsider = scheduledMatchUps[date].slice(i + 1);
49833
+ for (const consideredMatchUp of matchUpsToConsider) {
49834
+ const ignoreMatchUp2 = consideredMatchUp.matchUpStatus === BYE || [WALKOVER$2, DEFAULTED].includes(consideredMatchUp.matchUpStatus) && !scoreHasValue(consideredMatchUp);
49835
+ if (!ignoreMatchUp2 && consideredMatchUp.schedule?.scheduledTime) {
49836
+ const typeChange = matchUp.matchUpType !== consideredMatchUp.matchUpType;
49837
+ const notBeforeTime = typeChange ? typeChangeTimeAfterRecovery || timeAfterRecovery : timeAfterRecovery;
49838
+ const sameDraw = matchUp.drawId === consideredMatchUp.drawId;
49839
+ const bothPotential = matchUp.potential && consideredMatchUp.potential;
49840
+ const nextMinutes = timeStringMinutes(
49841
+ consideredMatchUp.schedule?.scheduledTime
49842
+ );
49843
+ const minutesDifference = nextMinutes - scheduledMinutes;
49844
+ const timeOverlap = scheduledMinutesDifference && !isNaN(scheduledMinutesDifference) ? minutesDifference <= scheduledMinutesDifference : timeStringMinutes(notBeforeTime) > timeStringMinutes(consideredMatchUp.schedule?.scheduledTime);
49845
+ if (timeOverlap && !(bothPotential && sameDraw)) {
49846
+ scheduleConflicts.push({
49847
+ priorScheduledMatchUpId: consideredMatchUp.matchUpId,
49848
+ matchUpIdWithConflict: matchUpId
49849
+ });
49850
+ }
49851
+ }
49852
+ }
50278
49853
  }
50279
- }
50280
- }
50281
- return deepCopyOption ? makeDeepCopy(value) : value;
50282
- }
50283
- function getMatchUp() {
50284
- return keyedMatchUps[matchUpId];
50285
- }
50286
- function getMatchUps() {
50287
- return Object.values(keyedMatchUps);
50288
- }
50289
- function reset() {
50290
- matchUpId = void 0;
50291
- keyedMatchUps = {};
49854
+ });
49855
+ });
49856
+ if (withStatistics)
49857
+ participant.statistics = [winRatioStat];
49858
+ return { scheduleConflicts, scheduleItems };
50292
49859
  }
50293
- function getState$2(params) {
50294
- return makeDeepCopy(
50295
- keyedMatchUps[matchUpId],
50296
- params?.convertExtensions,
50297
- false,
50298
- params?.removeExtensions
49860
+
49861
+ function getDrawDetails({
49862
+ eventEntries,
49863
+ sortConfig,
49864
+ event
49865
+ }) {
49866
+ const derivedInfo = {};
49867
+ const drawDetails = Object.assign(
49868
+ {},
49869
+ ...(event.drawDefinitions ?? []).map((drawDefinition) => {
49870
+ const entriesMap = Object.assign(
49871
+ {},
49872
+ ...(eventEntries ?? []).filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry })),
49873
+ ...drawDefinition.entries.filter((entry) => entry.participantId).map((entry) => ({ [entry.participantId]: entry }))
49874
+ );
49875
+ const drawEntries = Object.values(entriesMap);
49876
+ const mainStructure = getDrawStructures({
49877
+ stageSequence: 1,
49878
+ drawDefinition,
49879
+ stage: MAIN
49880
+ })?.structures?.[0];
49881
+ const mainPositionAssignments = mainStructure && getPositionAssignments$1({
49882
+ structure: mainStructure
49883
+ })?.positionAssignments;
49884
+ const drawSize = mainPositionAssignments?.length;
49885
+ const qualifyingStructure = getDrawStructures({
49886
+ stageSequence: 1,
49887
+ stage: QUALIFYING,
49888
+ drawDefinition
49889
+ })?.structures?.[0];
49890
+ const qualifyingPositionAssignments = mainStructure && getPositionAssignments$1({
49891
+ structure: qualifyingStructure
49892
+ })?.positionAssignments;
49893
+ const qualifyingDrawSize = qualifyingPositionAssignments?.length;
49894
+ const mainSeedAssignments = mainStructure?.seedAssignments;
49895
+ const qualifyingSeedAssignments = qualifyingStructure?.seedAssignments;
49896
+ const orderedStructureIds = (drawDefinition.structures || []).sort((a, b) => structureSort(a, b, sortConfig)).map(({ structureId, structures }) => {
49897
+ return [
49898
+ structureId,
49899
+ ...(structures || []).map(({ structureId: structureId2 }) => structureId2)
49900
+ ];
49901
+ }).flat(Infinity);
49902
+ const flightNumber = event?._flightProfile?.flights?.find(
49903
+ (flight) => flight.drawId === drawDefinition.drawId
49904
+ )?.flightNumber;
49905
+ derivedInfo[drawDefinition.drawId] = {
49906
+ qualifyingPositionAssignments,
49907
+ qualifyingSeedAssignments,
49908
+ mainPositionAssignments,
49909
+ mainSeedAssignments,
49910
+ orderedStructureIds,
49911
+ qualifyingDrawSize,
49912
+ flightNumber,
49913
+ drawSize
49914
+ };
49915
+ return {
49916
+ [drawDefinition.drawId]: {
49917
+ drawType: drawDefinition.drawType,
49918
+ drawEntries
49919
+ }
49920
+ };
49921
+ })
50299
49922
  );
49923
+ return { derivedInfo, drawDetails };
50300
49924
  }
50301
49925
 
50302
- const matchUpEngine = (() => {
50303
- const engine = {
50304
- getState: (params) => getState$2(params),
50305
- version: () => factoryVersion(),
50306
- reset: () => {
50307
- reset();
50308
- return { ...SUCCESS };
50309
- },
50310
- drawId: void 0,
50311
- error: void 0,
50312
- success: false,
50313
- devContext: (contextCriteria) => {
50314
- setDevContext(contextCriteria);
50315
- return engine;
50316
- },
50317
- setState: (definition, deepCopyOption, deepCopyAttributes) => {
50318
- setDeepCopy(deepCopyOption, deepCopyAttributes);
50319
- const result = setState$2(definition);
50320
- return processResult(result);
50321
- }
49926
+ function processMatchUp({
49927
+ relevantParticipantIdsMap,
49928
+ participantFilters,
49929
+ participantIdMap,
49930
+ derivedDrawInfo,
49931
+ eventDrawsCount,
49932
+ drawDetails,
49933
+ eventType,
49934
+ matchUp
49935
+ }) {
49936
+ const {
49937
+ collectionId,
49938
+ collectionPosition,
49939
+ drawId,
49940
+ drawName,
49941
+ eventId,
49942
+ eventName,
49943
+ finishingRound,
49944
+ finishingPositionRange,
49945
+ processCodes,
49946
+ loserTo,
49947
+ matchUpId,
49948
+ matchUpType,
49949
+ matchUpFormat,
49950
+ matchUpStatus,
49951
+ matchUpStatusCodes,
49952
+ matchUpTieId,
49953
+ roundName,
49954
+ roundNumber,
49955
+ roundPosition,
49956
+ score,
49957
+ sides,
49958
+ stage,
49959
+ stageSequence,
49960
+ schedule,
49961
+ structureName,
49962
+ structureId,
49963
+ tieFormat,
49964
+ tieMatchUps,
49965
+ tournamentId,
49966
+ winnerTo,
49967
+ winningSide
49968
+ } = matchUp;
49969
+ const targetParticipantIds = participantFilters?.participantIds;
49970
+ const getRelevantParticipantIds = (participantId) => {
49971
+ const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
49972
+ relevantParticipantIds.push(participantId);
49973
+ return relevantParticipantIds.some(
49974
+ (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
49975
+ ) ? relevantParticipantIds : [];
50322
49976
  };
50323
- function processResult(result) {
50324
- if (result?.error) {
50325
- engine.error = result.error;
50326
- engine.success = false;
50327
- } else {
50328
- engine.error = void 0;
50329
- engine.success = true;
50330
- engine.drawId = result.drawId;
50331
- }
50332
- return engine;
49977
+ const { winner, loser } = finishingPositionRange || {};
49978
+ const doublesTieParticipants = tieMatchUps?.length && tieMatchUps.filter(({ matchUpType: matchUpType2 }) => matchUpType2 === DOUBLES_MATCHUP).map(
49979
+ ({ sides: sides2 }) => sides2.map(
49980
+ ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
49981
+ sideNumber,
49982
+ participantId,
49983
+ participant
49984
+ }
49985
+ )
49986
+ ).flat().filter(Boolean) || [];
49987
+ if (eventType === TEAM_EVENT && matchUpType === DOUBLES_MATCHUP) {
49988
+ const participants = (matchUp.sides?.filter(Boolean) || []).map(
49989
+ ({ sideNumber, participantId, participant }) => sideNumber && participantId && {
49990
+ sideNumber,
49991
+ participantId,
49992
+ participant
49993
+ }
49994
+ ).filter(Boolean);
49995
+ doublesTieParticipants.push(...participants);
50333
49996
  }
50334
- importGovernors([
50335
- tieFormatGovernor,
50336
- historyGovernor,
50337
- queryGovernor$1,
50338
- scoreGovernor
50339
- ]);
50340
- return engine;
50341
- function importGovernors(governors) {
50342
- governors.forEach((governor) => {
50343
- Object.keys(governor).forEach((methodName) => {
50344
- engine[methodName] = (params) => {
50345
- if (getDevContext()) {
50346
- return invoke({ params, governor, methodName });
50347
- } else {
50348
- try {
50349
- return invoke({ params, governor, methodName });
50350
- } catch (err) {
50351
- handleCaughtError({
50352
- engineName: "matchUpEngine",
50353
- methodName,
50354
- params,
50355
- err
50356
- });
49997
+ sides?.forEach((params) => {
49998
+ const { participantId, sideNumber } = params;
49999
+ if (!participantId)
50000
+ return;
50001
+ const { drawType, drawEntries } = drawDetails[drawId];
50002
+ const participantScore = sideNumber === 1 ? score?.scoreStringSide1 : score?.scoreStringSide2;
50003
+ const participantWon = winningSide && sideNumber === winningSide;
50004
+ const opponent = matchUp.sides.find(
50005
+ (side) => side.sideNumber === 3 - sideNumber
50006
+ );
50007
+ const opponentParticipantId = opponent?.participantId;
50008
+ const relevantOpponents = opponentParticipantId && relevantParticipantIdsMap[opponentParticipantId] || [];
50009
+ const finishingPositionRange2 = participantWon ? winner : loser;
50010
+ const drawEntry = drawEntries.find(
50011
+ (entry) => entry.participantId === participantId
50012
+ );
50013
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50014
+ const addedPairParticipantIds = [];
50015
+ doublesTieParticipants?.filter((participant) => participant.sideNumber === sideNumber).forEach((p) => {
50016
+ const participantId2 = p.participantId;
50017
+ if (participantId2 && !addedPairParticipantIds.includes(participantId2)) {
50018
+ relevantParticipantIds.push({
50019
+ relevantParticipantId: participantId2,
50020
+ participantType: PAIR
50021
+ });
50022
+ addedPairParticipantIds.push(participantId2);
50023
+ }
50024
+ });
50025
+ const filteredRelevantParticipantIds = relevantParticipantIds.filter(
50026
+ (opponent2) => {
50027
+ return eventType !== TEAM_EVENT || eventType === TEAM_EVENT && [DOUBLES_MATCHUP, TEAM_MATCHUP].includes(matchUpType) && [PAIR, TEAM_PARTICIPANT].includes(opponent2.participantType) || eventType === TEAM_EVENT && [SINGLES_MATCHUP, DOUBLES_MATCHUP].includes(matchUpType) && [INDIVIDUAL].includes(opponent2.participantType);
50028
+ }
50029
+ );
50030
+ filteredRelevantParticipantIds?.forEach(
50031
+ ({ relevantParticipantId, participantType }) => {
50032
+ const { entryStage, entryStatus, entryPosition } = drawEntry || {};
50033
+ if (!participantIdMap[relevantParticipantId])
50034
+ return;
50035
+ if (!participantIdMap[relevantParticipantId].draws[drawId]) {
50036
+ const positionAssignments = getDerivedPositionAssignments({
50037
+ participantId: relevantParticipantId,
50038
+ derivedDrawInfo,
50039
+ drawId
50040
+ });
50041
+ const seedAssignments = getDerivedSeedAssignments({
50042
+ participantId: relevantParticipantId,
50043
+ derivedDrawInfo,
50044
+ drawId
50045
+ });
50046
+ participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
50047
+ qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
50048
+ drawSize: derivedDrawInfo[drawId]?.drawSize,
50049
+ partnerParticipantIds: [],
50050
+ positionAssignments,
50051
+ seedAssignments,
50052
+ entryPosition,
50053
+ entryStatus,
50054
+ entryStage,
50055
+ drawName,
50056
+ drawType,
50057
+ eventId,
50058
+ drawId
50059
+ });
50060
+ }
50061
+ if (!participantIdMap[relevantParticipantId].events[eventId]) {
50062
+ participantIdMap[relevantParticipantId].events[eventId] = {
50063
+ partnerParticipantIds: [],
50064
+ drawIds: [],
50065
+ eventName,
50066
+ eventId
50067
+ };
50068
+ }
50069
+ const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
50070
+ if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
50071
+ participantIdMap[relevantParticipantId].events[eventId].drawIds.push(
50072
+ drawId
50073
+ );
50074
+ }
50075
+ let partnerParticipantId;
50076
+ if (participantType === INDIVIDUAL && matchUpType === DOUBLES_MATCHUP) {
50077
+ const relevantParticipantInfo = filteredRelevantParticipantIds.find(
50078
+ (participantInfo) => {
50079
+ return participantInfo.relevantParticipantId !== relevantParticipantId && participantInfo.participantType === INDIVIDUAL;
50080
+ }
50081
+ );
50082
+ partnerParticipantId = relevantParticipantInfo?.relevantParticipantId;
50083
+ }
50084
+ const filteredRelevantOpponents = relevantOpponents?.filter(
50085
+ (opponent2) => matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT && opponent2.participantType === TEAM_PARTICIPANT || matchUpType === SINGLES_MATCHUP && opponent2.participantType === INDIVIDUAL || matchUpType === DOUBLES_MATCHUP && (participantType === INDIVIDUAL ? [INDIVIDUAL, PAIR].includes(opponent2.participantType) : (
50086
+ // for PAIR participants only show PAIR opponenents
50087
+ opponent2.participantType === PAIR
50088
+ ))
50089
+ ) || [];
50090
+ filteredRelevantOpponents.forEach(
50091
+ ({
50092
+ relevantParticipantId: opponentParticipantId2,
50093
+ participantType: opponentParticipantType
50094
+ }) => {
50095
+ if (!participantIdMap[relevantParticipantId].opponents) {
50096
+ participantIdMap[relevantParticipantId].opponents = {};
50357
50097
  }
50098
+ participantIdMap[relevantParticipantId].opponents[opponentParticipantId2] = {
50099
+ eventId,
50100
+ drawId,
50101
+ matchUpId,
50102
+ participantType: opponentParticipantType,
50103
+ participantId: opponentParticipantId2
50104
+ };
50358
50105
  }
50359
- };
50106
+ );
50107
+ const opponentParticipantInfo = filteredRelevantOpponents.map(
50108
+ ({ relevantParticipantId: relevantParticipantId2, participantType: participantType2 }) => ({
50109
+ participantId: relevantParticipantId2,
50110
+ participantType: participantType2
50111
+ })
50112
+ );
50113
+ const includeMatchUp = matchUpType !== TEAM_MATCHUP && [INDIVIDUAL, PAIR].includes(participantType) || matchUpType === TEAM_MATCHUP && participantType === TEAM_PARTICIPANT;
50114
+ if (includeMatchUp)
50115
+ participantIdMap[relevantParticipantId].matchUps[matchUpId] = definedAttributes({
50116
+ collectionId,
50117
+ collectionPosition,
50118
+ drawId,
50119
+ eventId,
50120
+ eventType,
50121
+ eventDrawsCount,
50122
+ finishingRound,
50123
+ finishingPositionRange: finishingPositionRange2,
50124
+ loserTo,
50125
+ matchUpId,
50126
+ matchUpType,
50127
+ matchUpFormat,
50128
+ matchUpStatus,
50129
+ matchUpStatusCodes,
50130
+ matchUpTieId,
50131
+ opponentParticipantInfo,
50132
+ participantWon,
50133
+ partnerParticipantId,
50134
+ perspectiveScoreString: participantScore,
50135
+ processCodes,
50136
+ roundName,
50137
+ roundNumber,
50138
+ roundPosition,
50139
+ schedule,
50140
+ score,
50141
+ sides,
50142
+ stage,
50143
+ stageSequence,
50144
+ structureName,
50145
+ structureId,
50146
+ tieFormat,
50147
+ tournamentId,
50148
+ winnerTo,
50149
+ winningSide
50150
+ });
50151
+ if (partnerParticipantId) {
50152
+ participantIdMap[relevantParticipantId].events[eventId].partnerParticipantIds.push(partnerParticipantId);
50153
+ participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantIds.push(partnerParticipantId);
50154
+ participantIdMap[relevantParticipantId].events[eventId].partnerParticipantId = partnerParticipantId;
50155
+ participantIdMap[relevantParticipantId].draws[drawId].partnerParticipantId = partnerParticipantId;
50156
+ }
50157
+ if (winningSide) {
50158
+ if (participantWon) {
50159
+ participantIdMap[relevantParticipantId].wins++;
50160
+ } else {
50161
+ participantIdMap[relevantParticipantId].losses++;
50162
+ }
50163
+ }
50164
+ }
50165
+ );
50166
+ });
50167
+ if (Array.isArray(matchUp.potentialParticipants)) {
50168
+ const potentialParticipantIds = getParticipantIds(
50169
+ matchUp.potentialParticipants.flat()
50170
+ );
50171
+ potentialParticipantIds?.forEach((participantId) => {
50172
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50173
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50174
+ participantIdMap[relevantParticipantId].potentialMatchUps[matchUpId] = definedAttributes({
50175
+ drawId,
50176
+ eventId,
50177
+ eventType,
50178
+ matchUpId,
50179
+ matchUpType,
50180
+ matchUpFormat,
50181
+ roundName,
50182
+ roundNumber,
50183
+ roundPosition,
50184
+ schedule,
50185
+ tieFormat,
50186
+ structureName,
50187
+ tournamentId,
50188
+ potential: true
50189
+ });
50360
50190
  });
50361
50191
  });
50362
50192
  }
50363
- function invoke({ params, governor, methodName }) {
50364
- engine.error = void 0;
50365
- engine.success = false;
50366
- const matchUp = params?.matchUp || getMatchUp();
50367
- const matchUps = params?.matchUps || getMatchUps();
50368
- const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
50369
- params = {
50370
- ...params,
50371
- matchUpId: matchUp?.matchUpId,
50372
- matchUps,
50373
- matchUp
50374
- };
50375
- const result = governor[methodName](params);
50376
- if (result?.error) {
50377
- if (snapshot)
50378
- setState$2(snapshot);
50379
- return { ...result, rolledBack: !!snapshot };
50380
- }
50381
- const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
50382
- if (notify)
50383
- notifySubscribers();
50384
- if (notify || !result?.success || params?.doNotNotify)
50385
- deleteNotices();
50386
- return result;
50387
- }
50388
- })();
50193
+ }
50389
50194
 
50390
- function matchUpEngineAsync(test) {
50391
- const result = createInstanceState();
50392
- if (result.error && !test)
50393
- return result;
50394
- const engine = {
50395
- getState: (params) => getState$2(params),
50396
- version: () => factoryVersion(),
50397
- reset: () => {
50398
- reset();
50399
- return { ...SUCCESS };
50400
- },
50401
- drawId: void 0,
50402
- error: void 0,
50403
- success: false,
50404
- devContext: (contextCriteria) => {
50405
- setDevContext(contextCriteria);
50406
- return engine;
50407
- },
50408
- setState: (definition, deepCopyOption, deepCopyAttributes) => {
50409
- setDeepCopy(deepCopyOption, deepCopyAttributes);
50410
- const result2 = setState$2(definition);
50411
- return processResult(result2);
50412
- }
50195
+ function addParticipantContext(params) {
50196
+ const participantIdsWithConflicts = [];
50197
+ const eventsPublishStatuses = {};
50198
+ const derivedDrawInfo = {};
50199
+ const participantIdMap = {};
50200
+ const initializeParticipantId = (participantId) => {
50201
+ if (!participantIdMap[participantId])
50202
+ participantIdMap[participantId] = {
50203
+ groupParticipantIds: [],
50204
+ teamParticipantIds: [],
50205
+ pairParticipantIds: [],
50206
+ potentialMatchUps: {},
50207
+ scheduleItems: [],
50208
+ opponents: {},
50209
+ matchUps: {},
50210
+ events: {},
50211
+ groups: [],
50212
+ teams: [],
50213
+ draws: {},
50214
+ losses: 0,
50215
+ wins: 0
50216
+ };
50217
+ };
50218
+ const { tournamentRecord, participantFilters, allTournamentParticipants } = params;
50219
+ const { relevantParticipantIdsMap } = getRelevantParticipantIdsMap({
50220
+ processParticipantId: initializeParticipantId,
50221
+ tournamentRecord
50222
+ });
50223
+ const targetParticipantIds = participantFilters?.participantIds;
50224
+ const getRelevantParticipantIds = (participantId) => {
50225
+ const relevantParticipantIds = participantId && relevantParticipantIdsMap[participantId] || [];
50226
+ relevantParticipantIds.push(participantId);
50227
+ return relevantParticipantIds.some(
50228
+ (obj) => !targetParticipantIds || targetParticipantIds.includes(obj.relevantParticipantId)
50229
+ ) ? relevantParticipantIds : [];
50413
50230
  };
50414
- function processResult(result2) {
50415
- if (result2?.error) {
50416
- engine.error = result2.error;
50417
- engine.success = false;
50418
- } else {
50419
- engine.error = void 0;
50420
- engine.success = true;
50421
- engine.drawId = result2.drawId;
50231
+ params.withGroupings && allTournamentParticipants.forEach((participant) => {
50232
+ if (participant.participantType === GROUP) {
50233
+ const groupParticipantId = participant.participantId;
50234
+ participant?.individualParticipantIds?.forEach((participantId) => {
50235
+ if (!participantIdMap[participantId].groupParticipantIds.includes(
50236
+ groupParticipantId
50237
+ )) {
50238
+ participantIdMap[participantId].groupParticipantIds.push(
50239
+ groupParticipantId
50240
+ );
50241
+ participantIdMap[participantId].groups.push({
50242
+ participantRoleResponsibilities: participant.participantRoleResponsibilities,
50243
+ participantOtherName: participant.participantOtherName,
50244
+ participantName: participant.participantName,
50245
+ participantId: participant.participantId
50246
+ });
50247
+ }
50248
+ });
50422
50249
  }
50423
- return engine;
50424
- }
50425
- importGovernors([
50426
- tieFormatGovernor,
50427
- historyGovernor,
50428
- queryGovernor$1,
50429
- scoreGovernor
50430
- ]);
50431
- return engine;
50432
- async function importGovernors(governors) {
50433
- for (const governor of governors) {
50434
- const governorMethods = Object.keys(governor);
50435
- for (const methodName of governorMethods) {
50436
- engine[methodName] = async (params) => {
50437
- if (getDevContext()) {
50438
- return await invoke({ params, governor, methodName });
50439
- } else {
50440
- try {
50441
- return await invoke({ params, governor, methodName });
50442
- } catch (err) {
50443
- handleCaughtError({
50444
- engineName: "matchUpEngine",
50445
- methodName,
50446
- params,
50447
- err
50448
- });
50449
- }
50450
- }
50451
- };
50452
- }
50250
+ if (participant.participantType === TEAM$2) {
50251
+ const teamParticipantId = participant.participantId;
50252
+ participant?.individualParticipantIds?.forEach((participantId) => {
50253
+ if (!participantIdMap[participantId]?.teamParticipantIds?.includes(
50254
+ teamParticipantId
50255
+ )) {
50256
+ participantIdMap[participantId]?.teamParticipantIds.push(
50257
+ teamParticipantId
50258
+ );
50259
+ participantIdMap[participantId]?.teams.push({
50260
+ participantRoleResponsibilities: participant.participantRoleResponsibilities,
50261
+ participantOtherName: participant.participantOtherName,
50262
+ participantName: participant.participantName,
50263
+ participantId: participant.participantId,
50264
+ teamId: participant.teamId
50265
+ });
50266
+ }
50267
+ });
50453
50268
  }
50454
- }
50455
- async function invoke({ params, governor, methodName }) {
50456
- engine.success = false;
50457
- engine.error = void 0;
50458
- const matchUp = params?.matchUp || getMatchUp();
50459
- const matchUps = params?.matchUps || getMatchUps();
50460
- const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
50461
- params = {
50462
- ...params,
50463
- matchUpId: matchUp?.matchUpId,
50464
- matchUps,
50465
- matchUp
50466
- };
50467
- const result2 = governor[methodName](params);
50468
- if (result2?.error) {
50469
- if (snapshot)
50470
- setState$2(snapshot);
50471
- return { ...result2, rolledBack: !!snapshot };
50269
+ if (participant.participantType === PAIR) {
50270
+ const pairParticipantId = participant.participantId;
50271
+ participant?.individualParticipantIds?.forEach((participantId) => {
50272
+ if (participantIdMap[participantId] && !participantIdMap[participantId].pairParticipantIds.includes(
50273
+ pairParticipantId
50274
+ )) {
50275
+ participantIdMap[participantId].pairParticipantIds.push(
50276
+ pairParticipantId
50277
+ );
50278
+ }
50279
+ });
50472
50280
  }
50473
- const notify = result2?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
50474
- if (notify)
50475
- await notifySubscribersAsync();
50476
- if (notify || !result2?.success || params?.doNotNotify)
50477
- deleteNotices();
50478
- return result2;
50479
- }
50480
- }
50481
-
50482
- function newTournamentRecord(params) {
50483
- const attributes = params || {};
50484
- if (!attributes.tournamentId)
50485
- attributes.tournamentId = UUID();
50486
- if (attributes.startDate && !isISODateString(attributes.startDate) && !validDateString.test(attributes.startDate)) {
50487
- return { error: INVALID_DATE };
50488
- }
50489
- if (attributes.endDate && !isISODateString(attributes.endDate) && !validDateString.test(attributes.endDate)) {
50490
- return { error: INVALID_DATE };
50491
- }
50492
- if (attributes.extensions) {
50493
- attributes.extensions = attributes.extensions.filter(isValidExtension);
50281
+ });
50282
+ if (params.withMatchUps) {
50283
+ getMatchUpDependencies({ tournamentRecord });
50494
50284
  }
50495
- return { ...attributes };
50496
- }
50497
-
50498
- function setState$1(tournament, deepCopyOption) {
50499
- if (typeof tournament !== "object")
50500
- return { error: INVALID_OBJECT };
50501
- const tournamentId = tournament.unifiedTournamentId?.tournamentId || tournament.tournamentId;
50502
- if (!tournamentId)
50503
- return { error: MISSING_TOURNAMENT_ID };
50504
- const tournamentRecord = deepCopyOption !== false ? makeDeepCopy(tournament) : tournament;
50505
- setTournamentRecords({ [tournamentId]: tournamentRecord });
50506
- setTournamentId(tournamentId);
50507
- return tournamentRecord;
50508
- }
50509
- function getState$1({
50510
- convertExtensions = false,
50511
- removeExtensions = false,
50512
- tournamentId
50513
- }) {
50514
- if (typeof tournamentId !== "string")
50515
- return {};
50516
- const tournamentRecord = getTournamentRecord(tournamentId);
50517
- return {
50518
- tournamentRecord: makeDeepCopy(
50519
- tournamentRecord,
50520
- convertExtensions,
50521
- false,
50522
- removeExtensions
50523
- )
50524
- };
50525
- }
50526
- function paramsMiddleware$1(tournamentRecord, params, prefetch) {
50527
- if (params) {
50528
- const drawId = params.drawId || params.matchUp?.drawId;
50529
- if (drawId) {
50530
- const { event, drawDefinition } = findEvent({
50531
- tournamentRecord,
50532
- drawId
50285
+ if (params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withSeeding || params.withEvents || params.withDraws) {
50286
+ params.tournamentEvents?.forEach((rawEvent) => {
50287
+ const event = makeDeepCopy(rawEvent, true, true);
50288
+ const flightProfile = getFlightProfile({ event }).flightProfile;
50289
+ const eventDrawsCount = flightProfile?.flights?.length || event.drawDefinitions?.length || 0;
50290
+ (event.drawDefinitions || []).forEach((drawDefinition, i) => {
50291
+ if (event?.eventType === TEAM$2) {
50292
+ const { extension } = findExtension$2({
50293
+ element: rawEvent.drawDefinitions[i],
50294
+ // rawEvent because deepCopy has converted extensions
50295
+ name: LINEUPS
50296
+ });
50297
+ if (extension)
50298
+ drawDefinition.extensions = [extension];
50299
+ }
50533
50300
  });
50534
- params = {
50535
- ...params,
50536
- event,
50537
- drawDefinition
50301
+ const { eventId, eventName, eventType, category } = event;
50302
+ const eventInfo = { eventId, eventName, eventType, category };
50303
+ const extensionKeys = event && Object.keys(event).filter((key) => key.startsWith("_"));
50304
+ extensionKeys?.forEach(
50305
+ (extensionKey) => eventInfo[extensionKey] = event[extensionKey]
50306
+ );
50307
+ const eventEntries = event.entries || [];
50308
+ const itemType = `${PUBLISH}.${STATUS$1}`;
50309
+ const { timeItem } = getEventTimeItem({
50310
+ itemType,
50311
+ event
50312
+ });
50313
+ if (timeItem?.itemValue?.PUBLIC) {
50314
+ const { drawIds: publishedDrawIds = [], seeding } = timeItem.itemValue.PUBLIC || {};
50315
+ const publishedSeeding = {
50316
+ published: void 0,
50317
+ // seeding can be present for all entries in an event when no flights have been defined
50318
+ seedingScaleNames: [],
50319
+ drawIds: []
50320
+ // seeding can be specific to drawIds
50321
+ };
50322
+ if (seeding)
50323
+ Object.assign(publishedSeeding, timeItem.itemValue.PUBLIC.seeding);
50324
+ eventsPublishStatuses[eventId] = {
50325
+ publishedDrawIds,
50326
+ publishedSeeding
50327
+ };
50328
+ }
50329
+ const disallowedConstants = [
50330
+ ...Object.values(extensionConstants)
50331
+ ];
50332
+ const disallowedKeys = disallowedConstants.map(
50333
+ (constant) => `_${constant}`
50334
+ );
50335
+ const filteredEventInfo = eventInfo && Object.keys(eventInfo).filter((key) => !disallowedKeys.includes(key)).reduce((obj, key) => {
50336
+ obj[key] = eventInfo[key];
50337
+ return obj;
50338
+ }, {});
50339
+ eventEntries?.filter((entry) => entry?.participantId).forEach((entry) => {
50340
+ const { participantId, entryStage, entryStatus, entryPosition } = entry;
50341
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50342
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50343
+ if (!participantIdMap[relevantParticipantId])
50344
+ initializeParticipantId(relevantParticipantId);
50345
+ participantIdMap[relevantParticipantId].events[eventId] = {
50346
+ ...filteredEventInfo,
50347
+ partnerParticipantIds: [],
50348
+ entryPosition,
50349
+ entryStatus,
50350
+ entryStage,
50351
+ drawIds: [],
50352
+ eventId
50353
+ };
50354
+ });
50355
+ });
50356
+ const addDrawData = ({ drawEntry, drawId }) => {
50357
+ const { participantId, entryStage, entryStatus, entryPosition } = drawEntry;
50358
+ const relevantParticipantIds = getRelevantParticipantIds(participantId);
50359
+ relevantParticipantIds?.forEach(({ relevantParticipantId }) => {
50360
+ if (!participantIdMap[relevantParticipantId].events[eventId]) {
50361
+ participantIdMap[relevantParticipantId].events[eventId] = {
50362
+ ...filteredEventInfo,
50363
+ partnerParticipantIds: [],
50364
+ entryPosition,
50365
+ entryStatus,
50366
+ entryStage,
50367
+ drawIds: [],
50368
+ eventId
50369
+ };
50370
+ }
50371
+ if (!participantIdMap[relevantParticipantId].draws[drawId]) {
50372
+ const positionAssignments = getDerivedPositionAssignments({
50373
+ participantId: relevantParticipantId,
50374
+ derivedDrawInfo,
50375
+ drawId
50376
+ });
50377
+ const seedAssignments = getDerivedSeedAssignments({
50378
+ participantId: relevantParticipantId,
50379
+ derivedDrawInfo,
50380
+ drawId
50381
+ });
50382
+ participantIdMap[relevantParticipantId].draws[drawId] = definedAttributes({
50383
+ qualifyingDrawSize: derivedDrawInfo[drawId]?.qualifyingDrawSize,
50384
+ drawSize: derivedDrawInfo[drawId]?.drawSize,
50385
+ partnerParticipantIds: [],
50386
+ positionAssignments,
50387
+ eventDrawsCount,
50388
+ seedAssignments,
50389
+ entryPosition,
50390
+ entryStatus,
50391
+ entryStage,
50392
+ eventId,
50393
+ drawId
50394
+ });
50395
+ }
50396
+ const eventDrawIds = participantIdMap[relevantParticipantId].events[eventId].drawIds;
50397
+ if (eventDrawIds && !eventDrawIds?.includes(drawId)) {
50398
+ participantIdMap[relevantParticipantId].events[eventId].drawIds.push(drawId);
50399
+ }
50400
+ });
50538
50401
  };
50539
- if (prefetch) {
50540
- const matchUpsMap = getMatchUpsMap({ drawDefinition });
50541
- const { matchUps: inContextDrawMatchUps } = getAllDrawMatchUps({
50402
+ const drawIdsWithDefinitions = event.drawDefinitions?.map(({ drawId }) => drawId) || [];
50403
+ eventInfo._flightProfile?.flights?.forEach((flight) => {
50404
+ const { drawId, drawEntries } = flight;
50405
+ if (!drawIdsWithDefinitions.includes(drawId)) {
50406
+ drawEntries?.forEach(
50407
+ (drawEntry) => addDrawData({ drawEntry, drawId })
50408
+ );
50409
+ }
50410
+ });
50411
+ const { drawDetails, derivedInfo } = getDrawDetails({
50412
+ eventEntries,
50413
+ event
50414
+ });
50415
+ Object.assign(derivedDrawInfo, derivedInfo);
50416
+ if (event.eventType === TEAM$2 || // for TEAM events some individual attributes can only be derived by processing
50417
+ params.withScheduleItems || params.scheduleAnalysis || params.withStatistics || params.withOpponents || params.withMatchUps || params.withDraws) {
50418
+ const matchUps = allEventMatchUps({
50419
+ afterRecoveryTimes: params.scheduleAnalysis,
50420
+ participants: allTournamentParticipants,
50421
+ nextMatchUps: true,
50422
+ tournamentRecord,
50542
50423
  inContext: true,
50543
- drawDefinition,
50544
- matchUpsMap
50545
- });
50546
- params.matchUpsMap = matchUpsMap;
50547
- params.inContextDrawMatchUps = inContextDrawMatchUps;
50424
+ event
50425
+ })?.matchUps;
50426
+ matchUps?.forEach(
50427
+ (matchUp) => processMatchUp({
50428
+ relevantParticipantIdsMap,
50429
+ participantFilters,
50430
+ participantIdMap,
50431
+ derivedDrawInfo,
50432
+ eventDrawsCount,
50433
+ drawDetails,
50434
+ eventType,
50435
+ matchUp
50436
+ })
50437
+ );
50548
50438
  }
50549
- }
50550
- if (params.eventId && !params.event) {
50551
- const { event } = findEvent({
50552
- eventId: params.eventId,
50553
- tournamentRecord
50439
+ });
50440
+ }
50441
+ params.tournamentParticipants?.forEach((participant) => {
50442
+ const { scheduleConflicts, scheduleItems } = annotateParticipant({
50443
+ ...params,
50444
+ eventsPublishStatuses,
50445
+ participantIdMap,
50446
+ derivedDrawInfo,
50447
+ participant
50448
+ });
50449
+ if (params.withSignInStatus) {
50450
+ const { timeItem } = getTimeItem({
50451
+ itemType: SIGN_IN_STATUS,
50452
+ element: participant
50554
50453
  });
50555
- if (event) {
50556
- params = { ...params, event };
50454
+ participant.signedIn = timeItem?.itemValue === SIGNED_IN;
50455
+ }
50456
+ if (params.withScheduleItems) {
50457
+ participant.scheduleItems = scheduleItems;
50458
+ }
50459
+ if (params.scheduleAnalysis) {
50460
+ participant.scheduleConflicts = scheduleConflicts;
50461
+ if (scheduleConflicts?.length && !participantIdsWithConflicts.includes(participant.participantId)) {
50462
+ participantIdsWithConflicts.push(participant.participantId);
50557
50463
  }
50558
50464
  }
50559
- }
50560
- return params;
50561
- }
50562
-
50563
- function getEligibleVoluntaryConsolationParticipants(params) {
50564
- if (!params.tournamentRecord)
50565
- return { error: MISSING_TOURNAMENT_RECORD };
50566
- return getEligibleVoluntaryConsolationParticipants$1(params);
50465
+ if (params.withGroupings !== false) {
50466
+ const participantAttributes = participantIdMap[participant.participantId];
50467
+ participant.groupParticipantIds = participantAttributes?.groupParticipantIds;
50468
+ participant.pairParticipantIds = participantAttributes?.pairParticipantIds;
50469
+ participant.teamParticipantIds = participantAttributes?.teamParticipantIds;
50470
+ participant.groups = participantAttributes?.groups;
50471
+ participant.teams = participantAttributes?.teams;
50472
+ }
50473
+ if (params.withTeamMatchUps) ;
50474
+ });
50475
+ return { participantIdsWithConflicts, eventsPublishStatuses };
50567
50476
  }
50568
50477
 
50569
- function getParticipantEventDetails({
50570
- tournamentRecord,
50571
- participantId
50572
- }) {
50478
+ function getTournamentParticipants(params) {
50479
+ const {
50480
+ participantFilters = {},
50481
+ convertExtensions,
50482
+ policyDefinitions,
50483
+ withScheduleItems,
50484
+ scheduleAnalysis,
50485
+ withSignInStatus,
50486
+ withTeamMatchUps,
50487
+ // not implemented
50488
+ tournamentRecord,
50489
+ usePublishState,
50490
+ withScaleValues,
50491
+ withStatistics,
50492
+ withGroupings,
50493
+ withOpponents,
50494
+ withMatchUps,
50495
+ withSeeding,
50496
+ withEvents,
50497
+ withDraws,
50498
+ inContext,
50499
+ withISO2,
50500
+ withIOC
50501
+ } = params;
50573
50502
  if (!tournamentRecord)
50574
50503
  return { error: MISSING_TOURNAMENT_RECORD };
50575
- if (!participantId)
50576
- return { error: MISSING_PARTICIPANT_ID };
50577
- const relevantParticipantIds = [participantId].concat(
50578
- (tournamentRecord.participants || []).filter(
50579
- (participant) => participant?.participantType && [TEAM, PAIR].includes(participant.participantType) && participant.individualParticipantIds?.includes(participantId)
50580
- ).map((participant) => participant.participantId)
50504
+ if (!tournamentRecord.participants)
50505
+ return { error: MISSING_PARTICIPANTS };
50506
+ const allTournamentParticipants = tournamentRecord.participants.map(
50507
+ // (participant) => makeDeepCopy(participant, convertExtensions, true)
50508
+ (participant) => makeDeepCopy(participant, convertExtensions)
50509
+ // removed until Mongo/Mongoose issues resolved
50581
50510
  );
50582
- const relevantEvents = (tournamentRecord.events || []).filter((event) => {
50583
- const enteredParticipantIds = (event?.entries || []).map(
50584
- (entry) => entry.participantId
50511
+ if (typeof participantFilters !== "object")
50512
+ return { error: INVALID_OBJECT, participantFilters };
50513
+ if (inContext) {
50514
+ allTournamentParticipants?.forEach((participant) => {
50515
+ if ([PAIR, TEAM, GROUP].includes(participant.participantType)) {
50516
+ participant.individualParticipants = participant.individualParticipantIds?.map((participantId) => {
50517
+ const targetParticipant = tournamentRecord.participants.find(
50518
+ (p) => p.participantId === participantId
50519
+ );
50520
+ const individualParticipant = makeDeepCopy(
50521
+ targetParticipant,
50522
+ convertExtensions,
50523
+ true
50524
+ );
50525
+ if (withScaleValues) {
50526
+ const { ratings, rankings } = getScaleValues({
50527
+ participant: individualParticipant
50528
+ });
50529
+ individualParticipant.ratings = ratings;
50530
+ individualParticipant.rankings = rankings;
50531
+ }
50532
+ if (withIOC || withISO2)
50533
+ addNationalityCode({
50534
+ participant: individualParticipant,
50535
+ withISO2,
50536
+ withIOC
50537
+ });
50538
+ return individualParticipant;
50539
+ });
50540
+ }
50541
+ });
50542
+ }
50543
+ let tournamentParticipants = participantFilters ? filterParticipants({
50544
+ participants: allTournamentParticipants,
50545
+ participantFilters,
50546
+ tournamentRecord
50547
+ }) : allTournamentParticipants;
50548
+ let participantIdsWithConflicts, eventsPublishStatuses;
50549
+ const addContext = withScheduleItems || withSignInStatus || scheduleAnalysis || withScaleValues || withStatistics || withGroupings || withOpponents || withMatchUps || withSeeding || withEvents || withDraws || withISO2 || withIOC;
50550
+ if (addContext) {
50551
+ const result = addParticipantContext({
50552
+ tournamentEvents: tournamentRecord.events,
50553
+ allTournamentParticipants,
50554
+ tournamentParticipants,
50555
+ participantFilters,
50556
+ withScheduleItems,
50557
+ withSignInStatus,
50558
+ tournamentRecord,
50559
+ scheduleAnalysis,
50560
+ withTeamMatchUps,
50561
+ usePublishState,
50562
+ withScaleValues,
50563
+ withStatistics,
50564
+ withGroupings,
50565
+ withOpponents,
50566
+ withMatchUps,
50567
+ withSeeding,
50568
+ withEvents,
50569
+ withDraws,
50570
+ withISO2,
50571
+ withIOC
50572
+ });
50573
+ participantIdsWithConflicts = result?.participantIdsWithConflicts;
50574
+ eventsPublishStatuses = result?.eventsPublishStatuses;
50575
+ }
50576
+ const participantAttributes = policyDefinitions?.[POLICY_TYPE_PARTICIPANT];
50577
+ if (participantAttributes?.participant) {
50578
+ tournamentParticipants = tournamentParticipants.map(
50579
+ (participant) => attributeFilter({
50580
+ template: participantAttributes.participant,
50581
+ source: participant
50582
+ })
50585
50583
  );
50586
- return overlap(enteredParticipantIds, relevantParticipantIds);
50587
- }).map((event) => ({ eventName: event.eventName, eventId: event.eventId }));
50588
- return { eventDetails: relevantEvents };
50584
+ }
50585
+ return {
50586
+ participantIdsWithConflicts,
50587
+ tournamentParticipants,
50588
+ eventsPublishStatuses
50589
+ };
50589
50590
  }
50590
50591
 
50591
50592
  function getParticipantMembership({
@@ -54089,6 +54090,11 @@ function updateCourtAvailability({ tournamentRecord }) {
54089
54090
  );
54090
54091
  return existing || { date, startTime, endTime };
54091
54092
  });
54093
+ const defaultAvailability = court.dateAvailability?.find(
54094
+ (availability) => !availability.date
54095
+ );
54096
+ if (defaultAvailability)
54097
+ updatedDateAvailability.unshift(defaultAvailability);
54092
54098
  court.dateAvailability = updatedDateAvailability;
54093
54099
  }
54094
54100
  return { ...SUCCESS };
@@ -59028,7 +59034,7 @@ function generateDrawDefinition(params) {
59028
59034
  drawDefinition.links = [];
59029
59035
  drawDefinition.links.push(link);
59030
59036
  }
59031
- drawDefinition.drawName = params.drawName ?? drawType;
59037
+ drawDefinition.drawName = params.drawName ?? (drawType && constantToString(drawType));
59032
59038
  if (typeof voluntaryConsolation === "object") {
59033
59039
  addVoluntaryConsolationStructure({
59034
59040
  ...voluntaryConsolation,