tods-competition-factory 0.65.2 → 0.67.2

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.
@@ -249,7 +249,7 @@ const matchUpFormatCode = {
249
249
  };
250
250
 
251
251
  function factoryVersion() {
252
- return '0.65.2';
252
+ return '0.67.2';
253
253
  }
254
254
 
255
255
  const FORMAT_STANDARD = 'SET3-S:6/TB7'; // Best of 3 Tiebreak Sets to 6
@@ -7525,6 +7525,7 @@ const LUCKY_PARTICIPANT_METHOD = 'luckyLoserDrawPositionAssignment';
7525
7525
  const REMOVE_ASSIGNMENT_METHOD = 'removeDrawPositionAssignment';
7526
7526
  const SWAP_PARTICIPANT_METHOD = 'swapDrawPositionAssignments';
7527
7527
  const ADD_NICKNAME_METHOD = 'modifyParticipantOtherName';
7528
+ const ASSIGN_SIDE_METHOD = 'assignMatchUpSideParticipant';
7528
7529
  const ASSIGN_PARTICIPANT_METHOD = 'assignDrawPosition';
7529
7530
  const ASSIGN_BYE_METHOD = 'assignDrawPositionBye';
7530
7531
  const SEED_VALUE_METHOD = 'modifySeedAssignment';
