tods-competition-factory 0.68.0 → 0.69.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.68.0';
252
+ return '0.69.2';
253
253
  }
254
254
 
255
255
  const FORMAT_STANDARD = 'SET3-S:6/TB7'; // Best of 3 Tiebreak Sets to 6
@@ -7325,12 +7325,14 @@ var collectionDefinitions = [
7325
7325
  }
7326
7326
  ];
7327
7327
  var tieFormatName = "Doubles Shuffle";
7328
+ var unrestrictedSelections = true;
7328
7329
  var winCriteria = {
7329
7330
  aggregateValue: true
7330
7331
  };
7331
7332
  var TEAM_AGGREGATION_TIE_FORMAT = {
7332
7333
  collectionDefinitions: collectionDefinitions,
7333
7334
  tieFormatName: tieFormatName,
7335
+ unrestrictedSelections: unrestrictedSelections,
7334
7336
  winCriteria: winCriteria
7335
7337
  };
7336
7338
 
@@ -7401,6 +7403,7 @@ const SINGLE_ELIMINATION = 'SINGLE_ELIMINATION';
7401
7403
  const DOUBLE_ELIMINATION = 'DOUBLE_ELIMINATION';
7402
7404
  const FIRST_MATCH_LOSER_CONSOLATION = 'FIRST_MATCH_LOSER_CONSOLATION';
7403
7405
  const FIRST_ROUND_LOSER_CONSOLATION = 'FIRST_ROUND_LOSER_CONSOLATION';
7406
+ const LUCKY_DRAW = 'LUCKY_DRAW';
7404
7407
  const CURTIS = 'CURTIS_CONSOLATION';
7405
7408
  const FICSF = 'FEED_IN_CHAMPIONSHIP_TO_SF';
7406
7409
  const FEED_IN_CHAMPIONSHIP_TO_SF = 'FEED_IN_CHAMPIONSHIP_TO_SF';
