tods-competition-factory 1.6.17 → 1.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -329,7 +329,7 @@ const matchUpFormatCode = {
329
329
  };
330
330
 
331
331
  function factoryVersion() {
332
- return "1.6.17";
332
+ return "1.6.18";
333
333
  }
334
334
 
335
335
  function getObjectTieFormat(obj) {
@@ -23475,8 +23475,9 @@ function getTargetMatchUps({
23475
23475
  return { drawPositions, matchUps, targetMatchUps };
23476
23476
  }
23477
23477
 
23478
- function cleanupLineUps({
23478
+ function resetLineUps({
23479
23479
  inContextDrawMatchUps,
23480
+ inheritance = true,
23480
23481
  tournamentRecord,
23481
23482
  drawDefinition,
23482
23483
  matchUpsMap,
@@ -23484,6 +23485,8 @@ function cleanupLineUps({
23484
23485
  structure,
23485
23486
  event
23486
23487
  }) {
23488
+ if (!drawDefinition)
23489
+ return { error: MISSING_DRAW_DEFINITION };
23487
23490
  const { drawPositions, matchUps, targetMatchUps } = getTargetMatchUps({
23488
23491
  inContextDrawMatchUps,
23489
23492
  matchUpsMap,
@@ -23499,10 +23502,14 @@ function cleanupLineUps({
23499
23502
  ({ matchUpId }) => matchUpId === inContextMatchUp.matchUpId
23500
23503
  );
23501
23504
  if (matchUp?.sides?.[sideIndex]) {
23502
- delete matchUp?.sides[sideIndex].lineUp;
23505
+ if (inheritance) {
23506
+ delete matchUp.sides[sideIndex].lineUp;
23507
+ } else {
23508
+ matchUp.sides[sideIndex].lineUp = [];
23509
+ }
23503
23510
  modifyMatchUpNotice({
23504
23511
  tournamentId: tournamentRecord?.tournamentId,
23505
- context: "cleanupLineUps",
23512
+ context: "resetLineUps",
23506
23513
  eventId: event?.eventId,
23507
23514
  drawDefinition,
23508
23515
  matchUp
@@ -23622,7 +23629,7 @@ function assignDrawPosition$1({
23622
23629
  if (drawPositionIsActive) {
23623
23630
  return decorateResult({ result: { error: DRAW_POSITION_ACTIVE }, stack });
23624
23631
  }
23625
- cleanupLineUps({
23632
+ resetLineUps({
23626
23633
  assignments: [positionAssignment],
23627
23634
  inContextDrawMatchUps,
23628
23635
  tournamentRecord,
@@ -44527,7 +44534,7 @@ function eliminationParticipantSwap({
44527
44534
  structure.positionAssignments = structure.positionAssignments.map(
44528
44535
  (assignment) => newAssignments[assignment.drawPosition] || assignment
44529
44536
  );
44530
- cleanupLineUps({
44537
+ resetLineUps({
44531
44538
  inContextDrawMatchUps,
44532
44539
  tournamentRecord,
44533
44540
  drawDefinition,
@@ -44559,7 +44566,7 @@ function roundRobinSwap({
44559
44566
  return { ...SUCCESS };
44560
44567
  if (assignments.filter(({ qualifier }) => qualifier).length === 2)
44561
44568
  return { ...SUCCESS };
44562
- cleanupLineUps({
44569
+ resetLineUps({
44563
44570
  inContextDrawMatchUps,
44564
44571
  tournamentRecord,
44565
44572
  drawDefinition,
@@ -44590,6 +44597,41 @@ function roundRobinSwap({
44590
44597
  return { ...SUCCESS };
44591
44598
  }
44592
44599
 
44600
+ function resetMatchUpLineUps$1({
44601
+ tournamentRecord,
44602
+ drawDefinition,
44603
+ inheritance,
44604
+ matchUpId,
44605
+ event
44606
+ }) {
44607
+ if (!drawDefinition)
44608
+ return { error: MISSING_DRAW_DEFINITION };
44609
+ const matchUp = findMatchUp$1({
44610
+ inContext: true,
44611
+ drawDefinition,
44612
+ matchUpId
44613
+ })?.matchUp;
44614
+ if (matchUp?.matchUpType !== TEAM_MATCHUP)
44615
+ return { error: INVALID_MATCHUP };
44616
+ let modificationsCount = 0;
44617
+ (matchUp.sides || []).forEach((side) => {
44618
+ modificationsCount += 1;
44619
+ if (inheritance) {
44620
+ delete side.lineUp;
44621
+ } else {
44622
+ side.lineUp = [];
44623
+ }
44624
+ modifyMatchUpNotice({
44625
+ tournamentId: tournamentRecord?.tournamentId,
44626
+ context: "resetLineUps",
44627
+ eventId: event?.eventId,
44628
+ drawDefinition,
44629
+ matchUp
44630
+ });
44631
+ });
44632
+ return { ...SUCCESS, modificationsCount };
44633
+ }
44634
+
44593
44635
  function setSubOrder({
44594
44636
  tournamentRecord,
44595
44637
  drawDefinition,
@@ -44656,6 +44698,7 @@ const positionGovernor = {
44656
44698
  swapDrawPositionAssignments: swapDrawPositionAssignments$1,
44657
44699
  alternateDrawPositionAssignment: alternateDrawPositionAssignment$1,
44658
44700
  resolveDrawPositions,
44701
+ resetMatchUpLineUps: resetMatchUpLineUps$1,
44659
44702
  // probably not part of drawEngine final
44660
44703
  initializeStructureSeedAssignments,
44661
44704
  getNextSeedBlock
@@ -51282,360 +51325,1498 @@ const publishingGovernor = {
51282
51325
  publishOrderOfPlay: publishOrderOfPlay$1
51283
51326
  };
51284
51327
 
51285
- function convertPointEight({ tournament }) {
51286
- if (!tournament)
51287
- return { error: MISSING_TOURNAMENT_RECORD };
51288
- const {
51289
- providerTournamentID: tournamentId,
51290
- hostCountryCode,
51291
- tournamentLevel,
51292
- totalPrizeMoney,
51293
- tournamentName,
51294
- extensions,
51295
- startDate,
51296
- endDate
51297
- } = tournament;
51298
- const tournamentRecord = newTournamentRecord({
51299
- hostCountryCode,
51300
- tournamentLevel,
51301
- totalPrizeMoney,
51302
- tournamentName,
51303
- tournamentId,
51304
- extensions,
51305
- startDate,
51306
- endDate
51307
- });
51308
- tournamentRecord.events = [];
51309
- for (const legacyEvent of tournament.events || []) {
51310
- const {
51311
- extensions: extensions2,
51312
- ageCategory,
51313
- discipline,
51314
- eventType,
51315
- eventId,
51316
- gender,
51317
- stages
51318
- } = legacyEvent;
51319
- const event = {
51320
- drawDefinitions: deriveDraws(stages),
51321
- category: { ageCategory },
51322
- gender: ["M", MALE].includes(gender) && MALE || ["F", FEMALE].includes(gender) && FEMALE || void 0,
51323
- eventType: ["D", DOUBLES].includes(eventType) && DOUBLES || ["T", TEAM$1].includes(eventType) ? TEAM$1 : SINGLES,
51324
- extensions: extensions2,
51325
- discipline,
51326
- eventId
51328
+ function removeCollectionAssignments({
51329
+ collectionPosition,
51330
+ teamParticipantId,
51331
+ dualMatchUpSide,
51332
+ drawDefinition,
51333
+ participantIds,
51334
+ collectionId
51335
+ }) {
51336
+ if (!collectionId || !collectionPosition || !Array.isArray(participantIds))
51337
+ return {
51338
+ modifiedLineUp: dualMatchUpSide?.lineUp || [],
51339
+ error: INVALID_VALUES
51327
51340
  };
51328
- tournamentRecord.events.push(event);
51329
- }
51330
- return { ...SUCCESS, tournamentRecord };
51331
- }
51332
- function deriveDraws(stages) {
51333
- const drawDefinitions = [];
51334
- for (const legacyStage of stages || []) {
51335
- const { stageType } = legacyStage;
51336
- const stage = ["M", MAIN].includes(stageType) && MAIN || ["Q", QUALIFYING].includes(stageType) && QUALIFYING || ["C", CONSOLATION].includes(stageType) && CONSOLATION || ["P", PLAY_OFF].includes(stageType) && PLAY_OFF || void 0;
51337
- for (const draw of legacyStage.draws || []) {
51338
- const { drawId, drawSize, matchUps } = draw;
51339
- const drawDefinition = { stage, drawId, drawSize };
51340
- drawDefinitions.push(drawDefinition);
51341
- console.log(
51342
- matchUps.map(({ roundNumber, roundPosition }) => ({
51343
- roundNumber,
51344
- roundPosition
51345
- })),
51346
- { draw, drawDefinition }
51347
- );
51341
+ const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
51342
+ participantId: teamParticipantId,
51343
+ drawDefinition
51344
+ })?.lineUp;
51345
+ const previousParticipantIds = [];
51346
+ const assignmentsRemoved = [];
51347
+ const modifiedLineUp = lineUp?.map((teamCompetitor) => {
51348
+ if (!participantIds.includes(teamCompetitor.participantId)) {
51349
+ return teamCompetitor;
51348
51350
  }
51349
- }
51350
- return drawDefinitions;
51351
- }
51352
-
51353
- const ABANDONED = "ABANDONED";
51354
- const ACTIVE = "ACTIVE";
51355
- const CANCELLED = "CANCELLED";
51356
- const COMPLETED = "COMPLETED";
51357
- const IN_PROGRESS = "IN_PROGRESS";
51358
- const tournamentConstants = {
51359
- ABANDONED,
51360
- ACTIVE,
51361
- CANCELLED,
51362
- COMPLETED,
51363
- IN_PROGRESS
51364
- };
51365
-
51366
- function setTournamentStatus({ tournamentRecord, status }) {
51367
- if (!tournamentRecord)
51368
- return { error: MISSING_TOURNAMENT_RECORD };
51369
- if (status && !Object.keys(tournamentConstants).includes(status))
51370
- return { error: INVALID_VALUES, info: "Unknown status" };
51371
- tournamentRecord.tournamentStatus = status;
51372
- return { ...SUCCESS };
51373
- }
51374
-
51375
- function analyzeDraws({ tournamentRecord }) {
51376
- if (!tournamentRecord)
51377
- return { error: MISSING_TOURNAMENT_RECORD };
51378
- const drawsAnalysis = {
51379
- positionsNoOutcomes: [],
51380
- // all positions assigned and no outcomes
51381
- canBePruned: [],
51382
- // partially assigned positions with outcomes => drawSizes can be reduced
51383
- matchPlay: [],
51384
- // only first round has active matchUps; some unassigned positions
51385
- inactive: [],
51386
- drawAnalysis: {}
51387
- };
51388
- const eventsMap = {};
51389
- const eventDraws = tournamentRecord.events?.map((event) => {
51390
- const eventId = event.eventId;
51391
- eventsMap[eventId] = event;
51392
- return (event?.drawDefinitions || []).map((drawDefinition) => ({
51393
- drawDefinition,
51394
- eventId
51395
- }));
51396
- }).flat().filter(Boolean);
51397
- eventDraws.forEach(({ drawDefinition, eventId }) => {
51398
- let positionsAssignedCount = 0;
51399
- let matchUpsWithWinningSideCount = 0;
51400
- let matchUpsNoOutcomeCount = 0;
51401
- const { allStructuresLinked } = getStructureGroups({ drawDefinition });
51402
- const event = eventsMap[eventId];
51403
- const structures = drawDefinition?.structures || [];
51404
- const structuresData = structures.map((structure) => {
51405
- const { stage, stageSequence, structureId } = structure;
51406
- const orderNumber = stageOrder$1[stage];
51407
- const { inContextStructureMatchUps } = getStructureDrawPositionProfiles({
51408
- drawDefinition,
51409
- structure,
51410
- event
51411
- });
51412
- const matchUpsWithWinningSide = inContextStructureMatchUps?.filter(
51413
- ({ winningSide }) => winningSide
51414
- );
51415
- const winningSideCount = matchUpsWithWinningSide.filter(Boolean).length || 0;
51416
- matchUpsWithWinningSideCount += winningSideCount;
51417
- matchUpsNoOutcomeCount += inContextStructureMatchUps.length - matchUpsWithWinningSideCount;
51418
- const maxWinningSideFirstRoundPosition = Math.max(
51419
- matchUpsWithWinningSide.filter(({ roundNumber }) => roundNumber === 1).map(({ roundPosition }) => roundPosition)
51420
- );
51421
- const { positionAssignments } = getPositionAssignments$1({ structure });
51422
- const positionsAssigned = positionAssignments?.filter(
51423
- ({ participantId }) => participantId
51424
- );
51425
- positionsAssignedCount += positionsAssigned?.length || 0;
51426
- const unassignedPositionsCount = (positionAssignments?.length || 0) - (positionsAssigned?.length || 0);
51427
- const { roundMatchUps, roundProfile, roundNumbers, maxMatchUpsCount } = getRoundMatchUps$1({ matchUps: inContextStructureMatchUps });
51428
- const activeRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => !roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
51429
- const inactiveRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
51430
- const inactiveStructure = roundProfile && Object.values(roundProfile).every((profile) => profile.inactiveRound);
51431
- return {
51432
- positionsAssignedCount: positionsAssigned?.length || 0,
51433
- maxWinningSideFirstRoundPosition,
51434
- unassignedPositionsCount,
51435
- inactiveStructure,
51436
- maxMatchUpsCount,
51437
- inactiveRounds,
51438
- roundMatchUps,
51439
- activeRounds,
51440
- roundNumbers,
51441
- roundProfile,
51442
- structureId,
51443
- stageSequence,
51444
- orderNumber,
51445
- stage
51446
- };
51447
- });
51448
- const mainStructure = structuresData.find(
51449
- (data) => data.orderNumber === 2 && data.stageSequence === 1
51450
- );
51451
- const activeStructuresCount = structuresData.filter(
51452
- ({ inactiveStructure }) => !inactiveStructure
51453
- ).length;
51454
- const { links } = getStructureLinks({
51455
- drawDefinition,
51456
- structureId: mainStructure.structureId
51351
+ const collectionAssignments = teamCompetitor.collectionAssignments?.filter((assignment) => {
51352
+ const target = assignment.collectionId === collectionId && assignment.collectionPosition === collectionPosition;
51353
+ if (target) {
51354
+ if (assignment.previousParticipantId) {
51355
+ previousParticipantIds.push(assignment.previousParticipantId);
51356
+ }
51357
+ assignmentsRemoved.push({
51358
+ participantId: teamCompetitor.participantId,
51359
+ ...assignment
51360
+ });
51361
+ }
51362
+ return !target;
51457
51363
  });
51458
- const isMatchPlay = ensureInt(mainStructure.activeRounds[0]) === 1 && mainStructure.activeRounds.length === 1 && activeStructuresCount === 1;
51459
- const inactiveDraw = structuresData?.every(
51460
- ({ inactiveStructure }) => inactiveStructure
51461
- );
51462
- const canBePruned = !links.length && mainStructure.activeRounds.length && (mainStructure.roundProfile[1].inactiveCount || mainStructure.inactiveRounds.length);
51463
- const drawId = drawDefinition.drawId;
51464
- if (positionsAssignedCount && !matchUpsWithWinningSideCount)
51465
- drawsAnalysis.positionsNoOutcomes.push(drawId);
51466
- if (inactiveDraw)
51467
- drawsAnalysis.inactive.push(drawId);
51468
- if (isMatchPlay)
51469
- drawsAnalysis.matchPlay.push(drawId);
51470
- if (canBePruned)
51471
- drawsAnalysis.canBePruned.push(drawId);
51472
- const drawAnalysis = {
51473
- matchUpsWithWinningSideCount,
51474
- matchUpsNoOutcomeCount,
51475
- positionsAssignedCount,
51476
- allStructuresLinked,
51477
- structuresData,
51478
- inactiveDraw,
51479
- isMatchPlay,
51480
- drawId
51364
+ return {
51365
+ participantId: teamCompetitor.participantId,
51366
+ collectionAssignments
51481
51367
  };
51482
- drawsAnalysis.drawAnalysis[drawId] = drawAnalysis;
51483
- });
51484
- return { ...SUCCESS, drawsAnalysis };
51485
- }
51486
-
51487
- function checkIsDual(tournamentRecord) {
51488
- const teamParticipants = tournamentRecord.participants?.filter(
51489
- ({ participantType }) => participantType === TEAM
51490
- );
51491
- const twoTeams = teamParticipants?.length === 2;
51492
- const event = tournamentRecord.events?.length === 1 && tournamentRecord.events[0];
51493
- const drawDefinition = event?.drawDefinitions?.length === 1 && event.drawDefinitions[0];
51494
- const structure = drawDefinition?.structures?.length === 1 && drawDefinition.structures[0];
51495
- const twoDrawPositions = structure?.positionAssignments?.length === 2;
51496
- return !!(event.tieFormat && twoTeams && twoDrawPositions);
51497
- }
51498
-
51499
- function analyzeTournament({ tournamentRecord }) {
51500
- if (!tournamentRecord)
51501
- return { error: MISSING_TOURNAMENT_RECORD };
51502
- const { drawsAnalysis } = analyzeDraws({ tournamentRecord });
51503
- const analysis = {
51504
- isDual: checkIsDual(tournamentRecord),
51505
- drawsAnalysis
51506
- };
51507
- return { ...SUCCESS, analysis };
51368
+ }).filter(Boolean) || [];
51369
+ return { modifiedLineUp, assignmentsRemoved, previousParticipantIds };
51508
51370
  }
51509
51371
 
51510
- function setTournamentName({
51511
- tournamentRecord,
51512
- promotionalName,
51513
- tournamentName,
51514
- formalName
51515
- }) {
51516
- if (!tournamentRecord)
51517
- return { error: MISSING_TOURNAMENT_RECORD };
51518
- if (tournamentName)
51519
- tournamentRecord.tournamentName = tournamentName;
51520
- if (promotionalName)
51521
- tournamentRecord.promotionalName = promotionalName;
51522
- if (formalName)
51523
- tournamentRecord.formalName = formalName;
51524
- if (tournamentRecord.promotionalName === tournamentRecord.tournamentName) {
51525
- delete tournamentRecord.promotionalName;
51526
- }
51527
- if (tournamentRecord.formalName === tournamentRecord.tournamentName) {
51528
- delete tournamentRecord.formalName;
51372
+ function validateLineUp({ lineUp, tieFormat }) {
51373
+ const errors = [];
51374
+ if (!Array.isArray(lineUp)) {
51375
+ errors.push(mustBeAnArray("lineUp"));
51376
+ return { valid: false, errors, error: INVALID_VALUES };
51529
51377
  }
51530
- return { ...SUCCESS };
51531
- }
51532
- function setTournamentNotes({ tournamentRecord, notes }) {
51533
- if (!tournamentRecord)
51534
- return { error: MISSING_TOURNAMENT_RECORD };
51535
- return addNotes({ element: tournamentRecord, notes });
51536
- }
51537
- function setTournamentCategories({ tournamentRecord, categories }) {
51538
- if (!tournamentRecord)
51539
- return { error: MISSING_TOURNAMENT_RECORD };
51540
- categories = (categories || []).filter((category) => {
51541
- return category.categoryName && category.type;
51378
+ const validItems = lineUp.every((item) => {
51379
+ if (typeof item !== "object") {
51380
+ errors.push(`lineUp entries must be objects`);
51381
+ return false;
51382
+ }
51383
+ const { participantId, collectionAssignments } = item;
51384
+ if (!participantId) {
51385
+ errors.push("Missing participantId");
51386
+ return false;
51387
+ }
51388
+ if (typeof participantId !== "string") {
51389
+ errors.push("participantIds must be strings");
51390
+ return false;
51391
+ }
51392
+ if (!Array.isArray(collectionAssignments)) {
51393
+ errors.push(mustBeAnArray("collectionAssignments"));
51394
+ return false;
51395
+ }
51396
+ return collectionAssignments.every((collectionAssignment) => {
51397
+ if (typeof collectionAssignment !== "object") {
51398
+ errors.push("collectionAssignments must be objects");
51399
+ return false;
51400
+ }
51401
+ const { collectionPosition } = collectionAssignment;
51402
+ if (typeof collectionPosition !== "number") {
51403
+ errors.push("collectionPosition must be a number");
51404
+ return false;
51405
+ }
51406
+ return true;
51407
+ });
51542
51408
  });
51543
- tournamentRecord.tournamentCategories = categories;
51544
- return { ...SUCCESS };
51409
+ const noDuplicates = unique(lineUp.map(getParticipantId)).length === lineUp.length;
51410
+ if (!noDuplicates)
51411
+ errors.push("Duplicated participantId(s)");
51412
+ const valid = validItems && noDuplicates;
51413
+ return { valid, errors, error: errors.length ? INVALID_VALUES : void 0 };
51545
51414
  }
51546
51415
 
51547
- function updateCourtAvailability({ tournamentRecord }) {
51548
- if (!tournamentRecord)
51549
- return { error: MISSING_TOURNAMENT_RECORD };
51550
- const { startDate, endDate } = tournamentRecord;
51551
- const tournamentDates = dateRange(startDate, endDate);
51552
- const courts = [];
51553
- for (const venue of tournamentRecord.venues || []) {
51554
- if (venue?.courts?.length)
51555
- courts.push(...venue.courts);
51556
- }
51557
- for (const court of courts) {
51558
- const { startTime, endTime } = (court.dateAvailability || []).reduce(
51559
- (extents, availability) => {
51560
- const startMinutes = timeStringMinutes(extents.startTime);
51561
- const endMinutes = timeStringMinutes(extents.endTime);
51562
- if (availability.startTime && timeStringMinutes(availability.startTime) < startMinutes)
51563
- extents.startTime = availability.startTime;
51564
- if (availability.endTime && timeStringMinutes(availability.endTime) > endMinutes)
51565
- extents.endTime = availability.endTime;
51566
- return extents;
51567
- },
51568
- { startTime: "08:00", endTime: "18:00" }
51569
- );
51570
- const updatedDateAvailability = tournamentDates.map((date) => {
51571
- const existing = court.dateAvailability?.find(
51572
- (availability) => availability.date === date
51573
- );
51574
- return existing || { date, startTime, endTime };
51575
- });
51576
- court.dateAvailability = updatedDateAvailability;
51577
- }
51416
+ function updateTeamLineUp({
51417
+ drawDefinition,
51418
+ participantId,
51419
+ tieFormat,
51420
+ lineUp
51421
+ }) {
51422
+ if (typeof drawDefinition !== "object")
51423
+ return { error: MISSING_DRAW_DEFINITION };
51424
+ if (typeof participantId !== "string")
51425
+ return { error: MISSING_PARTICIPANT_ID };
51426
+ const validation = validateLineUp({ lineUp, tieFormat });
51427
+ if (!validation.valid)
51428
+ return validation;
51429
+ const { extension: existingExtension } = findExtension({
51430
+ element: drawDefinition,
51431
+ name: LINEUPS
51432
+ });
51433
+ const value = existingExtension?.value || {};
51434
+ value[participantId] = removeLineUpSubstitutions({ lineUp });
51435
+ const extension = { name: LINEUPS, value };
51436
+ addExtension$1({ element: drawDefinition, extension });
51437
+ addDrawNotice({ drawDefinition });
51578
51438
  return { ...SUCCESS };
51579
51439
  }
51580
51440
 
51581
- function setTournamentDates({
51441
+ function getTieMatchUpContext({
51582
51442
  tournamentRecord,
51583
- startDate,
51584
- endDate
51443
+ drawDefinition,
51444
+ tieMatchUpId,
51445
+ event
51585
51446
  }) {
51586
51447
  if (!tournamentRecord)
51587
51448
  return { error: MISSING_TOURNAMENT_RECORD };
51588
- if (startDate && !dateValidation.test(startDate) || endDate && !dateValidation.test(endDate))
51589
- return { error: INVALID_DATE };
51590
- if (!startDate && !endDate)
51591
- return { error: MISSING_DATE };
51592
- if (endDate && startDate && new Date(endDate) < new Date(startDate))
51593
- return { error: INVALID_VALUES };
51594
- let checkScheduling;
51595
- if (startDate && tournamentRecord.startDate && new Date(startDate) > new Date(tournamentRecord.startDate) || endDate && tournamentRecord.endDate && new Date(endDate) < new Date(tournamentRecord.endDate)) {
51596
- checkScheduling = true;
51597
- }
51598
- if (startDate)
51599
- tournamentRecord.startDate = startDate;
51600
- if (endDate)
51601
- tournamentRecord.endDate = endDate;
51602
- if (startDate && tournamentRecord.endDate && new Date(startDate) > new Date(tournamentRecord.endDate)) {
51603
- tournamentRecord.endDate = startDate;
51604
- }
51605
- if (endDate && tournamentRecord.startDate && new Date(endDate) < new Date(tournamentRecord.startDate)) {
51606
- tournamentRecord.startDate = endDate;
51607
- }
51608
- const unscheduledMatchUpIds = checkScheduling && removeInvalidScheduling({ tournamentRecord })?.unscheduledMatchUpIds;
51609
- updateCourtAvailability({ tournamentRecord });
51610
- addNotice({
51611
- topic: MODIFY_TOURNAMENT_DETAIL,
51612
- payload: { startDate, endDate }
51449
+ if (!drawDefinition)
51450
+ return { error: MISSING_DRAW_ID };
51451
+ if (!event)
51452
+ return { error: EVENT_NOT_FOUND };
51453
+ const matchUpsMap = getMatchUpsMap({ drawDefinition });
51454
+ const { matchUp: tieMatchUp } = findMatchUp$1({
51455
+ matchUpId: tieMatchUpId,
51456
+ drawDefinition,
51457
+ matchUpsMap
51613
51458
  });
51614
- return { ...SUCCESS, unscheduledMatchUpIds };
51615
- }
51616
- function setTournamentStartDate({ tournamentRecord, startDate }) {
51617
- return setTournamentDates({ tournamentRecord, startDate });
51618
- }
51619
- function setTournamentEndDate({ tournamentRecord, endDate }) {
51620
- return setTournamentDates({ tournamentRecord, endDate });
51621
- }
51622
- function removeInvalidScheduling({ tournamentRecord }) {
51623
- const matchUps = allTournamentMatchUps({ tournamentRecord }).matchUps ?? [];
51624
- const startDate = tournamentRecord.startDate && new Date(tournamentRecord.startDate);
51625
- const endDate = tournamentRecord.endDate && new Date(tournamentRecord.endDate);
51626
- const invalidScheduledDates = [];
51627
- const invalidSchedulingMatchUpIds = [];
51628
- for (const matchUp of matchUps) {
51629
- const { schedule, matchUpId } = matchUp;
51630
- if (!schedule)
51631
- continue;
51632
- if (schedule.scheduledDate) {
51633
- const scheduledDate = new Date(schedule.scheduledDate);
51634
- if (startDate && scheduledDate < startDate || endDate && scheduledDate > endDate) {
51635
- invalidSchedulingMatchUpIds.push(matchUpId);
51636
- if (!invalidScheduledDates.includes(schedule.scheduledDate))
51637
- invalidScheduledDates.push(schedule.scheduledDate);
51638
- }
51459
+ if (!tieMatchUp)
51460
+ return { error: MATCHUP_NOT_FOUND };
51461
+ const { matchUp: inContextTieMatchUp, structure } = findMatchUp$1({
51462
+ tournamentParticipants: tournamentRecord.participants,
51463
+ matchUpId: tieMatchUpId,
51464
+ inContext: true,
51465
+ drawDefinition,
51466
+ matchUpsMap,
51467
+ event
51468
+ });
51469
+ if (!inContextTieMatchUp)
51470
+ return { error: MATCHUP_NOT_FOUND };
51471
+ const {
51472
+ collectionPosition,
51473
+ drawPositions,
51474
+ collectionId,
51475
+ matchUpTieId,
51476
+ matchUpType
51477
+ } = inContextTieMatchUp;
51478
+ if (matchUpType && ![SINGLES$1, DOUBLES$1].includes(matchUpType))
51479
+ return { error: INVALID_MATCHUP };
51480
+ const { positionAssignments } = getPositionAssignments$1({ structure });
51481
+ const relevantAssignments = positionAssignments?.filter(
51482
+ (assignment) => drawPositions?.includes(assignment.drawPosition)
51483
+ );
51484
+ const participantIds = relevantAssignments?.map(
51485
+ extractAttributes("participantId")
51486
+ );
51487
+ const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
51488
+ tournamentRecord,
51489
+ participantFilters: {
51490
+ participantTypes: [TEAM],
51491
+ participantIds
51492
+ }
51493
+ });
51494
+ const { matchUp: dualMatchUp } = findMatchUp$1({
51495
+ matchUpId: matchUpTieId,
51496
+ drawDefinition,
51497
+ matchUpsMap
51498
+ });
51499
+ const { matchUp: inContextDualMatchUp } = findMatchUp$1({
51500
+ matchUpId: matchUpTieId,
51501
+ inContext: true,
51502
+ drawDefinition,
51503
+ matchUpsMap
51504
+ });
51505
+ const tieFormat = resolveTieFormat({
51506
+ matchUp: dualMatchUp,
51507
+ drawDefinition,
51508
+ structure,
51509
+ event
51510
+ })?.tieFormat;
51511
+ return {
51512
+ inContextDualMatchUp,
51513
+ inContextTieMatchUp,
51514
+ relevantAssignments,
51515
+ collectionPosition,
51516
+ teamParticipants,
51517
+ collectionId,
51518
+ matchUpType,
51519
+ dualMatchUp,
51520
+ tieMatchUp,
51521
+ tieFormat,
51522
+ structure,
51523
+ ...SUCCESS
51524
+ };
51525
+ }
51526
+
51527
+ function assignTieMatchUpParticipantId(params) {
51528
+ const matchUpContext = getTieMatchUpContext(params);
51529
+ if (matchUpContext.error)
51530
+ return matchUpContext;
51531
+ const stack = "assignTieMatchUpParticipantId";
51532
+ let teamParticipantId = params.teamParticipantId;
51533
+ const { tournamentRecord, drawDefinition, participantId, event } = params;
51534
+ if (!participantId) {
51535
+ return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
51536
+ }
51537
+ if (params.sideNumber && ![1, 2].includes(params.sideNumber)) {
51538
+ return decorateResult({ result: { error: INVALID_SIDE_NUMBER }, stack });
51539
+ }
51540
+ const {
51541
+ inContextDualMatchUp,
51542
+ inContextTieMatchUp,
51543
+ relevantAssignments,
51544
+ collectionPosition,
51545
+ teamParticipants,
51546
+ collectionId,
51547
+ matchUpType,
51548
+ dualMatchUp,
51549
+ tieFormat
51550
+ } = matchUpContext;
51551
+ const allTieIndividualParticipantIds = inContextTieMatchUp?.sides?.flatMap(
51552
+ (side) => side.participant?.individualParticipantIds || side.participant?.participantId || []
51553
+ );
51554
+ if (allTieIndividualParticipantIds?.includes(participantId)) {
51555
+ return decorateResult({ result: { ...SUCCESS }, stack });
51556
+ }
51557
+ teamParticipantId = teamParticipantId || params.sideNumber && inContextDualMatchUp?.sides?.find(
51558
+ (side) => side.sideNumber === params.sideNumber
51559
+ )?.participantId;
51560
+ const {
51561
+ tournamentParticipants: [participantToAssign]
51562
+ } = getTournamentParticipants({
51563
+ tournamentRecord,
51564
+ participantFilters: {
51565
+ participantIds: [participantId]
51566
+ }
51567
+ });
51568
+ if (!participantToAssign) {
51569
+ return decorateResult({ result: { error: PARTICIPANT_NOT_FOUND }, stack });
51570
+ }
51571
+ const { appliedPolicies } = getAppliedPolicies({
51572
+ tournamentRecord,
51573
+ drawDefinition,
51574
+ event
51575
+ });
51576
+ const matchUpActionsPolicy = params.policyDefinitions?.[POLICY_TYPE_MATCHUP_ACTIONS] || appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS] || POLICY_MATCHUP_ACTIONS_DEFAULT[POLICY_TYPE_MATCHUP_ACTIONS];
51577
+ if (matchUpActionsPolicy?.participants?.enforceGender && [MALE, FEMALE].includes(inContextTieMatchUp?.gender) && inContextTieMatchUp?.gender !== participantToAssign.person?.sex) {
51578
+ return { error: INVALID_PARTICIPANT, info: "Gender mismatch" };
51579
+ }
51580
+ const { individualParticipantIds, participantType } = participantToAssign;
51581
+ if (matchUpType === SINGLES$1 && participantType !== INDIVIDUAL) {
51582
+ return { error: INVALID_PARTICIPANT_TYPE };
51583
+ }
51584
+ const relevantParticipantIds = participantType === INDIVIDUAL ? [participantId] : individualParticipantIds;
51585
+ const participantTeam = teamParticipantId && teamParticipants?.find(
51586
+ ({ participantId: participantId2 }) => participantId2 === teamParticipantId
51587
+ ) || teamParticipants?.find(
51588
+ ({ individualParticipantIds: individualParticipantIds2 }) => overlap(relevantParticipantIds, individualParticipantIds2)
51589
+ );
51590
+ if (!participantTeam) {
51591
+ return { error: TEAM_NOT_FOUND };
51592
+ }
51593
+ if (!teamParticipantId)
51594
+ teamParticipantId = participantTeam.participantId;
51595
+ if (!teamParticipantId)
51596
+ return { error: PARTICIPANT_NOT_FOUND };
51597
+ const teamAssignment = relevantAssignments?.find(
51598
+ (assignment) => assignment.participantId === participantTeam?.participantId
51599
+ );
51600
+ const teamDrawPosition = teamAssignment?.drawPosition;
51601
+ const teamSide = inContextTieMatchUp?.sides?.find(
51602
+ (side) => side.drawPosition === teamDrawPosition
51603
+ );
51604
+ const sideNumber = params.sideNumber || teamSide?.sideNumber;
51605
+ if (!tieFormat) {
51606
+ return { error: MISSING_TIE_FORMAT };
51607
+ }
51608
+ const collectionDefinition = tieFormat.collectionDefinitions?.find(
51609
+ (collectionDefinition2) => collectionDefinition2.collectionId === collectionId
51610
+ );
51611
+ if (!collectionDefinition)
51612
+ return { error: MISSING_COLLECTION_DEFINITION };
51613
+ if (!dualMatchUp?.sides?.length) {
51614
+ const { extension } = findExtension$2({
51615
+ element: drawDefinition,
51616
+ name: LINEUPS
51617
+ });
51618
+ const lineUps = makeDeepCopy(extension?.value || {}, false, true);
51619
+ const extractSideDetail = ({
51620
+ displaySideNumber,
51621
+ drawPosition,
51622
+ sideNumber: sideNumber2
51623
+ }) => ({ drawPosition, sideNumber: sideNumber2, displaySideNumber });
51624
+ if (dualMatchUp) {
51625
+ dualMatchUp.sides = inContextDualMatchUp?.sides?.map((side) => {
51626
+ const participantId2 = side.participantId;
51627
+ return {
51628
+ ...extractSideDetail(side),
51629
+ lineUp: participantId2 && lineUps[participantId2] || []
51630
+ };
51631
+ });
51632
+ }
51633
+ }
51634
+ const dualMatchUpSide = dualMatchUp?.sides?.find(
51635
+ (side) => side.sideNumber === sideNumber
51636
+ );
51637
+ const tieMatchUpSide = inContextTieMatchUp?.sides?.find(
51638
+ (side) => side.sideNumber === sideNumber
51639
+ );
51640
+ const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
51641
+ participantId: teamParticipantId,
51642
+ drawDefinition
51643
+ })?.lineUp;
51644
+ const targetAssignments = lineUp?.filter(
51645
+ (participantAssignment) => participantAssignment.collectionAssignments?.find(
51646
+ (assignment) => assignment.collectionPosition === collectionPosition && assignment.collectionId === collectionId && !assignment.previousParticipantId
51647
+ )
51648
+ );
51649
+ const assignedParticipantIds = targetAssignments?.map(
51650
+ (assignment) => assignment?.participantId
51651
+ );
51652
+ const participantIds = assignedParticipantIds?.length > 1 && assignedParticipantIds || (participantType === PAIR ? participantToAssign.individualParticipantIds : [participantId]);
51653
+ const removeResult = removeCollectionAssignments({
51654
+ collectionPosition,
51655
+ teamParticipantId,
51656
+ dualMatchUpSide,
51657
+ drawDefinition,
51658
+ participantIds,
51659
+ collectionId
51660
+ });
51661
+ if (removeResult.error)
51662
+ return decorateResult({ result: removeResult, stack });
51663
+ const { modifiedLineUp } = removeResult;
51664
+ let deleteParticipantId;
51665
+ if (matchUpType === DOUBLES$1) {
51666
+ if (participantType !== PAIR) {
51667
+ let result = updateLineUp({
51668
+ collectionPosition,
51669
+ teamParticipantId,
51670
+ drawDefinition,
51671
+ modifiedLineUp,
51672
+ participantId,
51673
+ collectionId,
51674
+ tieFormat
51675
+ });
51676
+ if (result?.error)
51677
+ return decorateResult({ result, stack });
51678
+ result = addParticipantId2Pair({
51679
+ side: tieMatchUpSide
51680
+ });
51681
+ if (result.error)
51682
+ return result;
51683
+ deleteParticipantId = result.deleteParticipantId;
51684
+ if (dualMatchUpSide)
51685
+ dualMatchUpSide.lineUp = modifiedLineUp;
51686
+ if (dualMatchUp) {
51687
+ modifyMatchUpNotice({
51688
+ tournamentId: tournamentRecord?.tournamentId,
51689
+ matchUp: dualMatchUp,
51690
+ context: stack,
51691
+ drawDefinition
51692
+ });
51693
+ }
51694
+ } else if (participantType === PAIR) {
51695
+ for (const participantId2 of participantIds) {
51696
+ updateLineUp({
51697
+ collectionPosition,
51698
+ teamParticipantId,
51699
+ drawDefinition,
51700
+ modifiedLineUp,
51701
+ participantId: participantId2,
51702
+ collectionId,
51703
+ tieFormat
51704
+ });
51705
+ }
51706
+ }
51707
+ } else {
51708
+ const result = updateLineUp({
51709
+ collectionPosition,
51710
+ teamParticipantId,
51711
+ drawDefinition,
51712
+ modifiedLineUp,
51713
+ participantId,
51714
+ collectionId,
51715
+ tieFormat
51716
+ });
51717
+ if (result?.error)
51718
+ return result;
51719
+ }
51720
+ if (dualMatchUpSide)
51721
+ dualMatchUpSide.lineUp = modifiedLineUp;
51722
+ if (dualMatchUp)
51723
+ modifyMatchUpNotice({
51724
+ tournamentId: tournamentRecord?.tournamentId,
51725
+ matchUp: dualMatchUp,
51726
+ context: stack,
51727
+ drawDefinition
51728
+ });
51729
+ if (deleteParticipantId) {
51730
+ const { error } = deleteParticipants({
51731
+ participantIds: [deleteParticipantId],
51732
+ tournamentRecord
51733
+ });
51734
+ if (error)
51735
+ console.log("cleanup");
51736
+ }
51737
+ return { ...SUCCESS, modifiedLineUp };
51738
+ function addParticipantId2Pair({ side }) {
51739
+ let deleteParticipantId2;
51740
+ if (!side.participant) {
51741
+ const newPairParticipant = {
51742
+ individualParticipantIds: [participantId],
51743
+ participantRole: COMPETITOR,
51744
+ participantType: PAIR
51745
+ };
51746
+ const result = addParticipant$1({
51747
+ participant: newPairParticipant,
51748
+ pairOverride: true,
51749
+ tournamentRecord
51750
+ });
51751
+ if (result.error)
51752
+ return result;
51753
+ } else {
51754
+ const individualParticipantIds2 = side.participant.individualParticipantIds || [];
51755
+ const sideParticipantsCount = individualParticipantIds2.filter(Boolean).length;
51756
+ if (sideParticipantsCount === 1) {
51757
+ const { participant } = getPairedParticipant({
51758
+ participantIds: individualParticipantIds2,
51759
+ tournamentRecord
51760
+ });
51761
+ individualParticipantIds2.push(participantId);
51762
+ const { participant: existingParticipant } = getPairedParticipant({
51763
+ participantIds: individualParticipantIds2,
51764
+ tournamentRecord
51765
+ });
51766
+ if (!existingParticipant && participant) {
51767
+ participant.individualParticipantIds = individualParticipantIds2;
51768
+ const result = modifyParticipant({
51769
+ pairOverride: true,
51770
+ tournamentRecord,
51771
+ participant
51772
+ });
51773
+ if (result.error)
51774
+ return result;
51775
+ } else {
51776
+ deleteParticipantId2 = participant?.participantId;
51777
+ }
51778
+ }
51779
+ }
51780
+ return { ...SUCCESS, deleteParticipantId: deleteParticipantId2 };
51781
+ }
51782
+ }
51783
+ function updateLineUp({
51784
+ collectionPosition,
51785
+ teamParticipantId,
51786
+ drawDefinition,
51787
+ modifiedLineUp,
51788
+ participantId,
51789
+ collectionId,
51790
+ tieFormat
51791
+ }) {
51792
+ const templateTeamLineUp = getTeamLineUp({
51793
+ participantId: teamParticipantId,
51794
+ drawDefinition
51795
+ })?.lineUp;
51796
+ const participantCompetitiorProfile = (modifiedLineUp || templateTeamLineUp)?.find((teamCompetitor) => teamCompetitor?.participantId === participantId);
51797
+ const newAssignment = { collectionId, collectionPosition };
51798
+ if (participantCompetitiorProfile) {
51799
+ participantCompetitiorProfile.collectionAssignments.push(newAssignment);
51800
+ } else {
51801
+ const teamCompetitor = {
51802
+ collectionAssignments: [newAssignment],
51803
+ participantId
51804
+ };
51805
+ modifiedLineUp.push(teamCompetitor);
51806
+ }
51807
+ return updateTeamLineUp({
51808
+ participantId: teamParticipantId,
51809
+ lineUp: modifiedLineUp,
51810
+ drawDefinition,
51811
+ tieFormat
51812
+ });
51813
+ }
51814
+
51815
+ const ASC = "ASC";
51816
+ const ASCENDING = "ASC";
51817
+ const DESC = "DESC";
51818
+ const DESCENDING = "DESC";
51819
+ const sortingConstants = { ASC, ASCENDING, DESC, DESCENDING };
51820
+
51821
+ function generateLineUps(params) {
51822
+ let { tieFormat } = params;
51823
+ const {
51824
+ useDefaultEventRanking,
51825
+ tournamentRecord,
51826
+ drawDefinition,
51827
+ scaleAccessor,
51828
+ // e.g. { scaleType: 'RANKINGS', scaleName: 'U18', accessor: 'wtnRating', sortOrder: 'ASC' }
51829
+ singlesOnly,
51830
+ // use singles scale for doubles events
51831
+ attach,
51832
+ // boolean - when true attach LINEUPS extension to drawDefinition and add new PAIR participants (where necessary)
51833
+ event
51834
+ } = params;
51835
+ if (event?.eventType !== TEAM_EVENT)
51836
+ return { error: INVALID_EVENT_TYPE };
51837
+ if (!tournamentRecord)
51838
+ return { error: MISSING_TOURNAMENT_RECORD };
51839
+ if (!tieFormat && !drawDefinition)
51840
+ return { error: DRAW_DEFINITION_NOT_FOUND };
51841
+ tieFormat = tieFormat || resolveTieFormat({ drawDefinition, event })?.tieFormat;
51842
+ if (validateTieFormat({ tieFormat }).error)
51843
+ return { error: INVALID_TIE_FORMAT };
51844
+ if (typeof scaleAccessor !== "object" && !useDefaultEventRanking)
51845
+ return { error: INVALID_VALUES, context: { scaleAccessor } };
51846
+ const lineUps = {};
51847
+ const targetEntries = (drawDefinition?.entries || event.entries).filter(
51848
+ (entry) => entry?.entryStatus === DIRECT_ACCEPTANCE
51849
+ );
51850
+ const participantIds = targetEntries.map(getParticipantId);
51851
+ const { participants = [] } = getParticipants$1({
51852
+ withIndividualParticipants: true,
51853
+ withScaleValues: true,
51854
+ tournamentRecord
51855
+ });
51856
+ const teamParticipants = participants.filter(
51857
+ ({ participantId }) => participantIds.includes(participantId)
51858
+ );
51859
+ const formatScaleType = (type) => type === RANKING$1 ? "rankings" : "ratings";
51860
+ const defaultScaleName = event?.category?.categoryName || event?.category?.ageCategoryCode;
51861
+ const {
51862
+ scaleName = defaultScaleName,
51863
+ scaleType = RANKING$1,
51864
+ sortOrder,
51865
+ accessor
51866
+ } = scaleAccessor || {};
51867
+ const formattedScaleType = formatScaleType(scaleType);
51868
+ const getScaleValue = (individualParticipant, matchUpType) => {
51869
+ let matchUpTypeScales = individualParticipant[formattedScaleType]?.[matchUpType];
51870
+ if (!matchUpTypeScales && useDefaultEventRanking) {
51871
+ matchUpTypeScales = individualParticipant[formattedScaleType]?.[SINGLES_MATCHUP];
51872
+ }
51873
+ if (Array.isArray(matchUpTypeScales)) {
51874
+ const scaleValue = matchUpTypeScales.find(
51875
+ (scale) => scale.scaleName === scaleName
51876
+ )?.scaleValue;
51877
+ if (isNumeric(scaleValue)) {
51878
+ return scaleValue;
51879
+ } else if (accessor && typeof scaleValue === "object")
51880
+ return scaleValue[accessor];
51881
+ }
51882
+ return 0;
51883
+ };
51884
+ const sortMethod = (a, b, matchUpType) => {
51885
+ const x = sortOrder === DESCENDING ? b : a;
51886
+ const y = sortOrder === DESCENDING ? a : b;
51887
+ return getScaleValue(x, matchUpType) - getScaleValue(y, matchUpType);
51888
+ };
51889
+ const singlesScaleSort = (a, b) => sortMethod(a, b, SINGLES_MATCHUP);
51890
+ const doublesScaleSort = (a, b) => sortMethod(a, b, DOUBLES_MATCHUP);
51891
+ const participantIdPairs = [];
51892
+ const collectionDefinitions = tieFormat.collectionDefinitions || [];
51893
+ for (const teamParticipant of teamParticipants) {
51894
+ const singlesSort = teamParticipant.individualParticipants.sort(singlesScaleSort);
51895
+ const doublesSort = singlesOnly ? singlesSort : teamParticipant.individualParticipants.sort(doublesScaleSort);
51896
+ const participantAssignments = {};
51897
+ for (const collectionDefinition of collectionDefinitions) {
51898
+ const collectionParticipantIds = [];
51899
+ const { collectionId, matchUpCount, matchUpType, gender } = collectionDefinition;
51900
+ const singlesMatchUp = matchUpType === SINGLES_MATCHUP;
51901
+ generateRange(0, matchUpCount).forEach((i) => {
51902
+ const typeSort = singlesMatchUp ? singlesSort : doublesSort;
51903
+ const collectionPosition = i + 1;
51904
+ const participantIds2 = [];
51905
+ generateRange(0, singlesMatchUp ? 1 : 2).forEach((i2) => {
51906
+ const nextParticipantId = typeSort.find((participant) => {
51907
+ const targetGender = [MALE, FEMALE].includes(gender) && gender || gender === MIXED && [MALE, FEMALE][i2];
51908
+ return (!targetGender || targetGender === participant.person.sex) && !collectionParticipantIds.includes(participant.participantId);
51909
+ }).participantId;
51910
+ if (nextParticipantId) {
51911
+ participantIds2.push(nextParticipantId);
51912
+ collectionParticipantIds.push(nextParticipantId);
51913
+ if (!participantAssignments[nextParticipantId])
51914
+ participantAssignments[nextParticipantId] = [];
51915
+ participantAssignments[nextParticipantId].push({
51916
+ collectionPosition,
51917
+ collectionId
51918
+ });
51919
+ }
51920
+ });
51921
+ if (!singlesMatchUp)
51922
+ participantIdPairs.push(participantIds2);
51923
+ });
51924
+ }
51925
+ const lineUp = Object.keys(participantAssignments).map((participantId) => ({
51926
+ collectionAssignments: participantAssignments[participantId],
51927
+ participantId
51928
+ }));
51929
+ lineUps[teamParticipant.participantId] = lineUp;
51930
+ }
51931
+ const participantsToAdd = [];
51932
+ for (const pairParticipantIds of participantIdPairs) {
51933
+ const { participant: existingPairParticipant } = getPairedParticipant({
51934
+ tournamentParticipants: participants,
51935
+ participantIds: pairParticipantIds
51936
+ });
51937
+ if (!existingPairParticipant) {
51938
+ const newPairParticipant = {
51939
+ individualParticipantIds: pairParticipantIds,
51940
+ participantRole: COMPETITOR,
51941
+ participantType: PAIR
51942
+ };
51943
+ participantsToAdd.push(newPairParticipant);
51944
+ }
51945
+ }
51946
+ if (attach) {
51947
+ while (participantsToAdd.length) {
51948
+ addParticipant$1({
51949
+ participant: participantsToAdd.pop(),
51950
+ tournamentRecord
51951
+ });
51952
+ }
51953
+ const extension = { name: LINEUPS, value: lineUps };
51954
+ addExtension$1({ element: drawDefinition, extension });
51955
+ }
51956
+ return { ...SUCCESS, lineUps, participantsToAdd };
51957
+ }
51958
+
51959
+ function generateOutcomeFromScoreString(params) {
51960
+ const { matchUpFormat, matchUpStatus, winningSide, scoreString } = params;
51961
+ if (!scoreString)
51962
+ return {
51963
+ outcome: {
51964
+ ...toBePlayed,
51965
+ winningSide,
51966
+ matchUpStatus
51967
+ }
51968
+ };
51969
+ if (winningSide && ![1, 2, void 0].includes(winningSide))
51970
+ return { error: INVALID_VALUES, winningSide };
51971
+ const neutralParsedSets = scoreString && parseScoreString({ scoreString });
51972
+ const score = {};
51973
+ const winningScoreString = generateScoreString({
51974
+ sets: neutralParsedSets,
51975
+ matchUpFormat
51976
+ });
51977
+ const losingScoreString = generateScoreString({
51978
+ sets: neutralParsedSets,
51979
+ reversed: true,
51980
+ matchUpFormat
51981
+ });
51982
+ if (winningSide === 2) {
51983
+ score.scoreStringSide1 = losingScoreString;
51984
+ score.scoreStringSide2 = winningScoreString;
51985
+ } else {
51986
+ score.scoreStringSide1 = winningScoreString;
51987
+ score.scoreStringSide2 = losingScoreString;
51988
+ }
51989
+ score.sets = parseScoreString({ scoreString: score.scoreStringSide1 });
51990
+ return definedAttributes({
51991
+ outcome: {
51992
+ matchUpStatus,
51993
+ winningSide,
51994
+ score
51995
+ }
51996
+ });
51997
+ }
51998
+
51999
+ const defaultStatusProfile = {
52000
+ [WALKOVER$2]: 2,
52001
+ [DOUBLE_WALKOVER]: 1,
52002
+ [DOUBLE_DEFAULT]: 1,
52003
+ [RETIRED$1]: 1,
52004
+ [DEFAULTED]: 4
52005
+ };
52006
+ function generateOutcome(params) {
52007
+ let { defaultWithScorePercent = 2, winningSide } = params;
52008
+ const {
52009
+ matchUpStatusProfile = defaultStatusProfile,
52010
+ // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
52011
+ matchUpFormat = FORMAT_STANDARD,
52012
+ pointsPerMinute = 1,
52013
+ sideWeight = 4
52014
+ } = params;
52015
+ if (!isValid(matchUpFormat))
52016
+ return { error: INVALID_MATCHUP_FORMAT };
52017
+ if (typeof matchUpStatusProfile !== "object")
52018
+ return { error: INVALID_VALUES };
52019
+ if (defaultWithScorePercent > 100)
52020
+ defaultWithScorePercent = 100;
52021
+ if (isNaN(defaultWithScorePercent) || isNaN(pointsPerMinute) || isNaN(sideWeight))
52022
+ return { error: INVALID_VALUES };
52023
+ const matchUpStatuses = Object.keys(matchUpStatusProfile).filter(
52024
+ (matchUpStatus2) => Object.keys(matchUpStatusConstants).includes(matchUpStatus2) && matchUpStatus2 !== COMPLETED$1
52025
+ );
52026
+ const matchUpStatusTotals = Object.keys(matchUpStatuses).reduce(
52027
+ (total, key) => total + matchUpStatusProfile[key],
52028
+ 0
52029
+ );
52030
+ if (matchUpStatusTotals > 100)
52031
+ return { error: INVALID_VALUES, matchUpStatusProfile };
52032
+ const matchUpStatusMap = matchUpStatuses.reduce(
52033
+ (statusMap, matchUpStatus2) => {
52034
+ statusMap.pointer = statusMap.pointer + matchUpStatusProfile[matchUpStatus2];
52035
+ statusMap.valueMap.push([statusMap.pointer, matchUpStatus2]);
52036
+ return statusMap;
52037
+ },
52038
+ { pointer: 0, valueMap: [] }
52039
+ );
52040
+ const outcomePointer = randomInt(1, 100);
52041
+ const matchUpStatus = (matchUpStatusMap.valueMap.find(
52042
+ (item) => outcomePointer <= item[0]
52043
+ ) || [100, COMPLETED$1])[1];
52044
+ const noScore = { sets: [], scoreStringSide1: "", side2ScoreString: "" };
52045
+ if ([WALKOVER$2, DEFAULTED].includes(matchUpStatus)) {
52046
+ winningSide = winningSide || randomInt(1, 2);
52047
+ const outcome2 = {
52048
+ score: noScore,
52049
+ winningSide,
52050
+ matchUpStatus
52051
+ };
52052
+ const scoreDefaulted = matchUpStatus === DEFAULTED && randomInt(1, 100) > 100 - defaultWithScorePercent;
52053
+ if (!scoreDefaulted)
52054
+ return { outcome: outcome2 };
52055
+ } else if ([DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(matchUpStatus)) {
52056
+ return { outcome: { score: noScore, matchUpStatus } };
52057
+ }
52058
+ const parsedFormat = parse(matchUpFormat);
52059
+ const { bestOf, setFormat, finalSetFormat } = parsedFormat || {};
52060
+ const sets = [];
52061
+ const weightedSide = randomInt(0, 1);
52062
+ const weightedRange = winningSide ? [winningSide - 1] : [
52063
+ ...generateRange(0, sideWeight).map(() => weightedSide),
52064
+ 1 - weightedSide
52065
+ ];
52066
+ const incompleteSet = [RETIRED$1, DEFAULTED, INCOMPLETE, SUSPENDED].includes(
52067
+ matchUpStatus
52068
+ );
52069
+ const incompleteAt = incompleteSet && (randomPop(generateRange(1, bestOf)) || 1);
52070
+ let weightedWinningSide;
52071
+ for (const setNumber of generateRange(1, (bestOf || 0) + 1)) {
52072
+ const isFinalSet = setNumber === bestOf;
52073
+ const { set, incomplete, winningSideNumber } = generateSet({
52074
+ incomplete: incompleteAt === setNumber,
52075
+ matchUpStatus,
52076
+ pointsPerMinute,
52077
+ setFormat: isFinalSet && finalSetFormat || setFormat,
52078
+ setNumber,
52079
+ weightedRange
52080
+ });
52081
+ sets.push(set);
52082
+ if (incomplete) {
52083
+ weightedWinningSide = winningSideNumber;
52084
+ break;
52085
+ }
52086
+ const analysis2 = analyzeMatchUp({
52087
+ matchUp: { score: { sets }, matchUpFormat }
52088
+ });
52089
+ if (analysis2.calculatedWinningSide)
52090
+ break;
52091
+ }
52092
+ const analysis = analyzeMatchUp({
52093
+ matchUp: { score: { sets }, matchUpFormat }
52094
+ });
52095
+ const matchUpWinningSide = weightedWinningSide ? winningSide || weightedWinningSide : analysis.calculatedWinningSide;
52096
+ const { score } = matchUpScore({
52097
+ score: { sets },
52098
+ winningSide: matchUpWinningSide,
52099
+ matchUpStatus
52100
+ });
52101
+ const outcome = {
52102
+ score,
52103
+ winningSide: matchUpWinningSide,
52104
+ matchUpStatus
52105
+ };
52106
+ return { outcome };
52107
+ }
52108
+ function generateSet({
52109
+ weightedRange = [0, 1],
52110
+ pointsPerMinute,
52111
+ matchUpStatus,
52112
+ incomplete,
52113
+ setFormat,
52114
+ setNumber
52115
+ }) {
52116
+ const set = { setNumber };
52117
+ const { setTo, tiebreakFormat, tiebreakAt, tiebreakSet, timed, minutes } = setFormat;
52118
+ const weightIndex = randomInt(0, weightedRange.length - 1);
52119
+ const reverseScores = weightedRange[weightIndex];
52120
+ let winningSideNumber;
52121
+ if (timed) {
52122
+ const calcPoints = minutes * pointsPerMinute;
52123
+ const pointsVariation = Math.round(calcPoints * 0.2);
52124
+ const totalPoints = calcPoints + randomPop([1, -1]) * pointsVariation;
52125
+ const sidePoints = weightedRandom(totalPoints, 2);
52126
+ const scores = [sidePoints, totalPoints - sidePoints];
52127
+ if (reverseScores)
52128
+ scores.reverse();
52129
+ winningSideNumber = weightedRange[weightIndex] + 1;
52130
+ let highSide = scores[0] > scores[1] && 1 || scores[1] > scores[0] && 2 || 0;
52131
+ if (incomplete) {
52132
+ const [side1Score2, side2Score2] = scores;
52133
+ Object.assign(set, { side1Score: side1Score2, side2Score: side2Score2 });
52134
+ if (completedMatchUpStatuses.includes(matchUpStatus)) {
52135
+ return { set, incomplete, winningSideNumber };
52136
+ }
52137
+ return { set, incomplete };
52138
+ }
52139
+ if (!highSide)
52140
+ scores[randomInt(0, 1)] += 1;
52141
+ highSide = scores[0] > scores[1] ? 1 : 2;
52142
+ if (highSide !== winningSideNumber)
52143
+ scores.reverse();
52144
+ const [side1Score, side2Score] = scores;
52145
+ Object.assign(set, {
52146
+ side1Score,
52147
+ side2Score,
52148
+ winningSide: winningSideNumber
52149
+ });
52150
+ return { set };
52151
+ } else if (incomplete) {
52152
+ set.side1Score = randomInt(0, tiebreakAt);
52153
+ set.side2Score = randomInt(0, tiebreakAt);
52154
+ if (completedMatchUpStatuses.includes(matchUpStatus)) {
52155
+ winningSideNumber = weightedRange[weightIndex] + 1;
52156
+ }
52157
+ return { set, incomplete, winningSideNumber };
52158
+ } else {
52159
+ const range = generateRange(1, setTo + 1).map((value) => generateRange(0, setTo + 2 - value).map(() => value)).flat();
52160
+ const lowValue = range[randomInt(0, range.length - 1)];
52161
+ const scores = setTo && getSetComplement({
52162
+ isSide1: true,
52163
+ tiebreakAt,
52164
+ lowValue,
52165
+ setTo
52166
+ });
52167
+ const isTiebreakSet = !scores;
52168
+ const specifiedWinningSide = weightedRange.length === 1 && weightedRange[weightIndex] + 1;
52169
+ if (!isTiebreakSet) {
52170
+ if (specifiedWinningSide) {
52171
+ const highSide = scores[0] > scores[1] ? 1 : 2;
52172
+ if (highSide !== specifiedWinningSide)
52173
+ scores.reverse();
52174
+ } else if (reverseScores) {
52175
+ scores.reverse();
52176
+ }
52177
+ const [side1Score, side2Score] = scores;
52178
+ Object.assign(set, { side1Score, side2Score });
52179
+ }
52180
+ const setAnalysis = analyzeSet({
52181
+ matchUpScoringFormat: { setFormat },
52182
+ setObject: set
52183
+ });
52184
+ let tiebreakWinningSide;
52185
+ if (setAnalysis.hasTiebreakCondition || isTiebreakSet) {
52186
+ const { NoAD: tiebreakNoAd, tiebreakTo } = tiebreakFormat || tiebreakSet || {};
52187
+ const range2 = generateRange(1, tiebreakTo + 1).map(
52188
+ (value) => generateRange(0, tiebreakTo + 2 - value).map(() => value)
52189
+ ).flat();
52190
+ const lowValue2 = range2[randomInt(0, range2.length - 1)];
52191
+ const scores2 = getTiebreakComplement({
52192
+ isSide1: true,
52193
+ tiebreakNoAd,
52194
+ tiebreakTo,
52195
+ lowValue: lowValue2
52196
+ });
52197
+ if (scores2) {
52198
+ if (isTiebreakSet) {
52199
+ const highSide = scores2[0] > scores2[1] ? 1 : 2;
52200
+ if (specifiedWinningSide) {
52201
+ if (highSide !== specifiedWinningSide)
52202
+ scores2.reverse();
52203
+ } else if (reverseScores) {
52204
+ scores2.reverse();
52205
+ }
52206
+ [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
52207
+ tiebreakWinningSide = scores2[0] > scores2[1] && 1 || scores2[1] > scores2[0] && 2 || void 0;
52208
+ } else if (setAnalysis.leadingSide === 2) {
52209
+ [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
52210
+ } else {
52211
+ [set.side2TiebreakScore, set.side1TiebreakScore] = scores2;
52212
+ }
52213
+ }
52214
+ }
52215
+ set.winningSide = setAnalysis.winningSide || setAnalysis.leadingSide || specifiedWinningSide || tiebreakWinningSide;
52216
+ }
52217
+ return { set };
52218
+ }
52219
+
52220
+ function completeDrawMatchUps(params) {
52221
+ const {
52222
+ matchUpStatusProfile,
52223
+ // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
52224
+ completeAllMatchUps,
52225
+ // qualifyingProfiles, // CONSIDER: allowing completionGoal per structureProfile
52226
+ randomWinningSide,
52227
+ tournamentRecord,
52228
+ completionGoal,
52229
+ drawDefinition,
52230
+ event
52231
+ } = params;
52232
+ if (!drawDefinition)
52233
+ return { error: MISSING_DRAW_DEFINITION };
52234
+ const matchUpFormat = params.matchUpFormat || drawDefinition.matchUpFormat || event?.matchUpFormat;
52235
+ const sortedStructures = drawDefinition.structures.slice().sort(structureSort);
52236
+ let completedCount = 0;
52237
+ const { matchUps: firstRoundDualMatchUps, matchUpsMap } = getAllDrawMatchUps({
52238
+ contextFilters: {
52239
+ stages: [MAIN, QUALIFYING]
52240
+ },
52241
+ matchUpFilters: {
52242
+ matchUpTypes: [TEAM$2],
52243
+ roundNumbers: [1]
52244
+ },
52245
+ inContext: true,
52246
+ drawDefinition
52247
+ });
52248
+ if (firstRoundDualMatchUps?.length) {
52249
+ const categoryName = event?.category?.ageCategoryCode || event?.category?.categoryName;
52250
+ if (categoryName) {
52251
+ const scaleAccessor = {
52252
+ scaleName: categoryName,
52253
+ sortOrder: ASCENDING,
52254
+ scaleType: RANKING$1
52255
+ };
52256
+ generateLineUps({
52257
+ singlesOnly: true,
52258
+ tournamentRecord,
52259
+ drawDefinition,
52260
+ scaleAccessor,
52261
+ attach: true,
52262
+ event
52263
+ });
52264
+ } else {
52265
+ const structureId = firstRoundDualMatchUps[0]?.structureId;
52266
+ const { positionAssignments } = getPositionAssignments$1({
52267
+ drawDefinition,
52268
+ structureId
52269
+ });
52270
+ if (positionAssignments?.length) {
52271
+ const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
52272
+ participantFilters: { participantTypes: [TEAM$2] },
52273
+ tournamentRecord
52274
+ });
52275
+ const assignParticipants = (dualMatchUp) => {
52276
+ const singlesMatchUps = dualMatchUp.tieMatchUps.filter(
52277
+ ({ matchUpType }) => matchUpType === SINGLES$1
52278
+ );
52279
+ const doublesMatchUps = dualMatchUp.tieMatchUps.filter(
52280
+ ({ matchUpType }) => matchUpType === DOUBLES$1
52281
+ );
52282
+ singlesMatchUps.forEach((singlesMatchUp, i) => {
52283
+ const tieMatchUpId = singlesMatchUp.matchUpId;
52284
+ singlesMatchUp.sides.forEach((side) => {
52285
+ const { drawPosition } = side;
52286
+ const teamParticipant = teamParticipants?.find(
52287
+ (teamParticipant2) => {
52288
+ const { participantId } = teamParticipant2;
52289
+ const assignment = positionAssignments.find(
52290
+ (assignment2) => assignment2.participantId === participantId
52291
+ );
52292
+ return assignment?.drawPosition === drawPosition;
52293
+ }
52294
+ );
52295
+ if (teamParticipant) {
52296
+ const individualParticipantId = teamParticipant.individualParticipantIds[i];
52297
+ assignTieMatchUpParticipantId({
52298
+ teamParticipantId: teamParticipant.participantId,
52299
+ participantId: individualParticipantId,
52300
+ tournamentRecord,
52301
+ drawDefinition,
52302
+ tieMatchUpId,
52303
+ event
52304
+ });
52305
+ }
52306
+ });
52307
+ });
52308
+ doublesMatchUps.forEach((doublesMatchUp, i) => {
52309
+ const tieMatchUpId = doublesMatchUp.matchUpId;
52310
+ doublesMatchUp.sides.forEach((side) => {
52311
+ const { drawPosition } = side;
52312
+ const teamParticipant = teamParticipants?.find(
52313
+ (teamParticipant2) => {
52314
+ const { participantId } = teamParticipant2;
52315
+ const assignment = positionAssignments.find(
52316
+ (assignment2) => assignment2.participantId === participantId
52317
+ );
52318
+ return assignment?.drawPosition === drawPosition;
52319
+ }
52320
+ );
52321
+ if (teamParticipant) {
52322
+ const individualParticipantIds = teamParticipant.individualParticipantIds.slice(
52323
+ i * 2,
52324
+ i * 2 + 2
52325
+ );
52326
+ individualParticipantIds.forEach((individualParticipantId) => {
52327
+ assignTieMatchUpParticipantId({
52328
+ teamParticipantId: teamParticipant.participantId,
52329
+ participantId: individualParticipantId,
52330
+ tournamentRecord,
52331
+ drawDefinition,
52332
+ tieMatchUpId,
52333
+ event
52334
+ });
52335
+ });
52336
+ }
52337
+ });
52338
+ });
52339
+ };
52340
+ firstRoundDualMatchUps.forEach(assignParticipants);
52341
+ }
52342
+ }
52343
+ }
52344
+ const scoreString = typeof completeAllMatchUps === "string" && completeAllMatchUps;
52345
+ const matchUpStatus = scoreString && COMPLETED$1;
52346
+ for (const structure of sortedStructures) {
52347
+ if (completedCount >= completionGoal)
52348
+ break;
52349
+ const { matchUps } = getAllStructureMatchUps({
52350
+ matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
52351
+ afterRecoveryTimes: false,
52352
+ tournamentRecord,
52353
+ inContext: true,
52354
+ drawDefinition,
52355
+ matchUpsMap,
52356
+ structure,
52357
+ event
52358
+ });
52359
+ const sortedMatchUpIds = matchUps.filter(({ winningSide }) => !winningSide).sort(matchUpSort).map(getMatchUpId);
52360
+ for (const matchUpId of sortedMatchUpIds) {
52361
+ if (!isNaN(completionGoal) && completedCount >= completionGoal)
52362
+ break;
52363
+ const { matchUps: matchUps2 } = getAllStructureMatchUps({
52364
+ matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
52365
+ afterRecoveryTimes: false,
52366
+ tournamentRecord,
52367
+ inContext: true,
52368
+ drawDefinition,
52369
+ matchUpsMap,
52370
+ structure,
52371
+ event
52372
+ });
52373
+ const targetMatchUp = matchUps2.find(
52374
+ (matchUp) => matchUp.matchUpId === matchUpId
52375
+ );
52376
+ const isDoubleExit = [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(
52377
+ targetMatchUp.matchUpStatus
52378
+ );
52379
+ if (targetMatchUp?.readyToScore && !isDoubleExit) {
52380
+ const result = smartComplete({
52381
+ winningSide: !randomWinningSide && 1,
52382
+ matchUpStatusProfile,
52383
+ tournamentRecord,
52384
+ drawDefinition,
52385
+ targetMatchUp,
52386
+ matchUpFormat,
52387
+ matchUpStatus,
52388
+ scoreString,
52389
+ event
52390
+ });
52391
+ if (result?.error)
52392
+ return result;
52393
+ completedCount += 1;
52394
+ }
52395
+ }
52396
+ }
52397
+ return { ...SUCCESS, completedCount };
52398
+ }
52399
+ function completeDrawMatchUp(params) {
52400
+ const {
52401
+ matchUpStatusCodes,
52402
+ policyDefinitions,
52403
+ tournamentRecord,
52404
+ drawDefinition,
52405
+ targetMatchUp,
52406
+ matchUpStatus,
52407
+ matchUpFormat,
52408
+ scoreString,
52409
+ winningSide,
52410
+ event
52411
+ } = params;
52412
+ if (!targetMatchUp || targetMatchUp.matchUpStatus === BYE) {
52413
+ return;
52414
+ }
52415
+ const { matchUpId } = targetMatchUp || {};
52416
+ const { outcome } = generateOutcomeFromScoreString({
52417
+ matchUpFormat,
52418
+ matchUpStatus,
52419
+ scoreString,
52420
+ winningSide
52421
+ });
52422
+ if (matchUpStatusCodes)
52423
+ outcome.matchUpStatusCodes = matchUpStatusCodes;
52424
+ return setMatchUpStatus$1({
52425
+ tournamentRecord,
52426
+ policyDefinitions,
52427
+ drawDefinition,
52428
+ matchUpFormat,
52429
+ matchUpId,
52430
+ outcome,
52431
+ event
52432
+ });
52433
+ }
52434
+ function smartComplete(params) {
52435
+ const {
52436
+ matchUpStatusProfile = {},
52437
+ tournamentRecord,
52438
+ policyDefinitions,
52439
+ drawDefinition,
52440
+ matchUpStatus,
52441
+ matchUpFormat,
52442
+ targetMatchUp,
52443
+ scoreString,
52444
+ winningSide,
52445
+ event
52446
+ } = params;
52447
+ if (scoreString || matchUpStatus)
52448
+ return completeDrawMatchUp(params);
52449
+ const { matchUpId } = targetMatchUp || {};
52450
+ const { outcome } = generateOutcome({
52451
+ matchUpStatusProfile,
52452
+ matchUpFormat,
52453
+ winningSide
52454
+ });
52455
+ return setMatchUpStatus$1({
52456
+ policyDefinitions,
52457
+ tournamentRecord,
52458
+ drawDefinition,
52459
+ matchUpFormat,
52460
+ matchUpId,
52461
+ outcome,
52462
+ event
52463
+ });
52464
+ }
52465
+
52466
+ function convertPointEight({ tournament }) {
52467
+ if (!tournament)
52468
+ return { error: MISSING_TOURNAMENT_RECORD };
52469
+ const {
52470
+ providerTournamentID: tournamentId,
52471
+ hostCountryCode,
52472
+ tournamentLevel,
52473
+ totalPrizeMoney,
52474
+ tournamentName,
52475
+ extensions,
52476
+ startDate,
52477
+ endDate
52478
+ } = tournament;
52479
+ const tournamentRecord = newTournamentRecord({
52480
+ hostCountryCode,
52481
+ tournamentLevel,
52482
+ totalPrizeMoney,
52483
+ tournamentName,
52484
+ tournamentId,
52485
+ extensions,
52486
+ startDate,
52487
+ endDate
52488
+ });
52489
+ tournamentRecord.events = [];
52490
+ for (const legacyEvent of tournament.events || []) {
52491
+ const {
52492
+ extensions: extensions2,
52493
+ ageCategory,
52494
+ discipline,
52495
+ eventType,
52496
+ eventId,
52497
+ gender,
52498
+ stages
52499
+ } = legacyEvent;
52500
+ const event = {
52501
+ drawDefinitions: deriveDraws(stages),
52502
+ category: { ageCategory },
52503
+ gender: ["M", MALE].includes(gender) && MALE || ["F", FEMALE].includes(gender) && FEMALE || void 0,
52504
+ eventType: ["D", DOUBLES].includes(eventType) && DOUBLES || ["T", TEAM$1].includes(eventType) ? TEAM$1 : SINGLES,
52505
+ extensions: extensions2,
52506
+ discipline,
52507
+ eventId
52508
+ };
52509
+ tournamentRecord.events.push(event);
52510
+ }
52511
+ return { ...SUCCESS, tournamentRecord };
52512
+ }
52513
+ function deriveDraws(stages) {
52514
+ const drawDefinitions = [];
52515
+ for (const legacyStage of stages || []) {
52516
+ const { stageType } = legacyStage;
52517
+ const stage = ["M", MAIN].includes(stageType) && MAIN || ["Q", QUALIFYING].includes(stageType) && QUALIFYING || ["C", CONSOLATION].includes(stageType) && CONSOLATION || ["P", PLAY_OFF].includes(stageType) && PLAY_OFF || void 0;
52518
+ for (const draw of legacyStage.draws || []) {
52519
+ const { drawId, drawSize, matchUps } = draw;
52520
+ const drawDefinition = { stage, drawId, drawSize };
52521
+ drawDefinitions.push(drawDefinition);
52522
+ console.log(
52523
+ matchUps.map(({ roundNumber, roundPosition }) => ({
52524
+ roundNumber,
52525
+ roundPosition
52526
+ })),
52527
+ { draw, drawDefinition }
52528
+ );
52529
+ }
52530
+ }
52531
+ return drawDefinitions;
52532
+ }
52533
+
52534
+ const ABANDONED = "ABANDONED";
52535
+ const ACTIVE = "ACTIVE";
52536
+ const CANCELLED = "CANCELLED";
52537
+ const COMPLETED = "COMPLETED";
52538
+ const IN_PROGRESS = "IN_PROGRESS";
52539
+ const tournamentConstants = {
52540
+ ABANDONED,
52541
+ ACTIVE,
52542
+ CANCELLED,
52543
+ COMPLETED,
52544
+ IN_PROGRESS
52545
+ };
52546
+
52547
+ function setTournamentStatus({ tournamentRecord, status }) {
52548
+ if (!tournamentRecord)
52549
+ return { error: MISSING_TOURNAMENT_RECORD };
52550
+ if (status && !Object.keys(tournamentConstants).includes(status))
52551
+ return { error: INVALID_VALUES, info: "Unknown status" };
52552
+ tournamentRecord.tournamentStatus = status;
52553
+ return { ...SUCCESS };
52554
+ }
52555
+
52556
+ function analyzeDraws({ tournamentRecord }) {
52557
+ if (!tournamentRecord)
52558
+ return { error: MISSING_TOURNAMENT_RECORD };
52559
+ const drawsAnalysis = {
52560
+ positionsNoOutcomes: [],
52561
+ // all positions assigned and no outcomes
52562
+ canBePruned: [],
52563
+ // partially assigned positions with outcomes => drawSizes can be reduced
52564
+ matchPlay: [],
52565
+ // only first round has active matchUps; some unassigned positions
52566
+ inactive: [],
52567
+ drawAnalysis: {}
52568
+ };
52569
+ const eventsMap = {};
52570
+ const eventDraws = tournamentRecord.events?.map((event) => {
52571
+ const eventId = event.eventId;
52572
+ eventsMap[eventId] = event;
52573
+ return (event?.drawDefinitions || []).map((drawDefinition) => ({
52574
+ drawDefinition,
52575
+ eventId
52576
+ }));
52577
+ }).flat().filter(Boolean);
52578
+ eventDraws.forEach(({ drawDefinition, eventId }) => {
52579
+ let positionsAssignedCount = 0;
52580
+ let matchUpsWithWinningSideCount = 0;
52581
+ let matchUpsNoOutcomeCount = 0;
52582
+ const { allStructuresLinked } = getStructureGroups({ drawDefinition });
52583
+ const event = eventsMap[eventId];
52584
+ const structures = drawDefinition?.structures || [];
52585
+ const structuresData = structures.map((structure) => {
52586
+ const { stage, stageSequence, structureId } = structure;
52587
+ const orderNumber = stageOrder$1[stage];
52588
+ const { inContextStructureMatchUps } = getStructureDrawPositionProfiles({
52589
+ drawDefinition,
52590
+ structure,
52591
+ event
52592
+ });
52593
+ const matchUpsWithWinningSide = inContextStructureMatchUps?.filter(
52594
+ ({ winningSide }) => winningSide
52595
+ );
52596
+ const winningSideCount = matchUpsWithWinningSide.filter(Boolean).length || 0;
52597
+ matchUpsWithWinningSideCount += winningSideCount;
52598
+ matchUpsNoOutcomeCount += inContextStructureMatchUps.length - matchUpsWithWinningSideCount;
52599
+ const maxWinningSideFirstRoundPosition = Math.max(
52600
+ matchUpsWithWinningSide.filter(({ roundNumber }) => roundNumber === 1).map(({ roundPosition }) => roundPosition)
52601
+ );
52602
+ const { positionAssignments } = getPositionAssignments$1({ structure });
52603
+ const positionsAssigned = positionAssignments?.filter(
52604
+ ({ participantId }) => participantId
52605
+ );
52606
+ positionsAssignedCount += positionsAssigned?.length || 0;
52607
+ const unassignedPositionsCount = (positionAssignments?.length || 0) - (positionsAssigned?.length || 0);
52608
+ const { roundMatchUps, roundProfile, roundNumbers, maxMatchUpsCount } = getRoundMatchUps$1({ matchUps: inContextStructureMatchUps });
52609
+ const activeRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => !roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
52610
+ const inactiveRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
52611
+ const inactiveStructure = roundProfile && Object.values(roundProfile).every((profile) => profile.inactiveRound);
52612
+ return {
52613
+ positionsAssignedCount: positionsAssigned?.length || 0,
52614
+ maxWinningSideFirstRoundPosition,
52615
+ unassignedPositionsCount,
52616
+ inactiveStructure,
52617
+ maxMatchUpsCount,
52618
+ inactiveRounds,
52619
+ roundMatchUps,
52620
+ activeRounds,
52621
+ roundNumbers,
52622
+ roundProfile,
52623
+ structureId,
52624
+ stageSequence,
52625
+ orderNumber,
52626
+ stage
52627
+ };
52628
+ });
52629
+ const mainStructure = structuresData.find(
52630
+ (data) => data.orderNumber === 2 && data.stageSequence === 1
52631
+ );
52632
+ const activeStructuresCount = structuresData.filter(
52633
+ ({ inactiveStructure }) => !inactiveStructure
52634
+ ).length;
52635
+ const { links } = getStructureLinks({
52636
+ drawDefinition,
52637
+ structureId: mainStructure.structureId
52638
+ });
52639
+ const isMatchPlay = ensureInt(mainStructure.activeRounds[0]) === 1 && mainStructure.activeRounds.length === 1 && activeStructuresCount === 1;
52640
+ const inactiveDraw = structuresData?.every(
52641
+ ({ inactiveStructure }) => inactiveStructure
52642
+ );
52643
+ const canBePruned = !links.length && mainStructure.activeRounds.length && (mainStructure.roundProfile[1].inactiveCount || mainStructure.inactiveRounds.length);
52644
+ const drawId = drawDefinition.drawId;
52645
+ if (positionsAssignedCount && !matchUpsWithWinningSideCount)
52646
+ drawsAnalysis.positionsNoOutcomes.push(drawId);
52647
+ if (inactiveDraw)
52648
+ drawsAnalysis.inactive.push(drawId);
52649
+ if (isMatchPlay)
52650
+ drawsAnalysis.matchPlay.push(drawId);
52651
+ if (canBePruned)
52652
+ drawsAnalysis.canBePruned.push(drawId);
52653
+ const drawAnalysis = {
52654
+ matchUpsWithWinningSideCount,
52655
+ matchUpsNoOutcomeCount,
52656
+ positionsAssignedCount,
52657
+ allStructuresLinked,
52658
+ structuresData,
52659
+ inactiveDraw,
52660
+ isMatchPlay,
52661
+ drawId
52662
+ };
52663
+ drawsAnalysis.drawAnalysis[drawId] = drawAnalysis;
52664
+ });
52665
+ return { ...SUCCESS, drawsAnalysis };
52666
+ }
52667
+
52668
+ function checkIsDual(tournamentRecord) {
52669
+ const teamParticipants = tournamentRecord.participants?.filter(
52670
+ ({ participantType }) => participantType === TEAM
52671
+ );
52672
+ const twoTeams = teamParticipants?.length === 2;
52673
+ const event = tournamentRecord.events?.length === 1 && tournamentRecord.events[0];
52674
+ const drawDefinition = event?.drawDefinitions?.length === 1 && event.drawDefinitions[0];
52675
+ const structure = drawDefinition?.structures?.length === 1 && drawDefinition.structures[0];
52676
+ const twoDrawPositions = structure?.positionAssignments?.length === 2;
52677
+ return !!(event.tieFormat && twoTeams && twoDrawPositions);
52678
+ }
52679
+
52680
+ function analyzeTournament({ tournamentRecord }) {
52681
+ if (!tournamentRecord)
52682
+ return { error: MISSING_TOURNAMENT_RECORD };
52683
+ const { drawsAnalysis } = analyzeDraws({ tournamentRecord });
52684
+ const analysis = {
52685
+ isDual: checkIsDual(tournamentRecord),
52686
+ drawsAnalysis
52687
+ };
52688
+ return { ...SUCCESS, analysis };
52689
+ }
52690
+
52691
+ function setTournamentName({
52692
+ tournamentRecord,
52693
+ promotionalName,
52694
+ tournamentName,
52695
+ formalName
52696
+ }) {
52697
+ if (!tournamentRecord)
52698
+ return { error: MISSING_TOURNAMENT_RECORD };
52699
+ if (tournamentName)
52700
+ tournamentRecord.tournamentName = tournamentName;
52701
+ if (promotionalName)
52702
+ tournamentRecord.promotionalName = promotionalName;
52703
+ if (formalName)
52704
+ tournamentRecord.formalName = formalName;
52705
+ if (tournamentRecord.promotionalName === tournamentRecord.tournamentName) {
52706
+ delete tournamentRecord.promotionalName;
52707
+ }
52708
+ if (tournamentRecord.formalName === tournamentRecord.tournamentName) {
52709
+ delete tournamentRecord.formalName;
52710
+ }
52711
+ return { ...SUCCESS };
52712
+ }
52713
+ function setTournamentNotes({ tournamentRecord, notes }) {
52714
+ if (!tournamentRecord)
52715
+ return { error: MISSING_TOURNAMENT_RECORD };
52716
+ return addNotes({ element: tournamentRecord, notes });
52717
+ }
52718
+ function setTournamentCategories({ tournamentRecord, categories }) {
52719
+ if (!tournamentRecord)
52720
+ return { error: MISSING_TOURNAMENT_RECORD };
52721
+ categories = (categories || []).filter((category) => {
52722
+ return category.categoryName && category.type;
52723
+ });
52724
+ tournamentRecord.tournamentCategories = categories;
52725
+ return { ...SUCCESS };
52726
+ }
52727
+
52728
+ function updateCourtAvailability({ tournamentRecord }) {
52729
+ if (!tournamentRecord)
52730
+ return { error: MISSING_TOURNAMENT_RECORD };
52731
+ const { startDate, endDate } = tournamentRecord;
52732
+ const tournamentDates = dateRange(startDate, endDate);
52733
+ const courts = [];
52734
+ for (const venue of tournamentRecord.venues || []) {
52735
+ if (venue?.courts?.length)
52736
+ courts.push(...venue.courts);
52737
+ }
52738
+ for (const court of courts) {
52739
+ const { startTime, endTime } = (court.dateAvailability || []).reduce(
52740
+ (extents, availability) => {
52741
+ const startMinutes = timeStringMinutes(extents.startTime);
52742
+ const endMinutes = timeStringMinutes(extents.endTime);
52743
+ if (availability.startTime && timeStringMinutes(availability.startTime) < startMinutes)
52744
+ extents.startTime = availability.startTime;
52745
+ if (availability.endTime && timeStringMinutes(availability.endTime) > endMinutes)
52746
+ extents.endTime = availability.endTime;
52747
+ return extents;
52748
+ },
52749
+ { startTime: "08:00", endTime: "18:00" }
52750
+ );
52751
+ const updatedDateAvailability = tournamentDates.map((date) => {
52752
+ const existing = court.dateAvailability?.find(
52753
+ (availability) => availability.date === date
52754
+ );
52755
+ return existing || { date, startTime, endTime };
52756
+ });
52757
+ court.dateAvailability = updatedDateAvailability;
52758
+ }
52759
+ return { ...SUCCESS };
52760
+ }
52761
+
52762
+ function setTournamentDates({
52763
+ tournamentRecord,
52764
+ startDate,
52765
+ endDate
52766
+ }) {
52767
+ if (!tournamentRecord)
52768
+ return { error: MISSING_TOURNAMENT_RECORD };
52769
+ if (startDate && !dateValidation.test(startDate) || endDate && !dateValidation.test(endDate))
52770
+ return { error: INVALID_DATE };
52771
+ if (!startDate && !endDate)
52772
+ return { error: MISSING_DATE };
52773
+ if (endDate && startDate && new Date(endDate) < new Date(startDate))
52774
+ return { error: INVALID_VALUES };
52775
+ let checkScheduling;
52776
+ if (startDate && tournamentRecord.startDate && new Date(startDate) > new Date(tournamentRecord.startDate) || endDate && tournamentRecord.endDate && new Date(endDate) < new Date(tournamentRecord.endDate)) {
52777
+ checkScheduling = true;
52778
+ }
52779
+ if (startDate)
52780
+ tournamentRecord.startDate = startDate;
52781
+ if (endDate)
52782
+ tournamentRecord.endDate = endDate;
52783
+ if (startDate && tournamentRecord.endDate && new Date(startDate) > new Date(tournamentRecord.endDate)) {
52784
+ tournamentRecord.endDate = startDate;
52785
+ }
52786
+ if (endDate && tournamentRecord.startDate && new Date(endDate) < new Date(tournamentRecord.startDate)) {
52787
+ tournamentRecord.startDate = endDate;
52788
+ }
52789
+ const unscheduledMatchUpIds = checkScheduling && removeInvalidScheduling({ tournamentRecord })?.unscheduledMatchUpIds;
52790
+ updateCourtAvailability({ tournamentRecord });
52791
+ addNotice({
52792
+ topic: MODIFY_TOURNAMENT_DETAIL,
52793
+ payload: { startDate, endDate }
52794
+ });
52795
+ return { ...SUCCESS, unscheduledMatchUpIds };
52796
+ }
52797
+ function setTournamentStartDate({ tournamentRecord, startDate }) {
52798
+ return setTournamentDates({ tournamentRecord, startDate });
52799
+ }
52800
+ function setTournamentEndDate({ tournamentRecord, endDate }) {
52801
+ return setTournamentDates({ tournamentRecord, endDate });
52802
+ }
52803
+ function removeInvalidScheduling({ tournamentRecord }) {
52804
+ const matchUps = allTournamentMatchUps({ tournamentRecord }).matchUps ?? [];
52805
+ const startDate = tournamentRecord.startDate && new Date(tournamentRecord.startDate);
52806
+ const endDate = tournamentRecord.endDate && new Date(tournamentRecord.endDate);
52807
+ const invalidScheduledDates = [];
52808
+ const invalidSchedulingMatchUpIds = [];
52809
+ for (const matchUp of matchUps) {
52810
+ const { schedule, matchUpId } = matchUp;
52811
+ if (!schedule)
52812
+ continue;
52813
+ if (schedule.scheduledDate) {
52814
+ const scheduledDate = new Date(schedule.scheduledDate);
52815
+ if (startDate && scheduledDate < startDate || endDate && scheduledDate > endDate) {
52816
+ invalidSchedulingMatchUpIds.push(matchUpId);
52817
+ if (!invalidScheduledDates.includes(schedule.scheduledDate))
52818
+ invalidScheduledDates.push(schedule.scheduledDate);
52819
+ }
51639
52820
  }
51640
52821
  }
51641
52822
  if (invalidScheduledDates.length) {
@@ -51654,6 +52835,7 @@ const tournamentGovernor = {
51654
52835
  removeNotes,
51655
52836
  analyzeDraws,
51656
52837
  analyzeTournament,
52838
+ completeDrawMatchUps,
51657
52839
  getRounds,
51658
52840
  getProfileRounds,
51659
52841
  setTournamentName,
@@ -52472,161 +53654,6 @@ function removeMatchUpSideParticipant({
52472
53654
  return { ...SUCCESS };
52473
53655
  }
52474
53656
 
52475
- function validateLineUp({ lineUp, tieFormat }) {
52476
- const errors = [];
52477
- if (!Array.isArray(lineUp)) {
52478
- errors.push(mustBeAnArray("lineUp"));
52479
- return { valid: false, errors, error: INVALID_VALUES };
52480
- }
52481
- const validItems = lineUp.every((item) => {
52482
- if (typeof item !== "object") {
52483
- errors.push(`lineUp entries must be objects`);
52484
- return false;
52485
- }
52486
- const { participantId, collectionAssignments } = item;
52487
- if (!participantId) {
52488
- errors.push("Missing participantId");
52489
- return false;
52490
- }
52491
- if (typeof participantId !== "string") {
52492
- errors.push("participantIds must be strings");
52493
- return false;
52494
- }
52495
- if (!Array.isArray(collectionAssignments)) {
52496
- errors.push(mustBeAnArray("collectionAssignments"));
52497
- return false;
52498
- }
52499
- return collectionAssignments.every((collectionAssignment) => {
52500
- if (typeof collectionAssignment !== "object") {
52501
- errors.push("collectionAssignments must be objects");
52502
- return false;
52503
- }
52504
- const { collectionPosition } = collectionAssignment;
52505
- if (typeof collectionPosition !== "number") {
52506
- errors.push("collectionPosition must be a number");
52507
- return false;
52508
- }
52509
- return true;
52510
- });
52511
- });
52512
- const noDuplicates = unique(lineUp.map(getParticipantId)).length === lineUp.length;
52513
- if (!noDuplicates)
52514
- errors.push("Duplicated participantId(s)");
52515
- const valid = validItems && noDuplicates;
52516
- return { valid, errors, error: errors.length ? INVALID_VALUES : void 0 };
52517
- }
52518
-
52519
- function updateTeamLineUp({
52520
- drawDefinition,
52521
- participantId,
52522
- tieFormat,
52523
- lineUp
52524
- }) {
52525
- if (typeof drawDefinition !== "object")
52526
- return { error: MISSING_DRAW_DEFINITION };
52527
- if (typeof participantId !== "string")
52528
- return { error: MISSING_PARTICIPANT_ID };
52529
- const validation = validateLineUp({ lineUp, tieFormat });
52530
- if (!validation.valid)
52531
- return validation;
52532
- const { extension: existingExtension } = findExtension({
52533
- element: drawDefinition,
52534
- name: LINEUPS
52535
- });
52536
- const value = existingExtension?.value || {};
52537
- value[participantId] = removeLineUpSubstitutions({ lineUp });
52538
- const extension = { name: LINEUPS, value };
52539
- addExtension$1({ element: drawDefinition, extension });
52540
- addDrawNotice({ drawDefinition });
52541
- return { ...SUCCESS };
52542
- }
52543
-
52544
- function getTieMatchUpContext({
52545
- tournamentRecord,
52546
- drawDefinition,
52547
- tieMatchUpId,
52548
- event
52549
- }) {
52550
- if (!tournamentRecord)
52551
- return { error: MISSING_TOURNAMENT_RECORD };
52552
- if (!drawDefinition)
52553
- return { error: MISSING_DRAW_ID };
52554
- if (!event)
52555
- return { error: EVENT_NOT_FOUND };
52556
- const matchUpsMap = getMatchUpsMap({ drawDefinition });
52557
- const { matchUp: tieMatchUp } = findMatchUp$1({
52558
- matchUpId: tieMatchUpId,
52559
- drawDefinition,
52560
- matchUpsMap
52561
- });
52562
- if (!tieMatchUp)
52563
- return { error: MATCHUP_NOT_FOUND };
52564
- const { matchUp: inContextTieMatchUp, structure } = findMatchUp$1({
52565
- tournamentParticipants: tournamentRecord.participants,
52566
- matchUpId: tieMatchUpId,
52567
- inContext: true,
52568
- drawDefinition,
52569
- matchUpsMap,
52570
- event
52571
- });
52572
- if (!inContextTieMatchUp)
52573
- return { error: MATCHUP_NOT_FOUND };
52574
- const {
52575
- collectionPosition,
52576
- drawPositions,
52577
- collectionId,
52578
- matchUpTieId,
52579
- matchUpType
52580
- } = inContextTieMatchUp;
52581
- if (matchUpType && ![SINGLES$1, DOUBLES$1].includes(matchUpType))
52582
- return { error: INVALID_MATCHUP };
52583
- const { positionAssignments } = getPositionAssignments$1({ structure });
52584
- const relevantAssignments = positionAssignments?.filter(
52585
- (assignment) => drawPositions?.includes(assignment.drawPosition)
52586
- );
52587
- const participantIds = relevantAssignments?.map(
52588
- extractAttributes("participantId")
52589
- );
52590
- const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
52591
- tournamentRecord,
52592
- participantFilters: {
52593
- participantTypes: [TEAM],
52594
- participantIds
52595
- }
52596
- });
52597
- const { matchUp: dualMatchUp } = findMatchUp$1({
52598
- matchUpId: matchUpTieId,
52599
- drawDefinition,
52600
- matchUpsMap
52601
- });
52602
- const { matchUp: inContextDualMatchUp } = findMatchUp$1({
52603
- matchUpId: matchUpTieId,
52604
- inContext: true,
52605
- drawDefinition,
52606
- matchUpsMap
52607
- });
52608
- const tieFormat = resolveTieFormat({
52609
- matchUp: dualMatchUp,
52610
- drawDefinition,
52611
- structure,
52612
- event
52613
- })?.tieFormat;
52614
- return {
52615
- inContextDualMatchUp,
52616
- inContextTieMatchUp,
52617
- relevantAssignments,
52618
- collectionPosition,
52619
- teamParticipants,
52620
- collectionId,
52621
- matchUpType,
52622
- dualMatchUp,
52623
- tieMatchUp,
52624
- tieFormat,
52625
- structure,
52626
- ...SUCCESS
52627
- };
52628
- }
52629
-
52630
53657
  function replaceTieMatchUpParticipantId(params) {
52631
53658
  const matchUpContext = getTieMatchUpContext(params);
52632
53659
  if (matchUpContext.error)
@@ -52880,338 +53907,6 @@ function replaceTieMatchUpParticipantId(params) {
52880
53907
  return { ...SUCCESS, modifiedLineUp, participantRemoved, participantAdded };
52881
53908
  }
52882
53909
 
52883
- function removeCollectionAssignments({
52884
- collectionPosition,
52885
- teamParticipantId,
52886
- dualMatchUpSide,
52887
- drawDefinition,
52888
- participantIds,
52889
- collectionId
52890
- }) {
52891
- if (!collectionId || !collectionPosition || !Array.isArray(participantIds))
52892
- return {
52893
- modifiedLineUp: dualMatchUpSide?.lineUp || [],
52894
- error: INVALID_VALUES
52895
- };
52896
- const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
52897
- participantId: teamParticipantId,
52898
- drawDefinition
52899
- })?.lineUp;
52900
- const previousParticipantIds = [];
52901
- const assignmentsRemoved = [];
52902
- const modifiedLineUp = lineUp?.map((teamCompetitor) => {
52903
- if (!participantIds.includes(teamCompetitor.participantId)) {
52904
- return teamCompetitor;
52905
- }
52906
- const collectionAssignments = teamCompetitor.collectionAssignments?.filter((assignment) => {
52907
- const target = assignment.collectionId === collectionId && assignment.collectionPosition === collectionPosition;
52908
- if (target) {
52909
- if (assignment.previousParticipantId) {
52910
- previousParticipantIds.push(assignment.previousParticipantId);
52911
- }
52912
- assignmentsRemoved.push({
52913
- participantId: teamCompetitor.participantId,
52914
- ...assignment
52915
- });
52916
- }
52917
- return !target;
52918
- });
52919
- return {
52920
- participantId: teamCompetitor.participantId,
52921
- collectionAssignments
52922
- };
52923
- }).filter(Boolean) || [];
52924
- return { modifiedLineUp, assignmentsRemoved, previousParticipantIds };
52925
- }
52926
-
52927
- function assignTieMatchUpParticipantId(params) {
52928
- const matchUpContext = getTieMatchUpContext(params);
52929
- if (matchUpContext.error)
52930
- return matchUpContext;
52931
- const stack = "assignTieMatchUpParticipantId";
52932
- let teamParticipantId = params.teamParticipantId;
52933
- const { tournamentRecord, drawDefinition, participantId, event } = params;
52934
- if (!participantId) {
52935
- return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
52936
- }
52937
- if (params.sideNumber && ![1, 2].includes(params.sideNumber)) {
52938
- return decorateResult({ result: { error: INVALID_SIDE_NUMBER }, stack });
52939
- }
52940
- const {
52941
- inContextDualMatchUp,
52942
- inContextTieMatchUp,
52943
- relevantAssignments,
52944
- collectionPosition,
52945
- teamParticipants,
52946
- collectionId,
52947
- matchUpType,
52948
- dualMatchUp,
52949
- tieFormat
52950
- } = matchUpContext;
52951
- const allTieIndividualParticipantIds = inContextTieMatchUp?.sides?.flatMap(
52952
- (side) => side.participant?.individualParticipantIds || side.participant?.participantId || []
52953
- );
52954
- if (allTieIndividualParticipantIds?.includes(participantId)) {
52955
- return decorateResult({ result: { ...SUCCESS }, stack });
52956
- }
52957
- teamParticipantId = teamParticipantId || params.sideNumber && inContextDualMatchUp?.sides?.find(
52958
- (side) => side.sideNumber === params.sideNumber
52959
- )?.participantId;
52960
- const {
52961
- tournamentParticipants: [participantToAssign]
52962
- } = getTournamentParticipants({
52963
- tournamentRecord,
52964
- participantFilters: {
52965
- participantIds: [participantId]
52966
- }
52967
- });
52968
- if (!participantToAssign) {
52969
- return decorateResult({ result: { error: PARTICIPANT_NOT_FOUND }, stack });
52970
- }
52971
- const { appliedPolicies } = getAppliedPolicies({
52972
- tournamentRecord,
52973
- drawDefinition,
52974
- event
52975
- });
52976
- const matchUpActionsPolicy = params.policyDefinitions?.[POLICY_TYPE_MATCHUP_ACTIONS] || appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS] || POLICY_MATCHUP_ACTIONS_DEFAULT[POLICY_TYPE_MATCHUP_ACTIONS];
52977
- if (matchUpActionsPolicy?.participants?.enforceGender && [MALE, FEMALE].includes(inContextTieMatchUp?.gender) && inContextTieMatchUp?.gender !== participantToAssign.person?.sex) {
52978
- return { error: INVALID_PARTICIPANT, info: "Gender mismatch" };
52979
- }
52980
- const { individualParticipantIds, participantType } = participantToAssign;
52981
- if (matchUpType === SINGLES$1 && participantType !== INDIVIDUAL) {
52982
- return { error: INVALID_PARTICIPANT_TYPE };
52983
- }
52984
- const relevantParticipantIds = participantType === INDIVIDUAL ? [participantId] : individualParticipantIds;
52985
- const participantTeam = teamParticipantId && teamParticipants?.find(
52986
- ({ participantId: participantId2 }) => participantId2 === teamParticipantId
52987
- ) || teamParticipants?.find(
52988
- ({ individualParticipantIds: individualParticipantIds2 }) => overlap(relevantParticipantIds, individualParticipantIds2)
52989
- );
52990
- if (!participantTeam) {
52991
- return { error: TEAM_NOT_FOUND };
52992
- }
52993
- if (!teamParticipantId)
52994
- teamParticipantId = participantTeam.participantId;
52995
- if (!teamParticipantId)
52996
- return { error: PARTICIPANT_NOT_FOUND };
52997
- const teamAssignment = relevantAssignments?.find(
52998
- (assignment) => assignment.participantId === participantTeam?.participantId
52999
- );
53000
- const teamDrawPosition = teamAssignment?.drawPosition;
53001
- const teamSide = inContextTieMatchUp?.sides?.find(
53002
- (side) => side.drawPosition === teamDrawPosition
53003
- );
53004
- const sideNumber = params.sideNumber || teamSide?.sideNumber;
53005
- if (!tieFormat) {
53006
- return { error: MISSING_TIE_FORMAT };
53007
- }
53008
- const collectionDefinition = tieFormat.collectionDefinitions?.find(
53009
- (collectionDefinition2) => collectionDefinition2.collectionId === collectionId
53010
- );
53011
- if (!collectionDefinition)
53012
- return { error: MISSING_COLLECTION_DEFINITION };
53013
- if (!dualMatchUp?.sides?.length) {
53014
- const { extension } = findExtension$2({
53015
- element: drawDefinition,
53016
- name: LINEUPS
53017
- });
53018
- const lineUps = makeDeepCopy(extension?.value || {}, false, true);
53019
- const extractSideDetail = ({
53020
- displaySideNumber,
53021
- drawPosition,
53022
- sideNumber: sideNumber2
53023
- }) => ({ drawPosition, sideNumber: sideNumber2, displaySideNumber });
53024
- if (dualMatchUp) {
53025
- dualMatchUp.sides = inContextDualMatchUp?.sides?.map((side) => {
53026
- const participantId2 = side.participantId;
53027
- return {
53028
- ...extractSideDetail(side),
53029
- lineUp: participantId2 && lineUps[participantId2] || []
53030
- };
53031
- });
53032
- }
53033
- }
53034
- const dualMatchUpSide = dualMatchUp?.sides?.find(
53035
- (side) => side.sideNumber === sideNumber
53036
- );
53037
- const tieMatchUpSide = inContextTieMatchUp?.sides?.find(
53038
- (side) => side.sideNumber === sideNumber
53039
- );
53040
- const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
53041
- participantId: teamParticipantId,
53042
- drawDefinition
53043
- })?.lineUp;
53044
- const targetAssignments = lineUp?.filter(
53045
- (participantAssignment) => participantAssignment.collectionAssignments?.find(
53046
- (assignment) => assignment.collectionPosition === collectionPosition && assignment.collectionId === collectionId && !assignment.previousParticipantId
53047
- )
53048
- );
53049
- const assignedParticipantIds = targetAssignments?.map(
53050
- (assignment) => assignment?.participantId
53051
- );
53052
- const participantIds = assignedParticipantIds?.length > 1 && assignedParticipantIds || (participantType === PAIR ? participantToAssign.individualParticipantIds : [participantId]);
53053
- const removeResult = removeCollectionAssignments({
53054
- collectionPosition,
53055
- teamParticipantId,
53056
- dualMatchUpSide,
53057
- drawDefinition,
53058
- participantIds,
53059
- collectionId
53060
- });
53061
- if (removeResult.error)
53062
- return decorateResult({ result: removeResult, stack });
53063
- const { modifiedLineUp } = removeResult;
53064
- let deleteParticipantId;
53065
- if (matchUpType === DOUBLES$1) {
53066
- if (participantType !== PAIR) {
53067
- let result = updateLineUp({
53068
- collectionPosition,
53069
- teamParticipantId,
53070
- drawDefinition,
53071
- modifiedLineUp,
53072
- participantId,
53073
- collectionId,
53074
- tieFormat
53075
- });
53076
- if (result?.error)
53077
- return decorateResult({ result, stack });
53078
- result = addParticipantId2Pair({
53079
- side: tieMatchUpSide
53080
- });
53081
- if (result.error)
53082
- return result;
53083
- deleteParticipantId = result.deleteParticipantId;
53084
- if (dualMatchUpSide)
53085
- dualMatchUpSide.lineUp = modifiedLineUp;
53086
- if (dualMatchUp) {
53087
- modifyMatchUpNotice({
53088
- tournamentId: tournamentRecord?.tournamentId,
53089
- matchUp: dualMatchUp,
53090
- context: stack,
53091
- drawDefinition
53092
- });
53093
- }
53094
- } else if (participantType === PAIR) {
53095
- for (const participantId2 of participantIds) {
53096
- updateLineUp({
53097
- collectionPosition,
53098
- teamParticipantId,
53099
- drawDefinition,
53100
- modifiedLineUp,
53101
- participantId: participantId2,
53102
- collectionId,
53103
- tieFormat
53104
- });
53105
- }
53106
- }
53107
- } else {
53108
- const result = updateLineUp({
53109
- collectionPosition,
53110
- teamParticipantId,
53111
- drawDefinition,
53112
- modifiedLineUp,
53113
- participantId,
53114
- collectionId,
53115
- tieFormat
53116
- });
53117
- if (result?.error)
53118
- return result;
53119
- }
53120
- if (dualMatchUpSide)
53121
- dualMatchUpSide.lineUp = modifiedLineUp;
53122
- if (dualMatchUp)
53123
- modifyMatchUpNotice({
53124
- tournamentId: tournamentRecord?.tournamentId,
53125
- matchUp: dualMatchUp,
53126
- context: stack,
53127
- drawDefinition
53128
- });
53129
- if (deleteParticipantId) {
53130
- const { error } = deleteParticipants({
53131
- participantIds: [deleteParticipantId],
53132
- tournamentRecord
53133
- });
53134
- if (error)
53135
- console.log("cleanup");
53136
- }
53137
- return { ...SUCCESS, modifiedLineUp };
53138
- function addParticipantId2Pair({ side }) {
53139
- let deleteParticipantId2;
53140
- if (!side.participant) {
53141
- const newPairParticipant = {
53142
- individualParticipantIds: [participantId],
53143
- participantRole: COMPETITOR,
53144
- participantType: PAIR
53145
- };
53146
- const result = addParticipant$1({
53147
- participant: newPairParticipant,
53148
- pairOverride: true,
53149
- tournamentRecord
53150
- });
53151
- if (result.error)
53152
- return result;
53153
- } else {
53154
- const individualParticipantIds2 = side.participant.individualParticipantIds || [];
53155
- const sideParticipantsCount = individualParticipantIds2.filter(Boolean).length;
53156
- if (sideParticipantsCount === 1) {
53157
- const { participant } = getPairedParticipant({
53158
- participantIds: individualParticipantIds2,
53159
- tournamentRecord
53160
- });
53161
- individualParticipantIds2.push(participantId);
53162
- const { participant: existingParticipant } = getPairedParticipant({
53163
- participantIds: individualParticipantIds2,
53164
- tournamentRecord
53165
- });
53166
- if (!existingParticipant && participant) {
53167
- participant.individualParticipantIds = individualParticipantIds2;
53168
- const result = modifyParticipant({
53169
- pairOverride: true,
53170
- tournamentRecord,
53171
- participant
53172
- });
53173
- if (result.error)
53174
- return result;
53175
- } else {
53176
- deleteParticipantId2 = participant?.participantId;
53177
- }
53178
- }
53179
- }
53180
- return { ...SUCCESS, deleteParticipantId: deleteParticipantId2 };
53181
- }
53182
- }
53183
- function updateLineUp({
53184
- collectionPosition,
53185
- teamParticipantId,
53186
- drawDefinition,
53187
- modifiedLineUp,
53188
- participantId,
53189
- collectionId,
53190
- tieFormat
53191
- }) {
53192
- const templateTeamLineUp = getTeamLineUp({
53193
- participantId: teamParticipantId,
53194
- drawDefinition
53195
- })?.lineUp;
53196
- const participantCompetitiorProfile = (modifiedLineUp || templateTeamLineUp)?.find((teamCompetitor) => teamCompetitor?.participantId === participantId);
53197
- const newAssignment = { collectionId, collectionPosition };
53198
- if (participantCompetitiorProfile) {
53199
- participantCompetitiorProfile.collectionAssignments.push(newAssignment);
53200
- } else {
53201
- const teamCompetitor = {
53202
- collectionAssignments: [newAssignment],
53203
- participantId
53204
- };
53205
- modifiedLineUp.push(teamCompetitor);
53206
- }
53207
- return updateTeamLineUp({
53208
- participantId: teamParticipantId,
53209
- lineUp: modifiedLineUp,
53210
- drawDefinition,
53211
- tieFormat
53212
- });
53213
- }
53214
-
53215
53910
  function removeTieMatchUpParticipantId(params) {
53216
53911
  const { tournamentRecord, drawDefinition, participantId, event } = params;
53217
53912
  const stack = "removeTieMatchUpParticiapantId";
@@ -55713,150 +56408,6 @@ function setOrderOfFinish(params) {
55713
56408
  return setOrderOfFinish$1(params);
55714
56409
  }
55715
56410
 
55716
- const ASC = "ASC";
55717
- const ASCENDING = "ASC";
55718
- const DESC = "DESC";
55719
- const DESCENDING = "DESC";
55720
- const sortingConstants = { ASC, ASCENDING, DESC, DESCENDING };
55721
-
55722
- function generateLineUps(params) {
55723
- let { tieFormat } = params;
55724
- const {
55725
- useDefaultEventRanking,
55726
- tournamentRecord,
55727
- drawDefinition,
55728
- scaleAccessor,
55729
- // e.g. { scaleType: 'RANKINGS', scaleName: 'U18', accessor: 'wtnRating', sortOrder: 'ASC' }
55730
- singlesOnly,
55731
- // use singles scale for doubles events
55732
- attach,
55733
- // boolean - when true attach LINEUPS extension to drawDefinition and add new PAIR participants (where necessary)
55734
- event
55735
- } = params;
55736
- if (event?.eventType !== TEAM_EVENT)
55737
- return { error: INVALID_EVENT_TYPE };
55738
- if (!tournamentRecord)
55739
- return { error: MISSING_TOURNAMENT_RECORD };
55740
- if (!tieFormat && !drawDefinition)
55741
- return { error: DRAW_DEFINITION_NOT_FOUND };
55742
- tieFormat = tieFormat || resolveTieFormat({ drawDefinition, event })?.tieFormat;
55743
- if (validateTieFormat({ tieFormat }).error)
55744
- return { error: INVALID_TIE_FORMAT };
55745
- if (typeof scaleAccessor !== "object" && !useDefaultEventRanking)
55746
- return { error: INVALID_VALUES, context: { scaleAccessor } };
55747
- const lineUps = {};
55748
- const targetEntries = (drawDefinition?.entries || event.entries).filter(
55749
- (entry) => entry?.entryStatus === DIRECT_ACCEPTANCE
55750
- );
55751
- const participantIds = targetEntries.map(getParticipantId);
55752
- const { participants = [] } = getParticipants$1({
55753
- withIndividualParticipants: true,
55754
- withScaleValues: true,
55755
- tournamentRecord
55756
- });
55757
- const teamParticipants = participants.filter(
55758
- ({ participantId }) => participantIds.includes(participantId)
55759
- );
55760
- const formatScaleType = (type) => type === RANKING$1 ? "rankings" : "ratings";
55761
- const defaultScaleName = event?.category?.categoryName || event?.category?.ageCategoryCode;
55762
- const {
55763
- scaleName = defaultScaleName,
55764
- scaleType = RANKING$1,
55765
- sortOrder,
55766
- accessor
55767
- } = scaleAccessor || {};
55768
- const formattedScaleType = formatScaleType(scaleType);
55769
- const getScaleValue = (individualParticipant, matchUpType) => {
55770
- let matchUpTypeScales = individualParticipant[formattedScaleType]?.[matchUpType];
55771
- if (!matchUpTypeScales && useDefaultEventRanking) {
55772
- matchUpTypeScales = individualParticipant[formattedScaleType]?.[SINGLES_MATCHUP];
55773
- }
55774
- if (Array.isArray(matchUpTypeScales)) {
55775
- const scaleValue = matchUpTypeScales.find(
55776
- (scale) => scale.scaleName === scaleName
55777
- )?.scaleValue;
55778
- if (isNumeric(scaleValue)) {
55779
- return scaleValue;
55780
- } else if (accessor && typeof scaleValue === "object")
55781
- return scaleValue[accessor];
55782
- }
55783
- return 0;
55784
- };
55785
- const sortMethod = (a, b, matchUpType) => {
55786
- const x = sortOrder === DESCENDING ? b : a;
55787
- const y = sortOrder === DESCENDING ? a : b;
55788
- return getScaleValue(x, matchUpType) - getScaleValue(y, matchUpType);
55789
- };
55790
- const singlesScaleSort = (a, b) => sortMethod(a, b, SINGLES_MATCHUP);
55791
- const doublesScaleSort = (a, b) => sortMethod(a, b, DOUBLES_MATCHUP);
55792
- const participantIdPairs = [];
55793
- const collectionDefinitions = tieFormat.collectionDefinitions || [];
55794
- for (const teamParticipant of teamParticipants) {
55795
- const singlesSort = teamParticipant.individualParticipants.sort(singlesScaleSort);
55796
- const doublesSort = singlesOnly ? singlesSort : teamParticipant.individualParticipants.sort(doublesScaleSort);
55797
- const participantAssignments = {};
55798
- for (const collectionDefinition of collectionDefinitions) {
55799
- const collectionParticipantIds = [];
55800
- const { collectionId, matchUpCount, matchUpType, gender } = collectionDefinition;
55801
- const singlesMatchUp = matchUpType === SINGLES_MATCHUP;
55802
- generateRange(0, matchUpCount).forEach((i) => {
55803
- const typeSort = singlesMatchUp ? singlesSort : doublesSort;
55804
- const collectionPosition = i + 1;
55805
- const participantIds2 = [];
55806
- generateRange(0, singlesMatchUp ? 1 : 2).forEach((i2) => {
55807
- const nextParticipantId = typeSort.find((participant) => {
55808
- const targetGender = [MALE, FEMALE].includes(gender) && gender || gender === MIXED && [MALE, FEMALE][i2];
55809
- return (!targetGender || targetGender === participant.person.sex) && !collectionParticipantIds.includes(participant.participantId);
55810
- }).participantId;
55811
- if (nextParticipantId) {
55812
- participantIds2.push(nextParticipantId);
55813
- collectionParticipantIds.push(nextParticipantId);
55814
- if (!participantAssignments[nextParticipantId])
55815
- participantAssignments[nextParticipantId] = [];
55816
- participantAssignments[nextParticipantId].push({
55817
- collectionPosition,
55818
- collectionId
55819
- });
55820
- }
55821
- });
55822
- if (!singlesMatchUp)
55823
- participantIdPairs.push(participantIds2);
55824
- });
55825
- }
55826
- const lineUp = Object.keys(participantAssignments).map((participantId) => ({
55827
- collectionAssignments: participantAssignments[participantId],
55828
- participantId
55829
- }));
55830
- lineUps[teamParticipant.participantId] = lineUp;
55831
- }
55832
- const participantsToAdd = [];
55833
- for (const pairParticipantIds of participantIdPairs) {
55834
- const { participant: existingPairParticipant } = getPairedParticipant({
55835
- tournamentParticipants: participants,
55836
- participantIds: pairParticipantIds
55837
- });
55838
- if (!existingPairParticipant) {
55839
- const newPairParticipant = {
55840
- individualParticipantIds: pairParticipantIds,
55841
- participantRole: COMPETITOR,
55842
- participantType: PAIR
55843
- };
55844
- participantsToAdd.push(newPairParticipant);
55845
- }
55846
- }
55847
- if (attach) {
55848
- while (participantsToAdd.length) {
55849
- addParticipant$1({
55850
- participant: participantsToAdd.pop(),
55851
- tournamentRecord
55852
- });
55853
- }
55854
- const extension = { name: LINEUPS, value: lineUps };
55855
- addExtension$1({ element: drawDefinition, extension });
55856
- }
55857
- return { ...SUCCESS, lineUps, participantsToAdd };
55858
- }
55859
-
55860
56411
  function modifyDrawName({ event, drawId, drawDefinition, drawName }) {
55861
56412
  if (!drawName || typeof drawName !== "string")
55862
56413
  return { error: INVALID_VALUES, drawName };
@@ -57148,6 +57699,12 @@ function enableTieAutoCalc(params) {
57148
57699
  return enableTieAutoCalc$1(params);
57149
57700
  }
57150
57701
 
57702
+ function resetMatchUpLineUps(params) {
57703
+ if (!params.tournamentRecord)
57704
+ return { error: MISSING_TOURNAMENT_RECORD };
57705
+ return resetMatchUpLineUps$1(params);
57706
+ }
57707
+
57151
57708
  const eventGovernor = {
57152
57709
  generateQualifyingStructure,
57153
57710
  attachQualifyingStructure,
@@ -57260,6 +57817,7 @@ const eventGovernor = {
57260
57817
  assignTieMatchUpParticipantId,
57261
57818
  removeTieMatchUpParticipantId,
57262
57819
  replaceTieMatchUpParticipantId,
57820
+ resetMatchUpLineUps,
57263
57821
  updateTeamLineUp,
57264
57822
  validateLineUp,
57265
57823
  getTeamLineUp
@@ -60008,513 +60566,6 @@ function generatePairParticipantName({
60008
60566
  return participantName;
60009
60567
  }
60010
60568
 
60011
- function generateOutcomeFromScoreString(params) {
60012
- const { matchUpFormat, matchUpStatus, winningSide, scoreString } = params;
60013
- if (!scoreString)
60014
- return {
60015
- outcome: {
60016
- ...toBePlayed,
60017
- winningSide,
60018
- matchUpStatus
60019
- }
60020
- };
60021
- if (winningSide && ![1, 2, void 0].includes(winningSide))
60022
- return { error: INVALID_VALUES, winningSide };
60023
- const neutralParsedSets = scoreString && parseScoreString({ scoreString });
60024
- const score = {};
60025
- const winningScoreString = generateScoreString({
60026
- sets: neutralParsedSets,
60027
- matchUpFormat
60028
- });
60029
- const losingScoreString = generateScoreString({
60030
- sets: neutralParsedSets,
60031
- reversed: true,
60032
- matchUpFormat
60033
- });
60034
- if (winningSide === 2) {
60035
- score.scoreStringSide1 = losingScoreString;
60036
- score.scoreStringSide2 = winningScoreString;
60037
- } else {
60038
- score.scoreStringSide1 = winningScoreString;
60039
- score.scoreStringSide2 = losingScoreString;
60040
- }
60041
- score.sets = parseScoreString({ scoreString: score.scoreStringSide1 });
60042
- return definedAttributes({
60043
- outcome: {
60044
- matchUpStatus,
60045
- winningSide,
60046
- score
60047
- }
60048
- });
60049
- }
60050
-
60051
- const defaultStatusProfile = {
60052
- [WALKOVER$2]: 2,
60053
- [DOUBLE_WALKOVER]: 1,
60054
- [DOUBLE_DEFAULT]: 1,
60055
- [RETIRED$1]: 1,
60056
- [DEFAULTED]: 4
60057
- };
60058
- function generateOutcome(params) {
60059
- let { defaultWithScorePercent = 2, winningSide } = params;
60060
- const {
60061
- matchUpStatusProfile = defaultStatusProfile,
60062
- // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
60063
- matchUpFormat = FORMAT_STANDARD,
60064
- pointsPerMinute = 1,
60065
- sideWeight = 4
60066
- } = params;
60067
- if (!isValid(matchUpFormat))
60068
- return { error: INVALID_MATCHUP_FORMAT };
60069
- if (typeof matchUpStatusProfile !== "object")
60070
- return { error: INVALID_VALUES };
60071
- if (defaultWithScorePercent > 100)
60072
- defaultWithScorePercent = 100;
60073
- if (isNaN(defaultWithScorePercent) || isNaN(pointsPerMinute) || isNaN(sideWeight))
60074
- return { error: INVALID_VALUES };
60075
- const matchUpStatuses = Object.keys(matchUpStatusProfile).filter(
60076
- (matchUpStatus2) => Object.keys(matchUpStatusConstants).includes(matchUpStatus2) && matchUpStatus2 !== COMPLETED$1
60077
- );
60078
- const matchUpStatusTotals = Object.keys(matchUpStatuses).reduce(
60079
- (total, key) => total + matchUpStatusProfile[key],
60080
- 0
60081
- );
60082
- if (matchUpStatusTotals > 100)
60083
- return { error: INVALID_VALUES, matchUpStatusProfile };
60084
- const matchUpStatusMap = matchUpStatuses.reduce(
60085
- (statusMap, matchUpStatus2) => {
60086
- statusMap.pointer = statusMap.pointer + matchUpStatusProfile[matchUpStatus2];
60087
- statusMap.valueMap.push([statusMap.pointer, matchUpStatus2]);
60088
- return statusMap;
60089
- },
60090
- { pointer: 0, valueMap: [] }
60091
- );
60092
- const outcomePointer = randomInt(1, 100);
60093
- const matchUpStatus = (matchUpStatusMap.valueMap.find(
60094
- (item) => outcomePointer <= item[0]
60095
- ) || [100, COMPLETED$1])[1];
60096
- const noScore = { sets: [], scoreStringSide1: "", side2ScoreString: "" };
60097
- if ([WALKOVER$2, DEFAULTED].includes(matchUpStatus)) {
60098
- winningSide = winningSide || randomInt(1, 2);
60099
- const outcome2 = {
60100
- score: noScore,
60101
- winningSide,
60102
- matchUpStatus
60103
- };
60104
- const scoreDefaulted = matchUpStatus === DEFAULTED && randomInt(1, 100) > 100 - defaultWithScorePercent;
60105
- if (!scoreDefaulted)
60106
- return { outcome: outcome2 };
60107
- } else if ([DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(matchUpStatus)) {
60108
- return { outcome: { score: noScore, matchUpStatus } };
60109
- }
60110
- const parsedFormat = parse(matchUpFormat);
60111
- const { bestOf, setFormat, finalSetFormat } = parsedFormat || {};
60112
- const sets = [];
60113
- const weightedSide = randomInt(0, 1);
60114
- const weightedRange = winningSide ? [winningSide - 1] : [
60115
- ...generateRange(0, sideWeight).map(() => weightedSide),
60116
- 1 - weightedSide
60117
- ];
60118
- const incompleteSet = [RETIRED$1, DEFAULTED, INCOMPLETE, SUSPENDED].includes(
60119
- matchUpStatus
60120
- );
60121
- const incompleteAt = incompleteSet && (randomPop(generateRange(1, bestOf)) || 1);
60122
- let weightedWinningSide;
60123
- for (const setNumber of generateRange(1, (bestOf || 0) + 1)) {
60124
- const isFinalSet = setNumber === bestOf;
60125
- const { set, incomplete, winningSideNumber } = generateSet({
60126
- incomplete: incompleteAt === setNumber,
60127
- matchUpStatus,
60128
- pointsPerMinute,
60129
- setFormat: isFinalSet && finalSetFormat || setFormat,
60130
- setNumber,
60131
- weightedRange
60132
- });
60133
- sets.push(set);
60134
- if (incomplete) {
60135
- weightedWinningSide = winningSideNumber;
60136
- break;
60137
- }
60138
- const analysis2 = analyzeMatchUp({
60139
- matchUp: { score: { sets }, matchUpFormat }
60140
- });
60141
- if (analysis2.calculatedWinningSide)
60142
- break;
60143
- }
60144
- const analysis = analyzeMatchUp({
60145
- matchUp: { score: { sets }, matchUpFormat }
60146
- });
60147
- const matchUpWinningSide = weightedWinningSide ? winningSide || weightedWinningSide : analysis.calculatedWinningSide;
60148
- const { score } = matchUpScore({
60149
- score: { sets },
60150
- winningSide: matchUpWinningSide,
60151
- matchUpStatus
60152
- });
60153
- const outcome = {
60154
- score,
60155
- winningSide: matchUpWinningSide,
60156
- matchUpStatus
60157
- };
60158
- return { outcome };
60159
- }
60160
- function generateSet({
60161
- weightedRange = [0, 1],
60162
- pointsPerMinute,
60163
- matchUpStatus,
60164
- incomplete,
60165
- setFormat,
60166
- setNumber
60167
- }) {
60168
- const set = { setNumber };
60169
- const { setTo, tiebreakFormat, tiebreakAt, tiebreakSet, timed, minutes } = setFormat;
60170
- const weightIndex = randomInt(0, weightedRange.length - 1);
60171
- const reverseScores = weightedRange[weightIndex];
60172
- let winningSideNumber;
60173
- if (timed) {
60174
- const calcPoints = minutes * pointsPerMinute;
60175
- const pointsVariation = Math.round(calcPoints * 0.2);
60176
- const totalPoints = calcPoints + randomPop([1, -1]) * pointsVariation;
60177
- const sidePoints = weightedRandom(totalPoints, 2);
60178
- const scores = [sidePoints, totalPoints - sidePoints];
60179
- if (reverseScores)
60180
- scores.reverse();
60181
- winningSideNumber = weightedRange[weightIndex] + 1;
60182
- let highSide = scores[0] > scores[1] && 1 || scores[1] > scores[0] && 2 || 0;
60183
- if (incomplete) {
60184
- const [side1Score2, side2Score2] = scores;
60185
- Object.assign(set, { side1Score: side1Score2, side2Score: side2Score2 });
60186
- if (completedMatchUpStatuses.includes(matchUpStatus)) {
60187
- return { set, incomplete, winningSideNumber };
60188
- }
60189
- return { set, incomplete };
60190
- }
60191
- if (!highSide)
60192
- scores[randomInt(0, 1)] += 1;
60193
- highSide = scores[0] > scores[1] ? 1 : 2;
60194
- if (highSide !== winningSideNumber)
60195
- scores.reverse();
60196
- const [side1Score, side2Score] = scores;
60197
- Object.assign(set, {
60198
- side1Score,
60199
- side2Score,
60200
- winningSide: winningSideNumber
60201
- });
60202
- return { set };
60203
- } else if (incomplete) {
60204
- set.side1Score = randomInt(0, tiebreakAt);
60205
- set.side2Score = randomInt(0, tiebreakAt);
60206
- if (completedMatchUpStatuses.includes(matchUpStatus)) {
60207
- winningSideNumber = weightedRange[weightIndex] + 1;
60208
- }
60209
- return { set, incomplete, winningSideNumber };
60210
- } else {
60211
- const range = generateRange(1, setTo + 1).map((value) => generateRange(0, setTo + 2 - value).map(() => value)).flat();
60212
- const lowValue = range[randomInt(0, range.length - 1)];
60213
- const scores = setTo && getSetComplement({
60214
- isSide1: true,
60215
- tiebreakAt,
60216
- lowValue,
60217
- setTo
60218
- });
60219
- const isTiebreakSet = !scores;
60220
- const specifiedWinningSide = weightedRange.length === 1 && weightedRange[weightIndex] + 1;
60221
- if (!isTiebreakSet) {
60222
- if (specifiedWinningSide) {
60223
- const highSide = scores[0] > scores[1] ? 1 : 2;
60224
- if (highSide !== specifiedWinningSide)
60225
- scores.reverse();
60226
- } else if (reverseScores) {
60227
- scores.reverse();
60228
- }
60229
- const [side1Score, side2Score] = scores;
60230
- Object.assign(set, { side1Score, side2Score });
60231
- }
60232
- const setAnalysis = analyzeSet({
60233
- matchUpScoringFormat: { setFormat },
60234
- setObject: set
60235
- });
60236
- let tiebreakWinningSide;
60237
- if (setAnalysis.hasTiebreakCondition || isTiebreakSet) {
60238
- const { NoAD: tiebreakNoAd, tiebreakTo } = tiebreakFormat || tiebreakSet || {};
60239
- const range2 = generateRange(1, tiebreakTo + 1).map(
60240
- (value) => generateRange(0, tiebreakTo + 2 - value).map(() => value)
60241
- ).flat();
60242
- const lowValue2 = range2[randomInt(0, range2.length - 1)];
60243
- const scores2 = getTiebreakComplement({
60244
- isSide1: true,
60245
- tiebreakNoAd,
60246
- tiebreakTo,
60247
- lowValue: lowValue2
60248
- });
60249
- if (scores2) {
60250
- if (isTiebreakSet) {
60251
- const highSide = scores2[0] > scores2[1] ? 1 : 2;
60252
- if (specifiedWinningSide) {
60253
- if (highSide !== specifiedWinningSide)
60254
- scores2.reverse();
60255
- } else if (reverseScores) {
60256
- scores2.reverse();
60257
- }
60258
- [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
60259
- tiebreakWinningSide = scores2[0] > scores2[1] && 1 || scores2[1] > scores2[0] && 2 || void 0;
60260
- } else if (setAnalysis.leadingSide === 2) {
60261
- [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
60262
- } else {
60263
- [set.side2TiebreakScore, set.side1TiebreakScore] = scores2;
60264
- }
60265
- }
60266
- }
60267
- set.winningSide = setAnalysis.winningSide || setAnalysis.leadingSide || specifiedWinningSide || tiebreakWinningSide;
60268
- }
60269
- return { set };
60270
- }
60271
-
60272
- function completeDrawMatchUps(params) {
60273
- const {
60274
- matchUpStatusProfile,
60275
- // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
60276
- completeAllMatchUps,
60277
- // qualifyingProfiles, // CONSIDER: allowing completionGoal per structureProfile
60278
- randomWinningSide,
60279
- tournamentRecord,
60280
- completionGoal,
60281
- drawDefinition,
60282
- event
60283
- } = params;
60284
- if (!drawDefinition)
60285
- return { error: MISSING_DRAW_DEFINITION };
60286
- const matchUpFormat = params.matchUpFormat || drawDefinition.matchUpFormat || event?.matchUpFormat;
60287
- const sortedStructures = drawDefinition.structures.slice().sort(structureSort);
60288
- let completedCount = 0;
60289
- const { matchUps: firstRoundDualMatchUps, matchUpsMap } = getAllDrawMatchUps({
60290
- contextFilters: {
60291
- stages: [MAIN, QUALIFYING]
60292
- },
60293
- matchUpFilters: {
60294
- matchUpTypes: [TEAM$2],
60295
- roundNumbers: [1]
60296
- },
60297
- inContext: true,
60298
- drawDefinition
60299
- });
60300
- if (firstRoundDualMatchUps?.length) {
60301
- const categoryName = event?.category?.ageCategoryCode || event?.category?.categoryName;
60302
- if (categoryName) {
60303
- const scaleAccessor = {
60304
- scaleName: categoryName,
60305
- sortOrder: ASCENDING,
60306
- scaleType: RANKING$1
60307
- };
60308
- generateLineUps({
60309
- singlesOnly: true,
60310
- tournamentRecord,
60311
- drawDefinition,
60312
- scaleAccessor,
60313
- attach: true,
60314
- event
60315
- });
60316
- } else {
60317
- const structureId = firstRoundDualMatchUps[0]?.structureId;
60318
- const { positionAssignments } = getPositionAssignments$1({
60319
- drawDefinition,
60320
- structureId
60321
- });
60322
- if (positionAssignments?.length) {
60323
- const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
60324
- participantFilters: { participantTypes: [TEAM$2] },
60325
- tournamentRecord
60326
- });
60327
- const assignParticipants = (dualMatchUp) => {
60328
- const singlesMatchUps = dualMatchUp.tieMatchUps.filter(
60329
- ({ matchUpType }) => matchUpType === SINGLES$1
60330
- );
60331
- const doublesMatchUps = dualMatchUp.tieMatchUps.filter(
60332
- ({ matchUpType }) => matchUpType === DOUBLES$1
60333
- );
60334
- singlesMatchUps.forEach((singlesMatchUp, i) => {
60335
- const tieMatchUpId = singlesMatchUp.matchUpId;
60336
- singlesMatchUp.sides.forEach((side) => {
60337
- const { drawPosition } = side;
60338
- const teamParticipant = teamParticipants?.find(
60339
- (teamParticipant2) => {
60340
- const { participantId } = teamParticipant2;
60341
- const assignment = positionAssignments.find(
60342
- (assignment2) => assignment2.participantId === participantId
60343
- );
60344
- return assignment?.drawPosition === drawPosition;
60345
- }
60346
- );
60347
- if (teamParticipant) {
60348
- const individualParticipantId = teamParticipant.individualParticipantIds[i];
60349
- assignTieMatchUpParticipantId({
60350
- teamParticipantId: teamParticipant.participantId,
60351
- participantId: individualParticipantId,
60352
- tournamentRecord,
60353
- drawDefinition,
60354
- tieMatchUpId,
60355
- event
60356
- });
60357
- }
60358
- });
60359
- });
60360
- doublesMatchUps.forEach((doublesMatchUp, i) => {
60361
- const tieMatchUpId = doublesMatchUp.matchUpId;
60362
- doublesMatchUp.sides.forEach((side) => {
60363
- const { drawPosition } = side;
60364
- const teamParticipant = teamParticipants?.find(
60365
- (teamParticipant2) => {
60366
- const { participantId } = teamParticipant2;
60367
- const assignment = positionAssignments.find(
60368
- (assignment2) => assignment2.participantId === participantId
60369
- );
60370
- return assignment?.drawPosition === drawPosition;
60371
- }
60372
- );
60373
- if (teamParticipant) {
60374
- const individualParticipantIds = teamParticipant.individualParticipantIds.slice(
60375
- i * 2,
60376
- i * 2 + 2
60377
- );
60378
- individualParticipantIds.forEach((individualParticipantId) => {
60379
- assignTieMatchUpParticipantId({
60380
- teamParticipantId: teamParticipant.participantId,
60381
- participantId: individualParticipantId,
60382
- tournamentRecord,
60383
- drawDefinition,
60384
- tieMatchUpId,
60385
- event
60386
- });
60387
- });
60388
- }
60389
- });
60390
- });
60391
- };
60392
- firstRoundDualMatchUps.forEach(assignParticipants);
60393
- }
60394
- }
60395
- }
60396
- const scoreString = typeof completeAllMatchUps === "string" && completeAllMatchUps;
60397
- const matchUpStatus = scoreString && COMPLETED$1;
60398
- for (const structure of sortedStructures) {
60399
- if (completedCount >= completionGoal)
60400
- break;
60401
- const { matchUps } = getAllStructureMatchUps({
60402
- matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
60403
- afterRecoveryTimes: false,
60404
- tournamentRecord,
60405
- inContext: true,
60406
- drawDefinition,
60407
- matchUpsMap,
60408
- structure,
60409
- event
60410
- });
60411
- const sortedMatchUpIds = matchUps.filter(({ winningSide }) => !winningSide).sort(matchUpSort).map(getMatchUpId);
60412
- for (const matchUpId of sortedMatchUpIds) {
60413
- if (!isNaN(completionGoal) && completedCount >= completionGoal)
60414
- break;
60415
- const { matchUps: matchUps2 } = getAllStructureMatchUps({
60416
- matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
60417
- afterRecoveryTimes: false,
60418
- tournamentRecord,
60419
- inContext: true,
60420
- drawDefinition,
60421
- matchUpsMap,
60422
- structure,
60423
- event
60424
- });
60425
- const targetMatchUp = matchUps2.find(
60426
- (matchUp) => matchUp.matchUpId === matchUpId
60427
- );
60428
- const isDoubleExit = [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(
60429
- targetMatchUp.matchUpStatus
60430
- );
60431
- if (targetMatchUp?.readyToScore && !isDoubleExit) {
60432
- const result = smartComplete({
60433
- winningSide: !randomWinningSide && 1,
60434
- matchUpStatusProfile,
60435
- tournamentRecord,
60436
- drawDefinition,
60437
- targetMatchUp,
60438
- matchUpFormat,
60439
- matchUpStatus,
60440
- scoreString,
60441
- event
60442
- });
60443
- if (result?.error)
60444
- return result;
60445
- completedCount += 1;
60446
- }
60447
- }
60448
- }
60449
- return { ...SUCCESS, completedCount };
60450
- }
60451
- function completeDrawMatchUp(params) {
60452
- const {
60453
- matchUpStatusCodes,
60454
- policyDefinitions,
60455
- tournamentRecord,
60456
- drawDefinition,
60457
- targetMatchUp,
60458
- matchUpStatus,
60459
- matchUpFormat,
60460
- scoreString,
60461
- winningSide,
60462
- event
60463
- } = params;
60464
- if (!targetMatchUp || targetMatchUp.matchUpStatus === BYE) {
60465
- return;
60466
- }
60467
- const { matchUpId } = targetMatchUp || {};
60468
- const { outcome } = generateOutcomeFromScoreString({
60469
- matchUpFormat,
60470
- matchUpStatus,
60471
- scoreString,
60472
- winningSide
60473
- });
60474
- if (matchUpStatusCodes)
60475
- outcome.matchUpStatusCodes = matchUpStatusCodes;
60476
- return setMatchUpStatus$1({
60477
- tournamentRecord,
60478
- policyDefinitions,
60479
- drawDefinition,
60480
- matchUpFormat,
60481
- matchUpId,
60482
- outcome,
60483
- event
60484
- });
60485
- }
60486
- function smartComplete(params) {
60487
- const {
60488
- matchUpStatusProfile = {},
60489
- tournamentRecord,
60490
- policyDefinitions,
60491
- drawDefinition,
60492
- matchUpStatus,
60493
- matchUpFormat,
60494
- targetMatchUp,
60495
- scoreString,
60496
- winningSide,
60497
- event
60498
- } = params;
60499
- if (scoreString || matchUpStatus)
60500
- return completeDrawMatchUp(params);
60501
- const { matchUpId } = targetMatchUp || {};
60502
- const { outcome } = generateOutcome({
60503
- matchUpStatusProfile,
60504
- matchUpFormat,
60505
- winningSide
60506
- });
60507
- return setMatchUpStatus$1({
60508
- policyDefinitions,
60509
- tournamentRecord,
60510
- drawDefinition,
60511
- matchUpFormat,
60512
- matchUpId,
60513
- outcome,
60514
- event
60515
- });
60516
- }
60517
-
60518
60569
  function generateFlightDrawDefinitions({
60519
60570
  matchUpStatusProfile,
60520
60571
  completeAllMatchUps,
@@ -62513,7 +62564,6 @@ const mocksGovernor = {
62513
62564
  generateOutcomeFromScoreString,
62514
62565
  generateTournamentRecord,
62515
62566
  generateEventWithDraw,
62516
- completeDrawMatchUps,
62517
62567
  generateParticipants,
62518
62568
  parseScoreString,
62519
62569
  generateOutcome,