tods-competition-factory 1.8.23 → 1.8.25

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
@@ -1021,6 +1021,10 @@ const SCHEDULED_MATCHUPS = {
1021
1021
  message: "Scheduled matchUps",
1022
1022
  code: "ERR_SCHEDULED_MATCHUPS"
1023
1023
  };
1024
+ const SCORES_PRESENT = {
1025
+ message: "Scores present",
1026
+ code: "ERR_SCORES_PRESENT"
1027
+ };
1024
1028
  const errorConditionConstants = {
1025
1029
  ANACHRONISM,
1026
1030
  CANNOT_CHANGE_WINNING_SIDE,
@@ -1183,6 +1187,7 @@ const errorConditionConstants = {
1183
1187
  POLICY_NOT_FOUND,
1184
1188
  SCHEDULE_NOT_CLEARED,
1185
1189
  SCHEDULED_MATCHUPS,
1190
+ SCORES_PRESENT,
1186
1191
  SEEDSCOUNT_GREATER_THAN_DRAW_SIZE,
1187
1192
  STAGE_SEQUENCE_LIMIT,
1188
1193
  STRUCTURE_NOT_FOUND,
@@ -2382,7 +2387,7 @@ const matchUpFormatCode = {
2382
2387
  };
2383
2388
 
2384
2389
  function factoryVersion() {
2385
- return "1.8.23";
2390
+ return "1.8.25";
2386
2391
  }
2387
2392
 
2388
2393
  function getObjectTieFormat(obj) {
@@ -3811,18 +3816,17 @@ function getTallyReport({ matchUps, order, report }) {
3811
3816
  readable.push(excluded);
3812
3817
  } else {
3813
3818
  const floatSort = (a, b) => parseFloat(step.reversed ? a : b) - parseFloat(step.reversed ? b : a);
3819
+ const participantsCount = step.groups ? Object.values(step.groups).flat(Infinity).length : step.participantIds?.length ?? 0;
3814
3820
  const getExplanation = (step2) => {
3815
- Object.keys(step2.groups).sort(floatSort).forEach((key) => {
3821
+ step2.groups && Object.keys(step2.groups).sort(floatSort).forEach((key) => {
3816
3822
  const participantNames = step2.groups[key].map((participantId) => participants[participantId]).join(", ");
3817
3823
  const explanation = `${key} ${step2.attribute}: ${participantNames}`;
3818
3824
  readable.push(explanation);
3819
3825
  });
3820
3826
  };
3821
3827
  const reversed = step.reversed ? " in reverse order" : "";
3822
- const participantsCount = Object.values(step.groups).flat(
3823
- Infinity
3824
- ).length;
3825
- const description = `Step ${i + 1}: ${participantsCount} particiants were grouped${reversed} by ${step.attribute}`;
3828
+ const action = step.groups ? "grouped" : "separated";
3829
+ const description = `Step ${i + 1}: ${participantsCount} particiants were ${action}${reversed} by ${step.attribute}`;
3826
3830
  readable.push(description);
3827
3831
  if (step.idsFilter) {
3828
3832
  const note = `${step.attribute} was calculated considering ONLY TIED PARTICIPANTS`;
@@ -3838,7 +3842,7 @@ function getTallyReport({ matchUps, order, report }) {
3838
3842
  const { participantId, resolved } = orderEntry;
3839
3843
  const pOrder = orderEntry.groupOrder || orderEntry.provisionalOrder;
3840
3844
  readable.push(
3841
- `${pOrder}: ${participants[participantId]} => resolved: ${resolved}`
3845
+ `${pOrder}: ${participants[participantId]} => resolved: ${!!resolved}`
3842
3846
  );
3843
3847
  });
3844
3848
  return readable.join("\r\n");
@@ -3927,7 +3931,7 @@ function getGroupOrder(params) {
3927
3931
  report.push({ attribute, groups: orderedTallyGroups });
3928
3932
  const groupOrder = Object.keys(orderedTallyGroups).map((key) => parseFloat(key)).sort((a, b) => b - a).map((key) => orderedTallyGroups[key]).map((participantIds) => {
3929
3933
  const result = groupSubSort({ participantIds, ...params });
3930
- report.push(result.report);
3934
+ report.push(...result.report || []);
3931
3935
  return result.order;
3932
3936
  }).flat(Infinity);
3933
3937
  let groupPosition = 1;
@@ -4019,7 +4023,7 @@ function processAttribute({
4019
4023
  tallyPolicy,
4020
4024
  matchUps
4021
4025
  });
4022
- report.push(result.report);
4026
+ report.push(...result.report || []);
4023
4027
  return result.order;
4024
4028
  }).flat(Infinity);
4025
4029
  }
@@ -4033,6 +4037,9 @@ function groupSubSort({
4033
4037
  tallyPolicy,
4034
4038
  matchUps
4035
4039
  }) {
4040
+ const excludedDirectives = [];
4041
+ const report = [];
4042
+ let result;
4036
4043
  if (participantIds?.length === 1) {
4037
4044
  const participantId = participantIds[0];
4038
4045
  return {
@@ -4041,13 +4048,13 @@ function groupSubSort({
4041
4048
  }
4042
4049
  if (participantIds?.length === 2 && (!tallyPolicy?.headToHead || !tallyPolicy.headToHead.disabled && !disableHeadToHead)) {
4043
4050
  const result2 = headToHeadWinner({ participantIds, participantResults });
4044
- if (result2)
4045
- return { order: [result2], headToHeadWinner: result2[0].participantId };
4051
+ if (result2) {
4052
+ const headToHeadWinner2 = result2[0].participantId;
4053
+ report.push({ attribute: "head2Head", participantIds, headToHeadWinner: headToHeadWinner2 });
4054
+ return { order: [result2], headToHeadWinner: headToHeadWinner2, report };
4055
+ }
4046
4056
  }
4047
4057
  const directives = tallyPolicy?.tallyDirectives || headToHeadTallyDirectives;
4048
- const excludedDirectives = [];
4049
- const report = [];
4050
- let result;
4051
4058
  const filteredDirectives = directives.filter((directive) => {
4052
4059
  const keepDirective = isNumeric(directive.maxParticipants) && participantIds?.length > directive.maxParticipants ? false : true;
4053
4060
  if (!keepDirective)
@@ -7775,7 +7782,8 @@ const POLICY_ROUND_NAMING_DEFAULT = {
7775
7782
  [POLICY_TYPE_ROUND_NAMING]: {
7776
7783
  policyName: "Round Naming Default",
7777
7784
  namingConventions: {
7778
- round: "Round"
7785
+ round: "Round",
7786
+ pre: "Pre"
7779
7787
  },
7780
7788
  qualifyingFinishMap: {
7781
7789
  1: "Final"
@@ -7819,12 +7827,11 @@ function getRoundContextProfile({
7819
7827
  const roundNamingProfile = {};
7820
7828
  const defaultRoundNamingPolicy = POLICY_ROUND_NAMING_DEFAULT[POLICY_TYPE_ROUND_NAMING];
7821
7829
  const isQualifying = structure.stage === QUALIFYING;
7822
- const qualifyingFinishgMap = isQualifying && (roundNamingPolicy?.qualifyingFinishMap || defaultRoundNamingPolicy?.qualifyingFinishMap || {});
7823
7830
  const qualifyingStageSequences = isQualifying ? Math.max(
7824
7831
  ...(drawDefinition?.structures ?? []).filter((structure2) => structure2.stage === QUALIFYING).map(({ stageSequence }) => stageSequence ?? 1),
7825
7832
  0
7826
7833
  ) : 0;
7827
- const preQualifyingSequence = qualifyingStageSequences ? qualifyingStageSequences - (structure.stageSequence ?? 1) || "" : "";
7834
+ const preQualifyingSequence = (structure.stageSequence ?? 1) < qualifyingStageSequences ? structure.stageSequence ?? 1 : "";
7828
7835
  const preQualifyingAffix = preQualifyingSequence ? roundNamingPolicy?.affixes?.preQualifying || defaultRoundNamingPolicy.affixes.preQualifying || "" : "";
7829
7836
  const roundNamingMap = roundNamingPolicy?.roundNamingMap || defaultRoundNamingPolicy.roundNamingMap || {};
7830
7837
  const abbreviatedRoundNamingMap = roundNamingPolicy?.abbreviatedRoundNamingMap || defaultRoundNamingPolicy.abbreviatedRoundNamingMap || {};
@@ -7848,6 +7855,7 @@ function getRoundContextProfile({
7848
7855
  })
7849
7856
  );
7850
7857
  } else {
7858
+ const qualifyingFinishgMap = isQualifying && (roundNamingPolicy?.qualifyingFinishMap || defaultRoundNamingPolicy?.qualifyingFinishMap || {});
7851
7859
  Object.assign(
7852
7860
  roundNamingProfile,
7853
7861
  ...roundProfileKeys.map((round) => {
@@ -10122,8 +10130,10 @@ function modifyMatchUpScore({
10122
10130
  const matchUpFilters = isDualMatchUp ? { matchUpTypes: [TEAM$2] } : void 0;
10123
10131
  const { matchUps } = getAllStructureMatchUps({
10124
10132
  afterRecoveryTimes: false,
10133
+ tournamentRecord,
10125
10134
  inContext: true,
10126
10135
  matchUpFilters,
10136
+ drawDefinition,
10127
10137
  structure: structure2,
10128
10138
  event
10129
10139
  });
@@ -23088,7 +23098,10 @@ function getAffectedTargetStructureIds({
23088
23098
  return { structureIds };
23089
23099
  }
23090
23100
 
23091
- function getPlayoffStructures({ drawDefinition, structureId }) {
23101
+ function getPlayoffStructures({
23102
+ drawDefinition,
23103
+ structureId
23104
+ }) {
23092
23105
  if (!drawDefinition)
23093
23106
  return { error: MISSING_DRAW_DEFINITION };
23094
23107
  const { structure } = findStructure({ drawDefinition, structureId });
@@ -23223,7 +23236,7 @@ function allPlayoffPositionsFilled(params) {
23223
23236
  return assignment?.bye || assignment?.participantId;
23224
23237
  }
23225
23238
  ).length;
23226
- return structurePositionsFilled && allFilled;
23239
+ return !!(structurePositionsFilled && allFilled);
23227
23240
  },
23228
23241
  !!playoffStructures.length
23229
23242
  );
@@ -43393,6 +43406,142 @@ function generateVoluntaryConsolation$1(params) {
43393
43406
  return { links, structures, ...SUCCESS };
43394
43407
  }
43395
43408
 
43409
+ function getStructureGroups({
43410
+ drawDefinition
43411
+ }) {
43412
+ const structures = drawDefinition.structures || [];
43413
+ const links = drawDefinition.links || [];
43414
+ const structureProfiles = /* @__PURE__ */ new Map();
43415
+ const initStructureProfile = (structureId) => {
43416
+ const profile = structureProfiles.get(structureId) || structureProfiles.set(structureId, {
43417
+ drawSources: [],
43418
+ drawTargets: [],
43419
+ progeny: [],
43420
+ sources: [],
43421
+ targets: []
43422
+ }) && structureProfiles.get(structureId);
43423
+ if (profile && !profile?.stage) {
43424
+ const structure = structures.find(
43425
+ (structure2) => structure2.structureId === structureId
43426
+ );
43427
+ profile.stage = structure?.stage;
43428
+ }
43429
+ return profile;
43430
+ };
43431
+ const sourceStructureIds = {};
43432
+ const hasDrawFeedProfile = {};
43433
+ let linkedStructureIds = links.map((link) => {
43434
+ const sourceId = link.source.structureId;
43435
+ const targetId = link.target.structureId;
43436
+ const sourceProfile = initStructureProfile(sourceId);
43437
+ const targetProfile = initStructureProfile(targetId);
43438
+ if ([BOTTOM_UP, TOP_DOWN, RANDOM, WATERFALL].includes(link.target.feedProfile)) {
43439
+ sourceProfile?.targets.push(targetId);
43440
+ targetProfile?.sources.push(sourceId);
43441
+ } else if (link.target.feedProfile === DRAW) {
43442
+ targetProfile?.drawSources.push(sourceId);
43443
+ sourceProfile?.drawTargets.push(targetId);
43444
+ }
43445
+ hasDrawFeedProfile[targetId] = hasDrawFeedProfile[targetId] || link.target.feedProfile === DRAW;
43446
+ sourceStructureIds[targetId] = unique([
43447
+ ...sourceStructureIds[targetId] || [],
43448
+ sourceId
43449
+ ]).filter(Boolean);
43450
+ return [link.source.structureId, link.target.structureId];
43451
+ });
43452
+ for (const structureId of structureProfiles.keys()) {
43453
+ const profile = structureProfiles.get(structureId);
43454
+ if (profile) {
43455
+ const sourceIds = profile.targets ?? [];
43456
+ while (sourceIds.length) {
43457
+ const sourceId = sourceIds.pop();
43458
+ const sourceProfile = sourceId && structureProfiles[sourceId];
43459
+ if (sourceProfile?.targets?.length) {
43460
+ sourceIds.push(...sourceProfile.targets);
43461
+ } else if (sourceProfile) {
43462
+ profile.rootStage = sourceProfile.stage;
43463
+ }
43464
+ }
43465
+ if (!profile.rootStage)
43466
+ profile.rootStage = profile.stage;
43467
+ if (!profile.targets?.length) {
43468
+ const targetIds = profile.sources ?? [];
43469
+ while (targetIds.length) {
43470
+ const targetId = targetIds.pop();
43471
+ const targetProfile = targetId && structureProfiles[targetId];
43472
+ if (targetProfile?.sources?.length) {
43473
+ for (const id of targetProfile.sources) {
43474
+ if (!profile.progeny?.includes(id))
43475
+ profile.progeny?.push(id);
43476
+ }
43477
+ targetIds.push(...targetProfile.sources);
43478
+ }
43479
+ }
43480
+ }
43481
+ }
43482
+ }
43483
+ let maxQualifyingDepth = 0;
43484
+ for (const structureId of structureProfiles.keys()) {
43485
+ const profile = structureProfiles.get(structureId);
43486
+ if (profile && profile.rootStage === QUALIFYING) {
43487
+ const drawTargets = [profile.drawTargets?.[0]];
43488
+ let distanceFromMain = 0;
43489
+ while (drawTargets.length) {
43490
+ distanceFromMain += 1;
43491
+ const drawTarget = drawTargets.pop();
43492
+ const targetProfile = drawTarget ? structureProfiles.get(drawTarget) : void 0;
43493
+ if (targetProfile?.drawTargets?.length) {
43494
+ drawTargets.push(targetProfile.drawTargets[0]);
43495
+ }
43496
+ }
43497
+ profile.distanceFromMain = distanceFromMain;
43498
+ if (distanceFromMain > maxQualifyingDepth)
43499
+ maxQualifyingDepth = distanceFromMain;
43500
+ }
43501
+ }
43502
+ const iterations = linkedStructureIds.length;
43503
+ generateRange(0, Math.ceil(iterations / 2)).forEach(() => {
43504
+ linkedStructureIds = generateRange(0, iterations).map((index) => {
43505
+ const structureIds = linkedStructureIds[index];
43506
+ const mergedWithOverlappingIds = linkedStructureIds.reduce((biggest, ids) => {
43507
+ const hasOverlap = overlap(structureIds, ids);
43508
+ return hasOverlap ? biggest.concat(...ids) : biggest;
43509
+ }, []) || [];
43510
+ return unique(structureIds.concat(...mergedWithOverlappingIds));
43511
+ });
43512
+ });
43513
+ const groupedStructureIds = linkedStructureIds[0];
43514
+ const identityLink = (a, b) => intersection(a, b).length === a.length;
43515
+ const allLinkStructuresLinked = linkedStructureIds.slice(1).reduce((allLinkStructuresLinked2, ids) => {
43516
+ return allLinkStructuresLinked2 && identityLink(ids, groupedStructureIds);
43517
+ }, true);
43518
+ const structureGroups = [groupedStructureIds].filter(Boolean);
43519
+ const linkCheck = [groupedStructureIds].filter(Boolean);
43520
+ structures.forEach((structure) => {
43521
+ const { structureId, stage } = structure;
43522
+ const existingGroup = structureGroups.find((group) => {
43523
+ return group.includes(structureId);
43524
+ });
43525
+ if (!existingGroup) {
43526
+ structureGroups.push([structureId]);
43527
+ if (stage !== VOLUNTARY_CONSOLATION)
43528
+ linkCheck.push([structureId]);
43529
+ }
43530
+ });
43531
+ const allStructuresLinked = allLinkStructuresLinked && linkCheck.length === 1;
43532
+ if (!links?.length && structures.length === 1) {
43533
+ initStructureProfile(structures[0].structureId);
43534
+ }
43535
+ return {
43536
+ structureProfiles: Object.fromEntries(structureProfiles),
43537
+ allStructuresLinked,
43538
+ maxQualifyingDepth,
43539
+ sourceStructureIds,
43540
+ hasDrawFeedProfile,
43541
+ structureGroups
43542
+ };
43543
+ }
43544
+
43396
43545
  function generateQualifyingStructure$1(params) {
43397
43546
  if (!params.drawDefinition)
43398
43547
  return { error: MISSING_DRAW_DEFINITION };
@@ -43417,65 +43566,25 @@ function generateQualifyingStructure$1(params) {
43417
43566
  let roundLimit, roundsCount, structure, matchUps;
43418
43567
  let qualifiersCount = 0;
43419
43568
  let finishingPositions;
43420
- let stageSequence = 1;
43569
+ const stageSequence = 1;
43421
43570
  if (!isConvertableInteger(drawSize)) {
43422
43571
  return decorateResult({ result: { error: MISSING_DRAW_SIZE }, stack });
43423
43572
  }
43424
- const result = findStructure({
43425
- structureId: targetStructureId,
43426
- drawDefinition
43427
- });
43428
- if (result.error) {
43573
+ const { structureProfiles } = getStructureGroups({ drawDefinition });
43574
+ const structureProfile = structureProfiles[targetStructureId];
43575
+ if (!structureProfile) {
43429
43576
  return decorateResult({
43577
+ result: { error: STRUCTURE_NOT_FOUND },
43430
43578
  context: { targetStructureId },
43431
- result,
43432
43579
  stack
43433
43580
  });
43434
43581
  }
43435
- if (!result.structure)
43436
- return { error: STRUCTURE_NOT_FOUND };
43437
- const targetStructure = result.structure;
43438
- const matchUpType = targetStructure.matchUpType;
43439
- if (targetStructure.stage === QUALIFYING) {
43440
- if (targetStructure.stageSequence && targetStructure.stageSequence > 1) {
43441
- stageSequence = targetStructure.stageSequence - 1;
43442
- } else {
43443
- let nextStructureId = targetStructureId;
43444
- let nextStageSequence = 2;
43445
- let chainModified;
43446
- while (!chainModified && nextStructureId) {
43447
- console.log("check getRoundContextProfile preqQualifyingStageSequence");
43448
- targetStructure.stageSequence = nextStageSequence;
43449
- const targetTargetStructureId = drawDefinition.links?.find(
43450
- (link2) => link2.source.structureId === nextStructureId
43451
- )?.target?.structureId;
43452
- nextStructureId = targetTargetStructureId;
43453
- nextStageSequence += 1;
43454
- if (!targetTargetStructureId) {
43455
- chainModified = true;
43456
- } else {
43457
- const result2 = findStructure({
43458
- structureId: targetTargetStructureId,
43459
- drawDefinition
43460
- });
43461
- if (!result2.structure)
43462
- return { error: STRUCTURE_NOT_FOUND };
43463
- if (result2.error) {
43464
- return decorateResult({
43465
- context: { targetTargetStructureId },
43466
- result: result2,
43467
- stack
43468
- });
43469
- }
43470
- if (result2.structure.stage !== QUALIFYING)
43471
- chainModified = true;
43472
- }
43473
- }
43474
- }
43475
- }
43582
+ const matchUpType = drawDefinition.matchUpType;
43476
43583
  const roundTargetName = roundTarget ? `${roundTarget}-` : "";
43477
- const stageSequenceName = `${stageSequence}`;
43478
- const qualifyingStructureName = structureName ?? (roundTargetName || stageSequenceName ? `${constantToString(QUALIFYING)} ${roundTargetName}${stageSequenceName}` : constantToString(QUALIFYING));
43584
+ const isPreQualifying = structureProfile.stage === QUALIFYING;
43585
+ const preQualifyingNaming = appliedPolicies?.[POLICY_TYPE_ROUND_NAMING]?.namingConventions?.pre ?? POLICY_ROUND_NAMING_DEFAULT[POLICY_TYPE_ROUND_NAMING]?.namingConventions?.pre;
43586
+ const pre = isPreQualifying && preQualifyingNaming ? `${preQualifyingNaming}-` : "";
43587
+ const qualifyingStructureName = structureName ?? (roundTargetName ? `${pre}${constantToString(QUALIFYING)} ${roundTargetName}` : `${pre}${constantToString(QUALIFYING)}`);
43479
43588
  if (drawType === ROUND_ROBIN) {
43480
43589
  const { maxRoundNumber, structures, groupCount } = generateRoundRobin({
43481
43590
  structureName: structureName ?? qualifyingStructureName,
@@ -43530,13 +43639,13 @@ function generateQualifyingStructure$1(params) {
43530
43639
  )?.length;
43531
43640
  }
43532
43641
  const linkType = drawType === ROUND_ROBIN ? LinkTypeEnum.Position : LinkTypeEnum.Winner;
43533
- const { link } = generateQualifyingLink({
43642
+ const link = structure && roundLimit && generateQualifyingLink({
43534
43643
  sourceStructureId: structure.structureId,
43535
43644
  sourceRoundNumber: roundLimit,
43536
43645
  targetStructureId,
43537
43646
  finishingPositions,
43538
43647
  linkType
43539
- });
43648
+ })?.link;
43540
43649
  return {
43541
43650
  qualifyingDrawPositionsCount: drawSize,
43542
43651
  qualifiersCount,
@@ -43546,6 +43655,19 @@ function generateQualifyingStructure$1(params) {
43546
43655
  };
43547
43656
  }
43548
43657
 
43658
+ function resequenceStructures({ drawDefinition }) {
43659
+ const { maxQualifyingDepth, structureProfiles } = getStructureGroups({
43660
+ drawDefinition
43661
+ });
43662
+ for (const structure of drawDefinition.structures) {
43663
+ const profile = structureProfiles[structure.structureId];
43664
+ if (profile.distanceFromMain) {
43665
+ structure.stageSequence = maxQualifyingDepth + 1 - profile.distanceFromMain;
43666
+ }
43667
+ }
43668
+ return { ...SUCCESS };
43669
+ }
43670
+
43549
43671
  function attachQualifyingStructure$1({
43550
43672
  drawDefinition,
43551
43673
  tournamentId,
@@ -43576,6 +43698,7 @@ function attachQualifyingStructure$1({
43576
43698
  drawDefinition.links = [];
43577
43699
  drawDefinition.structures.push(structure);
43578
43700
  drawDefinition.links.push(link);
43701
+ resequenceStructures({ drawDefinition });
43579
43702
  const matchUps = getAllStructureMatchUps({ structure })?.matchUps || [];
43580
43703
  addMatchUpsNotice({
43581
43704
  drawDefinition,
@@ -43799,6 +43922,10 @@ function getAdvancingParticipantId(matchUp) {
43799
43922
  }
43800
43923
 
43801
43924
  function addQualifyingStructure$1(params) {
43925
+ if (!params.drawDefinition)
43926
+ return { error: MISSING_DRAW_DEFINITION };
43927
+ if (!params.targetStructureId)
43928
+ return { error: MISSING_STRUCTURE_ID };
43802
43929
  const result = generateQualifyingStructure$1(params);
43803
43930
  if (result.error)
43804
43931
  return result;
@@ -44082,7 +44209,8 @@ function removeStructure({
44082
44209
  tournamentRecord,
44083
44210
  drawDefinition,
44084
44211
  structureId,
44085
- event
44212
+ event,
44213
+ force
44086
44214
  }) {
44087
44215
  if (typeof structureId !== "string")
44088
44216
  return { error: INVALID_VALUES };
@@ -44092,10 +44220,21 @@ function removeStructure({
44092
44220
  return { error: MISSING_STRUCTURE_ID };
44093
44221
  const structures = drawDefinition.structures || [];
44094
44222
  const removedStructureIds = [];
44223
+ const structure = structures.find(
44224
+ (structure2) => structure2.structureId === structureId
44225
+ );
44226
+ if (!structure)
44227
+ return { error: STRUCTURE_NOT_FOUND };
44228
+ const structureMatchUps = getAllStructureMatchUps({ structure }).matchUps;
44229
+ const scoresPresent = structureMatchUps.some(
44230
+ ({ score }) => scoreHasValue({ score })
44231
+ );
44232
+ if (scoresPresent && !force)
44233
+ return { error: SCORES_PRESENT };
44095
44234
  const mainStageSequence1 = structures.find(
44096
44235
  ({ stage, stageSequence }) => stage === MAIN && stageSequence === 1
44097
44236
  );
44098
- const isMainStageSequence1 = structureId === mainStageSequence1.structureId;
44237
+ const isMainStageSequence1 = structureId === mainStageSequence1?.structureId;
44099
44238
  const qualifyingStructureIds = structures.filter(({ stage }) => stage === QUALIFYING).map(extractAttributes("structureId"));
44100
44239
  if (isMainStageSequence1 && !qualifyingStructureIds.length) {
44101
44240
  return { error: CANNOT_REMOVE_MAIN_STRUCTURE };
@@ -44104,11 +44243,11 @@ function removeStructure({
44104
44243
  const removedMatchUpIds = [];
44105
44244
  const idsToRemove = [structureId];
44106
44245
  const getTargetedStructureIds = (structureId2) => drawDefinition.links?.map(
44107
- (link) => link.source.structureId === structureId2 && link.target.structureId !== mainStageSequence1.structureId && link.target.structureId
44108
- ).filter(Boolean);
44246
+ (link) => link.source.structureId === structureId2 && link.target.structureId !== mainStageSequence1?.structureId && link.target.structureId
44247
+ ).filter(Boolean) ?? [];
44109
44248
  const getQualifyingSourceStructureIds = (structureId2) => drawDefinition.links?.map(
44110
44249
  (link) => qualifyingStructureIds.includes(link.source.structureId) && link.target.structureId === structureId2 && link.source.structureId
44111
- ).filter(Boolean);
44250
+ ).filter(Boolean) ?? [];
44112
44251
  const isQualifyingStructure = qualifyingStructureIds.includes(structureId);
44113
44252
  const relatedStructureIdsMap = /* @__PURE__ */ new Map();
44114
44253
  structureIds.forEach(
@@ -44119,11 +44258,11 @@ function removeStructure({
44119
44258
  );
44120
44259
  while (idsToRemove.length) {
44121
44260
  const idBeingRemoved = idsToRemove.pop();
44122
- const { structure } = findStructure({
44261
+ const { structure: structure2 } = findStructure({
44123
44262
  structureId: idBeingRemoved,
44124
44263
  drawDefinition
44125
44264
  });
44126
- const { matchUps: matchUps2 } = getAllStructureMatchUps({ structure });
44265
+ const { matchUps: matchUps2 } = getAllStructureMatchUps({ structure: structure2 });
44127
44266
  const matchUpIds = getMatchUpIds(matchUps2);
44128
44267
  removedMatchUpIds.push(...matchUpIds);
44129
44268
  drawDefinition.links = drawDefinition.links?.filter(
@@ -44131,10 +44270,10 @@ function removeStructure({
44131
44270
  ) || [];
44132
44271
  if (!isMainStageSequence1 || idBeingRemoved !== structureId) {
44133
44272
  drawDefinition.structures = (drawDefinition.structures ?? []).filter(
44134
- (structure2) => {
44135
- if (idBeingRemoved && idBeingRemoved === structure2.structureId)
44273
+ (structure3) => {
44274
+ if (idBeingRemoved && idBeingRemoved === structure3.structureId)
44136
44275
  removedStructureIds.push(idBeingRemoved);
44137
- return structure2.structureId !== idBeingRemoved;
44276
+ return structure3.structureId !== idBeingRemoved;
44138
44277
  }
44139
44278
  );
44140
44279
  }
@@ -44142,7 +44281,7 @@ function removeStructure({
44142
44281
  relatedStructureIdsMap.get(idBeingRemoved)?.filter(
44143
44282
  (id) => (
44144
44283
  // IMPORTANT: only delete MAIN stageSequence: 1 if specified to protect against DOUBLE_ELIMINATION scenario
44145
- id !== mainStageSequence1.structureId || structureId === mainStageSequence1.structureId
44284
+ id !== mainStageSequence1?.structureId || structureId === mainStageSequence1.structureId
44146
44285
  )
44147
44286
  );
44148
44287
  if (targetedStructureIds?.length)
@@ -44165,6 +44304,7 @@ function removeStructure({
44165
44304
  mainStageSequence1.extensions = [];
44166
44305
  }
44167
44306
  }
44307
+ isQualifyingStructure && resequenceStructures({ drawDefinition });
44168
44308
  deleteMatchUpsNotice({
44169
44309
  tournamentId: tournamentRecord?.tournamentId,
44170
44310
  matchUpIds: removedMatchUpIds,
@@ -52351,59 +52491,6 @@ function unPublishEvent({
52351
52491
  return { eventId: event.eventId, ...SUCCESS };
52352
52492
  }
52353
52493
 
52354
- function getStructureGroups({ drawDefinition }) {
52355
- const links = drawDefinition.links || [];
52356
- const sourceStructureIds = {};
52357
- const hasDrawFeedProfile = {};
52358
- let linkedStructureIds = links.map((link) => {
52359
- const sourceId = link.source.structureId;
52360
- const targetId = link.target.structureId;
52361
- hasDrawFeedProfile[targetId] = hasDrawFeedProfile[targetId] || link.target.feedProfile === DRAW;
52362
- sourceStructureIds[targetId] = unique([
52363
- ...sourceStructureIds[targetId] || [],
52364
- sourceId
52365
- ]).filter(Boolean);
52366
- return [link.source.structureId, link.target.structureId];
52367
- });
52368
- const iterations = linkedStructureIds.length;
52369
- generateRange(0, Math.ceil(iterations / 2)).forEach(() => {
52370
- linkedStructureIds = generateRange(0, iterations).map((index) => {
52371
- const structureIds = linkedStructureIds[index];
52372
- const mergedWithOverlappingIds = linkedStructureIds.reduce((biggest, ids) => {
52373
- const hasOverlap = overlap(structureIds, ids);
52374
- return hasOverlap ? biggest.concat(...ids) : biggest;
52375
- }, []) || [];
52376
- return unique(structureIds.concat(...mergedWithOverlappingIds));
52377
- });
52378
- });
52379
- const groupedStructureIds = linkedStructureIds[0];
52380
- const identityLink = (a, b) => intersection(a, b).length === a.length;
52381
- const allLinkStructuresLinked = linkedStructureIds.slice(1).reduce((allLinkStructuresLinked2, ids) => {
52382
- return allLinkStructuresLinked2 && identityLink(ids, groupedStructureIds);
52383
- }, true);
52384
- const structureGroups = [groupedStructureIds].filter(Boolean);
52385
- const linkCheck = [groupedStructureIds].filter(Boolean);
52386
- const structures = drawDefinition.structures || [];
52387
- structures.forEach((structure) => {
52388
- const { structureId, stage } = structure;
52389
- const existingGroup = structureGroups.find((group) => {
52390
- return group.includes(structureId);
52391
- });
52392
- if (!existingGroup) {
52393
- structureGroups.push([structureId]);
52394
- if (stage !== VOLUNTARY_CONSOLATION)
52395
- linkCheck.push(structureId);
52396
- }
52397
- });
52398
- const allStructuresLinked = allLinkStructuresLinked && linkCheck.length === 1;
52399
- return {
52400
- allStructuresLinked,
52401
- sourceStructureIds,
52402
- hasDrawFeedProfile,
52403
- structureGroups
52404
- };
52405
- }
52406
-
52407
52494
  function getDrawData(params) {
52408
52495
  const {
52409
52496
  tournamentParticipants = [],
@@ -52462,12 +52549,18 @@ function getDrawData(params) {
52462
52549
  }
52463
52550
  return structure;
52464
52551
  }).sort((a, b) => structureSort(a, b, sortConfig)).map((structure) => {
52465
- const { structureId } = structure;
52552
+ if (!structure)
52553
+ return;
52554
+ const structureId = structure?.structureId;
52466
52555
  let seedAssignments = [];
52467
- if ([MAIN, CONSOLATION, PLAY_OFF].includes(structure.stage)) {
52556
+ if (structure.stage && [
52557
+ StageTypeEnum.Main,
52558
+ StageTypeEnum.Consolation,
52559
+ StageTypeEnum.PlayOff
52560
+ ].includes(structure.stage)) {
52468
52561
  seedAssignments = mainStageSeedAssignments;
52469
52562
  }
52470
- if (structure.stage === QUALIFYING) {
52563
+ if (structure?.stage === QUALIFYING) {
52471
52564
  seedAssignments = qualificationStageSeedAssignments;
52472
52565
  }
52473
52566
  const { matchUps, roundMatchUps, roundProfile } = getAllStructureMatchUps({
@@ -52498,7 +52591,7 @@ function getDrawData(params) {
52498
52591
  participantResult: extension.value
52499
52592
  };
52500
52593
  }).filter((f) => f?.participantResult);
52501
- const structureInfo = (({
52594
+ const structureInfo = structure ? (({
52502
52595
  stageSequence,
52503
52596
  structureName,
52504
52597
  structureType,
@@ -52510,7 +52603,7 @@ function getDrawData(params) {
52510
52603
  structureType,
52511
52604
  matchUpFormat,
52512
52605
  stage
52513
- }))(structure);
52606
+ }))(structure) : {};
52514
52607
  structureInfo.sourceStructureIds = sourceStructureIds[structureId];
52515
52608
  structureInfo.hasDrawFeedProfile = hasDrawFeedProfile[structureId];
52516
52609
  structureInfo.positionAssignments = positionAssignments;
@@ -54627,7 +54720,7 @@ function getEntryStatusReports({
54627
54720
  drawDefinitionsCount += 1;
54628
54721
  const stageFilter = ({ stage, stageSequence }) => stage === MAIN && stageSequence === 1 || stage === QUALIFYING;
54629
54722
  const structures = params.structures ?? [];
54630
- const assignedParticipantIds = structures.filter(stageFilter).flatMap(({ positionAssignments }) => positionAssignments).map(({ participantId }) => participantId).filter(Boolean);
54723
+ const assignedParticipantIds = structures.filter(stageFilter).flatMap(({ positionAssignments }) => positionAssignments).filter(Boolean).map(({ participantId }) => participantId);
54631
54724
  const entryFilter = ({ participantId }) => assignedParticipantIds.includes(participantId);
54632
54725
  const createEntryProfile = (params2) => {
54633
54726
  const { participantId, entryStatus, entryStage } = params2;
@@ -59444,7 +59537,10 @@ function isValidForQualifying({ structureId, drawDefinition }) {
59444
59537
  if (result.error)
59445
59538
  return result;
59446
59539
  const targetFeedProfiles = result.links.target.flatMap((t) => t.target.feedProfile).filter(Boolean);
59447
- const valid = !intersection([BOTTOM_UP, TOP_DOWN, RANDOM], targetFeedProfiles).length;
59540
+ const valid = !intersection(
59541
+ [BOTTOM_UP, TOP_DOWN, RANDOM, WATERFALL],
59542
+ targetFeedProfiles
59543
+ ).length;
59448
59544
  return { ...SUCCESS, valid };
59449
59545
  }
59450
59546