@@ -7471,8 +7474,8 @@ const OLYMPIC_ATTRIBUTES = {
7471
7474
 
7472
7475
  const WIN_RATIO = 'WIN_RATIO';
7473
7476
  const ROUND_OUTCOME = 'ROUND_OUTCOME';
7474
- const MULTI_STRUCTURE_DRAWS = [FEED_IN$1, COMPASS, PLAY_OFF, OLYMPIC, CURTIS, FICSF, FICQF, FICR16, FIRST_MATCH_LOSER_CONSOLATION, FIRST_ROUND_LOSER_CONSOLATION, MODIFIED_FEED_IN_CHAMPIONSHIP, FEED_IN_CHAMPIONSHIP_TO_R16, FEED_IN_CHAMPIONSHIP_TO_QF, FEED_IN_CHAMPIONSHIP_TO_SF, FEED_IN_CHAMPIONSHIP, ROUND_ROBIN_WITH_PLAYOFF];
7475
- const generatedDrawTypes = [AD_HOC, COMPASS, CURTIS, DOUBLE_ELIMINATION, FEED_IN_CHAMPIONSHIP_TO_QF, FEED_IN_CHAMPIONSHIP_TO_R16, FEED_IN_CHAMPIONSHIP_TO_SF, FEED_IN_CHAMPIONSHIP, FEED_IN$1, FIRST_MATCH_LOSER_CONSOLATION, FIRST_ROUND_LOSER_CONSOLATION, MODIFIED_FEED_IN_CHAMPIONSHIP, OLYMPIC, PLAY_OFF, ROUND_ROBIN, ROUND_ROBIN_WITH_PLAYOFF, SINGLE_ELIMINATION];
7477
+ const MULTI_STRUCTURE_DRAWS = [COMPASS, CURTIS, FEED_IN_CHAMPIONSHIP_TO_QF, FEED_IN_CHAMPIONSHIP_TO_R16, FEED_IN_CHAMPIONSHIP_TO_SF, FEED_IN_CHAMPIONSHIP, FICQF, FICR16, FICSF, FIRST_MATCH_LOSER_CONSOLATION, FIRST_ROUND_LOSER_CONSOLATION, LUCKY_DRAW, MODIFIED_FEED_IN_CHAMPIONSHIP, OLYMPIC, PLAY_OFF, ROUND_ROBIN_WITH_PLAYOFF];
7478
+ const generatedDrawTypes = [AD_HOC, COMPASS, CURTIS, DOUBLE_ELIMINATION, FEED_IN_CHAMPIONSHIP_TO_QF, FEED_IN_CHAMPIONSHIP_TO_R16, FEED_IN_CHAMPIONSHIP_TO_SF, FEED_IN_CHAMPIONSHIP, FEED_IN$1, FIRST_MATCH_LOSER_CONSOLATION, FIRST_ROUND_LOSER_CONSOLATION, LUCKY_DRAW, MODIFIED_FEED_IN_CHAMPIONSHIP, OLYMPIC, PLAY_OFF, ROUND_ROBIN, ROUND_ROBIN_WITH_PLAYOFF, SINGLE_ELIMINATION];
7476
7479
  const drawDefinitionConstants = {
7477
7480
  MAIN,
7478
7481
  QUALIFYING,
@@ -7516,7 +7519,8 @@ const drawDefinitionConstants = {
7516
7519
  WIN_RATIO,
7517
7520
  ROUND_OUTCOME,
7518
7521
  MULTI_STRUCTURE_DRAWS,
7519
- generatedDrawTypes
7522
+ generatedDrawTypes,
7523
+ stageOrder
7520
7524
  };
7521
7525
 
7522
7526
  const WITHDRAW_PARTICIPANT_METHOD = 'withdrawParticipantAtDrawPosition';
@@ -9325,11 +9329,11 @@ function getTeamLineUp({
9325
9329
 
9326
9330
  const extractor = object => attr => object[attr];
9327
9331
 
9328
- const getMatchUpIds = (o = []) => o.map(getMatchUpId$1).filter(Boolean);
9332
+ const getMatchUpIds = (o = []) => o.map(getMatchUpId).filter(Boolean);
9329
9333
  const getParticipantIds = (o = []) => o.map(getParticipantId).filter(Boolean);
9330
9334
  const getParticipantId = (o = {}) => extractor(o)('participantId');
9331
9335
  const getDrawPosition = (o = {}) => extractor(o)('drawPosition');
9332
- const getMatchUpId$1 = (o = {}) => extractor(o)('matchUpId');
9336
+ const getMatchUpId = (o = {}) => extractor(o)('matchUpId');
9333
9337
 
9334
9338
  function getDrawPositionCollectionAssignment({
9335
9339
  tournamentParticipants,
@@ -9609,6 +9613,7 @@ function getMappedStructureMatchUps({
9609
9613
 
9610
9614
  if (inContext) {
9611
9615
  return matchUps.map(matchUp => Object.assign(makeDeepCopy(matchUp, true, true), {
9616
+ containerStructureId: structureId,
9612
9617
  structureId: itemStructureId,
9613
9618
  structureName
9614
9619
  }));
@@ -10685,6 +10690,31 @@ function getOrderedDrawPositions({
10685
10690
  };
10686
10691
  }
10687
10692
 
10693
+ function isLucky({
10694
+ drawDefinition,
10695
+ structure
10696
+ }) {
10697
+ var _roundMatchUps$, _roundMatchUps$2;
10698
+
10699
+ if (!structure) return false;
10700
+ const {
10701
+ roundProfile,
10702
+ roundMatchUps
10703
+ } = getRoundMatchUps$1({
10704
+ matchUps: structure.matchUps || []
10705
+ });
10706
+ const hasFirstRoundDrawPositions = !!(roundMatchUps !== null && roundMatchUps !== void 0 && (_roundMatchUps$ = roundMatchUps[1]) !== null && _roundMatchUps$ !== void 0 && _roundMatchUps$.find(({
10707
+ drawPositions
10708
+ }) => drawPositions));
10709
+ const noSecondRoundDrawPositions = !(roundMatchUps !== null && roundMatchUps !== void 0 && (_roundMatchUps$2 = roundMatchUps[2]) !== null && _roundMatchUps$2 !== void 0 && _roundMatchUps$2.find(({
10710
+ drawPositions
10711
+ }) => drawPositions));
10712
+ const hasOddMatchUpsCount = Object.values(roundProfile).find(({
10713
+ matchUpsCount
10714
+ }) => !isPowerOf2(matchUpsCount));
10715
+ return hasOddMatchUpsCount && !(structure !== null && structure !== void 0 && structure.structures) && hasFirstRoundDrawPositions && noSecondRoundDrawPositions && !(drawDefinition !== null && drawDefinition !== void 0 && drawDefinition.drawType && drawDefinition.drawType !== LUCKY_DRAW);
10716
+ }
10717
+
10688
10718
  function isAdHoc({
10689
10719
  drawDefinition,
10690
10720
  structure
@@ -10705,6 +10735,9 @@ function getRoundContextProfile({
10705
10735
  const isAdHocStructure = isAdHoc({
10706
10736
  structure
10707
10737
  });
10738
+ const isLuckyStructure = isLucky({
10739
+ structure
10740
+ });
10708
10741
  const {
10709
10742
  roundProfile
10710
10743
  } = getRoundMatchUps$1({
@@ -10722,12 +10755,14 @@ function getRoundContextProfile({
10722
10755
  const stageConstants = roundNamingPolicy === null || roundNamingPolicy === void 0 ? void 0 : roundNamingPolicy.stageConstants;
10723
10756
  const stageConstant = stageConstants && stageConstants[stage] || stageInitial;
10724
10757
 
10725
- if (isRoundRobin || isAdHocStructure) {
10758
+ if (isRoundRobin || isAdHocStructure || isLuckyStructure) {
10726
10759
  Object.assign(roundNamingProfile, ...Object.keys(roundProfile).map(key => {
10727
- const profileSize = `R${key}`;
10760
+ const roundName = `Round ${key}`;
10761
+ const abbreviatedRoundName = `R${key}`;
10728
10762
  return {
10729
10763
  [key]: {
10730
- roundName: profileSize
10764
+ roundName,
10765
+ abbreviatedRoundName
10731
10766
  }
10732
10767
  };
10733
10768
  }));
@@ -11218,10 +11253,10 @@ function getAllStructureMatchUps({
11218
11253
 
11219
11254
  if (!structure) {
11220
11255
  return {
11221
- matchUps: [],
11222
11256
  collectionPositionMatchUps,
11257
+ error: MISSING_STRUCTURE,
11223
11258
  roundMatchUps,
11224
- error: MISSING_STRUCTURE
11259
+ matchUps: []
11225
11260
  };
11226
11261
  }
11227
11262
 
@@ -14002,7 +14037,7 @@ function bulkScheduleMatchUps({
14002
14037
  const {
14003
14038
  tournamentId
14004
14039
  } = tournamentRecord;
14005
- const matchUpIds = matchUpContextIds.filter(contextIds => contextIds.tournamentId === tournamentId).map(getMatchUpId$1);
14040
+ const matchUpIds = matchUpContextIds.filter(contextIds => contextIds.tournamentId === tournamentId).map(getMatchUpId);
14006
14041
 
14007
14042
  if (matchUpIds !== null && matchUpIds !== void 0 && matchUpIds.length) {
14008
14043
  const result = bulkScheduleMatchUps$1({
@@ -14391,7 +14426,11 @@ function validateSchedulingProfile({
14391
14426
  });
14392
14427
  return validVenues;
14393
14428
  });
14394
- if (!isValid && !error) error = INVALID_VALUES;
14429
+
14430
+ if (!isValid && !error) {
14431
+ error = INVALID_VALUES;
14432
+ }
14433
+
14395
14434
  return {
14396
14435
  valid: !!isValid,
14397
14436
  error,
@@ -14431,8 +14470,9 @@ function tournamentRelevantSchedulingIds({
14431
14470
  drawDefinition
14432
14471
  });
14433
14472
  (structures || []).forEach(structure => {
14473
+ var _structure$structures;
14474
+
14434
14475
  const structureId = structure.structureId;
14435
- structureIds.push(structureId);
14436
14476
  const {
14437
14477
  matchUps
14438
14478
  } = getAllStructureMatchUps({
@@ -14445,6 +14485,14 @@ function tournamentRelevantSchedulingIds({
14445
14485
  });
14446
14486
  const rounds = roundMatchUps && Object.keys(roundMatchUps).map(roundNumber => parseInt(roundNumber));
14447
14487
  tournamentMap[tournamentId][eventId][drawId][structureId] = rounds;
14488
+ structureIds.push(structureId);
14489
+
14490
+ if ((_structure$structures = structure.structures) !== null && _structure$structures !== void 0 && _structure$structures.length) {
14491
+ structure.structures.forEach(itemStructure => {
14492
+ structureIds.push(itemStructure.structureId);
14493
+ tournamentMap[tournamentId][eventId][drawId][itemStructure.structureId] = rounds;
14494
+ });
14495
+ }
14448
14496
  });
14449
14497
  });
14450
14498
  });
@@ -19823,13 +19871,6 @@ function setMatchUpStatus$2(params) {
19823
19871
  return {
19824
19872
  error: INVALID_MATCHUP_STATUS
19825
19873
  };
19826
- }
19827
-
19828
- if (score) {
19829
- const result = validateScore({
19830
- score
19831
- });
19832
- if (result.error) return result;
19833
19874
  } // Get map of all drawMatchUps and inContextDrawMatchUPs ---------------------
19834
19875
 
19835
19876
 
@@ -19857,6 +19898,16 @@ function setMatchUpStatus$2(params) {
19857
19898
  })); // Find target matchUp ------------------------------------------------------
19858
19899
 
19859
19900
  const matchUp = matchUpsMap.drawMatchUps.find(matchUp => matchUp.matchUpId === matchUpId);
19901
+
19902
+ if (score) {
19903
+ const result = validateScore({
19904
+ score,
19905
+ matchUp,
19906
+ winningSide
19907
+ });
19908
+ if (result.error) return result;
19909
+ }
19910
+
19860
19911
  const inContextMatchUp = inContextDrawMatchUps.find(matchUp => matchUp.matchUpId === matchUpId);
19861
19912
  if (!matchUp || !inContextDrawMatchUps) return {
19862
19913
  error: MATCHUP_NOT_FOUND
@@ -24527,7 +24578,7 @@ function getScheduledRoundsDetails({
24527
24578
  const matchUpIds = roundMatchUps.filter(({
24528
24579
  matchUpStatus
24529
24580
  }) => // don't attempt to scheduled completed matchUpstatuses
24530
- !completedMatchUpStatuses.includes(matchUpStatus) && matchUpStatus !== BYE).map(getMatchUpId$1);
24581
+ !completedMatchUpStatuses.includes(matchUpStatus) && matchUpStatus !== BYE).map(getMatchUpId);
24531
24582
  matchUpIds.forEach(matchUpId => {
24532
24583
  minutesMap[matchUpId] = {
24533
24584
  typeChangeRecoveryMinutes,
@@ -24716,7 +24767,7 @@ function calculateScheduleTimes({
24716
24767
  } = getScheduleTimes(timingParameters); // if a single venue specified, or only one venue available, return venueId
24717
24768
 
24718
24769
  const venueId = (venueIds === null || venueIds === void 0 ? void 0 : venueIds.length) === 1 ? venueIds[0] : (venues === null || venues === void 0 ? void 0 : venues.length) === 1 ? venues[0].venueId : undefined;
24719
- const dateScheduledMatchUpIds = relevantMatchUps.map(getMatchUpId$1);
24770
+ const dateScheduledMatchUpIds = relevantMatchUps.map(getMatchUpId);
24720
24771
  return {
24721
24772
  venueId,
24722
24773
  scheduleTimes,
@@ -25558,7 +25609,7 @@ function clearScheduledMatchUps$1({
25558
25609
  const relevantMatchUpIds = matchUps.filter(matchUp => !ignoreMatchUpStatuses.includes(matchUp.matchUpStatus) && hasSchedule({
25559
25610
  schedule: matchUp.schedule,
25560
25611
  scheduleAttributes
25561
- }) && (!(venueIds !== null && venueIds !== void 0 && venueIds.length) || venueIds.includes(matchUp.schedule.venueId))).map(getMatchUpId$1);
25612
+ }) && (!(venueIds !== null && venueIds !== void 0 && venueIds.length) || venueIds.includes(matchUp.schedule.venueId))).map(getMatchUpId);
25562
25613
  const clearedScheduleValues = {
25563
25614
  venueId: '',
25564
25615
  scheduledDate: '',
@@ -25859,7 +25910,7 @@ function generateScheduleTimes({
25859
25910
  } = getScheduleTimes(timingParameters); // if a single venue specified, or only one venue available, return venueId
25860
25911
 
25861
25912
  const venueId = (venueIds === null || venueIds === void 0 ? void 0 : venueIds.length) === 1 ? venueIds[0] : (venues === null || venues === void 0 ? void 0 : venues.length) === 1 ? venues[0].venueId : undefined;
25862
- const dateScheduledMatchUpIds = dateScheduledMatchUps.map(getMatchUpId$1);
25913
+ const dateScheduledMatchUpIds = dateScheduledMatchUps.map(getMatchUpId);
25863
25914
  return {
25864
25915
  venueId,
25865
25916
  scheduleTimes,
@@ -26011,8 +26062,8 @@ function jinnScheduler({
26011
26062
  orderedMatchUpIds,
26012
26063
  minutesMap
26013
26064
  } = getScheduledRoundsDetails({
26014
- tournamentRecords,
26015
26065
  containedStructureIds,
26066
+ tournamentRecords,
26016
26067
  periodLength,
26017
26068
  matchUps,
26018
26069
  rounds
@@ -26351,7 +26402,7 @@ function jinnScheduler({
26351
26402
  });
26352
26403
  }
26353
26404
  });
26354
- noTimeMatchUpIds[scheduleDate] = venueScheduledRoundDetails[venueId].matchUpsToSchedule.map(getMatchUpId$1);
26405
+ noTimeMatchUpIds[scheduleDate] = venueScheduledRoundDetails[venueId].matchUpsToSchedule.map(getMatchUpId);
26355
26406
  scheduleTimesRemaining[scheduleDate][venueId] = venueScheduledRoundDetails[venueId].scheduleTimes.sort((a, b) => timeStringMinutes(a.scheduleTime) - timeStringMinutes(b.scheduleTime));
26356
26407
  }
26357
26408
  } // returns the original form of the dateStrings, before extractDate()
@@ -31065,123 +31116,70 @@ const structureTemplate = ({
31065
31116
  return structure;
31066
31117
  };
31067
31118
 
31068
- function treeMatchUps({
31069
- qualifyingRoundNumber,
31070
- // round at which participants qualify
31071
- finishingPositionOffset,
31072
- qualifyingPositions,
31073
- // number of positions which qualify
31074
- matchUpType,
31075
- roundLimit,
31076
- idPrefix,
31077
- drawSize,
31078
- isMock,
31079
- uuids
31080
- }) {
31081
- if (isNaN(drawSize) || !isPowerOf2(drawSize) || drawSize < 2) {
31082
- return {
31083
- matchUps: [],
31084
- roundsCount: 0
31085
- };
31086
- }
31087
-
31088
- const nodes = generateRange(1, parseInt(drawSize) + 1).map(drawPosition => ({
31089
- drawPosition
31090
- }));
31091
- let roundNodes;
31092
- let matchUps = [];
31093
- let roundNumber = 1;
31094
- ({
31095
- roundNodes,
31096
- matchUps
31097
- } = buildRound({
31098
- roundNumber,
31099
- matchUpType,
31100
- idPrefix,
31101
- matchUps,
31102
- isMock,
31103
- nodes,
31104
- uuids
31105
- }));
31106
- roundNumber++;
31107
- roundLimit = roundLimit || qualifyingRoundNumber;
31108
-
31109
- while (roundNodes.length > 1) {
31110
- if (qualifyingPositions && roundNodes.length === qualifyingPositions) roundLimit = roundNumber - 1;
31111
- ({
31112
- roundNodes,
31113
- matchUps
31114
- } = buildRound({
31115
- nodes: roundNodes,
31116
- roundNumber,
31117
- matchUpType,
31118
- idPrefix,
31119
- matchUps,
31120
- isMock,
31121
- uuids
31122
- }));
31123
- roundNumber++;
31124
- }
31125
-
31126
- const roundsCount = roundNumber - 1;
31127
- matchUps = addFinishingRounds({
31128
- finishingPositionOffset,
31129
- roundsCount,
31130
- roundLimit,
31131
- matchUps
31132
- });
31133
-
31134
- if (roundLimit) {
31135
- matchUps = matchUps.filter(matchUp => matchUp.roundNumber <= roundLimit);
31136
- }
31137
-
31138
- return {
31139
- matchUps,
31140
- roundsCount,
31141
- roundLimit
31142
- };
31143
- }
31144
-
31145
31119
  function addFinishingRounds({
31146
31120
  finishingPositionOffset = 0,
31147
31121
  positionsFed,
31148
31122
  roundsCount,
31149
31123
  roundLimit,
31150
31124
  matchUps,
31125
+ lucky,
31151
31126
  fmlc
31152
31127
  }) {
31153
- // object containing # of matchUps (value) for each round (attribute)
31154
- const roundMatchCounts = matchUps.reduce((p, matchUp) => {
31155
- p[matchUp.roundNumber] = (p[matchUp.roundNumber] || 0) + 1;
31156
- return p;
31157
- }, {}); // array of # of matchUps (value) for eaach round (index)
31128
+ const {
31129
+ roundProfile,
31130
+ roundNumbers
31131
+ } = getRoundMatchUps$1({
31132
+ matchUps
31133
+ }); // array of # of matchUps (value) for eaach round (index)
31158
31134
 
31159
- const roundMatchCountArray = Object.values(roundMatchCounts); // returns a range for array of possible finishing drawPositions
31135
+ const roundMatchUpsCountArray = Object.values(roundProfile).map(({
31136
+ matchUpsCount
31137
+ }) => matchUpsCount); // returns a range for array of possible finishing drawPositions
31160
31138
 
31161
31139
  const finishingRange = drawPositions => [Math.min(...drawPositions), Math.max(...drawPositions)]; // for qualifying, offset the final round so that qualifyinground is finishingRound
31162
31140
 
31163
31141
 
31164
31142
  const finishingRoundOffset = roundLimit ? roundsCount - roundLimit : 0;
31165
- matchUps.forEach(matchUp => {
31166
- matchUp.finishingRound = roundsCount + 1 - matchUp.roundNumber - finishingRoundOffset; // in the case of FMLC the finishingPositionRange in consolation is not modified after first fed round
31143
+ const roundFinishingData = Object.assign({}, ...roundNumbers.map(roundNumber => {
31144
+ const finishingRound = roundsCount + 1 - roundNumber - finishingRoundOffset;
31145
+ const matchUpsCount = roundProfile[roundNumber].matchUpsCount;
31146
+ const finishingData = {
31147
+ finishingRound
31148
+ };
31149
+ const upcomingMatchUps = roundMatchUpsCountArray.slice(roundNumber - 1).reduce((a, b) => a + b, 0); // in the case of FMLC the finishingPositionRange in consolation is not modified after first fed round
31167
31150
 
31168
- const fmlcException = fmlc && matchUp.roundNumber !== 1;
31151
+ const fmlcException = fmlc && roundNumber !== 1;
31169
31152
  const rangeOffset = 1 + finishingPositionOffset + (fmlcException ? positionsFed : 0);
31170
- const currentMatchUps = roundMatchCounts[matchUp.roundNumber];
31171
- const upcomingMatchUps = roundMatchCountArray.slice(matchUp.roundNumber - 1).reduce((a, b) => a + b, 0);
31172
31153
  const finalPosition = 1;
31173
- const finishingPositionRange = generateRange(rangeOffset, upcomingMatchUps + rangeOffset + finalPosition);
31174
- const slicer = upcomingMatchUps + finalPosition - currentMatchUps;
31175
- const loser = finishingRange(finishingPositionRange.slice(slicer));
31176
- const winner = finishingRange(finishingPositionRange.slice(0, slicer));
31177
- matchUp.finishingPositionRange = {
31154
+ const positionRange = generateRange(rangeOffset, lucky ? rangeOffset + matchUpsCount * 2 : upcomingMatchUps + rangeOffset + finalPosition);
31155
+ const slicer = upcomingMatchUps + finalPosition - matchUpsCount;
31156
+ const loser = finishingRange(positionRange.slice(slicer));
31157
+ const winner = finishingRange(positionRange.slice(0, slicer));
31158
+ finishingData.finishingPositionRange = {
31178
31159
  loser,
31179
31160
  winner
31180
31161
  };
31162
+ return {
31163
+ [roundNumber]: finishingData
31164
+ };
31165
+ }));
31166
+ matchUps.forEach(matchUp => {
31167
+ const roundData = roundFinishingData[matchUp.roundNumber];
31168
+ matchUp.finishingRound = roundData.finishingRound;
31169
+ matchUp.finishingPositionRange = roundData.finishingPositionRange;
31181
31170
  });
31182
31171
  return matchUps;
31183
31172
  }
31184
31173
 
31174
+ function generateMatchUpId({
31175
+ idPrefix,
31176
+ roundNumber,
31177
+ roundPosition,
31178
+ uuids
31179
+ }) {
31180
+ return idPrefix ? `${idPrefix}-${roundNumber}-${roundPosition}` : (uuids === null || uuids === void 0 ? void 0 : uuids.pop()) || UUID();
31181
+ }
31182
+
31185
31183
  function buildRound({
31186
31184
  includeMatchUpType,
31187
31185
  matchUpType,
@@ -31203,7 +31201,7 @@ function buildRound({
31203
31201
  const child2 = nodes[index + 1];
31204
31202
  if (matchRoundNumber) child1.roundNumber = matchRoundNumber;
31205
31203
  if (child2 && matchRoundNumber) child2.roundNumber = matchRoundNumber;
31206
- const matchUpId = getMatchUpId({
31204
+ const matchUpId = generateMatchUpId({
31207
31205
  roundPosition,
31208
31206
  roundNumber,
31209
31207
  idPrefix,
@@ -31229,8 +31227,8 @@ function buildRound({
31229
31227
  if (includeMatchUpType) matchUp.matchUpType = matchUpType;
31230
31228
  if (isMock) matchUp.isMock = true;
31231
31229
  matchUps.push(matchUp);
31232
- index += 2;
31233
31230
  roundPosition++;
31231
+ index += 2;
31234
31232
  }
31235
31233
 
31236
31234
  return {
@@ -31239,247 +31237,103 @@ function buildRound({
31239
31237
  };
31240
31238
  }
31241
31239
 
31242
- function roundMatchCounts({
31243
- drawSize
31244
- }) {
31245
- const rounds = Math.ceil(Math.log(drawSize) / Math.log(2));
31246
- const range = generateRange(0, rounds).reverse();
31247
- return range.map(r => Math.pow(2, r));
31248
- }
31249
-
31250
- function feedInMatchUps({
31251
- linkFedFinishingRoundNumbers = [],
31252
- linkFedRoundNumbers = [],
31240
+ function treeMatchUps({
31241
+ qualifyingRoundNumber,
31242
+ // round at which participants qualify
31253
31243
  finishingPositionOffset,
31254
- feedRoundsProfile = [],
31255
- feedRounds = 0,
31256
- skipRounds = 0,
31257
- feedsFromFinal,
31258
- isConsolation,
31259
- baseDrawSize,
31244
+ qualifyingPositions,
31245
+ // number of positions which qualify
31260
31246
  matchUpType,
31247
+ roundLimit,
31261
31248
  idPrefix,
31262
31249
  drawSize,
31263
31250
  isMock,
31264
- uuids,
31265
- fmlc
31251
+ uuids
31266
31252
  }) {
31267
- // calculate the number of rounds and the number of matchUps in each round
31268
- // for normal elimination structure
31269
- baseDrawSize = baseDrawSize || getBaseDrawSize(drawSize);
31270
- const baseDrawRounds = roundMatchCounts({
31271
- drawSize: baseDrawSize
31272
- });
31273
- const baseRoundsCount = baseDrawRounds.length;
31274
- let positionsFed = 0;
31275
-
31276
- if (feedRoundsProfile.length) {
31277
- positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
31278
- } else if (drawSize) {
31279
- // having a drawSize defined trumps other configuration options
31280
- let positionsToFeed = drawSize - baseDrawSize;
31281
- feedRoundsProfile = baseDrawRounds.filter(feedSize => {
31282
- if (feedSize <= positionsToFeed) {
31283
- positionsToFeed -= feedSize;
31284
- return true;
31285
- }
31286
-
31287
- return false;
31288
- });
31289
- positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
31290
- feedRounds = feedRoundsProfile.length;
31291
- } else {
31292
- // if skipRounds is set higher than baseRoundsCount then there are no feedRounds
31293
- if (skipRounds >= baseRoundsCount) feedRounds = 0; // if feedsFromFinal is defined, calculate number of feed rounds from Final Match
31294
- // e.g. feedsFromFinal is 1 for Semifinal, 2 for QuarterFinals, 3 for Round of 16
31295
-
31296
- if (feedsFromFinal) {
31297
- feedRounds = baseRoundsCount - feedsFromFinal;
31298
- skipRounds = 0;
31299
- } // Given the above, feedsFromFinal trumps skipRounds
31300
- // and skipRounds >= baseRoundsCount negates feedRounds
31301
-
31302
-
31303
- feedRoundsProfile = baseDrawRounds.filter((feedSize, i) => {
31304
- if (feedsFromFinal && !feedRounds) return 0;
31305
- if (feedRounds && i >= skipRounds + feedRounds) return 0;
31306
- if (i < skipRounds) return 0;
31307
- return feedSize;
31308
- });
31309
- positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
31310
- drawSize = baseDrawSize + positionsFed;
31311
- feedRounds = feedRoundsProfile.length;
31253
+ if (isNaN(drawSize) || !isPowerOf2(drawSize) || drawSize < 2) {
31254
+ return {
31255
+ matchUps: [],
31256
+ roundsCount: 0
31257
+ };
31312
31258
  }
31313
31259
 
31314
- const allRounds = [...baseDrawRounds, ...feedRoundsProfile].sort((a, b) => b - a);
31315
- const roundsCount = allRounds.length; // rounds which have linkFed participants can be specified two ways:
31316
- // linkFedRoundNumbers[] and linkFedFinishingRoundNumbers[]
31317
- // the difference being which end of the draw structure === 1
31318
-
31319
- const linkFedRoundNumbersIndices = [...linkFedRoundNumbers.map(n => n - 1), ...linkFedFinishingRoundNumbers.map(n => roundsCount - n)]; // positionsFedByLinks can be determined by summing the values in allRounds
31320
- // which are found at linkFedRoundNumbersIndices
31321
-
31322
- const positionsFedByLinks = linkFedRoundNumbersIndices.map(i => allRounds[i]).reduce((a, b) => a + b, 0);
31323
- positionsFed = positionsFed - positionsFedByLinks; // initialize round creation variables
31324
-
31325
- let fed = 0; // keep track of even/odd feed rounds
31326
-
31327
- let matchUps = []; // accumulate matchUps
31328
-
31329
- let roundNodes; // an array of nodes
31330
-
31331
- let roundNumber = 1; // initial roundNumber
31332
- // firstRoundDrawPositions are generated and assigned drawPositions
31333
-
31334
- const firstRoundDrawPositions = generateRange(0, baseDrawSize).map((x, i) => ({
31335
- drawPosition: i + 1 + positionsFed
31336
- })); // initial nodes fed into buildRound
31337
-
31338
- let nodes = firstRoundDrawPositions; // drawPosition within structure; offset used for feedRounds
31260
+ const nodes = generateRange(1, parseInt(drawSize) + 1).map(drawPosition => ({
31261
+ drawPosition
31262
+ }));
31263
+ let roundNodes;
31264
+ let matchUps = [];
31265
+ let roundNumber = 1;
31266
+ ({
31267
+ roundNodes,
31268
+ matchUps
31269
+ } = buildRound({
31270
+ roundNumber,
31271
+ matchUpType,
31272
+ idPrefix,
31273
+ matchUps,
31274
+ isMock,
31275
+ nodes,
31276
+ uuids
31277
+ }));
31278
+ roundNumber++;
31279
+ roundLimit = roundLimit || qualifyingRoundNumber;
31339
31280
 
31340
- let drawPosition = positionsFed + 1;
31281
+ while (roundNodes.length > 1) {
31282
+ if (qualifyingPositions && roundNodes.length === qualifyingPositions) {
31283
+ roundLimit = roundNumber - 1;
31284
+ }
31341
31285
 
31342
- for (const baseDrawRound of baseDrawRounds) {
31343
31286
  ({
31344
31287
  roundNodes,
31345
31288
  matchUps
31346
31289
  } = buildRound({
31290
+ nodes: roundNodes,
31347
31291
  roundNumber,
31348
31292
  matchUpType,
31349
31293
  idPrefix,
31350
31294
  matchUps,
31351
31295
  isMock,
31352
- nodes,
31353
31296
  uuids
31354
31297
  }));
31355
31298
  roundNumber++;
31356
-
31357
- if (feedRoundsProfile.includes(baseDrawRound)) {
31358
- const roundIterations = instanceCount(feedRoundsProfile)[baseDrawRound];
31359
- const iterationRange = generateRange(0, roundIterations);
31360
- const finishingRoundNumber = roundsCount + 1 - roundNumber;
31361
- const isLinkFedRound = linkFedFinishingRoundNumbers.includes(finishingRoundNumber) || linkFedRoundNumbers.includes(roundNumber);
31362
-
31363
- for (const roundIteration of iterationRange) {
31364
- const iterationDrawPosition = !isLinkFedRound && drawPosition || undefined;
31365
- ({
31366
- roundNodes,
31367
- matchUps,
31368
- drawPosition
31369
- } = buildFeedRound({
31370
- drawPosition: iterationDrawPosition,
31371
- nodes: roundNodes,
31372
- roundIteration,
31373
- // meaningless; avoids eslint value never used
31374
- roundNumber,
31375
- matchUpType,
31376
- idPrefix,
31377
- matchUps,
31378
- uuids,
31379
- fed
31380
- }));
31381
- roundNumber++;
31382
- fed += 1;
31383
- }
31384
- }
31385
-
31386
- nodes = roundNodes;
31387
31299
  }
31388
31300
 
31389
- if (roundsCount !== roundNumber - 1) console.log('ERROR'); // if this is a feed-in consolation then finishing drawPositions must be offset ...
31390
- // ... by the number of drawPositions which will be fed into the consolation draw
31391
- // final drawPositions will be played off twice up until the final feed round
31392
-
31393
- const consolationFinish = baseDrawSize - positionsFed;
31394
- const modifiedFinishingPositionOffset = isConsolation ? consolationFinish : finishingPositionOffset;
31301
+ const roundsCount = roundNumber - 1;
31395
31302
  matchUps = addFinishingRounds({
31396
- finishingPositionOffset: modifiedFinishingPositionOffset,
31397
- positionsFed,
31303
+ finishingPositionOffset,
31398
31304
  roundsCount,
31399
- matchUps,
31400
- fmlc
31305
+ roundLimit,
31306
+ matchUps
31401
31307
  });
31402
- const draw = roundNodes && roundNodes.length ? roundNodes[0] : roundNodes;
31403
-
31404
- if (draw) {
31405
- draw.roundNumber = roundNumber - 1;
31406
- draw.matchUps = matchUps;
31407
- }
31408
-
31409
- return {
31410
- draw,
31411
- matchUps,
31412
- roundsCount
31413
- };
31414
-
31415
- function getBaseDrawSize(drawSize) {
31416
- const nearestP2 = nearestPowerOf2(drawSize);
31417
- return nearestP2 > drawSize ? nearestP2 / 2 : nearestP2;
31418
- }
31419
- }
31420
-
31421
- function buildFeedRound({
31422
- includeMatchUpType,
31423
- drawPosition,
31424
- matchUpType,
31425
- roundNumber,
31426
- idPrefix,
31427
- matchUps,
31428
- uuids,
31429
- nodes,
31430
- fed
31431
- }) {
31432
- const feedRoundMatchUpsCount = nodes.length;
31433
- const initialGroupDrawPosition = drawPosition ? drawPosition - feedRoundMatchUpsCount : undefined;
31434
- const drawPositionGroup = generateRange(0, feedRoundMatchUpsCount).map(value => initialGroupDrawPosition ? initialGroupDrawPosition + value : undefined);
31435
- const roundNodes = [];
31436
31308
 
31437
- for (let nodeIndex = 0; nodeIndex < feedRoundMatchUpsCount; nodeIndex++) {
31438
- const feedDrawPosition = drawPositionGroup.shift();
31439
- const feedArm = {
31440
- feed: true,
31441
- fed: fed + 1,
31442
- drawPosition: feedDrawPosition
31443
- };
31444
- const position = nodes[nodeIndex];
31445
- position.roundNumber = roundNumber - 1;
31446
- const matchUpId = getMatchUpId({
31447
- roundPosition: position.roundPosition,
31448
- roundNumber,
31449
- idPrefix,
31450
- uuids
31451
- });
31452
- const newMatchUp = {
31453
- roundNumber,
31454
- matchUpId,
31455
- roundPosition: position.roundPosition,
31456
- drawPositions: [undefined, feedDrawPosition]
31457
- }; // matchUpType is derived for inContext matchUps from structure or drawDefinition
31458
-
31459
- if (includeMatchUpType) newMatchUp.matchUpType = matchUpType;
31460
- matchUps.push(newMatchUp);
31461
- const roundNode = {
31462
- children: [position, feedArm]
31463
- };
31464
- roundNodes.push(roundNode);
31309
+ if (roundLimit) {
31310
+ matchUps = matchUps.filter(matchUp => matchUp.roundNumber <= roundLimit);
31465
31311
  }
31466
31312
 
31467
- const nextDrawPosition = drawPosition ? drawPosition - feedRoundMatchUpsCount : undefined;
31468
31313
  return {
31469
- roundNodes,
31470
31314
  matchUps,
31471
- drawPosition: nextDrawPosition
31315
+ roundsCount,
31316
+ roundLimit
31472
31317
  };
31473
31318
  }
31474
-
31475
- function getMatchUpId({
31476
- idPrefix,
31477
- roundNumber,
31478
- roundPosition,
31479
- uuids
31480
- }) {
31481
- return idPrefix ? `${idPrefix}-${roundNumber}-${roundPosition}` : (uuids === null || uuids === void 0 ? void 0 : uuids.pop()) || UUID();
31319
+ /*
31320
+ export function feedDrawSize({ opponentCount }) {
31321
+ const baseRanges = generateRange(0, 10).map((i) => {
31322
+ const positionsBase = Math.pow(2, i);
31323
+ const feedPositions = positionsBase - 1;
31324
+ const maxByes = positionsBase / 2 - 1;
31325
+ const maxPositions = positionsBase + feedPositions;
31326
+ const positionRange = { positionsBase, maxPositions, maxByes };
31327
+ return positionRange;
31328
+ });
31329
+ const positionsBase = baseRanges.reduce((p, c) => {
31330
+ return opponentCount >= c.positionsBase && opponentCount <= c.maxPositions
31331
+ ? c
31332
+ : p;
31333
+ }, undefined);
31334
+ return positionsBase;
31482
31335
  }
31336
+ */
31483
31337
 
31484
31338
  function generateVoluntaryConsolationStructure$1({
31485
31339
  structureName = VOLUNTARY_CONSOLATION,
@@ -32561,6 +32415,239 @@ function generateTieMatchUps({
32561
32415
  };
32562
32416
  }
32563
32417
 
32418
+ function buildFeedRound({
32419
+ includeMatchUpType,
32420
+ drawPosition,
32421
+ matchUpType,
32422
+ roundNumber,
32423
+ idPrefix,
32424
+ matchUps,
32425
+ uuids,
32426
+ nodes,
32427
+ fed
32428
+ }) {
32429
+ const feedRoundMatchUpsCount = nodes.length;
32430
+ const initialGroupDrawPosition = drawPosition ? drawPosition - feedRoundMatchUpsCount : undefined;
32431
+ const drawPositionGroup = generateRange(0, feedRoundMatchUpsCount).map(value => initialGroupDrawPosition ? initialGroupDrawPosition + value : undefined);
32432
+ const roundNodes = [];
32433
+
32434
+ for (let nodeIndex = 0; nodeIndex < feedRoundMatchUpsCount; nodeIndex++) {
32435
+ const feedDrawPosition = drawPositionGroup.shift();
32436
+ const feedArm = {
32437
+ feed: true,
32438
+ fed: fed + 1,
32439
+ drawPosition: feedDrawPosition
32440
+ };
32441
+ const position = nodes[nodeIndex];
32442
+ position.roundNumber = roundNumber - 1;
32443
+ const matchUpId = generateMatchUpId({
32444
+ roundPosition: position.roundPosition,
32445
+ roundNumber,
32446
+ idPrefix,
32447
+ uuids
32448
+ });
32449
+ const newMatchUp = {
32450
+ roundNumber,
32451
+ matchUpId,
32452
+ roundPosition: position.roundPosition,
32453
+ drawPositions: [undefined, feedDrawPosition]
32454
+ }; // matchUpType is derived for inContext matchUps from structure or drawDefinition
32455
+
32456
+ if (includeMatchUpType) newMatchUp.matchUpType = matchUpType;
32457
+ matchUps.push(newMatchUp);
32458
+ const roundNode = {
32459
+ children: [position, feedArm]
32460
+ };
32461
+ roundNodes.push(roundNode);
32462
+ }
32463
+
32464
+ const nextDrawPosition = drawPosition ? drawPosition - feedRoundMatchUpsCount : undefined;
32465
+ return {
32466
+ roundNodes,
32467
+ matchUps,
32468
+ drawPosition: nextDrawPosition
32469
+ };
32470
+ }
32471
+
32472
+ function feedInMatchUps({
32473
+ linkFedFinishingRoundNumbers = [],
32474
+ linkFedRoundNumbers = [],
32475
+ finishingPositionOffset,
32476
+ feedRoundsProfile = [],
32477
+ feedRounds = 0,
32478
+ skipRounds = 0,
32479
+ feedsFromFinal,
32480
+ isConsolation,
32481
+ baseDrawSize,
32482
+ matchUpType,
32483
+ idPrefix,
32484
+ drawSize,
32485
+ isMock,
32486
+ uuids,
32487
+ fmlc
32488
+ }) {
32489
+ // calculate the number of rounds and the number of matchUps in each round
32490
+ // for normal elimination structure
32491
+ baseDrawSize = baseDrawSize || getBaseDrawSize(drawSize);
32492
+ const baseDrawRounds = roundMatchCounts({
32493
+ drawSize: baseDrawSize
32494
+ });
32495
+ const baseRoundsCount = baseDrawRounds.length;
32496
+ let positionsFed = 0;
32497
+
32498
+ if (feedRoundsProfile.length) {
32499
+ positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
32500
+ } else if (drawSize) {
32501
+ // having a drawSize defined trumps other configuration options
32502
+ let positionsToFeed = drawSize - baseDrawSize;
32503
+ feedRoundsProfile = baseDrawRounds.filter(feedSize => {
32504
+ if (feedSize <= positionsToFeed) {
32505
+ positionsToFeed -= feedSize;
32506
+ return true;
32507
+ }
32508
+
32509
+ return false;
32510
+ });
32511
+ positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
32512
+ feedRounds = feedRoundsProfile.length;
32513
+ } else {
32514
+ // if skipRounds is set higher than baseRoundsCount then there are no feedRounds
32515
+ if (skipRounds >= baseRoundsCount) feedRounds = 0; // if feedsFromFinal is defined, calculate number of feed rounds from Final Match
32516
+ // e.g. feedsFromFinal is 1 for Semifinal, 2 for QuarterFinals, 3 for Round of 16
32517
+
32518
+ if (feedsFromFinal) {
32519
+ feedRounds = baseRoundsCount - feedsFromFinal;
32520
+ skipRounds = 0;
32521
+ } // Given the above, feedsFromFinal trumps skipRounds
32522
+ // and skipRounds >= baseRoundsCount negates feedRounds
32523
+
32524
+
32525
+ feedRoundsProfile = baseDrawRounds.filter((feedSize, i) => {
32526
+ if (feedsFromFinal && !feedRounds) return 0;
32527
+ if (feedRounds && i >= skipRounds + feedRounds) return 0;
32528
+ if (i < skipRounds) return 0;
32529
+ return feedSize;
32530
+ });
32531
+ positionsFed = feedRoundsProfile.reduce((a, b) => a + b, 0);
32532
+ drawSize = baseDrawSize + positionsFed;
32533
+ feedRounds = feedRoundsProfile.length;
32534
+ }
32535
+
32536
+ const allRounds = [...baseDrawRounds, ...feedRoundsProfile].sort((a, b) => b - a);
32537
+ const roundsCount = allRounds.length; // rounds which have linkFed participants can be specified two ways:
32538
+ // linkFedRoundNumbers[] and linkFedFinishingRoundNumbers[]
32539
+ // the difference being which end of the draw structure === 1
32540
+
32541
+ const linkFedRoundNumbersIndices = [...linkFedRoundNumbers.map(n => n - 1), ...linkFedFinishingRoundNumbers.map(n => roundsCount - n)]; // positionsFedByLinks can be determined by summing the values in allRounds
32542
+ // which are found at linkFedRoundNumbersIndices
32543
+
32544
+ const positionsFedByLinks = linkFedRoundNumbersIndices.map(i => allRounds[i]).reduce((a, b) => a + b, 0);
32545
+ positionsFed = positionsFed - positionsFedByLinks; // initialize round creation variables
32546
+
32547
+ let fed = 0; // keep track of even/odd feed rounds
32548
+
32549
+ let matchUps = []; // accumulate matchUps
32550
+
32551
+ let roundNodes; // an array of nodes
32552
+
32553
+ let roundNumber = 1; // initial roundNumber
32554
+ // firstRoundDrawPositions are generated and assigned drawPositions
32555
+
32556
+ const firstRoundDrawPositions = generateRange(0, baseDrawSize).map((x, i) => ({
32557
+ drawPosition: i + 1 + positionsFed
32558
+ })); // initial nodes fed into buildRound
32559
+
32560
+ let nodes = firstRoundDrawPositions; // drawPosition within structure; offset used for feedRounds
32561
+
32562
+ let drawPosition = positionsFed + 1;
32563
+
32564
+ for (const baseDrawRound of baseDrawRounds) {
32565
+ ({
32566
+ roundNodes,
32567
+ matchUps
32568
+ } = buildRound({
32569
+ roundNumber,
32570
+ matchUpType,
32571
+ idPrefix,
32572
+ matchUps,
32573
+ isMock,
32574
+ nodes,
32575
+ uuids
32576
+ }));
32577
+ roundNumber++;
32578
+
32579
+ if (feedRoundsProfile.includes(baseDrawRound)) {
32580
+ const roundIterations = instanceCount(feedRoundsProfile)[baseDrawRound];
32581
+ const iterationRange = generateRange(0, roundIterations);
32582
+ const finishingRoundNumber = roundsCount + 1 - roundNumber;
32583
+ const isLinkFedRound = linkFedFinishingRoundNumbers.includes(finishingRoundNumber) || linkFedRoundNumbers.includes(roundNumber);
32584
+
32585
+ for (const roundIteration of iterationRange) {
32586
+ const iterationDrawPosition = !isLinkFedRound && drawPosition || undefined;
32587
+ ({
32588
+ roundNodes,
32589
+ matchUps,
32590
+ drawPosition
32591
+ } = buildFeedRound({
32592
+ drawPosition: iterationDrawPosition,
32593
+ nodes: roundNodes,
32594
+ roundIteration,
32595
+ // meaningless; avoids eslint value never used
32596
+ roundNumber,
32597
+ matchUpType,
32598
+ idPrefix,
32599
+ matchUps,
32600
+ uuids,
32601
+ fed
32602
+ }));
32603
+ roundNumber++;
32604
+ fed += 1;
32605
+ }
32606
+ }
32607
+
32608
+ nodes = roundNodes;
32609
+ }
32610
+
32611
+ if (roundsCount !== roundNumber - 1) console.log('ERROR'); // if this is a feed-in consolation then finishing drawPositions must be offset ...
32612
+ // ... by the number of drawPositions which will be fed into the consolation draw
32613
+ // final drawPositions will be played off twice up until the final feed round
32614
+
32615
+ const consolationFinish = baseDrawSize - positionsFed;
32616
+ const modifiedFinishingPositionOffset = isConsolation ? consolationFinish : finishingPositionOffset;
32617
+ matchUps = addFinishingRounds({
32618
+ finishingPositionOffset: modifiedFinishingPositionOffset,
32619
+ positionsFed,
32620
+ roundsCount,
32621
+ matchUps,
32622
+ fmlc
32623
+ });
32624
+ const draw = roundNodes && roundNodes.length ? roundNodes[0] : roundNodes;
32625
+
32626
+ if (draw) {
32627
+ draw.roundNumber = roundNumber - 1;
32628
+ draw.matchUps = matchUps;
32629
+ }
32630
+
32631
+ return {
32632
+ draw,
32633
+ matchUps,
32634
+ roundsCount
32635
+ };
32636
+
32637
+ function getBaseDrawSize(drawSize) {
32638
+ const nearestP2 = nearestPowerOf2(drawSize);
32639
+ return nearestP2 > drawSize ? nearestP2 / 2 : nearestP2;
32640
+ }
32641
+ } // returns an array of the number of matchUps in each round of an elimination draw
32642
+
32643
+ function roundMatchCounts({
32644
+ drawSize
32645
+ }) {
32646
+ const rounds = Math.ceil(Math.log(drawSize) / Math.log(2));
32647
+ const range = generateRange(0, rounds).reverse();
32648
+ return range.map(r => Math.pow(2, r));
32649
+ }
32650
+
32564
32651
  function playoff(params) {
32565
32652
  const {
32566
32653
  structure,
@@ -32860,7 +32947,7 @@ function addPlayoffStructures$1(params) {
32860
32947
  });
32861
32948
  const addedMatchUpIds = inContextDrawMatchUps.filter(({
32862
32949
  structureId
32863
- }) => newStructureIds.includes(structureId)).map(getMatchUpId$1);
32950
+ }) => newStructureIds.includes(structureId)).map(getMatchUpId);
32864
32951
  const addedMatchUps = matchUpsMap === null || matchUpsMap === void 0 ? void 0 : (_matchUpsMap$drawMatc = matchUpsMap.drawMatchUps) === null || _matchUpsMap$drawMatc === void 0 ? void 0 : _matchUpsMap$drawMatc.filter(({
32865
32952
  matchUpId
32866
32953
  }) => addedMatchUpIds.includes(matchUpId));
@@ -33479,7 +33566,7 @@ function generateQualifyingStructures({
33479
33566
  const sequenceSort = (a, b) => a.stageSequence - b.stageSequence;
33480
33567
 
33481
33568
  let qualifyingDrawPositionsCount = 0,
33482
- finalyQualifyingRoundNumber,
33569
+ finalQualifyingRoundNumber,
33483
33570
  finalQualifyingStructureId,
33484
33571
  qualifiersCount = 0,
33485
33572
  stageSequence = 0;
@@ -33507,13 +33594,25 @@ function generateQualifyingStructures({
33507
33594
  isMock,
33508
33595
  uuids
33509
33596
  });
33510
- stageSequence += 1; // order of operations is important here!! finalyQualifier positions is not yet updated when this step occurs
33597
+ stageSequence += 1;
33598
+ const qualifyingStructureName = structureName || (qualifyingProfiles.length > 1 ? `${QUALIFYING} ${stageSequence}` : QUALIFYING);
33599
+ const structure = structureTemplate({
33600
+ structureName: qualifyingStructureName,
33601
+ qualifyingRoundNumber: roundLimit,
33602
+ structureId: uuids === null || uuids === void 0 ? void 0 : uuids.pop(),
33603
+ stage: QUALIFYING,
33604
+ stageSequence,
33605
+ matchUpType,
33606
+ roundLimit,
33607
+ // redundant
33608
+ matchUps
33609
+ }); // order of operations is important here!! finalyQualifier positions is not yet updated when this step occurs
33511
33610
 
33512
33611
  if (stageSequence > 1) {
33513
33612
  generateQualifyingLink$1({
33514
33613
  sourceStructureId: finalQualifyingStructureId,
33515
33614
  targetStructureId: structure.structureId,
33516
- sourceRoundNumber: qualifyingRoundNumber,
33615
+ sourceRoundNumber: finalQualifyingRoundNumber,
33517
33616
  drawDefinition
33518
33617
  }); // if more than one qualifying stageSequence, remove last stageSequence qualifier positions from count
33519
33618
 
@@ -33522,26 +33621,15 @@ function generateQualifyingStructures({
33522
33621
  qualifyingDrawPositionsCount += drawSize;
33523
33622
  }
33524
33623
 
33525
- const structure = structureTemplate({
33526
- structureName: structureName || QUALIFYING,
33527
- qualifyingRoundNumber: roundLimit,
33528
- structureId: uuids === null || uuids === void 0 ? void 0 : uuids.pop(),
33529
- stage: QUALIFYING,
33530
- stageSequence,
33531
- matchUpType,
33532
- roundLimit,
33533
- // redundant
33534
- matchUps
33535
- });
33536
33624
  qualifiersCount = (_matchUps$filter = matchUps.filter(matchUp => matchUp.roundNumber === roundLimit)) === null || _matchUps$filter === void 0 ? void 0 : _matchUps$filter.length;
33537
33625
  finalQualifyingStructureId = structure.structureId;
33538
- finalyQualifyingRoundNumber = roundLimit;
33626
+ finalQualifyingRoundNumber = roundLimit;
33539
33627
  structures.push(structure);
33540
33628
  }
33541
33629
 
33542
33630
  return {
33543
33631
  qualifyingDrawPositionsCount,
33544
- finalyQualifyingRoundNumber,
33632
+ finalQualifyingRoundNumber,
33545
33633
  finalQualifyingStructureId,
33546
33634
  qualifiersCount,
33547
33635
  structures,
@@ -33626,6 +33714,120 @@ function feedInChampionship(params = {}) {
33626
33714
  });
33627
33715
  }
33628
33716
 
33717
+ function luckyDraw(params) {
33718
+ const {
33719
+ qualifyingRoundNumber,
33720
+ // round at which participants qualify
33721
+ finishingPositionOffset,
33722
+ qualifyingPositions,
33723
+ // number of positions which qualify
33724
+ matchUpType,
33725
+ idPrefix,
33726
+ drawSize,
33727
+ isMock,
33728
+ uuids
33729
+ } = params;
33730
+
33731
+ if (!isConvertableInteger(drawSize) || drawSize < 2) {
33732
+ return {
33733
+ matchUps: [],
33734
+ roundsCount: 0
33735
+ };
33736
+ }
33737
+
33738
+ if (isPowerOf2(drawSize)) return treeMatchUps(params);
33739
+ const roundProfiles = luckyRoundProfiles(drawSize);
33740
+ const firstRound = roundProfiles.shift();
33741
+ const nodes = generateRange(1, firstRound.participantsCount + 1).map(drawPosition => ({
33742
+ drawPosition
33743
+ }));
33744
+ let matchUps = [];
33745
+ let roundNumber = 1;
33746
+ ({
33747
+ matchUps
33748
+ } = buildRound({
33749
+ roundNumber,
33750
+ matchUpType,
33751
+ idPrefix,
33752
+ matchUps,
33753
+ isMock,
33754
+ nodes,
33755
+ uuids
33756
+ }));
33757
+ roundNumber++;
33758
+ let roundLimit = params.roundLimit || qualifyingRoundNumber;
33759
+
33760
+ for (const roundProfile of roundProfiles) {
33761
+ const roundMatchUpsCount = roundProfile.participantsCount / 2;
33762
+ const roundPositionRange = generateRange(1, roundMatchUpsCount + 1);
33763
+
33764
+ if (qualifyingPositions && roundMatchUpsCount === qualifyingPositions) {
33765
+ roundLimit = roundNumber - 1;
33766
+ }
33767
+
33768
+ const roundMatchUps = roundPositionRange.map(roundPosition => {
33769
+ const matchUpId = generateMatchUpId({
33770
+ roundPosition: roundPosition,
33771
+ roundNumber,
33772
+ idPrefix,
33773
+ uuids
33774
+ });
33775
+ const newMatchUp = {
33776
+ roundPosition,
33777
+ roundNumber,
33778
+ matchUpId
33779
+ };
33780
+ return newMatchUp;
33781
+ });
33782
+ matchUps.push(...roundMatchUps);
33783
+ roundNumber++;
33784
+ }
33785
+
33786
+ const roundsCount = roundNumber - 1;
33787
+ matchUps = addFinishingRounds({
33788
+ finishingPositionOffset,
33789
+ lucky: true,
33790
+ roundsCount,
33791
+ roundLimit,
33792
+ matchUps
33793
+ });
33794
+
33795
+ if (roundLimit) {
33796
+ matchUps = matchUps.filter(matchUp => matchUp.roundNumber <= roundLimit);
33797
+ }
33798
+
33799
+ return {
33800
+ matchUps,
33801
+ roundsCount,
33802
+ roundLimit
33803
+ };
33804
+ }
33805
+
33806
+ function luckyRoundProfiles(drawSize) {
33807
+ const intDrawSize = parseInt(drawSize);
33808
+ let participantsCount = intDrawSize % 2 ? intDrawSize + 1 : intDrawSize;
33809
+ const preFeedRound = !!(Math.ceil(participantsCount / 2) % 2);
33810
+ const rounds = [{
33811
+ participantsCount,
33812
+ preFeedRound
33813
+ }];
33814
+
33815
+ while (participantsCount > 2) {
33816
+ const nextRound = Math.ceil(participantsCount / 2);
33817
+ const nextIsFinal = nextRound === 1;
33818
+ const feedRound = !!(!nextIsFinal && nextRound % 2);
33819
+ participantsCount = !nextIsFinal && feedRound ? nextRound + 1 : nextRound;
33820
+ const preFeedRound = !!(participantsCount !== 2 && Math.ceil(participantsCount / 2) % 2);
33821
+ rounds.push({
33822
+ participantsCount,
33823
+ preFeedRound,
33824
+ feedRound
33825
+ });
33826
+ }
33827
+
33828
+ return rounds;
33829
+ }
33830
+
33629
33831
  function generateRoundRobin({
33630
33832
  structureName = MAIN,
33631
33833
  stageSequence = 1,
@@ -34053,7 +34255,7 @@ function generateDrawType(params = {}) {
34053
34255
  }));
34054
34256
  const validDoubleEliminationSize = isPowerOf2(drawSize * 2 / 3); // check that drawSize is a valid value
34055
34257
 
34056
- const invalidDrawSize = drawSize < 2 || !staggeredEntry && ![FEED_IN$1, AD_HOC].includes(drawType) && (drawType === ROUND_ROBIN && drawSize < 3 || drawType === DOUBLE_ELIMINATION && !validDoubleEliminationSize || ![ROUND_ROBIN, DOUBLE_ELIMINATION, ROUND_ROBIN_WITH_PLAYOFF].includes(drawType) && !isPowerOf2(drawSize));
34258
+ const invalidDrawSize = drawSize < 2 || !staggeredEntry && ![FEED_IN$1, AD_HOC, LUCKY_DRAW].includes(drawType) && (drawType === ROUND_ROBIN && drawSize < 3 || drawType === DOUBLE_ELIMINATION && !validDoubleEliminationSize || ![ROUND_ROBIN, DOUBLE_ELIMINATION, ROUND_ROBIN_WITH_PLAYOFF].includes(drawType) && !isPowerOf2(drawSize));
34057
34259
 
34058
34260
  if (invalidDrawSize) {
34059
34261
  return {
@@ -34099,6 +34301,23 @@ function generateDrawType(params = {}) {
34099
34301
  structures: [structure]
34100
34302
  }, SUCCESS);
34101
34303
  },
34304
+ [LUCKY_DRAW]: () => {
34305
+ const {
34306
+ matchUps
34307
+ } = luckyDraw(params);
34308
+ const structure = structureTemplate({
34309
+ structureName: structureName || MAIN,
34310
+ structureId: uuids === null || uuids === void 0 ? void 0 : uuids.pop(),
34311
+ stageSequence,
34312
+ matchUpType,
34313
+ stage: MAIN,
34314
+ matchUps
34315
+ });
34316
+ drawDefinition.structures.push(structure);
34317
+ return Object.assign({
34318
+ structures: [structure]
34319
+ }, SUCCESS);
34320
+ },
34102
34321
  [SINGLE_ELIMINATION]: () => {
34103
34322
  const {
34104
34323
  matchUps
@@ -34180,17 +34399,17 @@ function generateDrawType(params = {}) {
34180
34399
 
34181
34400
  if (qualifyingResult !== null && qualifyingResult !== void 0 && (_qualifyingResult$str = qualifyingResult.structures) !== null && _qualifyingResult$str !== void 0 && _qualifyingResult$str.length) {
34182
34401
  const {
34183
- finalyQualifyingRoundNumber: qualifyingRoundNumber,
34184
- qualifyingStructureId
34402
+ finalQualifyingRoundNumber: qualifyingRoundNumber,
34403
+ finalQualifyingStructureId: qualifyingStructureId
34185
34404
  } = qualifyingResult;
34186
- const mainStructureId = generatorResult.structures.find(({
34405
+ const mainStructure = generatorResult.structures.find(({
34187
34406
  stage,
34188
34407
  stageSequence
34189
34408
  }) => stage === MAIN && stageSequence === 1);
34190
34409
  generateQualifyingLink$1({
34191
34410
  sourceStructureId: qualifyingStructureId,
34192
34411
  sourceRoundNumber: qualifyingRoundNumber,
34193
- targetStructureId: mainStructureId,
34412
+ targetStructureId: mainStructure.structureId,
34194
34413
  drawDefinition
34195
34414
  });
34196
34415
  }
@@ -37061,8 +37280,8 @@ function setOrderOfFinish$1({
37061
37280
  inContext: true,
37062
37281
  drawDefinition
37063
37282
  });
37064
- const matchUpIds = completedMatchUps.map(getMatchUpId$1);
37065
- const targetMatchUpIds = finishingOrder.map(getMatchUpId$1);
37283
+ const matchUpIds = completedMatchUps.map(getMatchUpId);
37284
+ const targetMatchUpIds = finishingOrder.map(getMatchUpId);
37066
37285
  const {
37067
37286
  matchUpTypes,
37068
37287
  roundNumbers,
@@ -39342,8 +39561,8 @@ function setParticipantScaleItem({
39342
39561
  };
39343
39562
  }
39344
39563
  function setParticipantScaleItems({
39345
- tournamentRecord,
39346
- scaleItemsWithParticipantIds = []
39564
+ scaleItemsWithParticipantIds = [],
39565
+ tournamentRecord
39347
39566
  }) {
39348
39567
  if (!tournamentRecord) return {
39349
39568
  error: MISSING_TOURNAMENT_RECORD
@@ -40310,9 +40529,10 @@ function modifyIndividualParticipantIds({
40310
40529
  */
40311
40530
 
40312
40531
  function generateTeamsFromParticipantAttribute({
40313
- tournamentRecord,
40314
40532
  participantAttribute,
40533
+ tournamentRecord,
40315
40534
  personAttribute,
40535
+ teamNames,
40316
40536
  accessor,
40317
40537
  uuids
40318
40538
  }) {
@@ -40324,6 +40544,7 @@ function generateTeamsFromParticipantAttribute({
40324
40544
  participantType,
40325
40545
  participantRole
40326
40546
  }) => participantType === INDIVIDUAL$1 && participantRole === COMPETITOR);
40547
+ let teamIndex = 0;
40327
40548
 
40328
40549
  for (const individualParticipant of individualParticipants) {
40329
40550
  const {
@@ -40337,7 +40558,7 @@ function generateTeamsFromParticipantAttribute({
40337
40558
  if (attributeValue) {
40338
40559
  if (!Object.keys(teams).includes(attributeValue)) {
40339
40560
  teams[attributeValue] = {
40340
- participantName: attributeValue,
40561
+ participantName: (teamNames === null || teamNames === void 0 ? void 0 : teamNames[teamIndex]) || attributeValue,
40341
40562
  participantId: (uuids === null || uuids === void 0 ? void 0 : uuids.pop()) || UUID(),
40342
40563
  participantType: TEAM$1,
40343
40564
  participantRole: COMPETITOR,
@@ -40351,6 +40572,7 @@ function generateTeamsFromParticipantAttribute({
40351
40572
  element: teams[attributeValue],
40352
40573
  extension
40353
40574
  });
40575
+ teamIndex += 1;
40354
40576
  }
40355
40577
 
40356
40578
  teams[attributeValue].individualParticipantIds.push(individualParticipant.participantId);
@@ -41371,11 +41593,11 @@ function getEventData({
41371
41593
  }
41372
41594
 
41373
41595
  function publishEvent({
41374
- tournamentRecord,
41375
41596
  policyDefinitions,
41376
- status = PUBLIC,
41377
41597
  structureIds = [],
41598
+ tournamentRecord,
41378
41599
  drawIdsToRemove,
41600
+ status = PUBLIC,
41379
41601
  drawIdsToAdd,
41380
41602
  drawIds,
41381
41603
  event
@@ -44926,11 +45148,11 @@ function removeDelegatedOutcome(params) {
44926
45148
  }
44927
45149
 
44928
45150
  function generateSeedingScaleItems({
45151
+ scaleAttributes,
44929
45152
  scaledEntries,
45153
+ stageEntries,
44930
45154
  seedsCount,
44931
- scaleAttributes,
44932
- scaleName,
44933
- stageEntries
45155
+ scaleName
44934
45156
  }) {
44935
45157
  if (!scaleAttributes) return {
44936
45158
  error: MISSING_VALUE
@@ -49039,6 +49261,7 @@ function generatePersons({
49039
49261
  error: INVALID_VALUES
49040
49262
  };
49041
49263
  let validPersonData = defaultPersonData.filter(person => !sex || person.sex === sex);
49264
+ let nationalityCodes = [];
49042
49265
 
49043
49266
  if (Array.isArray(personData)) {
49044
49267
  const validatedPersonData = personData.filter(person => {
@@ -49049,6 +49272,7 @@ function generatePersons({
49049
49272
  iso,
49050
49273
  ioc
49051
49274
  }) => [iso, ioc].includes(person.nationalityCode)))) return false;
49275
+ if (person.nationalityCode) nationalityCodes.push(person.nationalityCode);
49052
49276
  return true;
49053
49277
  });
49054
49278
 
@@ -49133,7 +49357,8 @@ function generatePersons({
49133
49357
  }), person);
49134
49358
  });
49135
49359
  return {
49136
- persons: persons.length && persons || shuffledPersons[0]
49360
+ persons: persons.length && persons || shuffledPersons[0],
49361
+ nationalityCodes
49137
49362
  };
49138
49363
  }
49139
49364
 
@@ -50249,7 +50474,7 @@ function completeDrawMatchUps({
50249
50474
  });
50250
50475
  const sortedMatchUpIds = matchUps.filter(({
50251
50476
  winningSide
50252
- }) => !winningSide).sort(matchUpSort).map(getMatchUpId$1);
50477
+ }) => !winningSide).sort(matchUpSort).map(getMatchUpId);
50253
50478
 
50254
50479
  for (const matchUpId of sortedMatchUpIds) {
50255
50480
  if (!isNaN(completionGoal) && completedCount >= completionGoal) break;
@@ -50575,6 +50800,7 @@ function generateParticipants({
50575
50800
  const team = participantType === TEAM$1 || matchUpType === TEAM$1;
50576
50801
  const individualParticipantsCount = participantsCount * (doubles ? 2 : team ? 8 : 1);
50577
50802
  const {
50803
+ nationalityCodes: personNationalityCodes,
50578
50804
  persons: mockedPersons,
50579
50805
  error
50580
50806
  } = generatePersons({
@@ -50724,7 +50950,7 @@ function generateParticipants({
50724
50950
  const standardFamilyName = lastName || 'FamilyName';
50725
50951
  const participantName = `${standardGivenName} ${standardFamilyName}`;
50726
50952
  const country = countriesList[participantIndex];
50727
- const nationalityCode = country && (nationalityCodeType === 'ISO' ? country.iso : country.ioc || country.iso) || personNationalityCode;
50953
+ const nationalityCode = (personNationalityCodes === null || personNationalityCodes === void 0 ? void 0 : personNationalityCodes.length) && personNationalityCode || country && (nationalityCodeType === 'ISO' ? country.iso : country.ioc || country.iso) || personNationalityCode;
50728
50954
 
50729
50955
  if (countriesList !== null && countriesList !== void 0 && countriesList.length && !nationalityCode && !personNationalityCode) {
50730
50956
  console.log('%c Invalid Nationality Code', {
@@ -50756,7 +50982,7 @@ function generateParticipants({
50756
50982
  standardGivenName,
50757
50983
  nationalityCode,
50758
50984
  extensions,
50759
- birthDate,
50985
+ birthDate: isValidDateString(birthDate) ? birthDate : undefined,
50760
50986
  sex
50761
50987
  }
50762
50988
  });
@@ -51284,6 +51510,7 @@ function generateEventWithFlights({
51284
51510
  tournamentRecord,
51285
51511
  eventProfile,
51286
51512
  eventIndex,
51513
+ publish,
51287
51514
  uuids
51288
51515
  }) {
51289
51516
  let gender = eventProfile.gender;
@@ -51413,6 +51640,14 @@ function generateEventWithFlights({
51413
51640
  });
51414
51641
  if (result.error) return result;
51415
51642
  const drawIds = result.drawIds;
51643
+
51644
+ if (publish) {
51645
+ publishEvent({
51646
+ tournamentRecord,
51647
+ event
51648
+ });
51649
+ }
51650
+
51416
51651
  return {
51417
51652
  drawIds,
51418
51653
  eventId,
@@ -51441,6 +51676,7 @@ function generateEventWithDraw({
51441
51676
  excessParticipantAlternates = true,
51442
51677
  matchUpFormat = FORMAT_STANDARD,
51443
51678
  drawType = SINGLE_ELIMINATION,
51679
+ tournamentAlternates = 0,
51444
51680
  alternatesCount = 0,
51445
51681
  generate = true,
51446
51682
  eventExtensions,
@@ -51450,6 +51686,7 @@ function generateEventWithDraw({
51450
51686
  seedsCount,
51451
51687
  category,
51452
51688
  idPrefix,
51689
+ publish,
51453
51690
  gender,
51454
51691
  stage
51455
51692
  } = drawProfile;
@@ -51594,7 +51831,7 @@ function generateEventWithDraw({
51594
51831
 
51595
51832
  const alternatesParticipantIds = excessParticipantAlternates && (tournamentRecord === null || tournamentRecord === void 0 ? void 0 : (_tournamentRecord$par = tournamentRecord.participants) === null || _tournamentRecord$par === void 0 ? void 0 : _tournamentRecord$par.filter(({
51596
51833
  participantId
51597
- }) => !participantIds.includes(participantId)).filter(isEventParticipantType).filter(isEventGender).slice(0, alternatesCount || drawSize - participantsCount).map(p => p.participantId));
51834
+ }) => !participantIds.includes(participantId)).filter(isEventParticipantType).filter(isEventGender).slice(0, alternatesCount || drawSize - participantsCount || tournamentAlternates).map(p => p.participantId));
51598
51835
 
51599
51836
  if (alternatesParticipantIds !== null && alternatesParticipantIds !== void 0 && alternatesParticipantIds.length) {
51600
51837
  const result = addEventEntries({
@@ -51782,6 +52019,13 @@ function generateEventWithDraw({
51782
52019
 
51783
52020
  }
51784
52021
  }
52022
+
52023
+ if (publish) {
52024
+ publishEvent({
52025
+ tournamentRecord,
52026
+ event
52027
+ });
52028
+ }
51785
52029
  }
51786
52030
 
51787
52031
  return { ...SUCCESS,
@@ -51929,7 +52173,8 @@ function modifyTournamentRecord({
51929
52173
  eventType
51930
52174
  } = event;
51931
52175
  const {
51932
- drawProfiles
52176
+ drawProfiles,
52177
+ publish
51933
52178
  } = eventProfile;
51934
52179
  const eventParticipantType = eventType === SINGLES ? INDIVIDUAL : eventType === DOUBLES ? PAIR : eventType;
51935
52180
 
@@ -51990,6 +52235,13 @@ function modifyTournamentRecord({
51990
52235
  if (result.error) return result;
51991
52236
  drawIds.push(...result.drawIds);
51992
52237
  }
52238
+
52239
+ if (publish) {
52240
+ publishEvent({
52241
+ tournamentRecord,
52242
+ event
52243
+ });
52244
+ }
51993
52245
  }
51994
52246
  }
51995
52247
  }