@@ -9455,7 +9456,9 @@ function getRoundMatchUps$1({
9455
9456
  const currentRoundMatchUps = roundMatchUps[roundNumber].sort((a, b) => a.roundPosition - b.roundPosition);
9456
9457
  const currentRoundDrawPositions = currentRoundMatchUps.map(matchUp => (matchUp === null || matchUp === void 0 ? void 0 : matchUp.drawPositions) || []).flat();
9457
9458
  roundProfile[roundNumber].roundNumber = roundNumber; // convenience
9459
+ // convenience for display calculations
9458
9460
 
9461
+ roundProfile[roundNumber].roundFactor = roundProfile[roundNumber].matchUpsCount ? maxMatchUpsCount / roundProfile[roundNumber].matchUpsCount : 1;
9459
9462
  roundProfile[roundNumber].finishingRound = finishingRoundMap[roundNumber].finishingRound;
9460
9463
  roundProfile[roundNumber].roundName = finishingRoundMap[roundNumber].roundName;
9461
9464
  roundProfile[roundNumber].abbreviatedRoundName = finishingRoundMap[roundNumber].abbreviatedRoundName;
@@ -10671,6 +10674,16 @@ function getOrderedDrawPositions({
10671
10674
  };
10672
10675
  }
10673
10676
 
10677
+ function isAdHoc({
10678
+ drawDefinition,
10679
+ structure
10680
+ }) {
10681
+ if (!drawDefinition || !structure) return false;
10682
+ return !(structure !== null && structure !== void 0 && structure.structures) && !(drawDefinition !== null && drawDefinition !== void 0 && drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) && !(structure !== null && structure !== void 0 && structure.matchUps.find(({
10683
+ roundPosition
10684
+ }) => !!roundPosition));
10685
+ }
10686
+
10674
10687
  function getRoundContextProfile({
10675
10688
  roundNamingPolicy,
10676
10689
  structure,
@@ -10678,6 +10691,9 @@ function getRoundContextProfile({
10678
10691
  }) {
10679
10692
  const roundNamingProfile = {};
10680
10693
  const isRoundRobin = structure.structures;
10694
+ const isAdHocStructure = isAdHoc({
10695
+ structure
10696
+ });
10681
10697
  const {
10682
10698
  roundProfile
10683
10699
  } = getRoundMatchUps$1({
@@ -10695,7 +10711,7 @@ function getRoundContextProfile({
10695
10711
  const stageConstants = roundNamingPolicy === null || roundNamingPolicy === void 0 ? void 0 : roundNamingPolicy.stageConstants;
10696
10712
  const stageConstant = stageConstants && stageConstants[stage] || stageInitial;
10697
10713
 
10698
- if (isRoundRobin) {
10714
+ if (isRoundRobin || isAdHocStructure) {
10699
10715
  Object.assign(roundNamingProfile, ...Object.keys(roundProfile).map(key => {
10700
10716
  const profileSize = `R${key}`;
10701
10717
  return {
@@ -11379,7 +11395,7 @@ function getAllStructureMatchUps({
11379
11395
  matchUp,
11380
11396
  event
11381
11397
  }) {
11382
- var _roundNamingProfile$r, _roundNamingProfile$r2, _roundProfile$roundNu, _roundProfile$roundNu2;
11398
+ var _roundNamingProfile$r, _roundNamingProfile$r2, _roundProfile$roundNu, _roundProfile$roundNu2, _roundProfile$roundNu3;
11383
11399
 
11384
11400
  const tieFormat = matchUp.tieFormat || structure.tieFormat || (drawDefinition === null || drawDefinition === void 0 ? void 0 : drawDefinition.tieFormat) || (event === null || event === void 0 ? void 0 : event.tieFormat);
11385
11401
  const collectionDefinitions = tieFormat === null || tieFormat === void 0 ? void 0 : tieFormat.collectionDefinitions;
@@ -11421,6 +11437,7 @@ function getAllStructureMatchUps({
11421
11437
  const abbreviatedRoundName = roundNamingProfile && ((_roundNamingProfile$r2 = roundNamingProfile[roundNumber]) === null || _roundNamingProfile$r2 === void 0 ? void 0 : _roundNamingProfile$r2.abbreviatedRoundName) || additionalContext.abbreviatedRoundName;
11422
11438
  const feedRound = roundProfile === null || roundProfile === void 0 ? void 0 : (_roundProfile$roundNu = roundProfile[roundNumber]) === null || _roundProfile$roundNu === void 0 ? void 0 : _roundProfile$roundNu.feedRound;
11423
11439
  const preFeedRound = roundProfile === null || roundProfile === void 0 ? void 0 : (_roundProfile$roundNu2 = roundProfile[roundNumber]) === null || _roundProfile$roundNu2 === void 0 ? void 0 : _roundProfile$roundNu2.preFeedRound;
11440
+ const roundFactor = roundProfile === null || roundProfile === void 0 ? void 0 : (_roundProfile$roundNu3 = roundProfile[roundNumber]) === null || _roundProfile$roundNu3 === void 0 ? void 0 : _roundProfile$roundNu3.roundFactor;
11424
11441
  const drawPositionsRoundRanges = drawPositionsRanges && drawPositionsRanges[roundNumber];
11425
11442
  const drawPositionsRange = drawPositionsRoundRanges && drawPositionsRoundRanges[roundPosition];
11426
11443
  const sourceDrawPositionRoundRanges = sourceDrawPositionRanges && sourceDrawPositionRanges[roundNumber]; // order is important here as Round Robin matchUps already have inContext structureId
@@ -11437,8 +11454,10 @@ function getAllStructureMatchUps({
11437
11454
  stageSequence,
11438
11455
  drawPositions,
11439
11456
  matchUpStatus,
11457
+ isRoundRobin,
11440
11458
  matchUpTieId,
11441
11459
  preFeedRound,
11460
+ roundFactor,
11442
11461
  matchUpType,
11443
11462
  exitProfile,
11444
11463
  structureId,
@@ -13038,7 +13057,7 @@ function addUpcomingMatchUps({
13038
13057
  }
13039
13058
 
13040
13059
  if ((_loserTo = loserTo) !== null && _loserTo !== void 0 && (_loserTo$schedule = _loserTo.schedule) !== null && _loserTo$schedule !== void 0 && _loserTo$schedule.scheduledTime) {
13041
- const scheduleConflict = timeStringMinutes(winnerTo.schedule.scheduledTime) < timeStringMinutes(timeAfterRecovery);
13060
+ const scheduleConflict = timeStringMinutes(loserTo.schedule.scheduledTime) < timeStringMinutes(timeAfterRecovery);
13042
13061
 
13043
13062
  if (scheduleConflict) {
13044
13063
  scheduleConflictMatchUpIds[loserTo.matchUpId] = inContextMatchUp.matchUpId;
@@ -16373,15 +16392,23 @@ function removeDirectedParticipants(params) {
16373
16392
  structure,
16374
16393
  event
16375
16394
  } = params;
16376
- const isCollectionMatchUp = Boolean(params.matchUp.collectionId); // targetData will have team matchUp when params.matchUp is a collectionMatchUp
16395
+ const isCollectionMatchUp = Boolean(params.matchUp.collectionId);
16396
+ const isAdHocMatchUp = isAdHoc({
16397
+ drawDefinition,
16398
+ structure
16399
+ }); // targetData will have team matchUp when params.matchUp is a collectionMatchUp
16377
16400
 
16378
16401
  const {
16379
16402
  drawPositions,
16380
16403
  winningSide
16381
16404
  } = targetData.matchUp || {};
16382
- if (!drawPositions) return {
16383
- error: MISSING_DRAW_POSITIONS
16384
- };
16405
+
16406
+ if (!isAdHocMatchUp && !drawPositions) {
16407
+ return {
16408
+ error: MISSING_DRAW_POSITIONS
16409
+ };
16410
+ }
16411
+
16385
16412
  const {
16386
16413
  targetLinks: {
16387
16414
  loserTargetLink,
@@ -16392,27 +16419,6 @@ function removeDirectedParticipants(params) {
16392
16419
  winnerMatchUp
16393
16420
  }
16394
16421
  } = targetData;
16395
- const {
16396
- positionAssignments
16397
- } = structureAssignedDrawPositions({
16398
- structure
16399
- });
16400
- const winningIndex = winningSide - 1;
16401
- const losingIndex = 1 - winningIndex;
16402
- const winningDrawPosition = drawPositions[winningIndex];
16403
- const loserDrawPosition = drawPositions[losingIndex]; // use reduce for single pass resolution of both
16404
-
16405
- const {
16406
- winnerParticipantId,
16407
- loserParticipantId
16408
- } = positionAssignments.reduce((assignments, assignment) => {
16409
- if (assignment.drawPosition === loserDrawPosition) assignments.loserParticipantId = assignment.participantId;
16410
- if (assignment.drawPosition === winningDrawPosition) assignments.winnerParticipantId = assignment.participantId;
16411
- return assignments;
16412
- }, {
16413
- winnerParticipantId: undefined,
16414
- loserParticipantId: undefined
16415
- });
16416
16422
  const result = modifyMatchUpScore({ ...params,
16417
16423
  matchUpStatus: matchUpStatus || TO_BE_PLAYED,
16418
16424
  removeWinningSide: true
@@ -16435,6 +16441,8 @@ function removeDirectedParticipants(params) {
16435
16441
  };
16436
16442
  }
16437
16443
 
16444
+ if (isAdHocMatchUp) return { ...SUCCESS
16445
+ };
16438
16446
  const {
16439
16447
  matchUps: sourceMatchUps
16440
16448
  } = getAllStructureMatchUps({
@@ -16443,6 +16451,27 @@ function removeDirectedParticipants(params) {
16443
16451
  matchUpsMap,
16444
16452
  structure
16445
16453
  });
16454
+ const {
16455
+ positionAssignments
16456
+ } = structureAssignedDrawPositions({
16457
+ structure
16458
+ });
16459
+ const winningIndex = winningSide - 1;
16460
+ const losingIndex = 1 - winningIndex;
16461
+ const winningDrawPosition = drawPositions[winningIndex];
16462
+ const loserDrawPosition = drawPositions[losingIndex]; // use reduce for single pass resolution of both
16463
+
16464
+ const {
16465
+ winnerParticipantId,
16466
+ loserParticipantId
16467
+ } = positionAssignments.reduce((assignments, assignment) => {
16468
+ if (assignment.drawPosition === loserDrawPosition) assignments.loserParticipantId = assignment.participantId;
16469
+ if (assignment.drawPosition === winningDrawPosition) assignments.winnerParticipantId = assignment.participantId;
16470
+ return assignments;
16471
+ }, {
16472
+ winnerParticipantId: undefined,
16473
+ loserParticipantId: undefined
16474
+ });
16446
16475
  const drawPositionMatchUps = sourceMatchUps.filter(matchUp => matchUp.drawPositions.includes(loserDrawPosition));
16447
16476
 
16448
16477
  if (winnerMatchUp) {
@@ -18037,40 +18066,6 @@ function checkConnectedStructures({
18037
18066
  };
18038
18067
  }
18039
18068
 
18040
- function getAvailableAdHocParticipantIds({
18041
- drawDefinition,
18042
- drawPosition,
18043
- structure
18044
- }) {
18045
- var _structure$matchUps, _structure$matchUps2, _structure$positionAs;
18046
-
18047
- // In AdHoc draws a participant can be assigned to multiple drawPositions ...
18048
- // ... because each round is unique ...
18049
- // therfore, the targetMatchUp must be found...
18050
- const targetMatchUp = structure === null || structure === void 0 ? void 0 : (_structure$matchUps = structure.matchUps) === null || _structure$matchUps === void 0 ? void 0 : _structure$matchUps.find(matchUp => {
18051
- var _matchUp$drawPosition;
18052
-
18053
- return (_matchUp$drawPosition = matchUp.drawPositions) === null || _matchUp$drawPosition === void 0 ? void 0 : _matchUp$drawPosition.includes(drawPosition);
18054
- }); // ... so that the target roundNumber can be found ...
18055
-
18056
- const roundNumber = targetMatchUp === null || targetMatchUp === void 0 ? void 0 : targetMatchUp.roundNumber; // ... so that the round's drawPositions can be found ...
18057
-
18058
- const roundDrawPositions = structure === null || structure === void 0 ? void 0 : (_structure$matchUps2 = structure.matchUps) === null || _structure$matchUps2 === void 0 ? void 0 : _structure$matchUps2.filter(matchUp => matchUp.roundNumber === roundNumber).map(({
18059
- drawPositions
18060
- }) => drawPositions).flat(); // ... so that the round's assigned participantIds can be found ...
18061
-
18062
- const roundAssignedParticipantIds = structure === null || structure === void 0 ? void 0 : (_structure$positionAs = structure.positionAssignments) === null || _structure$positionAs === void 0 ? void 0 : _structure$positionAs.filter(({
18063
- drawPosition,
18064
- participantId
18065
- }) => roundDrawPositions.includes(drawPosition) && participantId).map(getParticipantId);
18066
- const enteredParticipantIds = (drawDefinition === null || drawDefinition === void 0 ? void 0 : drawDefinition.entries.filter(({
18067
- entryStatus
18068
- }) => [DIRECT_ACCEPTANCE, ORGANISER_ACCEPTANCE, WILDCARD].includes(entryStatus)).map(getParticipantId)) || []; // AdHoc available participants are those entered in the draw who are not assigned to the target round
18069
-
18070
- const availableParticipantIds = enteredParticipantIds.filter(participantId => !roundAssignedParticipantIds.includes(participantId));
18071
- return availableParticipantIds;
18072
- }
18073
-
18074
18069
  function conditionallyDisableLinkPositioning({
18075
18070
  drawPositions,
18076
18071
  structure
@@ -18686,6 +18681,12 @@ function assignDrawPosition$1({
18686
18681
  if (error) return {
18687
18682
  error
18688
18683
  };
18684
+ if (isAdHoc({
18685
+ drawDefinition,
18686
+ structure
18687
+ })) return {
18688
+ error: INVALID_MATCHUP
18689
+ };
18689
18690
  const {
18690
18691
  positionAssignments
18691
18692
  } = structureAssignedDrawPositions({
@@ -18719,16 +18720,7 @@ function assignDrawPosition$1({
18719
18720
  if (!participantId) return {
18720
18721
  error: MISSING_PARTICIPANT_ID
18721
18722
  };
18722
- const isAdHoc = !(structure !== null && structure !== void 0 && structure.structures) && !(structure !== null && structure !== void 0 && structure.matchUps.find(({
18723
- roundPosition
18724
- }) => !!roundPosition)); // in adHoc structures participants may have a drawPosition assigned in each round
18725
- // whereas in other types of structures they may appear only once in positionAssignments
18726
-
18727
- const participantAlreadyAssigned = isAdHoc ? !getAvailableAdHocParticipantIds({
18728
- drawDefinition,
18729
- drawPosition,
18730
- structure
18731
- }).includes(participantId) : positionAssignments.map(getParticipantId).includes(participantId);
18723
+ const participantAlreadyAssigned = positionAssignments.map(getParticipantId).includes(participantId);
18732
18724
 
18733
18725
  if (participantAlreadyAssigned) {
18734
18726
  return {
@@ -19215,7 +19207,11 @@ function directParticipants(params) {
19215
19207
  score
19216
19208
  } = params;
19217
19209
  const isCollectionMatchUp = Boolean(matchUp.collectionId);
19218
- const validToScore = isCollectionMatchUp || drawPositionsAssignedParticipantIds({
19210
+ const isAdHocMatchUp = isAdHoc({
19211
+ drawDefinition,
19212
+ structure
19213
+ });
19214
+ const validToScore = isCollectionMatchUp || isAdHocMatchUp || drawPositionsAssignedParticipantIds({
19219
19215
  structure,
19220
19216
  matchUp
19221
19217
  });
@@ -19264,6 +19260,11 @@ function directParticipants(params) {
19264
19260
  };
19265
19261
  }
19266
19262
 
19263
+ if (isAdHocMatchUp) {
19264
+ return { ...SUCCESS
19265
+ };
19266
+ }
19267
+
19267
19268
  if (drawPositions) {
19268
19269
  const winningIndex = winningSide - 1;
19269
19270
  const losingIndex = 1 - winningIndex;
@@ -19778,7 +19779,7 @@ function swapWinnerLoser(params) {
19778
19779
  // WOULDBENICE: return object containing all modified { matchUpIds, structureIds, drawIds }
19779
19780
 
19780
19781
  function setMatchUpStatus$2(params) {
19781
- var _inContextMatchUp$dra;
19782
+ var _inContextMatchUp$dra, _matchUp$sides;
19782
19783
 
19783
19784
  // matchUpStatus in params is the new status
19784
19785
  // winningSide in params is new winningSide
@@ -19857,12 +19858,6 @@ function setMatchUpStatus$2(params) {
19857
19858
 
19858
19859
  const assignedDrawPositions = (_inContextMatchUp$dra = inContextMatchUp.drawPositions) === null || _inContextMatchUp$dra === void 0 ? void 0 : _inContextMatchUp$dra.filter(Boolean);
19859
19860
 
19860
- if (matchUpStatus && particicipantsRequiredMatchUpStatuses.includes(matchUpStatus) && (!assignedDrawPositions || (assignedDrawPositions === null || assignedDrawPositions === void 0 ? void 0 : assignedDrawPositions.length) < 2)) {
19861
- return {
19862
- error: INVALID_MATCHUP_STATUS
19863
- };
19864
- }
19865
-
19866
19861
  if (matchUp.matchUpType === TEAM$3) {
19867
19862
  // do not direclty set team score... unless walkover/default/double walkover/Retirement
19868
19863
  return {
@@ -19885,6 +19880,14 @@ function setMatchUpStatus$2(params) {
19885
19880
  drawDefinition,
19886
19881
  structureId
19887
19882
  });
19883
+ const bothSideParticipants = ((_matchUp$sides = matchUp.sides) === null || _matchUp$sides === void 0 ? void 0 : _matchUp$sides.map(side => side.participantId).filter(Boolean).length) === 2 || (assignedDrawPositions === null || assignedDrawPositions === void 0 ? void 0 : assignedDrawPositions.length) === 2;
19884
+
19885
+ if (matchUpStatus && particicipantsRequiredMatchUpStatuses.includes(matchUpStatus) && !bothSideParticipants) {
19886
+ return {
19887
+ error: INVALID_MATCHUP_STATUS
19888
+ };
19889
+ }
19890
+
19888
19891
  Object.assign(params, {
19889
19892
  inContextDrawMatchUps,
19890
19893
  inContextMatchUp,
@@ -28408,6 +28411,7 @@ const matchUpActionConstants = {
28408
28411
  */
28409
28412
 
28410
28413
  function matchUpActions$2({
28414
+ tournamentParticipants = [],
28411
28415
  inContextDrawMatchUps,
28412
28416
  drawDefinition,
28413
28417
  matchUpsMap,
@@ -28422,6 +28426,9 @@ function matchUpActions$2({
28422
28426
  if (!matchUpId) return {
28423
28427
  error: MISSING_MATCHUP_ID
28424
28428
  };
28429
+ const {
28430
+ drawId
28431
+ } = drawDefinition;
28425
28432
  const {
28426
28433
  matchUp,
28427
28434
  structure
@@ -28446,6 +28453,46 @@ function matchUpActions$2({
28446
28453
  if (!structureId) return {
28447
28454
  validActions
28448
28455
  };
28456
+
28457
+ if (isAdHoc({
28458
+ drawDefinition,
28459
+ structure
28460
+ })) {
28461
+ const roundMatchUps = (structure.matchUps || []).filter(({
28462
+ roundNumber
28463
+ }) => roundNumber === matchUp.roundNumber);
28464
+ const enteredParticipantIds = (drawDefinition === null || drawDefinition === void 0 ? void 0 : drawDefinition.entries.filter(({
28465
+ entryStatus
28466
+ }) => [DIRECT_ACCEPTANCE, ORGANISER_ACCEPTANCE, WILDCARD].includes(entryStatus)).map(getParticipantId)) || [];
28467
+ const roundAssignedParticipantIds = roundMatchUps.map(matchUp => (matchUp.sides || []).map(side => side.participantId)).flat().filter(Boolean);
28468
+ const availableParticipantIds = enteredParticipantIds.filter(participantId => !roundAssignedParticipantIds.includes(participantId));
28469
+ const participantsAvailable = tournamentParticipants === null || tournamentParticipants === void 0 ? void 0 : tournamentParticipants.filter(participant => availableParticipantIds === null || availableParticipantIds === void 0 ? void 0 : availableParticipantIds.includes(participant.participantId));
28470
+ participantsAvailable === null || participantsAvailable === void 0 ? void 0 : participantsAvailable.forEach(participant => {
28471
+ const entry = (drawDefinition.entries || []).find(entry => entry.participantId === participant.participantId);
28472
+ participant.entryPosition = entry === null || entry === void 0 ? void 0 : entry.entryPosition;
28473
+ });
28474
+
28475
+ if (availableParticipantIds.length) {
28476
+ validActions.push({
28477
+ type: ASSIGN_PARTICIPANT,
28478
+ availableParticipantIds,
28479
+ participantsAvailable,
28480
+ method: ASSIGN_SIDE_METHOD,
28481
+ payload: {
28482
+ drawId,
28483
+ matchUpId,
28484
+ structureId
28485
+ /*, sideNumber*/
28486
+
28487
+ }
28488
+ });
28489
+ }
28490
+
28491
+ validActions.push({
28492
+ type: ALTERNATE_PARTICIPANT
28493
+ });
28494
+ }
28495
+
28449
28496
  const structureIsComplete = isCompletedStructure({
28450
28497
  drawDefinition,
28451
28498
  structure
@@ -28510,9 +28557,6 @@ function matchUpActions$2({
28510
28557
  }
28511
28558
 
28512
28559
  const readyToScore = (matchUpDrawPositionsAreAssigned || hasParticipants) && !(isDoubleWalkover && activeDownstream);
28513
- const {
28514
- drawId
28515
- } = drawDefinition;
28516
28560
  const addPenaltyAction = {
28517
28561
  type: ADD_PENALTY,
28518
28562
  method: ADD_PENALTY_METHOD,
@@ -31477,70 +31521,6 @@ function generateVoluntaryConsolationStructure$1({
31477
31521
  };
31478
31522
  }
31479
31523
 
31480
- /**
31481
- *
31482
- * @param {string} drawId - when called via tournamentEngine enabled drawDefinition discovery
31483
- * @param {object} drawDefinition - required when called via drawEngine
31484
- * @param {string} structureId
31485
- * @param {object[]} matchUps
31486
- *
31487
- */
31488
-
31489
- function addAdHocMatchUps$1({
31490
- drawDefinition,
31491
- structureId,
31492
- matchUps
31493
- }) {
31494
- var _drawDefinition$struc;
31495
-
31496
- if (typeof drawDefinition !== 'object') return {
31497
- error: MISSING_DRAW_DEFINITION
31498
- };
31499
- if (typeof structureId !== 'string') return {
31500
- error: MISSING_STRUCTURE_ID
31501
- };
31502
- if (!Array.isArray(matchUps)) return {
31503
- error: INVALID_VALUES
31504
- };
31505
- const structure = (_drawDefinition$struc = drawDefinition.structures) === null || _drawDefinition$struc === void 0 ? void 0 : _drawDefinition$struc.find(structure => structure.structureId === structureId);
31506
- if (!structure) return {
31507
- error: STRUCTURE_NOT_FOUND
31508
- };
31509
- const existingMatchUps = structure === null || structure === void 0 ? void 0 : structure.matchUps;
31510
- const structureHasRoundPositions = existingMatchUps.find(matchUp => !!matchUp.roundPosition);
31511
-
31512
- if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
31513
- return {
31514
- error: INVALID_STRUCTURE
31515
- };
31516
- }
31517
-
31518
- const existingDrawPositions = (structure.matchUps || []).map(({
31519
- drawPositions
31520
- }) => drawPositions).flat().sort((a, b) => a - b);
31521
- const nextDrawPosition = Math.max(...existingDrawPositions, 0) + 1;
31522
- const matchUpsCount = matchUps.length;
31523
- const newDrawPositions = generateRange(nextDrawPosition, nextDrawPosition + matchUpsCount * 2);
31524
- const newDrawPositionPairs = chunkArray(newDrawPositions, 2);
31525
- matchUps.forEach((matchUp, i) => matchUp.drawPositions = newDrawPositionPairs[i]);
31526
- structure.matchUps.push(...matchUps);
31527
- const newPositionAssignments = newDrawPositions.map(drawPosition => ({
31528
- drawPosition
31529
- }));
31530
- if (!structure.positionAssignments) structure.positionAssignments = [];
31531
- structure.positionAssignments.push(...newPositionAssignments);
31532
- addMatchUpsNotice({
31533
- drawDefinition,
31534
- matchUps
31535
- });
31536
- modifyDrawNotice({
31537
- drawDefinition,
31538
- structureIds: [structureId]
31539
- });
31540
- return { ...SUCCESS
31541
- };
31542
- }
31543
-
31544
31524
  /**
31545
31525
  *
31546
31526
  * @param {string} drawId - required - tournamentEngine discovers and passes { drawDefinition }
@@ -31555,12 +31535,12 @@ function addAdHocMatchUps$1({
31555
31535
  */
31556
31536
 
31557
31537
  function generateAdHocMatchUps$1({
31558
- drawDefinition,
31559
- structureId,
31560
- addMatchUps = false,
31561
- matchUpsCount = 1,
31538
+ participantIdPairings,
31562
31539
  matchUpIds = [],
31540
+ drawDefinition,
31541
+ matchUpsCount,
31563
31542
  roundNumber,
31543
+ structureId,
31564
31544
  newRound
31565
31545
  }) {
31566
31546
  var _drawDefinition$struc;
@@ -31571,7 +31551,7 @@ function generateAdHocMatchUps$1({
31571
31551
  if (typeof structureId !== 'string') return {
31572
31552
  error: MISSING_STRUCTURE_ID
31573
31553
  };
31574
- if (!isConvertableInteger(matchUpsCount) || !Array.isArray(matchUpIds)) return {
31554
+ if (participantIdPairings && !Array.isArray(participantIdPairings) || matchUpsCount && !isConvertableInteger(matchUpsCount) || matchUpIds && !Array.isArray(matchUpIds) || !participantIdPairings && !matchUpsCount) return {
31575
31555
  error: INVALID_VALUES
31576
31556
  }; // if drawDefinition and structureId are provided it is possible to infer roundNumber
31577
31557
 
@@ -31595,25 +31575,74 @@ function generateAdHocMatchUps$1({
31595
31575
  error: INVALID_VALUES
31596
31576
  };
31597
31577
  const nextRoundNumber = roundNumber || (newRound ? lastRoundNumber + 1 : lastRoundNumber || 1);
31598
- const matchUps = generateRange(0, matchUpsCount).map(() => ({
31599
- matchUpId: matchUpIds.pop() || UUID(),
31600
- roundNumber: nextRoundNumber,
31601
- matchUpStatus: TO_BE_PLAYED,
31602
- drawPositions: []
31578
+ participantIdPairings = participantIdPairings || generateRange(0, matchUpsCount).map(() => ({
31579
+ participantIds: []
31603
31580
  }));
31581
+ const matchUps = participantIdPairings.map(pairing => {
31582
+ // ensure there are always 2 sides in generated matchUps
31583
+ const participantIds = ((pairing === null || pairing === void 0 ? void 0 : pairing.participantIds) || []).concat([undefined, undefined]).slice(0, 2);
31584
+ const sides = participantIds.map((participantId, i) => definedAttributes({
31585
+ sideNumber: i + 1,
31586
+ participantId
31587
+ }));
31588
+ return {
31589
+ matchUpId: matchUpIds.pop() || UUID(),
31590
+ roundNumber: nextRoundNumber,
31591
+ matchUpStatus: TO_BE_PLAYED,
31592
+ sides
31593
+ };
31594
+ });
31595
+ const result = addAdHocMatchUps({
31596
+ drawDefinition,
31597
+ structureId,
31598
+ matchUps
31599
+ });
31600
+ if (result.error) return result;
31601
+ return {
31602
+ matchUpsCount: matchUps.length,
31603
+ ...SUCCESS
31604
+ };
31605
+ }
31604
31606
 
31605
- if (addMatchUps) {
31606
- const result = addAdHocMatchUps$1({
31607
- drawDefinition,
31608
- structureId,
31609
- matchUps
31610
- });
31611
- if (result.error) return result;
31607
+ function addAdHocMatchUps({
31608
+ drawDefinition,
31609
+ structureId,
31610
+ matchUps
31611
+ }) {
31612
+ var _drawDefinition$struc2;
31613
+
31614
+ if (typeof drawDefinition !== 'object') return {
31615
+ error: MISSING_DRAW_DEFINITION
31616
+ };
31617
+ if (typeof structureId !== 'string') return {
31618
+ error: MISSING_STRUCTURE_ID
31619
+ };
31620
+ if (!Array.isArray(matchUps)) return {
31621
+ error: INVALID_VALUES
31622
+ };
31623
+ const structure = (_drawDefinition$struc2 = drawDefinition.structures) === null || _drawDefinition$struc2 === void 0 ? void 0 : _drawDefinition$struc2.find(structure => structure.structureId === structureId);
31624
+ if (!structure) return {
31625
+ error: STRUCTURE_NOT_FOUND
31626
+ };
31627
+ const existingMatchUps = structure === null || structure === void 0 ? void 0 : structure.matchUps;
31628
+ const structureHasRoundPositions = existingMatchUps.find(matchUp => !!matchUp.roundPosition);
31629
+
31630
+ if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
31631
+ return {
31632
+ error: INVALID_STRUCTURE
31633
+ };
31612
31634
  }
31613
31635
 
31614
- return {
31615
- matchUps,
31616
- ...SUCCESS
31636
+ structure.matchUps.push(...matchUps);
31637
+ addMatchUpsNotice({
31638
+ drawDefinition,
31639
+ matchUps
31640
+ });
31641
+ modifyDrawNotice({
31642
+ drawDefinition,
31643
+ structureIds: [structureId]
31644
+ });
31645
+ return { ...SUCCESS
31617
31646
  };
31618
31647
  }
31619
31648
 
@@ -34152,7 +34181,6 @@ const structureGovernor = {
34152
34181
  getAvailablePlayoffRounds: getAvailablePlayoffRounds$1,
34153
34182
  addPlayoffStructures: addPlayoffStructures$1,
34154
34183
  removeStructure,
34155
- addAdHocMatchUps: addAdHocMatchUps$1,
34156
34184
  generateAdHocMatchUps: generateAdHocMatchUps$1,
34157
34185
  deleteAdHocMatchUps: deleteAdHocMatchUps$1,
34158
34186
  structureSort,
@@ -36261,51 +36289,80 @@ function participantScaleItem({
36261
36289
  }
36262
36290
 
36263
36291
  function generateCandidate({
36264
- rankedPairings,
36292
+ maxIterations = 5000,
36293
+ // cap the processing intensity of the candidate generator
36294
+ valueSortedPairings,
36295
+ // pairings sorted by value from low to high
36265
36296
  pairingValues,
36266
- deltaObjects,
36267
- candidateGoal = 2000,
36268
- actorDivisor = 100
36297
+ deltaObjects
36269
36298
  }) {
36270
- const rankedMatchUpValues = Object.assign({}, ...rankedPairings.map(rm => ({
36271
- [rm.matchUp]: rm.value
36272
- })));
36299
+ const rankedMatchUpValues = Object.assign({}, ...valueSortedPairings.map(rm => ({
36300
+ [rm.pairing]: rm.value
36301
+ }))); // generate an initial candidate value with no stipulated pairings
36302
+
36273
36303
  let candidate = roundCandidate({
36274
- rankedPairings,
36275
36304
  rankedMatchUpValues,
36305
+ valueSortedPairings,
36276
36306
  deltaObjects
36277
36307
  });
36278
- let deltaCandidate = candidate; // for each actor generate a roundCandidate using all of their matchUp values
36308
+ let deltaCandidate = candidate;
36309
+ const actors = Object.keys(pairingValues); // iterations is the number of loops over valueSortedPairings
36310
+
36311
+ let candidatesCount = 0;
36312
+ let iterations; // calculate the number of opponents to consider for each participantId
36313
+
36314
+ let opponentCount = actors.length;
36315
+
36316
+ do {
36317
+ opponentCount -= 1;
36318
+ iterations = actors.length * opponentCount * valueSortedPairings.length / 2;
36319
+ } while (iterations > maxIterations && opponentCount > 2);
36320
+
36321
+ let stipulatedPairs = []; // for each actor generate a roundCandidate using opponentCount of pairing values
36279
36322
 
36280
- const actors = Object.keys(pairingValues);
36281
- const divisor = candidateGoal / (actors.length / actorDivisor);
36282
- let iterations = Math.floor(divisor / actors.length);
36283
- if (iterations > candidateGoal) iterations = candidateGoal;
36284
36323
  actors.forEach(actor => {
36285
- const participantIdPairings = pairingValues[actor];
36286
- participantIdPairings.slice(0, iterations).forEach(pairing => {
36287
- const proposed = roundCandidate({
36288
- rankedPairings,
36289
- rankedMatchUpValues,
36290
- stipulated: [pairing.participantIds],
36291
- deltaObjects
36292
- });
36293
- if (proposed.maxDelta < deltaCandidate.maxDelta) deltaCandidate = proposed;
36294
- if (proposed.value < candidate.value) candidate = proposed;
36324
+ const participantIdPairings = pairingValues[actor]; // opponentCount limits the number of opponents to consider
36325
+
36326
+ participantIdPairings.slice(0, opponentCount).forEach(pairing => {
36327
+ const stipulatedPair = pairingHash(actor, pairing.opponent);
36328
+
36329
+ if (!stipulatedPairs.includes(stipulatedPair)) {
36330
+ const proposed = roundCandidate({
36331
+ // each roundCandidate starts with stipulated pairings
36332
+ stipulated: [[actor, pairing.opponent]],
36333
+ rankedMatchUpValues,
36334
+ valueSortedPairings,
36335
+ deltaObjects
36336
+ });
36337
+ if (proposed.maxDelta < deltaCandidate.maxDelta) deltaCandidate = proposed;
36338
+ if (proposed.value < candidate.value) candidate = proposed;
36339
+ stipulatedPairs.push(stipulatedPair);
36340
+ candidatesCount += 1;
36341
+ }
36295
36342
  });
36296
36343
  });
36297
- return candidate;
36344
+ return {
36345
+ candidate,
36346
+ deltaCandidate,
36347
+ candidatesCount,
36348
+ iterations
36349
+ };
36298
36350
  }
36299
36351
 
36300
36352
  function roundCandidate({
36301
- rankedPairings,
36302
36353
  rankedMatchUpValues,
36354
+ valueSortedPairings,
36303
36355
  stipulated = [],
36304
36356
  deltaObjects
36305
36357
  }) {
36306
- let candidateValue = 0;
36307
- let participantIdPairings = [];
36308
- let roundPlayers = [].concat(...stipulated);
36358
+ // roundPlayers starts with the stipulated pairing
36359
+ const roundPlayers = [].concat(...stipulated); // aggregates the pairings generated for a roundCandidate
36360
+
36361
+ const participantIdPairings = []; // candidateValue is the sum of all participantIdPairings in a roundCandidate
36362
+ // the winning candidate has the LOWEST total value
36363
+
36364
+ let candidateValue = 0; // candidateValue is initialized with any stipulated pairings
36365
+
36309
36366
  stipulated.filter(Boolean).forEach(participantIds => {
36310
36367
  const pairing = pairingHash(...participantIds);
36311
36368
  const value = rankedMatchUpValues[pairing];
@@ -36314,13 +36371,15 @@ function roundCandidate({
36314
36371
  value
36315
36372
  });
36316
36373
  candidateValue += rankedMatchUpValues[pairing];
36317
- });
36318
- rankedPairings.forEach(rankedPairing => {
36374
+ }); // go through the valueSortedPairings (of all possible unique pairings)
36375
+ // this is an array sorted from lowest value to highest value
36376
+
36377
+ valueSortedPairings.forEach(rankedPairing => {
36319
36378
  const participantIds = rankedPairing.pairing.split('|');
36320
- const opponent_exists = participantIds.reduce((p, c) => roundPlayers.indexOf(c) >= 0 || p, false);
36379
+ const opponentExists = participantIds.reduce((p, c) => roundPlayers.includes(c) || p, false);
36321
36380
 
36322
- if (!opponent_exists) {
36323
- roundPlayers = roundPlayers.concat(...participantIds);
36381
+ if (!opponentExists) {
36382
+ roundPlayers.push(...participantIds);
36324
36383
  let value = rankedPairing.value;
36325
36384
  candidateValue += value;
36326
36385
  participantIdPairings.push({
@@ -36328,8 +36387,10 @@ function roundCandidate({
36328
36387
  value
36329
36388
  });
36330
36389
  }
36331
- });
36332
- participantIdPairings.sort((a, b) => a.value - b.value);
36390
+ }); // sort the candidate's proposed pairings by value
36391
+
36392
+ participantIdPairings.sort((a, b) => a.value - b.value); // determine the greatest delta in the candidate's pairings
36393
+
36333
36394
  const maxDelta = participantIdPairings.reduce((p, c) => {
36334
36395
  const hash = pairingHash(...c.participantIds);
36335
36396
  const delta = deltaObjects[hash];
@@ -36346,15 +36407,16 @@ function pairingHash(id1, id2) {
36346
36407
  return [id1, id2].sort().join('|');
36347
36408
  }
36348
36409
 
36410
+ // import { assignDrawPosition } from '../../governors/positionGovernor/positionAssignment';
36411
+
36349
36412
  const ENCOUNTER_VALUE = 50;
36350
36413
  const SAME_TEAM_VALUE = 60;
36351
36414
  const DEFAULT_RATING = 0;
36352
- const CANDIDATE_GOAL = 2000;
36353
- const ACTOR_DIVISOR = 100; // valueObjects provide "weighting" to each possible pairing of participants
36354
- // deltaObjects contain the difference in ratings between two participants
36355
-
36415
+ const MAX_ITERATIONS = 5000;
36356
36416
  function generateDrawMaticRound({
36417
+ maxIterations = MAX_ITERATIONS,
36357
36418
  tournamentParticipants,
36419
+ generateMatchUps,
36358
36420
  drawDefinition,
36359
36421
  participantIds,
36360
36422
  adHocRatings,
@@ -36364,17 +36426,16 @@ function generateDrawMaticRound({
36364
36426
  structure
36365
36427
  }) {
36366
36428
  // create valueObject for each previous encounter within the structure
36367
- const {
36368
- positionAssignments
36369
- } = getPositionAssignments$1({
36370
- structure
36371
- });
36372
36429
  const {
36373
36430
  encounters
36374
36431
  } = getEncounters({
36375
- matchUps: structure.matchUps,
36376
- positionAssignments
36432
+ matchUps: structure.matchUps
36377
36433
  }); // valueObjects provide "weighting" to each possible pairing of participants
36434
+ // {
36435
+ // 'P-I-0|P-I-1': 1,
36436
+ // 'P-I-0|P-I-2': 1,
36437
+ // 'P-I-0|P-I-3': 1
36438
+ // }
36378
36439
 
36379
36440
  const valueObjects = {};
36380
36441
 
@@ -36402,7 +36463,13 @@ function generateDrawMaticRound({
36402
36463
  valueObjects[pairing] += SAME_TEAM_VALUE;
36403
36464
  }
36404
36465
  }
36405
- }
36466
+ } // deltaObjects contain the difference in ratings between two participants
36467
+ // {
36468
+ // 'P-I-0|P-I-1': 0,
36469
+ // 'P-I-0|P-I-2': 0,
36470
+ // 'P-I-0|P-I-3': 0
36471
+ // }
36472
+
36406
36473
 
36407
36474
  const {
36408
36475
  uniquePairings,
@@ -36411,82 +36478,108 @@ function generateDrawMaticRound({
36411
36478
  } = getPairingsData({
36412
36479
  participantIds
36413
36480
  });
36414
- const matchUpsCount = Math.floor(participantIds.length / 2); // TODO: for client/server sync...
36415
- // ... this needs to be called BEFORE drawMatic and the matchUpIds of pre-generated matchUps passed in...
36416
- // ... and draw position assignments need to be passed in bulk AFTER
36417
-
36418
- const result = generateAdHocMatchUps$1({
36419
- newRound: true,
36420
- drawDefinition,
36421
- matchUpsCount,
36422
- structureId,
36423
- matchUpIds,
36424
- addMatchUps: true
36425
- }); // OR: the matchUps don't get added here...
36426
- // ... and the drawPositions to be added are retrieved by query then added ...
36427
- // ... and then the addAdHocMatchUps method can be called with drawPositions in place ...
36428
- // ... and it needs to do an integrity check to insure the drawPositions are all valid.
36429
- // This approach would require drawPositions to be assigned without calling assignDrawPosition
36430
-
36431
- if (result.error) return result;
36432
- const roundMatchUps = result.matchUps;
36433
36481
  const params = {
36482
+ tournamentParticipants,
36483
+ possiblePairings,
36434
36484
  drawDefinition,
36435
36485
  participantIds,
36436
- possiblePairings,
36437
36486
  uniquePairings,
36487
+ maxIterations,
36438
36488
  adHocRatings,
36439
36489
  deltaObjects,
36440
36490
  valueObjects,
36491
+ eventType,
36441
36492
  structure
36442
36493
  };
36443
36494
  const {
36444
- participantIdPairings
36445
- } = eventType === DOUBLES ? getDoublesPairings(params) : getSinglesPairings(params);
36446
- console.log(participantIdPairings);
36447
-
36448
- for (const [index, matchUp] of roundMatchUps.entries()) {
36449
- const drawPositions = matchUp.drawPositions;
36450
- const {
36451
- participantIds
36452
- } = participantIdPairings[index];
36495
+ candidatesCount,
36496
+ participantIdPairings,
36497
+ iterations
36498
+ } = getPairings(params);
36499
+ if (!candidatesCount) return {
36500
+ error: 'No Candidates'
36501
+ };
36453
36502
 
36454
- for (const i of drawPositions.keys()) {
36455
- const participantId = participantIds[i];
36456
- const drawPosition = drawPositions[i];
36457
- const result = assignDrawPosition$1({
36458
- drawDefinition,
36459
- structureId,
36460
- participantId,
36461
- drawPosition
36462
- });
36463
- if (result.error) return result;
36464
- }
36503
+ if (generateMatchUps) {
36504
+ const result = generateAdHocMatchUps$1({
36505
+ participantIdPairings,
36506
+ drawDefinition,
36507
+ newRound: true,
36508
+ structureId,
36509
+ matchUpIds
36510
+ });
36511
+ if (result.error) return result;
36465
36512
  }
36466
36513
 
36467
- return { ...SUCCESS
36514
+ return { ...SUCCESS,
36515
+ participantIdPairings,
36516
+ candidatesCount,
36517
+ iterations
36468
36518
  };
36469
36519
  }
36470
36520
 
36471
- function getSinglesPairings({
36472
- deltaObjects,
36473
- valueObjects,
36521
+ function getSideRatings({
36522
+ tournamentParticipants,
36523
+ adHocRatings,
36524
+ eventType,
36525
+ pairing
36526
+ }) {
36527
+ const ratings = pairing.split('|').map(participantId => {
36528
+ if (eventType === DOUBLES) {
36529
+ var _tournamentParticipan;
36530
+
36531
+ const individualParticipantIds = tournamentParticipants === null || tournamentParticipants === void 0 ? void 0 : (_tournamentParticipan = tournamentParticipants.find(participant => participant.participantId === participantId)) === null || _tournamentParticipan === void 0 ? void 0 : _tournamentParticipan.individualParticipantIds;
36532
+ return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds.map(participantId => adHocRatings[participantId || DEFAULT_RATING]);
36533
+ } else {
36534
+ return adHocRatings[participantId] || DEFAULT_RATING;
36535
+ }
36536
+ });
36537
+ return ratings;
36538
+ }
36539
+
36540
+ function getPairings({
36541
+ tournamentParticipants,
36474
36542
  adHocRatings = {},
36543
+ possiblePairings,
36544
+ // participant keyed; provides array of possible opponents
36475
36545
  uniquePairings,
36476
- possiblePairings
36546
+ // hashes of all possible participantId pairings
36547
+ maxIterations,
36548
+ deltaObjects,
36549
+ // difference in rating between paired participants
36550
+ valueObjects,
36551
+ // calculated value of a pairing of participants, used for sorting pairings
36552
+ eventType
36477
36553
  }) {
36478
- // modify valueObjects by ratings differential squared
36554
+ // modify valueObjects by ratings ratingsDifference squared
36555
+ // update deltaObjects to reflect the current difference between participant's ratings
36479
36556
  uniquePairings.forEach(pairing => {
36480
- const ratings = pairing.split('|').map(participantId => adHocRatings[participantId] || DEFAULT_RATING);
36481
- const differential = Math.abs(ratings[0] - ratings[1]) + 1;
36557
+ const ratings = getSideRatings({
36558
+ tournamentParticipants,
36559
+ adHocRatings,
36560
+ eventType,
36561
+ pairing
36562
+ });
36563
+ const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
36482
36564
  deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
36483
36565
  if (!valueObjects[pairing]) valueObjects[pairing] = 0;
36484
- valueObjects[pairing] += Math.pow(differential, 2);
36566
+ valueObjects[pairing] += Math.pow(ratingsDifference, 2);
36485
36567
  });
36486
- const rankedPairings = uniquePairings.map(pairing => ({
36568
+ /**
36569
+ * valueSortedPairings are uniquePairings sorted by the value of the pairings, lowest to highest
36570
+ */
36571
+
36572
+ const valueSortedPairings = uniquePairings.map(pairing => ({
36487
36573
  pairing,
36488
36574
  value: valueObjects[pairing]
36489
36575
  })).sort((a, b) => a.value - b.value);
36576
+ /**
36577
+ * pairingValues is keyed by participantId and provides a value-sorted array of pairings for each participantId
36578
+ * 'actorId': [
36579
+ { opponent: 'potentialId1', value: 1 },
36580
+ { opponent: 'potentialId2', value: 1 },
36581
+ */
36582
+
36490
36583
  const {
36491
36584
  pairingValues
36492
36585
  } = getParticipantPairingValues({
@@ -36494,24 +36587,22 @@ function getSinglesPairings({
36494
36587
  valueObjects
36495
36588
  });
36496
36589
  const {
36497
- participantIdPairings
36590
+ candidate,
36591
+ candidatesCount,
36592
+ iterations
36498
36593
  } = generateCandidate({
36499
- rankedPairings,
36594
+ valueSortedPairings,
36595
+ maxIterations,
36500
36596
  pairingValues,
36501
- deltaObjects,
36502
- candidateGoal: CANDIDATE_GOAL,
36503
- actorDivisor: ACTOR_DIVISOR
36597
+ deltaObjects
36504
36598
  });
36505
- return {
36599
+ const {
36506
36600
  participantIdPairings
36507
- };
36508
- }
36509
-
36510
- function getDoublesPairings({
36511
- roundMatchUps
36512
- }) {
36601
+ } = candidate;
36513
36602
  return {
36514
- matchUps: roundMatchUps
36603
+ candidatesCount,
36604
+ participantIdPairings,
36605
+ iterations
36515
36606
  };
36516
36607
  }
36517
36608
 
@@ -36523,7 +36614,7 @@ function getPairingsData({
36523
36614
  participantIds.forEach(participantId => {
36524
36615
  possiblePairings[participantId] = participantIds.filter(id => id !== participantId);
36525
36616
  possiblePairings[participantId].forEach(id => {
36526
- const pairing = matchupHash(id, participantId);
36617
+ const pairing = pairingHash(id, participantId);
36527
36618
  if (!uniquePairings.includes(pairing)) uniquePairings.push(pairing);
36528
36619
  });
36529
36620
  });
@@ -36538,18 +36629,15 @@ function getPairingsData({
36538
36629
  }
36539
36630
 
36540
36631
  function getEncounters({
36541
- matchUps,
36542
- positionAssignments
36632
+ matchUps
36543
36633
  }) {
36544
36634
  let encounters = [];
36545
36635
 
36546
36636
  for (const matchUp of matchUps) {
36547
- const participantIds = positionAssignments.filter(({
36548
- drawPosition
36549
- }) => matchUp.drawPositions.includes(drawPosition)).map(getParticipantId).filter(Boolean);
36637
+ const participantIds = matchUp.sides.map(getParticipantId);
36550
36638
 
36551
36639
  if (participantIds.length === 2) {
36552
- const pairing = matchupHash(...participantIds);
36640
+ const pairing = pairingHash(...participantIds);
36553
36641
  if (!encounters.includes(pairing)) encounters.push(pairing);
36554
36642
  }
36555
36643
  }
@@ -36571,7 +36659,7 @@ function getParticipantPairingValues({
36571
36659
  }
36572
36660
 
36573
36661
  function pairingValue(participantId, opponent) {
36574
- let key = matchupHash(participantId, opponent);
36662
+ let key = pairingHash(participantId, opponent);
36575
36663
  return {
36576
36664
  opponent,
36577
36665
  value: valueObjects[key]
@@ -36583,14 +36671,10 @@ function getParticipantPairingValues({
36583
36671
  };
36584
36672
  }
36585
36673
 
36586
- function matchupHash(id1, id2) {
36587
- return [id1, id2].sort().join('|');
36588
- }
36589
-
36590
36674
  /**
36591
36675
  *
36592
- * @param {object} drawDefinition
36593
- * @param {string} structureId
36676
+ * @param {object} drawDefinition - provided automatically by drawEngine
36677
+ * @param {string} structureId - optional - defaults to the first structure of latest stage
36594
36678
  * @param {string[]} participantIds - optional - allows a subset of drawDefinition.entries to be specified
36595
36679
  *
36596
36680
  */
@@ -36598,19 +36682,24 @@ function matchupHash(id1, id2) {
36598
36682
  function drawMatic$1({
36599
36683
  tournamentParticipants,
36600
36684
  restrictEntryStatus,
36685
+ generateMatchUps,
36601
36686
  drawDefinition,
36602
36687
  participantIds,
36688
+ maxIterations,
36603
36689
  structureId,
36604
36690
  matchUpIds,
36605
36691
  scaleName,
36606
36692
  // custom rating name to seed dynamic ratings
36607
36693
  event
36608
36694
  }) {
36609
- var _drawDefinition$struc2;
36695
+ var _drawDefinition$struc3;
36610
36696
 
36611
- if (typeof drawDefinition !== 'object') return {
36697
+ if (typeof drawDefinition !== 'object' || drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) return {
36612
36698
  error: INVALID_DRAW_DEFINITION
36613
36699
  };
36700
+ if (!Array.isArray(drawDefinition.entries) || participantIds && !Array.isArray(participantIds)) return {
36701
+ error: INVALID_VALUES
36702
+ };
36614
36703
  const {
36615
36704
  eventType
36616
36705
  } = event || {};
@@ -36620,35 +36709,40 @@ function drawMatic$1({
36620
36709
 
36621
36710
  if (participantIds) {
36622
36711
  // ensure all participantIds are in drawDefinition.entries
36623
- const invalidParticipantId = !!participantIds.find(participantId => enteredParticipantIds.includes(participantId));
36624
- if (invalidParticipantId) return {
36712
+ const invalidParticipantIds = participantIds.filter(participantId => !enteredParticipantIds.includes(participantId));
36713
+ if (invalidParticipantIds !== null && invalidParticipantIds !== void 0 && invalidParticipantIds.length) return {
36625
36714
  error: INVALID_PARTICIPANT_ID,
36626
- participantId: invalidParticipantId
36715
+ invalidParticipantIds
36627
36716
  };
36628
36717
  } else {
36629
36718
  participantIds = enteredParticipantIds;
36630
- }
36631
-
36632
- const isAdHoc = structure => !(structure !== null && structure !== void 0 && structure.structures) && !(structure !== null && structure !== void 0 && structure.matchUps.find(({
36633
- roundPosition
36634
- }) => !!roundPosition)); // if no structureId is specified find the latest stage which has matchUps
36719
+ } // if no structureId is specified find the latest AD_HOC stage which has matchUps
36635
36720
 
36636
36721
 
36637
36722
  if (!structureId) {
36638
- var _drawDefinition$struc;
36723
+ var _drawDefinition$struc, _drawDefinition$struc2;
36639
36724
 
36640
- const targetStructure = (_drawDefinition$struc = drawDefinition.structures) === null || _drawDefinition$struc === void 0 ? void 0 : _drawDefinition$struc.find(structure => structure.stageSequence === 1).recuce((targetStructure, structure) => {
36725
+ const targetStructure = (_drawDefinition$struc = drawDefinition.structures) === null || _drawDefinition$struc === void 0 ? void 0 : (_drawDefinition$struc2 = _drawDefinition$struc.filter(structure => structure.stageSequence === 1)) === null || _drawDefinition$struc2 === void 0 ? void 0 : _drawDefinition$struc2.reduce((targetStructure, structure) => {
36641
36726
  const orderNumber = stageOrder[structure.stage];
36642
- return isAdHoc(structure) && orderNumber > stageOrder[targetStructure.stage] ? structure : targetStructure;
36727
+ const structureIsAdHoc = isAdHoc({
36728
+ drawDefinition,
36729
+ structure
36730
+ });
36731
+ return structureIsAdHoc && orderNumber > (stageOrder[targetStructure === null || targetStructure === void 0 ? void 0 : targetStructure.stage] || 1) ? structure : targetStructure;
36643
36732
  }, undefined);
36644
36733
  structureId = targetStructure === null || targetStructure === void 0 ? void 0 : targetStructure.structureId;
36645
36734
  }
36646
36735
 
36647
- const structure = (_drawDefinition$struc2 = drawDefinition.structures) === null || _drawDefinition$struc2 === void 0 ? void 0 : _drawDefinition$struc2.find(structure => structure.structureId === structureId);
36736
+ const structure = (_drawDefinition$struc3 = drawDefinition.structures) === null || _drawDefinition$struc3 === void 0 ? void 0 : _drawDefinition$struc3.find(structure => structure.structureId === structureId);
36648
36737
  if (!structure) return {
36649
36738
  error: STRUCTURE_NOT_FOUND
36650
- };
36651
- if (!isAdHoc(structure)) return {
36739
+ }; // an AD_HOC structure is one that has no child structures and in which no matchUps have roundPosition
36740
+
36741
+ const structureIsAdHoc = isAdHoc({
36742
+ drawDefinition,
36743
+ structure
36744
+ });
36745
+ if (!structureIsAdHoc) return {
36652
36746
  error: INVALID_DRAW_DEFINITION
36653
36747
  };
36654
36748
  const adHocRatings = {};
@@ -36673,11 +36767,15 @@ function drawMatic$1({
36673
36767
  }
36674
36768
 
36675
36769
  const {
36676
- matchUps
36770
+ candidatesCount,
36771
+ iterations,
36772
+ participantIdPairings
36677
36773
  } = generateDrawMaticRound({
36678
36774
  tournamentParticipants,
36775
+ generateMatchUps,
36679
36776
  drawDefinition,
36680
36777
  participantIds,
36778
+ maxIterations,
36681
36779
  adHocRatings,
36682
36780
  matchUpIds,
36683
36781
  structureId,
@@ -36685,7 +36783,9 @@ function drawMatic$1({
36685
36783
  eventType
36686
36784
  });
36687
36785
  return { ...SUCCESS,
36688
- matchUps
36786
+ candidatesCount,
36787
+ iterations,
36788
+ participantIdPairings
36689
36789
  };
36690
36790
  }
36691
36791
 
@@ -37479,10 +37579,6 @@ function getValidAssignmentActions({
37479
37579
  };
37480
37580
  }
37481
37581
 
37482
- const isAdHoc = !(structure !== null && structure !== void 0 && structure.structures) && !(structure !== null && structure !== void 0 && structure.matchUps.find(({
37483
- roundPosition
37484
- }) => !!roundPosition));
37485
-
37486
37582
  if (unfilledPositions.includes(drawPosition) || isByePosition) {
37487
37583
  var _unplacedSeedAssignme;
37488
37584
 
@@ -37497,12 +37593,6 @@ function getValidAssignmentActions({
37497
37593
  });
37498
37594
  validToAssign.sort(validAssignmentsSort);
37499
37595
  availableParticipantIds = validToAssign.map(assignment => assignment.participantId);
37500
- } else if (isAdHoc) {
37501
- availableParticipantIds = getAvailableAdHocParticipantIds({
37502
- drawDefinition,
37503
- drawPosition,
37504
- structure
37505
- });
37506
37596
  } else {
37507
37597
  // otherwise look for any unplaced entries
37508
37598
  // 1) unassigned DIRECT_ACCEPTANCE or WILDCARD structure entries
@@ -41751,309 +41841,109 @@ const policyGovernor = {
41751
41841
  getEventAppliedPolicies
41752
41842
  };
41753
41843
 
41754
- const COLLEGE_DEFAULT = 'COLLEGE_DEFAULT';
41755
- const COLLEGE_JUCO = 'COLLEGE_JUCO';
41756
- const COLLEGE_D3 = 'COLLEGE_D3';
41757
- const DOMINANT_DUO = 'DOMINANT_DUO';
41758
- const LAVER_CUP = 'LAVER_CUP';
41759
- const TEAM_DOUBLES_3_AGGREGATION = 'TEAM_DOUBLES_3_AGGREGATION';
41760
- const tieFormatConstants = {
41761
- COLLEGE_D3,
41762
- COLLEGE_DEFAULT,
41763
- COLLEGE_JUCO,
41764
- DOMINANT_DUO,
41765
- LAVER_CUP,
41766
- TEAM_DOUBLES_3_AGGREGATION
41767
- };
41768
-
41769
- const namedFormats = {
41770
- STANDARD: {
41771
- hydrate: true,
41772
- doubles: {
41773
- matchUpCount: 3,
41774
- matchUpValue: 1
41775
- },
41776
- singles: {
41777
- matchUpCount: 6,
41778
- matchUpValue: 1
41779
- },
41780
- valueGoal: 5
41781
- },
41782
- [COLLEGE_D3]: {
41783
- hydrate: true,
41784
- doubles: {
41785
- matchUpCount: 3,
41786
- matchUpValue: 1,
41787
- matchUpFormat: 'SET1-S:8/TB7@7'
41788
- },
41789
- singles: {
41790
- matchUpCount: 6,
41791
- matchUpValue: 1,
41792
- matchUpFormat: 'SET3-S:6/TB7'
41793
- },
41794
- tieFormatName: 'COLLEGE_D3',
41795
- valueGoal: 5
41796
- },
41797
- [COLLEGE_DEFAULT]: {
41798
- hydrate: true,
41799
- doubles: {
41800
- matchUpCount: 3,
41801
- collectionValue: 1,
41802
- matchUpFormat: 'SET1-S:6/TB7'
41803
- },
41804
- singles: {
41805
- matchUpCount: 6,
41806
- matchUpValue: 1,
41807
- matchUpFormat: 'SET3-S:6/TB7'
41808
- },
41809
- tieFormatName: 'COLLEGE_DEFAULT',
41810
- valueGoal: 4
41811
- },
41812
- [COLLEGE_JUCO]: {
41813
- hydrate: true,
41814
- doubles: {
41815
- matchUpCount: 3,
41816
- matchUpValue: 1,
41817
- matchUpFormat: 'SET1-S:8/TB7'
41818
- },
41819
- singles: {
41820
- matchUpCount: 6,
41821
- matchUpValue: 1,
41822
- matchUpFormat: 'SET3-S:6/TB7'
41823
- },
41824
- tieFormatName: 'COLLEGE_JUCO',
41825
- valueGoal: 5
41826
- },
41827
- [LAVER_CUP]: LAVER_CUP_TIE_FORMAT,
41828
- [DOMINANT_DUO]: DOMINANT_DUO_TIE_FORMAT,
41829
- [TEAM_DOUBLES_3_AGGREGATION]: TEAM_AGGREGATION_TIE_FORMAT
41830
- };
41831
- const tieFormatDefaults = ({
41832
- namedFormat,
41833
- uuids = []
41834
- } = {}) => {
41835
- var _uuids, _uuids2;
41836
-
41837
- if (!Object.keys(namedFormats).includes(namedFormat)) namedFormat = 'STANDARD';
41838
- if (!Array.isArray(uuids)) uuids = [];
41839
- const template = namedFormats[namedFormat];
41840
-
41841
- if (!template.hydrate) {
41842
- template.collectionDefinitions.forEach(collectionDefinition => collectionDefinition.collectionId = UUID());
41843
- return template;
41844
- }
41845
-
41846
- const tieFormat = {
41847
- winCriteria: {
41848
- valueGoal: template.valueGoal
41849
- },
41850
- collectionDefinitions: [{
41851
- collectionId: ((_uuids = uuids) === null || _uuids === void 0 ? void 0 : _uuids.pop()) || UUID(),
41852
- collectionName: 'Doubles',
41853
- matchUpType: DOUBLES$1,
41854
- matchUpFormat: 'SET3-S:6/TB7-F:TB10',
41855
- ...template.doubles
41856
- }, {
41857
- collectionId: ((_uuids2 = uuids) === null || _uuids2 === void 0 ? void 0 : _uuids2.pop()) || UUID(),
41858
- collectionName: 'Singles',
41859
- matchUpType: SINGLES$1,
41860
- matchUpFormat: 'SET3-S:6/TB7',
41861
- ...template.singles
41862
- }]
41863
- };
41864
- if (template.tieFormatName) tieFormat.tieFormatName = template.tieFormatName;
41865
- return tieFormat;
41866
- };
41867
-
41868
- function addEvent({
41869
- tournamentRecord,
41844
+ function assignMatchUpSideParticipant({
41845
+ drawDefinition,
41846
+ participantId,
41847
+ sideNumber,
41848
+ matchUpId,
41870
41849
  event
41871
41850
  }) {
41872
- if (!tournamentRecord) return {
41873
- error: MISSING_TOURNAMENT_RECORD
41874
- };
41875
- if (!tournamentRecord.events) tournamentRecord.events = []; // set default startDate, endDate based on tournamentRecord
41876
-
41877
- const {
41878
- startDate,
41879
- endDate
41880
- } = tournamentRecord;
41881
- const eventRecord = Object.assign({}, {
41882
- startDate,
41883
- endDate,
41884
- eventType: SINGLES
41885
- }, event);
41886
-
41887
- if (event.eventType === TEAM$2 && event.tieFormatName && tieFormats[event.tieFormatName]) {
41888
- eventRecord.tieFormat = tieFormatDefaults({
41889
- namedFormat: event.tieFormatName
41890
- });
41891
- }
41892
-
41893
- if (!eventRecord.eventId) eventRecord.eventId = UUID();
41894
- const eventExists = tournamentRecord.events.reduce((exists, event) => {
41895
- return exists || event.eventId === eventRecord.eventId;
41896
- }, undefined);
41897
-
41898
- if (!eventExists) {
41899
- tournamentRecord.events.push(eventRecord);
41900
- return { ...SUCCESS,
41901
- event: eventRecord
41902
- };
41903
- } else {
41904
- return {
41905
- error: EVENT_EXISTS
41906
- };
41907
- }
41908
- }
41909
-
41910
- const DELETE_EVENTS = 'deleteEvents';
41911
- const DELETE_DRAW_DEFINITIONS = 'deleteDrawDefinitions';
41912
- const auditConstants = {
41913
- DELETE_EVENTS,
41914
- DELETE_DRAW_DEFINITIONS
41915
- };
41851
+ var _matchUp$score;
41916
41852
 
41917
- function deleteEvents({
41918
- tournamentRecord,
41919
- eventIds
41920
- }) {
41921
- if (!tournamentRecord) return {
41922
- error: MISSING_TOURNAMENT_RECORD
41853
+ if (participantId && typeof participantId !== 'string') return {
41854
+ error: INVALID_PARTICIPANT_ID
41923
41855
  };
41924
- if (!tournamentRecord.events) return {
41925
- error: EVENT_NOT_FOUND
41856
+ if (!drawDefinition) return {
41857
+ error: MISSING_DRAW_DEFINITION
41926
41858
  };
41927
- if (!Array.isArray(eventIds)) return {
41928
- error: MISSING_VALUE
41859
+ if (!sideNumber) return {
41860
+ error: MISSING_SIDE_NUMBER
41929
41861
  };
41930
- const auditTrail = [];
41931
- const deletedEventDetails = [];
41932
- tournamentRecord.events = (tournamentRecord.events || []).filter(event => {
41933
- if (eventIds.includes(event.eventId)) {
41934
- const auditData = {
41935
- action: DELETE_EVENTS,
41936
- payload: {
41937
- events: [event]
41938
- }
41939
- };
41940
- auditTrail.push(auditData);
41941
- deletedEventDetails.push({
41942
- eventName: event.eventName,
41943
- eventType: event.eventType,
41944
- category: event.category,
41945
- eventId: event.eventId,
41946
- gender: event.gender
41947
- });
41948
- }
41949
-
41950
- return !eventIds.includes(event.eventId);
41951
- }); // cleanup references to eventId in schedulingProfile extension
41952
-
41953
- checkSchedulingProfile({
41954
- tournamentRecord
41862
+ if (!matchUpId) return {
41863
+ error: MISSING_MATCHUP_ID
41864
+ };
41865
+ if (![1, 2].includes(sideNumber)) return {
41866
+ error: INVALID_VALUES,
41867
+ sideNumber
41868
+ };
41869
+ const {
41870
+ matchUp,
41871
+ structure
41872
+ } = findMatchUp$1({
41873
+ drawDefinition,
41874
+ matchUpId,
41875
+ event
41955
41876
  });
41877
+ const isAdHoc = !(structure !== null && structure !== void 0 && structure.structures) && !(drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) && !(structure !== null && structure !== void 0 && structure.matchUps.find(({
41878
+ roundPosition
41879
+ }) => !!roundPosition));
41880
+ if (!isAdHoc) return {
41881
+ error: INVALID_DRAW_TYPE
41882
+ }; // if no participantId / participant is being un-assigned, there cannot be a score or completed outcome
41956
41883
 
41957
- if (auditTrail.length) {
41958
- addNotice({
41959
- topic: AUDIT,
41960
- payload: auditTrail
41961
- });
41962
- const timeItem = {
41963
- itemType: DELETE_EVENTS,
41964
- itemValue: deletedEventDetails
41965
- };
41966
- addTournamentTimeItem({
41967
- tournamentRecord,
41968
- timeItem
41969
- });
41970
- }
41884
+ if (!participantId && ((_matchUp$score = matchUp.score) !== null && _matchUp$score !== void 0 && _matchUp$score.scoreStringSide1 || completedMatchUpStatuses.includes(matchUp.matchUpstatus) || matchUp.matchUpStatus === DOUBLE_WALKOVER)) return {
41885
+ error: CANNOT_REMOVE_PARTICIPANTS,
41886
+ message: 'matchUp has completed status or score'
41887
+ };
41888
+ matchUp.sides = [1, 2].map(currentSideNumber => {
41889
+ var _matchUp$sides;
41971
41890
 
41972
- return SUCCESS;
41891
+ const existingSide = ((_matchUp$sides = matchUp.sides) === null || _matchUp$sides === void 0 ? void 0 : _matchUp$sides.find(side => side.sideNumber === currentSideNumber)) || {
41892
+ sideNumber: currentSideNumber
41893
+ };
41894
+ return sideNumber === currentSideNumber ? { ...existingSide,
41895
+ participantId
41896
+ } : existingSide;
41897
+ });
41898
+ addMatchUpsNotice({
41899
+ drawDefinition,
41900
+ matchUps: [matchUp]
41901
+ });
41902
+ return { ...SUCCESS
41903
+ };
41973
41904
  }
41974
41905
 
41975
- function promoteAlternate({
41976
- tournamentRecord,
41906
+ function assignDrawPosition({
41977
41907
  drawDefinition,
41978
- event,
41908
+ drawPosition,
41909
+ structureId,
41979
41910
  participantId,
41980
- stage = MAIN,
41981
- stageSequence
41911
+ qualifier,
41912
+ bye
41982
41913
  }) {
41983
- if (!tournamentRecord) return {
41984
- error: MISSING_TOURNAMENT_RECORD
41914
+ if (!drawDefinition) return {
41915
+ error: MISSING_DRAW_DEFINITION
41985
41916
  };
41986
- if (!event) return {
41987
- error: MISSING_EVENT
41917
+ if (!drawPosition) return {
41918
+ error: MISSING_DRAW_POSITION
41919
+ };
41920
+ if (!structureId) return {
41921
+ error: MISSING_STRUCTURE_ID
41988
41922
  };
41989
41923
 
41990
- if (event) {
41991
- const result = promoteWithinElement({
41992
- element: event,
41993
- participantId,
41994
- stageSequence,
41995
- stage
41924
+ if (bye) {
41925
+ const result = assignDrawPositionBye$1({
41926
+ drawDefinition,
41927
+ drawPosition,
41928
+ structureId
41996
41929
  });
41997
41930
  if (result.error) return result;
41998
- }
41999
-
42000
- if (drawDefinition) {
42001
- const result = promoteWithinElement({
42002
- element: drawDefinition,
42003
- participantId,
42004
- stageSequence,
42005
- stage
41931
+ } else if (qualifier) {
41932
+ return {
41933
+ error: NOT_IMPLEMENTED
41934
+ };
41935
+ } else {
41936
+ const result = assignDrawPosition$1({
41937
+ drawDefinition,
41938
+ structureId,
41939
+ drawPosition,
41940
+ participantId
42006
41941
  });
42007
41942
  if (result.error) return result;
42008
41943
  }
42009
41944
 
42010
- return SUCCESS;
42011
- }
42012
-
42013
- function promoteWithinElement({
42014
- element,
42015
- participantId,
42016
- stage,
42017
- stageSequence
42018
- }) {
42019
- const alternates = (element.entries || []).filter(entry => entry.entryStatus === ALTERNATE); // if no participantId is provided, take the alternate with the lowest entryPosition
42020
-
42021
- const participantEntry = (element.entries || []).find(entry => entry.participantId === participantId) || alternates.reduce((participantEntry, entry) => {
42022
- const {
42023
- entryPosition
42024
- } = entry;
42025
- return isNaN(entryPosition) ? participantEntry : !participantEntry || entryPosition < participantEntry.entryPosition ? entry : participantEntry;
42026
- }, undefined);
42027
- if (!participantEntry) return {
42028
- error: PARTICIPANT_ENTRY_NOT_FOUND
42029
- };
42030
- if (participantEntry.entryStatus !== ALTERNATE) return {
42031
- error: INVALID_ENTRY_STATUS
42032
- };
42033
- if (participantEntry.stage && participantEntry.entryStage !== stage) return {
42034
- error: PARTICIPANT_NOT_ENTERED_IN_STAGE
42035
- };
42036
- if (stageSequence && participantEntry.stageSequence !== stageSequence) return {
42037
- error: PARTICIPANT_NOT_FOUND_IN_STAGE
41945
+ return { ...SUCCESS
42038
41946
  };
42039
- participantEntry.entryStatus = DIRECT_ACCEPTANCE; // cleanUp
42040
-
42041
- const entryPosition = participantEntry === null || participantEntry === void 0 ? void 0 : participantEntry.entryPosition;
42042
-
42043
- if (!isNaN(entryPosition)) {
42044
- // if promoted participant has an entryPosition, adjust all other alternates with an entryPosition higher than promoted participant
42045
- element.entries.forEach(entry => {
42046
- if (entry.entryStatus === ALTERNATE && entry.entryPosition > entryPosition) {
42047
- entry.entryPosition = entry.entryPosition - 1;
42048
- }
42049
- });
42050
- }
42051
-
42052
- let maxEntryPosition = Math.max(...element.entries.filter(entry => entry.entryStatus === DIRECT_ACCEPTANCE && !isNaN(entry.entryPosition)).map(({
42053
- entryPosition
42054
- }) => parseInt(entryPosition || 0)), 0);
42055
- participantEntry.entryPosition = maxEntryPosition || 0;
42056
- return SUCCESS;
42057
41947
  }
42058
41948
 
42059
41949
  /**
@@ -42208,47 +42098,88 @@ function checkValidEntries({
42208
42098
  return SUCCESS;
42209
42099
  }
42210
42100
 
42211
- function assignDrawPosition({
42101
+ function promoteAlternate({
42102
+ tournamentRecord,
42212
42103
  drawDefinition,
42213
- drawPosition,
42214
- structureId,
42104
+ event,
42215
42105
  participantId,
42216
- qualifier,
42217
- bye
42106
+ stage = MAIN,
42107
+ stageSequence
42218
42108
  }) {
42219
- if (!drawDefinition) return {
42220
- error: MISSING_DRAW_DEFINITION
42221
- };
42222
- if (!drawPosition) return {
42223
- error: MISSING_DRAW_POSITION
42109
+ if (!tournamentRecord) return {
42110
+ error: MISSING_TOURNAMENT_RECORD
42224
42111
  };
42225
- if (!structureId) return {
42226
- error: MISSING_STRUCTURE_ID
42112
+ if (!event) return {
42113
+ error: MISSING_EVENT
42227
42114
  };
42228
42115
 
42229
- if (bye) {
42230
- const result = assignDrawPositionBye$1({
42231
- drawDefinition,
42232
- drawPosition,
42233
- structureId
42116
+ if (event) {
42117
+ const result = promoteWithinElement({
42118
+ element: event,
42119
+ participantId,
42120
+ stageSequence,
42121
+ stage
42234
42122
  });
42235
42123
  if (result.error) return result;
42236
- } else if (qualifier) {
42237
- return {
42238
- error: NOT_IMPLEMENTED
42239
- };
42240
- } else {
42241
- const result = assignDrawPosition$1({
42242
- drawDefinition,
42243
- structureId,
42244
- drawPosition,
42245
- participantId
42124
+ }
42125
+
42126
+ if (drawDefinition) {
42127
+ const result = promoteWithinElement({
42128
+ element: drawDefinition,
42129
+ participantId,
42130
+ stageSequence,
42131
+ stage
42246
42132
  });
42247
42133
  if (result.error) return result;
42248
42134
  }
42249
42135
 
42250
- return { ...SUCCESS
42136
+ return SUCCESS;
42137
+ }
42138
+
42139
+ function promoteWithinElement({
42140
+ element,
42141
+ participantId,
42142
+ stage,
42143
+ stageSequence
42144
+ }) {
42145
+ const alternates = (element.entries || []).filter(entry => entry.entryStatus === ALTERNATE); // if no participantId is provided, take the alternate with the lowest entryPosition
42146
+
42147
+ const participantEntry = (element.entries || []).find(entry => entry.participantId === participantId) || alternates.reduce((participantEntry, entry) => {
42148
+ const {
42149
+ entryPosition
42150
+ } = entry;
42151
+ return isNaN(entryPosition) ? participantEntry : !participantEntry || entryPosition < participantEntry.entryPosition ? entry : participantEntry;
42152
+ }, undefined);
42153
+ if (!participantEntry) return {
42154
+ error: PARTICIPANT_ENTRY_NOT_FOUND
42251
42155
  };
42156
+ if (participantEntry.entryStatus !== ALTERNATE) return {
42157
+ error: INVALID_ENTRY_STATUS
42158
+ };
42159
+ if (participantEntry.stage && participantEntry.entryStage !== stage) return {
42160
+ error: PARTICIPANT_NOT_ENTERED_IN_STAGE
42161
+ };
42162
+ if (stageSequence && participantEntry.stageSequence !== stageSequence) return {
42163
+ error: PARTICIPANT_NOT_FOUND_IN_STAGE
42164
+ };
42165
+ participantEntry.entryStatus = DIRECT_ACCEPTANCE; // cleanUp
42166
+
42167
+ const entryPosition = participantEntry === null || participantEntry === void 0 ? void 0 : participantEntry.entryPosition;
42168
+
42169
+ if (!isNaN(entryPosition)) {
42170
+ // if promoted participant has an entryPosition, adjust all other alternates with an entryPosition higher than promoted participant
42171
+ element.entries.forEach(entry => {
42172
+ if (entry.entryStatus === ALTERNATE && entry.entryPosition > entryPosition) {
42173
+ entry.entryPosition = entry.entryPosition - 1;
42174
+ }
42175
+ });
42176
+ }
42177
+
42178
+ let maxEntryPosition = Math.max(...element.entries.filter(entry => entry.entryStatus === DIRECT_ACCEPTANCE && !isNaN(entry.entryPosition)).map(({
42179
+ entryPosition
42180
+ }) => parseInt(entryPosition || 0)), 0);
42181
+ participantEntry.entryPosition = maxEntryPosition || 0;
42182
+ return SUCCESS;
42252
42183
  }
42253
42184
 
42254
42185
  /*
@@ -42335,6 +42266,227 @@ function assignSeedPositions(params) {
42335
42266
  };
42336
42267
  }
42337
42268
 
42269
+ const DELETE_EVENTS = 'deleteEvents';
42270
+ const DELETE_DRAW_DEFINITIONS = 'deleteDrawDefinitions';
42271
+ const auditConstants = {
42272
+ DELETE_EVENTS,
42273
+ DELETE_DRAW_DEFINITIONS
42274
+ };
42275
+
42276
+ function deleteEvents({
42277
+ tournamentRecord,
42278
+ eventIds
42279
+ }) {
42280
+ if (!tournamentRecord) return {
42281
+ error: MISSING_TOURNAMENT_RECORD
42282
+ };
42283
+ if (!tournamentRecord.events) return {
42284
+ error: EVENT_NOT_FOUND
42285
+ };
42286
+ if (!Array.isArray(eventIds)) return {
42287
+ error: MISSING_VALUE
42288
+ };
42289
+ const auditTrail = [];
42290
+ const deletedEventDetails = [];
42291
+ tournamentRecord.events = (tournamentRecord.events || []).filter(event => {
42292
+ if (eventIds.includes(event.eventId)) {
42293
+ const auditData = {
42294
+ action: DELETE_EVENTS,
42295
+ payload: {
42296
+ events: [event]
42297
+ }
42298
+ };
42299
+ auditTrail.push(auditData);
42300
+ deletedEventDetails.push({
42301
+ eventName: event.eventName,
42302
+ eventType: event.eventType,
42303
+ category: event.category,
42304
+ eventId: event.eventId,
42305
+ gender: event.gender
42306
+ });
42307
+ }
42308
+
42309
+ return !eventIds.includes(event.eventId);
42310
+ }); // cleanup references to eventId in schedulingProfile extension
42311
+
42312
+ checkSchedulingProfile({
42313
+ tournamentRecord
42314
+ });
42315
+
42316
+ if (auditTrail.length) {
42317
+ addNotice({
42318
+ topic: AUDIT,
42319
+ payload: auditTrail
42320
+ });
42321
+ const timeItem = {
42322
+ itemType: DELETE_EVENTS,
42323
+ itemValue: deletedEventDetails
42324
+ };
42325
+ addTournamentTimeItem({
42326
+ tournamentRecord,
42327
+ timeItem
42328
+ });
42329
+ }
42330
+
42331
+ return SUCCESS;
42332
+ }
42333
+
42334
+ const COLLEGE_DEFAULT = 'COLLEGE_DEFAULT';
42335
+ const COLLEGE_JUCO = 'COLLEGE_JUCO';
42336
+ const COLLEGE_D3 = 'COLLEGE_D3';
42337
+ const DOMINANT_DUO = 'DOMINANT_DUO';
42338
+ const LAVER_CUP = 'LAVER_CUP';
42339
+ const TEAM_DOUBLES_3_AGGREGATION = 'TEAM_DOUBLES_3_AGGREGATION';
42340
+ const tieFormatConstants = {
42341
+ COLLEGE_D3,
42342
+ COLLEGE_DEFAULT,
42343
+ COLLEGE_JUCO,
42344
+ DOMINANT_DUO,
42345
+ LAVER_CUP,
42346
+ TEAM_DOUBLES_3_AGGREGATION
42347
+ };
42348
+
42349
+ const namedFormats = {
42350
+ STANDARD: {
42351
+ hydrate: true,
42352
+ doubles: {
42353
+ matchUpCount: 3,
42354
+ matchUpValue: 1
42355
+ },
42356
+ singles: {
42357
+ matchUpCount: 6,
42358
+ matchUpValue: 1
42359
+ },
42360
+ valueGoal: 5
42361
+ },
42362
+ [COLLEGE_D3]: {
42363
+ hydrate: true,
42364
+ doubles: {
42365
+ matchUpCount: 3,
42366
+ matchUpValue: 1,
42367
+ matchUpFormat: 'SET1-S:8/TB7@7'
42368
+ },
42369
+ singles: {
42370
+ matchUpCount: 6,
42371
+ matchUpValue: 1,
42372
+ matchUpFormat: 'SET3-S:6/TB7'
42373
+ },
42374
+ tieFormatName: 'COLLEGE_D3',
42375
+ valueGoal: 5
42376
+ },
42377
+ [COLLEGE_DEFAULT]: {
42378
+ hydrate: true,
42379
+ doubles: {
42380
+ matchUpCount: 3,
42381
+ collectionValue: 1,
42382
+ matchUpFormat: 'SET1-S:6/TB7'
42383
+ },
42384
+ singles: {
42385
+ matchUpCount: 6,
42386
+ matchUpValue: 1,
42387
+ matchUpFormat: 'SET3-S:6/TB7'
42388
+ },
42389
+ tieFormatName: 'COLLEGE_DEFAULT',
42390
+ valueGoal: 4
42391
+ },
42392
+ [COLLEGE_JUCO]: {
42393
+ hydrate: true,
42394
+ doubles: {
42395
+ matchUpCount: 3,
42396
+ matchUpValue: 1,
42397
+ matchUpFormat: 'SET1-S:8/TB7'
42398
+ },
42399
+ singles: {
42400
+ matchUpCount: 6,
42401
+ matchUpValue: 1,
42402
+ matchUpFormat: 'SET3-S:6/TB7'
42403
+ },
42404
+ tieFormatName: 'COLLEGE_JUCO',
42405
+ valueGoal: 5
42406
+ },
42407
+ [LAVER_CUP]: LAVER_CUP_TIE_FORMAT,
42408
+ [DOMINANT_DUO]: DOMINANT_DUO_TIE_FORMAT,
42409
+ [TEAM_DOUBLES_3_AGGREGATION]: TEAM_AGGREGATION_TIE_FORMAT
42410
+ };
42411
+ const tieFormatDefaults = ({
42412
+ namedFormat,
42413
+ uuids = []
42414
+ } = {}) => {
42415
+ var _uuids, _uuids2;
42416
+
42417
+ if (!Object.keys(namedFormats).includes(namedFormat)) namedFormat = 'STANDARD';
42418
+ if (!Array.isArray(uuids)) uuids = [];
42419
+ const template = namedFormats[namedFormat];
42420
+
42421
+ if (!template.hydrate) {
42422
+ template.collectionDefinitions.forEach(collectionDefinition => collectionDefinition.collectionId = UUID());
42423
+ return template;
42424
+ }
42425
+
42426
+ const tieFormat = {
42427
+ winCriteria: {
42428
+ valueGoal: template.valueGoal
42429
+ },
42430
+ collectionDefinitions: [{
42431
+ collectionId: ((_uuids = uuids) === null || _uuids === void 0 ? void 0 : _uuids.pop()) || UUID(),
42432
+ collectionName: 'Doubles',
42433
+ matchUpType: DOUBLES$1,
42434
+ matchUpFormat: 'SET3-S:6/TB7-F:TB10',
42435
+ ...template.doubles
42436
+ }, {
42437
+ collectionId: ((_uuids2 = uuids) === null || _uuids2 === void 0 ? void 0 : _uuids2.pop()) || UUID(),
42438
+ collectionName: 'Singles',
42439
+ matchUpType: SINGLES$1,
42440
+ matchUpFormat: 'SET3-S:6/TB7',
42441
+ ...template.singles
42442
+ }]
42443
+ };
42444
+ if (template.tieFormatName) tieFormat.tieFormatName = template.tieFormatName;
42445
+ return tieFormat;
42446
+ };
42447
+
42448
+ function addEvent({
42449
+ tournamentRecord,
42450
+ event
42451
+ }) {
42452
+ if (!tournamentRecord) return {
42453
+ error: MISSING_TOURNAMENT_RECORD
42454
+ };
42455
+ if (!tournamentRecord.events) tournamentRecord.events = []; // set default startDate, endDate based on tournamentRecord
42456
+
42457
+ const {
42458
+ startDate,
42459
+ endDate
42460
+ } = tournamentRecord;
42461
+ const eventRecord = Object.assign({}, {
42462
+ startDate,
42463
+ endDate,
42464
+ eventType: SINGLES
42465
+ }, event);
42466
+
42467
+ if (event.eventType === TEAM$2 && event.tieFormatName && tieFormats[event.tieFormatName]) {
42468
+ eventRecord.tieFormat = tieFormatDefaults({
42469
+ namedFormat: event.tieFormatName
42470
+ });
42471
+ }
42472
+
42473
+ if (!eventRecord.eventId) eventRecord.eventId = UUID();
42474
+ const eventExists = tournamentRecord.events.reduce((exists, event) => {
42475
+ return exists || event.eventId === eventRecord.eventId;
42476
+ }, undefined);
42477
+
42478
+ if (!eventExists) {
42479
+ tournamentRecord.events.push(eventRecord);
42480
+ return { ...SUCCESS,
42481
+ event: eventRecord
42482
+ };
42483
+ } else {
42484
+ return {
42485
+ error: EVENT_EXISTS
42486
+ };
42487
+ }
42488
+ }
42489
+
42338
42490
  /**
42339
42491
  *
42340
42492
  * @param {string} drawId - tournamentEngine will resovle event and drawDefinition
@@ -45132,10 +45284,6 @@ function setOrderOfFinish(params) {
45132
45284
  return setOrderOfFinish$1(params);
45133
45285
  }
45134
45286
 
45135
- function addAdHocMatchUps(params) {
45136
- return addAdHocMatchUps$1(params);
45137
- }
45138
-
45139
45287
  // if those entries are assigned positions in any structures...
45140
45288
 
45141
45289
  function modifyEventEntries({
@@ -45489,7 +45637,6 @@ const eventGovernor = {
45489
45637
  getFlightProfile,
45490
45638
  getScaledEntries,
45491
45639
  addFlight,
45492
- addAdHocMatchUps,
45493
45640
  generateAdHocMatchUps,
45494
45641
  deleteAdHocMatchUps,
45495
45642
  drawMatic,
@@ -45507,6 +45654,7 @@ const eventGovernor = {
45507
45654
  assignDrawPosition,
45508
45655
  assignSeedPositions,
45509
45656
  assignDrawPositionBye,
45657
+ assignMatchUpSideParticipant,
45510
45658
  swapDrawPositionAssignments,
45511
45659
  removeDrawPositionAssignment,
45512
45660
  alternateDrawPositionAssignment,
@@ -50056,6 +50204,21 @@ function generateFlightDrawDefinitions({
50056
50204
  if (result.error === DRAW_ID_EXISTS) break;
50057
50205
  if (result.error) return result;
50058
50206
 
50207
+ if (drawProfile.drawType === AD_HOC && drawProfile.drawMatic) {
50208
+ const roundsCount = drawProfile.roundsCount || 1;
50209
+
50210
+ for (const roundNumber of generateRange(1, roundsCount + 1)) {
50211
+ const result = drawMatic({
50212
+ generateMatchUps: true,
50213
+ tournamentRecord,
50214
+ drawDefinition,
50215
+ roundNumber // this is not a real parameter
50216
+
50217
+ });
50218
+ if (result.error) return result;
50219
+ }
50220
+ }
50221
+
50059
50222
  if (drawProfile !== null && drawProfile !== void 0 && drawProfile.withPlayoffs) {
50060
50223
  const structureId = drawDefinition.structures[0].structureId;
50061
50224
  const result = addPlayoffStructures({
@@ -51255,6 +51418,21 @@ function generateEventWithDraw({
51255
51418
  event
51256
51419
  });
51257
51420
 
51421
+ if (drawType === AD_HOC && drawProfile.drawMatic) {
51422
+ const roundsCount = drawProfile.roundsCount || 1;
51423
+
51424
+ for (const roundNumber of generateRange(1, roundsCount + 1)) {
51425
+ const result = drawMatic({
51426
+ generateMatchUps: true,
51427
+ tournamentRecord,
51428
+ drawDefinition,
51429
+ roundNumber // this is not a real parameter
51430
+
51431
+ });
51432
+ if (result.error) return result;
51433
+ }
51434
+ }
51435
+
51258
51436
  if (drawProfile.withPlayoffs) {
51259
51437
  const structureId = drawDefinition.structures[0].structureId;
51260
51438
  const result = addPlayoffStructures({ ...drawProfile.withPlayoffs,