tods-competition-factory 1.6.22 → 1.6.23
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/forge/generate.d.ts +55 -6
- package/dist/forge/generate.mjs +911 -844
- package/dist/forge/generate.mjs.map +1 -1
- package/dist/forge/query.mjs +10 -10
- package/dist/forge/query.mjs.map +1 -1
- package/dist/forge/transform.mjs +10 -10
- package/dist/forge/transform.mjs.map +1 -1
- package/dist/index.mjs +91 -23
- package/dist/index.mjs.map +1 -1
- package/dist/tods-competition-factory.development.cjs.js +84 -30
- package/dist/tods-competition-factory.development.cjs.js.map +1 -1
- package/dist/tods-competition-factory.production.cjs.min.js +1 -1
- package/dist/tods-competition-factory.production.cjs.min.js.map +1 -1
- package/package.json +2 -2
package/dist/forge/generate.mjs
CHANGED
|
@@ -8053,25 +8053,25 @@ function targetByRoundOutcome({
|
|
|
8053
8053
|
matchUp,
|
|
8054
8054
|
targetLinks: { loserTargetLink, winnerTargetLink, byeTargetLink },
|
|
8055
8055
|
targetMatchUps: {
|
|
8056
|
-
|
|
8057
|
-
loserMatchUp,
|
|
8058
|
-
winnerMatchUp,
|
|
8059
|
-
byeTargetDrawPosition,
|
|
8060
|
-
loserTargetDrawPosition,
|
|
8061
|
-
winnerTargetDrawPosition,
|
|
8062
|
-
byeMatchUpDrawPositionIndex,
|
|
8056
|
+
winnerMatchUpDrawPositionIndex,
|
|
8063
8057
|
loserMatchUpDrawPositionIndex,
|
|
8064
|
-
|
|
8058
|
+
byeMatchUpDrawPositionIndex,
|
|
8059
|
+
winnerTargetDrawPosition,
|
|
8060
|
+
loserTargetDrawPosition,
|
|
8061
|
+
byeTargetDrawPosition,
|
|
8062
|
+
winnerMatchUp,
|
|
8063
|
+
loserMatchUp,
|
|
8064
|
+
byeMatchUp
|
|
8065
8065
|
},
|
|
8066
8066
|
targetMatchUpIds: !!(winnerMatchUpId || loserMatchUpId)
|
|
8067
8067
|
});
|
|
8068
8068
|
}
|
|
8069
8069
|
function targetByWinRatio({ matchUp }) {
|
|
8070
8070
|
return {
|
|
8071
|
-
matchUp,
|
|
8072
8071
|
targetLinks: { loserTargetLink: void 0, winnerTargetLink: void 0 },
|
|
8073
8072
|
// returned for testing
|
|
8074
|
-
targetMatchUps: { loserMatchUp: void 0, winnerMatchUp: void 0 }
|
|
8073
|
+
targetMatchUps: { loserMatchUp: void 0, winnerMatchUp: void 0 },
|
|
8074
|
+
matchUp
|
|
8075
8075
|
};
|
|
8076
8076
|
}
|
|
8077
8077
|
|
|
@@ -17488,6 +17488,36 @@ function generateAndPopulatePlayoffStructures(params) {
|
|
|
17488
17488
|
if (result.error)
|
|
17489
17489
|
console.log(result.error);
|
|
17490
17490
|
});
|
|
17491
|
+
const byeMatchUps = inContextDrawMatchUps?.filter(
|
|
17492
|
+
(matchUp) => matchUp.matchUpStatus === BYE && matchUp.structureId === sourceStructureId
|
|
17493
|
+
);
|
|
17494
|
+
byeMatchUps?.forEach((matchUp) => {
|
|
17495
|
+
const { matchUpId } = matchUp;
|
|
17496
|
+
const targetData = positionTargets({
|
|
17497
|
+
inContextDrawMatchUps,
|
|
17498
|
+
drawDefinition,
|
|
17499
|
+
matchUpId
|
|
17500
|
+
});
|
|
17501
|
+
const {
|
|
17502
|
+
targetLinks: { loserTargetLink },
|
|
17503
|
+
targetMatchUps: {
|
|
17504
|
+
loserMatchUpDrawPositionIndex,
|
|
17505
|
+
// only present when positionTargets found without loserMatchUpId
|
|
17506
|
+
loserMatchUp
|
|
17507
|
+
}
|
|
17508
|
+
} = targetData;
|
|
17509
|
+
const targetStructureId = loserTargetLink.target.structureId;
|
|
17510
|
+
const targetDrawPosition = loserMatchUp.drawPositions[loserMatchUpDrawPositionIndex];
|
|
17511
|
+
const result = assignDrawPositionBye({
|
|
17512
|
+
drawPosition: targetDrawPosition,
|
|
17513
|
+
structureId: targetStructureId,
|
|
17514
|
+
tournamentRecord,
|
|
17515
|
+
drawDefinition,
|
|
17516
|
+
event
|
|
17517
|
+
});
|
|
17518
|
+
if (result.error)
|
|
17519
|
+
console.log(result.error);
|
|
17520
|
+
});
|
|
17491
17521
|
const matchUpModifications = [];
|
|
17492
17522
|
const goesToMap = addGoesTo({
|
|
17493
17523
|
inContextDrawMatchUps,
|
|
@@ -19545,188 +19575,600 @@ function generateVoluntaryConsolation(params) {
|
|
|
19545
19575
|
return generateVoluntaryConsolation$1({ participants: tournamentParticipants, ...params });
|
|
19546
19576
|
}
|
|
19547
19577
|
|
|
19548
|
-
function
|
|
19549
|
-
|
|
19550
|
-
|
|
19551
|
-
|
|
19552
|
-
|
|
19553
|
-
|
|
19554
|
-
|
|
19578
|
+
function generateCandidate({
|
|
19579
|
+
maxIterations = 5e3,
|
|
19580
|
+
// cap the processing intensity of the candidate generator
|
|
19581
|
+
valueSortedPairings,
|
|
19582
|
+
// pairings sorted by value from low to high
|
|
19583
|
+
pairingValues,
|
|
19584
|
+
deltaObjects
|
|
19555
19585
|
}) {
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
19562
|
-
|
|
19563
|
-
|
|
19564
|
-
},
|
|
19565
|
-
target: {
|
|
19566
|
-
feedProfile: DRAW,
|
|
19567
|
-
// positions are not automatically placed
|
|
19568
|
-
roundNumber: targetEntryRound,
|
|
19569
|
-
structureId: targetStructureId
|
|
19570
|
-
}
|
|
19586
|
+
const rankedMatchUpValues = Object.assign(
|
|
19587
|
+
{},
|
|
19588
|
+
...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
|
|
19589
|
+
);
|
|
19590
|
+
let candidate = roundCandidate({
|
|
19591
|
+
rankedMatchUpValues,
|
|
19592
|
+
valueSortedPairings,
|
|
19593
|
+
deltaObjects
|
|
19571
19594
|
});
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
for (const structureProfile of (structureProfiles || []).sort(
|
|
19594
|
-
sequenceSort
|
|
19595
|
-
)) {
|
|
19596
|
-
let drawSize = structureProfile.drawSize || coerceEven(structureProfile.participantsCount);
|
|
19597
|
-
const {
|
|
19598
|
-
qualifyingRoundNumber,
|
|
19599
|
-
qualifyingPositions,
|
|
19600
|
-
structureOptions,
|
|
19601
|
-
matchUpFormat,
|
|
19602
|
-
structureName,
|
|
19603
|
-
structureId,
|
|
19604
|
-
drawType
|
|
19605
|
-
} = structureProfile;
|
|
19606
|
-
const matchUpType = structureProfile.matchUpType;
|
|
19607
|
-
let roundLimit, structure, matchUps;
|
|
19608
|
-
if (!isConvertableInteger(drawSize)) {
|
|
19609
|
-
return decorateResult({
|
|
19610
|
-
result: { error: MISSING_DRAW_SIZE },
|
|
19611
|
-
stack
|
|
19612
|
-
});
|
|
19613
|
-
}
|
|
19614
|
-
const roundTargetName = qualifyingProfiles.length > 1 ? `${roundTarget}-` : "";
|
|
19615
|
-
const stageSequenceName = structureProfiles.length > 1 || roundTargetName ? stageSequence : "";
|
|
19616
|
-
const qualifyingStructureName = structureName || (roundTargetName || stageSequenceName ? `${QUALIFYING} ${roundTargetName}${stageSequenceName}` : QUALIFYING);
|
|
19617
|
-
if (drawType === ROUND_ROBIN) {
|
|
19618
|
-
const {
|
|
19619
|
-
structures: structures2,
|
|
19620
|
-
groupCount,
|
|
19621
|
-
maxRoundNumber
|
|
19622
|
-
/*, groupSize*/
|
|
19623
|
-
} = generateRoundRobin({
|
|
19624
|
-
structureName: structureProfile.structureName || qualifyingStructureName,
|
|
19625
|
-
structureId: structureId || uuids?.pop(),
|
|
19626
|
-
// qualifyingPositions,
|
|
19627
|
-
stage: QUALIFYING,
|
|
19628
|
-
structureOptions,
|
|
19629
|
-
appliedPolicies,
|
|
19630
|
-
stageSequence,
|
|
19631
|
-
matchUpType,
|
|
19632
|
-
roundTarget,
|
|
19633
|
-
drawSize,
|
|
19634
|
-
idPrefix,
|
|
19635
|
-
isMock,
|
|
19636
|
-
uuids
|
|
19637
|
-
});
|
|
19638
|
-
targetRoundQualifiersCount = groupCount;
|
|
19639
|
-
roundLimit = maxRoundNumber;
|
|
19640
|
-
structure = structures2[0];
|
|
19641
|
-
finishingPositions = [1];
|
|
19642
|
-
} else {
|
|
19643
|
-
({ drawSize, matchUps, roundLimit } = treeMatchUps({
|
|
19644
|
-
qualifyingRoundNumber,
|
|
19645
|
-
qualifyingPositions,
|
|
19646
|
-
matchUpType,
|
|
19647
|
-
drawSize,
|
|
19648
|
-
idPrefix,
|
|
19649
|
-
isMock,
|
|
19650
|
-
uuids
|
|
19651
|
-
}));
|
|
19652
|
-
structure = structureTemplate({
|
|
19653
|
-
structureName: structureProfile.structureName || qualifyingStructureName,
|
|
19654
|
-
structureId: structureId || uuids?.pop(),
|
|
19655
|
-
qualifyingRoundNumber: roundLimit,
|
|
19656
|
-
stage: QUALIFYING,
|
|
19657
|
-
matchUpFormat,
|
|
19658
|
-
stageSequence,
|
|
19659
|
-
matchUpType,
|
|
19660
|
-
roundLimit,
|
|
19661
|
-
// redundant
|
|
19662
|
-
matchUps
|
|
19663
|
-
});
|
|
19664
|
-
if (roundTarget) {
|
|
19665
|
-
addExtension({
|
|
19666
|
-
element: structure,
|
|
19667
|
-
extension: { name: ROUND_TARGET, value: roundTarget }
|
|
19668
|
-
});
|
|
19669
|
-
}
|
|
19670
|
-
targetRoundQualifiersCount = matchUps?.filter((matchUp) => matchUp.roundNumber === roundLimit)?.length || 0;
|
|
19671
|
-
}
|
|
19672
|
-
if (stageSequence > 1) {
|
|
19673
|
-
const { link } = generateQualifyingLink({
|
|
19674
|
-
sourceStructureId: finalQualifyingStructureId,
|
|
19675
|
-
sourceRoundNumber: finalQualifyingRoundNumber,
|
|
19676
|
-
targetStructureId: structure.structureId,
|
|
19677
|
-
finishingPositions: linkType === POSITION ? [1] : void 0,
|
|
19678
|
-
linkType
|
|
19595
|
+
let deltaCandidate = candidate;
|
|
19596
|
+
const actors = Object.keys(pairingValues);
|
|
19597
|
+
let candidatesCount = 0;
|
|
19598
|
+
let iterations;
|
|
19599
|
+
let opponentCount = actors.length;
|
|
19600
|
+
do {
|
|
19601
|
+
opponentCount -= 1;
|
|
19602
|
+
iterations = actors.length * opponentCount * valueSortedPairings.length / 2;
|
|
19603
|
+
} while (iterations > maxIterations && opponentCount > 2);
|
|
19604
|
+
const stipulatedPairs = [];
|
|
19605
|
+
actors.forEach((actor) => {
|
|
19606
|
+
const participantIdPairings = pairingValues[actor];
|
|
19607
|
+
participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
|
|
19608
|
+
const stipulatedPair = pairingHash(actor, pairing.opponent);
|
|
19609
|
+
if (!stipulatedPairs.includes(stipulatedPair)) {
|
|
19610
|
+
const proposed = roundCandidate({
|
|
19611
|
+
// each roundCandidate starts with stipulated pairings
|
|
19612
|
+
stipulated: [[actor, pairing.opponent]],
|
|
19613
|
+
rankedMatchUpValues,
|
|
19614
|
+
valueSortedPairings,
|
|
19615
|
+
deltaObjects
|
|
19679
19616
|
});
|
|
19680
|
-
|
|
19681
|
-
|
|
19682
|
-
|
|
19683
|
-
|
|
19617
|
+
if (proposed.maxDelta < deltaCandidate.maxDelta)
|
|
19618
|
+
deltaCandidate = proposed;
|
|
19619
|
+
if (proposed.value < candidate.value)
|
|
19620
|
+
candidate = proposed;
|
|
19621
|
+
stipulatedPairs.push(stipulatedPair);
|
|
19622
|
+
candidatesCount += 1;
|
|
19684
19623
|
}
|
|
19685
|
-
linkType = drawType === ROUND_ROBIN ? POSITION : WINNER;
|
|
19686
|
-
finalQualifyingStructureId = structure.structureId;
|
|
19687
|
-
finalQualifyingRoundNumber = roundLimit;
|
|
19688
|
-
structures.push(structure);
|
|
19689
|
-
stageSequence += 1;
|
|
19690
|
-
}
|
|
19691
|
-
totalQualifiersCount += targetRoundQualifiersCount;
|
|
19692
|
-
qualifyingDetails.push({
|
|
19693
|
-
qualifiersCount: targetRoundQualifiersCount,
|
|
19694
|
-
finalQualifyingRoundNumber,
|
|
19695
|
-
finalQualifyingStructureId,
|
|
19696
|
-
finishingPositions,
|
|
19697
|
-
roundTarget,
|
|
19698
|
-
linkType
|
|
19699
19624
|
});
|
|
19700
|
-
|
|
19701
|
-
|
|
19702
|
-
}
|
|
19703
|
-
return {
|
|
19704
|
-
qualifiersCount: totalQualifiersCount,
|
|
19705
|
-
qualifyingDrawPositionsCount,
|
|
19706
|
-
qualifyingDetails,
|
|
19707
|
-
structures,
|
|
19708
|
-
...SUCCESS,
|
|
19709
|
-
links
|
|
19710
|
-
};
|
|
19625
|
+
});
|
|
19626
|
+
return { candidate, deltaCandidate, candidatesCount, iterations };
|
|
19711
19627
|
}
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
19722
|
-
|
|
19723
|
-
|
|
19724
|
-
|
|
19725
|
-
|
|
19726
|
-
|
|
19727
|
-
}
|
|
19728
|
-
|
|
19729
|
-
|
|
19628
|
+
function roundCandidate({
|
|
19629
|
+
rankedMatchUpValues,
|
|
19630
|
+
valueSortedPairings,
|
|
19631
|
+
stipulated = [],
|
|
19632
|
+
deltaObjects
|
|
19633
|
+
}) {
|
|
19634
|
+
const roundPlayers = [].concat(...stipulated);
|
|
19635
|
+
const participantIdPairings = [];
|
|
19636
|
+
let candidateValue = 0;
|
|
19637
|
+
stipulated.filter(Boolean).forEach((participantIds) => {
|
|
19638
|
+
const [p1, p2] = participantIds;
|
|
19639
|
+
const pairing = pairingHash(p1, p2);
|
|
19640
|
+
const value = rankedMatchUpValues[pairing];
|
|
19641
|
+
participantIdPairings.push({ participantIds, value });
|
|
19642
|
+
candidateValue += rankedMatchUpValues[pairing];
|
|
19643
|
+
});
|
|
19644
|
+
valueSortedPairings.forEach((rankedPairing) => {
|
|
19645
|
+
const participantIds = rankedPairing.pairing.split("|");
|
|
19646
|
+
const opponentExists = participantIds.reduce(
|
|
19647
|
+
(p, c) => roundPlayers.includes(c) || p,
|
|
19648
|
+
false
|
|
19649
|
+
);
|
|
19650
|
+
if (!opponentExists) {
|
|
19651
|
+
roundPlayers.push(...participantIds);
|
|
19652
|
+
const value = rankedPairing.value;
|
|
19653
|
+
candidateValue += value;
|
|
19654
|
+
participantIdPairings.push({ participantIds, value });
|
|
19655
|
+
}
|
|
19656
|
+
});
|
|
19657
|
+
participantIdPairings.sort((a, b) => a.value - b.value);
|
|
19658
|
+
const maxDelta = participantIdPairings.reduce((p, c) => {
|
|
19659
|
+
const [p1, p2] = c.participantIds;
|
|
19660
|
+
const hash = pairingHash(p1, p2);
|
|
19661
|
+
const delta = deltaObjects[hash];
|
|
19662
|
+
return delta > p ? delta : p;
|
|
19663
|
+
}, 0);
|
|
19664
|
+
return { value: candidateValue, participantIdPairings, maxDelta };
|
|
19665
|
+
}
|
|
19666
|
+
function pairingHash(id1, id2) {
|
|
19667
|
+
return [id1, id2].sort().join("|");
|
|
19668
|
+
}
|
|
19669
|
+
|
|
19670
|
+
function generateAdHocMatchUps({
|
|
19671
|
+
participantIdPairings,
|
|
19672
|
+
addToStructure = true,
|
|
19673
|
+
tournamentRecord,
|
|
19674
|
+
matchUpIds = [],
|
|
19675
|
+
drawDefinition,
|
|
19676
|
+
matchUpsCount,
|
|
19677
|
+
roundNumber,
|
|
19678
|
+
structureId,
|
|
19679
|
+
newRound
|
|
19680
|
+
}) {
|
|
19681
|
+
if (typeof drawDefinition !== "object")
|
|
19682
|
+
return { error: MISSING_DRAW_DEFINITION };
|
|
19683
|
+
if (!structureId && drawDefinition.structures?.length === 1)
|
|
19684
|
+
structureId = drawDefinition.structures?.[0]?.structureId;
|
|
19685
|
+
if (typeof structureId !== "string")
|
|
19686
|
+
return { error: MISSING_STRUCTURE_ID };
|
|
19687
|
+
if (participantIdPairings && !Array.isArray(participantIdPairings) || matchUpsCount && !isConvertableInteger(matchUpsCount) || matchUpIds && !Array.isArray(matchUpIds) || !participantIdPairings && !matchUpsCount) {
|
|
19688
|
+
return { error: INVALID_VALUES, info: "matchUpsCount or pairings error" };
|
|
19689
|
+
}
|
|
19690
|
+
const structure = drawDefinition?.structures?.find(
|
|
19691
|
+
(structure2) => structure2.structureId === structureId
|
|
19692
|
+
);
|
|
19693
|
+
let structureHasRoundPositions;
|
|
19694
|
+
const existingMatchUps = structure?.matchUps;
|
|
19695
|
+
const lastRoundNumber = existingMatchUps?.reduce(
|
|
19696
|
+
(roundNumber2, matchUp) => {
|
|
19697
|
+
if (matchUp.roundPosition)
|
|
19698
|
+
structureHasRoundPositions = true;
|
|
19699
|
+
return (matchUp?.roundNumber || 0) > roundNumber2 ? matchUp.roundNumber : roundNumber2;
|
|
19700
|
+
},
|
|
19701
|
+
0
|
|
19702
|
+
);
|
|
19703
|
+
if (structure?.structures || structureHasRoundPositions || structure?.finishingPosition === ROUND_OUTCOME) {
|
|
19704
|
+
return { error: INVALID_STRUCTURE };
|
|
19705
|
+
}
|
|
19706
|
+
if (roundNumber && roundNumber - 1 > (lastRoundNumber || 0))
|
|
19707
|
+
return { error: INVALID_VALUES, info: "roundNumber error" };
|
|
19708
|
+
const nextRoundNumber = roundNumber ?? (newRound ? (lastRoundNumber ?? 0) + 1 : lastRoundNumber ?? 1);
|
|
19709
|
+
participantIdPairings = participantIdPairings ?? generateRange(0, matchUpsCount).map(() => ({
|
|
19710
|
+
participantIds: [void 0, void 0]
|
|
19711
|
+
}));
|
|
19712
|
+
const matchUps = participantIdPairings?.map((pairing) => {
|
|
19713
|
+
const idStack = pairing?.participantIds ?? [void 0, void 0];
|
|
19714
|
+
idStack.push(...[void 0, void 0]);
|
|
19715
|
+
const participantIds = idStack.slice(0, 2);
|
|
19716
|
+
const sides = participantIds.map(
|
|
19717
|
+
(participantId, i) => definedAttributes({
|
|
19718
|
+
sideNumber: i + 1,
|
|
19719
|
+
participantId
|
|
19720
|
+
})
|
|
19721
|
+
);
|
|
19722
|
+
return {
|
|
19723
|
+
matchUpStatus: MatchUpStatusEnum.ToBePlayed,
|
|
19724
|
+
matchUpId: matchUpIds.pop() ?? UUID(),
|
|
19725
|
+
roundNumber: nextRoundNumber,
|
|
19726
|
+
sides
|
|
19727
|
+
};
|
|
19728
|
+
});
|
|
19729
|
+
if (addToStructure) {
|
|
19730
|
+
const result = addAdHocMatchUps({
|
|
19731
|
+
tournamentRecord,
|
|
19732
|
+
drawDefinition,
|
|
19733
|
+
structureId,
|
|
19734
|
+
matchUps
|
|
19735
|
+
});
|
|
19736
|
+
if (result.error)
|
|
19737
|
+
return result;
|
|
19738
|
+
}
|
|
19739
|
+
return { matchUpsCount: matchUps.length, matchUps, ...SUCCESS };
|
|
19740
|
+
}
|
|
19741
|
+
function addAdHocMatchUps({
|
|
19742
|
+
tournamentRecord,
|
|
19743
|
+
drawDefinition,
|
|
19744
|
+
structureId,
|
|
19745
|
+
matchUps
|
|
19746
|
+
}) {
|
|
19747
|
+
if (typeof drawDefinition !== "object")
|
|
19748
|
+
return { error: MISSING_DRAW_DEFINITION };
|
|
19749
|
+
if (!structureId && drawDefinition.structures?.length === 1)
|
|
19750
|
+
structureId = drawDefinition.structures?.[0]?.structureId;
|
|
19751
|
+
if (typeof structureId !== "string")
|
|
19752
|
+
return { error: MISSING_STRUCTURE_ID };
|
|
19753
|
+
if (!validMatchUps(matchUps))
|
|
19754
|
+
return { error: INVALID_VALUES, info: mustBeAnArray("matchUps") };
|
|
19755
|
+
const structure = drawDefinition.structures?.find(
|
|
19756
|
+
(structure2) => structure2.structureId === structureId
|
|
19757
|
+
);
|
|
19758
|
+
if (!structure)
|
|
19759
|
+
return { error: STRUCTURE_NOT_FOUND };
|
|
19760
|
+
const existingMatchUps = structure?.matchUps;
|
|
19761
|
+
const structureHasRoundPositions = existingMatchUps.find(
|
|
19762
|
+
(matchUp) => !!matchUp.roundPosition
|
|
19763
|
+
);
|
|
19764
|
+
if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
|
|
19765
|
+
return { error: INVALID_STRUCTURE };
|
|
19766
|
+
}
|
|
19767
|
+
const existingMatchUpIds = allTournamentMatchUps({
|
|
19768
|
+
tournamentRecord,
|
|
19769
|
+
inContext: false
|
|
19770
|
+
})?.matchUps?.map(getMatchUpId) ?? [];
|
|
19771
|
+
const newMatchUpIds = matchUps.map(getMatchUpId);
|
|
19772
|
+
if (overlap(existingMatchUpIds, newMatchUpIds)) {
|
|
19773
|
+
return {
|
|
19774
|
+
error: EXISTING_MATCHUP_ID,
|
|
19775
|
+
info: "One or more matchUpIds already present in tournamentRecord"
|
|
19776
|
+
};
|
|
19777
|
+
}
|
|
19778
|
+
structure.matchUps.push(...matchUps);
|
|
19779
|
+
addMatchUpsNotice({
|
|
19780
|
+
tournamentId: tournamentRecord?.tournamentId,
|
|
19781
|
+
drawDefinition,
|
|
19782
|
+
matchUps
|
|
19783
|
+
});
|
|
19784
|
+
modifyDrawNotice({ drawDefinition, structureIds: [structureId] });
|
|
19785
|
+
return { ...SUCCESS };
|
|
19786
|
+
}
|
|
19787
|
+
|
|
19788
|
+
const ENCOUNTER_VALUE = 50;
|
|
19789
|
+
const SAME_TEAM_VALUE = 60;
|
|
19790
|
+
const DEFAULT_RATING = 0;
|
|
19791
|
+
const MAX_ITERATIONS = 5e3;
|
|
19792
|
+
function generateDrawMaticRound({
|
|
19793
|
+
maxIterations = MAX_ITERATIONS,
|
|
19794
|
+
generateMatchUps = true,
|
|
19795
|
+
tournamentParticipants,
|
|
19796
|
+
tournamentRecord,
|
|
19797
|
+
participantIds,
|
|
19798
|
+
addToStructure,
|
|
19799
|
+
drawDefinition,
|
|
19800
|
+
adHocRatings,
|
|
19801
|
+
structureId,
|
|
19802
|
+
matchUpIds,
|
|
19803
|
+
eventType,
|
|
19804
|
+
structure
|
|
19805
|
+
}) {
|
|
19806
|
+
if (!drawDefinition)
|
|
19807
|
+
return { error: MISSING_DRAW_DEFINITION };
|
|
19808
|
+
if (!structure && !structureId)
|
|
19809
|
+
return { error: STRUCTURE_NOT_FOUND };
|
|
19810
|
+
if (!structure) {
|
|
19811
|
+
structure = findStructure({ drawDefinition, structureId }).structure;
|
|
19812
|
+
}
|
|
19813
|
+
if (!isObject(structure))
|
|
19814
|
+
return { error: MISSING_STRUCTURE };
|
|
19815
|
+
if (!participantIds?.length) {
|
|
19816
|
+
return { error: MISSING_PARTICIPANT_IDS };
|
|
19817
|
+
}
|
|
19818
|
+
const { encounters } = getEncounters({ matchUps: structure?.matchUps ?? [] });
|
|
19819
|
+
const valueObjects = {};
|
|
19820
|
+
for (const pairing of encounters) {
|
|
19821
|
+
if (!valueObjects[pairing])
|
|
19822
|
+
valueObjects[pairing] = 0;
|
|
19823
|
+
valueObjects[pairing] += ENCOUNTER_VALUE;
|
|
19824
|
+
}
|
|
19825
|
+
const teamParticipants = tournamentParticipants?.filter(
|
|
19826
|
+
({ participantType }) => participantType === TEAM
|
|
19827
|
+
);
|
|
19828
|
+
if (teamParticipants) {
|
|
19829
|
+
for (const teamParticipant of teamParticipants) {
|
|
19830
|
+
const participantIds2 = teamParticipant.individualParticipantIds || [];
|
|
19831
|
+
const { uniquePairings: uniquePairings2 } = getPairingsData({ participantIds: participantIds2 });
|
|
19832
|
+
for (const pairing of uniquePairings2) {
|
|
19833
|
+
if (!valueObjects[pairing])
|
|
19834
|
+
valueObjects[pairing] = 0;
|
|
19835
|
+
valueObjects[pairing] += SAME_TEAM_VALUE;
|
|
19836
|
+
}
|
|
19837
|
+
}
|
|
19838
|
+
}
|
|
19839
|
+
const { uniquePairings, possiblePairings, deltaObjects } = getPairingsData({
|
|
19840
|
+
participantIds
|
|
19841
|
+
});
|
|
19842
|
+
const params = {
|
|
19843
|
+
tournamentParticipants,
|
|
19844
|
+
possiblePairings,
|
|
19845
|
+
drawDefinition,
|
|
19846
|
+
participantIds,
|
|
19847
|
+
uniquePairings,
|
|
19848
|
+
maxIterations,
|
|
19849
|
+
adHocRatings,
|
|
19850
|
+
deltaObjects,
|
|
19851
|
+
valueObjects,
|
|
19852
|
+
eventType,
|
|
19853
|
+
structure
|
|
19854
|
+
};
|
|
19855
|
+
const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
|
|
19856
|
+
if (!candidatesCount)
|
|
19857
|
+
return { error: NO_CANDIDATES };
|
|
19858
|
+
let matchUps;
|
|
19859
|
+
if (generateMatchUps) {
|
|
19860
|
+
const result = generateAdHocMatchUps({
|
|
19861
|
+
structureId: structure?.structureId,
|
|
19862
|
+
participantIdPairings,
|
|
19863
|
+
tournamentRecord,
|
|
19864
|
+
addToStructure,
|
|
19865
|
+
newRound: true,
|
|
19866
|
+
drawDefinition,
|
|
19867
|
+
matchUpIds
|
|
19868
|
+
});
|
|
19869
|
+
if (result.error)
|
|
19870
|
+
return result;
|
|
19871
|
+
matchUps = result.matchUps;
|
|
19872
|
+
}
|
|
19873
|
+
return {
|
|
19874
|
+
...SUCCESS,
|
|
19875
|
+
participantIdPairings,
|
|
19876
|
+
candidatesCount,
|
|
19877
|
+
iterations,
|
|
19878
|
+
matchUps
|
|
19879
|
+
};
|
|
19880
|
+
}
|
|
19881
|
+
function getSideRatings({
|
|
19882
|
+
tournamentParticipants,
|
|
19883
|
+
adHocRatings,
|
|
19884
|
+
eventType,
|
|
19885
|
+
pairing
|
|
19886
|
+
}) {
|
|
19887
|
+
return pairing.split("|").map((participantId) => {
|
|
19888
|
+
if (eventType === DOUBLES) {
|
|
19889
|
+
const individualParticipantIds = tournamentParticipants?.find(
|
|
19890
|
+
(participant) => participant.participantId === participantId
|
|
19891
|
+
)?.individualParticipantIds;
|
|
19892
|
+
return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
|
|
19893
|
+
(participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
|
|
19894
|
+
);
|
|
19895
|
+
} else {
|
|
19896
|
+
return adHocRatings[participantId] || DEFAULT_RATING;
|
|
19897
|
+
}
|
|
19898
|
+
});
|
|
19899
|
+
}
|
|
19900
|
+
function getPairings({
|
|
19901
|
+
tournamentParticipants,
|
|
19902
|
+
adHocRatings = {},
|
|
19903
|
+
possiblePairings,
|
|
19904
|
+
// participant keyed; provides array of possible opponents
|
|
19905
|
+
uniquePairings,
|
|
19906
|
+
// hashes of all possible participantId pairings
|
|
19907
|
+
maxIterations,
|
|
19908
|
+
deltaObjects,
|
|
19909
|
+
// difference in rating between paired participants
|
|
19910
|
+
valueObjects,
|
|
19911
|
+
// calculated value of a pairing of participants, used for sorting pairings
|
|
19912
|
+
eventType
|
|
19913
|
+
}) {
|
|
19914
|
+
uniquePairings.forEach((pairing) => {
|
|
19915
|
+
const ratings = getSideRatings({
|
|
19916
|
+
tournamentParticipants,
|
|
19917
|
+
adHocRatings,
|
|
19918
|
+
eventType,
|
|
19919
|
+
pairing
|
|
19920
|
+
});
|
|
19921
|
+
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
|
|
19922
|
+
deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
|
|
19923
|
+
if (!valueObjects[pairing])
|
|
19924
|
+
valueObjects[pairing] = 0;
|
|
19925
|
+
valueObjects[pairing] += Math.pow(ratingsDifference, 2);
|
|
19926
|
+
});
|
|
19927
|
+
const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
|
|
19928
|
+
const { pairingValues } = getParticipantPairingValues({
|
|
19929
|
+
possiblePairings,
|
|
19930
|
+
valueObjects
|
|
19931
|
+
});
|
|
19932
|
+
const { candidate, candidatesCount, iterations } = generateCandidate({
|
|
19933
|
+
valueSortedPairings,
|
|
19934
|
+
maxIterations,
|
|
19935
|
+
pairingValues,
|
|
19936
|
+
deltaObjects
|
|
19937
|
+
});
|
|
19938
|
+
const { participantIdPairings } = candidate;
|
|
19939
|
+
return { candidatesCount, participantIdPairings, iterations };
|
|
19940
|
+
}
|
|
19941
|
+
function getPairingsData({ participantIds }) {
|
|
19942
|
+
const possiblePairings = {};
|
|
19943
|
+
const uniquePairings = [];
|
|
19944
|
+
participantIds.forEach((participantId) => {
|
|
19945
|
+
possiblePairings[participantId] = participantIds.filter(
|
|
19946
|
+
(id) => id !== participantId
|
|
19947
|
+
);
|
|
19948
|
+
possiblePairings[participantId].forEach((id) => {
|
|
19949
|
+
const pairing = pairingHash(id, participantId);
|
|
19950
|
+
if (!uniquePairings.includes(pairing))
|
|
19951
|
+
uniquePairings.push(pairing);
|
|
19952
|
+
});
|
|
19953
|
+
});
|
|
19954
|
+
const deltaObjects = Object.assign(
|
|
19955
|
+
{},
|
|
19956
|
+
...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
|
|
19957
|
+
);
|
|
19958
|
+
return { uniquePairings, possiblePairings, deltaObjects };
|
|
19959
|
+
}
|
|
19960
|
+
function getEncounters({ matchUps }) {
|
|
19961
|
+
const encounters = [];
|
|
19962
|
+
for (const matchUp of matchUps) {
|
|
19963
|
+
const participantIds = matchUp.sides.map(getParticipantId);
|
|
19964
|
+
if (participantIds.length === 2) {
|
|
19965
|
+
const [p1, p2] = participantIds;
|
|
19966
|
+
const pairing = pairingHash(p1, p2);
|
|
19967
|
+
if (!encounters.includes(pairing))
|
|
19968
|
+
encounters.push(pairing);
|
|
19969
|
+
}
|
|
19970
|
+
}
|
|
19971
|
+
return { encounters };
|
|
19972
|
+
}
|
|
19973
|
+
function getParticipantPairingValues({ possiblePairings, valueObjects }) {
|
|
19974
|
+
const pairingValues = {};
|
|
19975
|
+
for (const participantId of Object.keys(possiblePairings)) {
|
|
19976
|
+
const participantValues = possiblePairings[participantId].map(
|
|
19977
|
+
(opponent) => pairingValue(participantId, opponent)
|
|
19978
|
+
);
|
|
19979
|
+
pairingValues[participantId] = participantValues.sort(
|
|
19980
|
+
(a, b) => a.value - b.value
|
|
19981
|
+
);
|
|
19982
|
+
}
|
|
19983
|
+
function pairingValue(participantId, opponent) {
|
|
19984
|
+
const key = pairingHash(participantId, opponent);
|
|
19985
|
+
return { opponent, value: valueObjects[key] };
|
|
19986
|
+
}
|
|
19987
|
+
return { pairingValues };
|
|
19988
|
+
}
|
|
19989
|
+
|
|
19990
|
+
function generateQualifyingLink({
|
|
19991
|
+
targetEntryRound = 1,
|
|
19992
|
+
finishingPositions,
|
|
19993
|
+
sourceRoundNumber,
|
|
19994
|
+
sourceStructureId,
|
|
19995
|
+
targetStructureId,
|
|
19996
|
+
linkType = LinkTypeEnum.Winner
|
|
19997
|
+
}) {
|
|
19998
|
+
if (!sourceStructureId || !targetStructureId)
|
|
19999
|
+
return { error: MISSING_STRUCTURE_ID };
|
|
20000
|
+
const link = definedAttributes({
|
|
20001
|
+
linkType,
|
|
20002
|
+
source: {
|
|
20003
|
+
roundNumber: sourceRoundNumber,
|
|
20004
|
+
structureId: sourceStructureId,
|
|
20005
|
+
finishingPositions
|
|
20006
|
+
},
|
|
20007
|
+
target: {
|
|
20008
|
+
feedProfile: DRAW,
|
|
20009
|
+
// positions are not automatically placed
|
|
20010
|
+
roundNumber: targetEntryRound,
|
|
20011
|
+
structureId: targetStructureId
|
|
20012
|
+
}
|
|
20013
|
+
});
|
|
20014
|
+
return { link };
|
|
20015
|
+
}
|
|
20016
|
+
|
|
20017
|
+
function generateQualifyingStructures({
|
|
20018
|
+
qualifyingProfiles,
|
|
20019
|
+
appliedPolicies,
|
|
20020
|
+
idPrefix,
|
|
20021
|
+
isMock,
|
|
20022
|
+
uuids
|
|
20023
|
+
}) {
|
|
20024
|
+
const stack = "generateQualifyingSTructures";
|
|
20025
|
+
const qualifyingDetails = [];
|
|
20026
|
+
const structures = [];
|
|
20027
|
+
const links = [];
|
|
20028
|
+
const sequenceSort = (a, b) => a.stageSequence - b.stageSequence;
|
|
20029
|
+
const roundTargetSort = (a, b) => a.roundTarget - b.roundTarget;
|
|
20030
|
+
let qualifyingDrawPositionsCount = 0, totalQualifiersCount = 0, finishingPositions, roundTarget = 1;
|
|
20031
|
+
for (const roundTargetProfile of qualifyingProfiles.sort(roundTargetSort)) {
|
|
20032
|
+
const structureProfiles = roundTargetProfile.structureProfiles || [];
|
|
20033
|
+
roundTarget = roundTargetProfile.roundTarget || roundTarget;
|
|
20034
|
+
let stageSequence = 1, targetRoundQualifiersCount = 0, finalQualifyingRoundNumber, finalQualifyingStructureId, linkType;
|
|
20035
|
+
for (const structureProfile of (structureProfiles || []).sort(
|
|
20036
|
+
sequenceSort
|
|
20037
|
+
)) {
|
|
20038
|
+
let drawSize = structureProfile.drawSize || coerceEven(structureProfile.participantsCount);
|
|
20039
|
+
const {
|
|
20040
|
+
qualifyingRoundNumber,
|
|
20041
|
+
qualifyingPositions,
|
|
20042
|
+
structureOptions,
|
|
20043
|
+
matchUpFormat,
|
|
20044
|
+
structureName,
|
|
20045
|
+
structureId,
|
|
20046
|
+
drawType
|
|
20047
|
+
} = structureProfile;
|
|
20048
|
+
const matchUpType = structureProfile.matchUpType;
|
|
20049
|
+
let roundLimit, structure, matchUps;
|
|
20050
|
+
if (!isConvertableInteger(drawSize)) {
|
|
20051
|
+
return decorateResult({
|
|
20052
|
+
result: { error: MISSING_DRAW_SIZE },
|
|
20053
|
+
stack
|
|
20054
|
+
});
|
|
20055
|
+
}
|
|
20056
|
+
const roundTargetName = qualifyingProfiles.length > 1 ? `${roundTarget}-` : "";
|
|
20057
|
+
const stageSequenceName = structureProfiles.length > 1 || roundTargetName ? stageSequence : "";
|
|
20058
|
+
const qualifyingStructureName = structureName || (roundTargetName || stageSequenceName ? `${QUALIFYING} ${roundTargetName}${stageSequenceName}` : QUALIFYING);
|
|
20059
|
+
if (drawType === ROUND_ROBIN) {
|
|
20060
|
+
const {
|
|
20061
|
+
structures: structures2,
|
|
20062
|
+
groupCount,
|
|
20063
|
+
maxRoundNumber
|
|
20064
|
+
/*, groupSize*/
|
|
20065
|
+
} = generateRoundRobin({
|
|
20066
|
+
structureName: structureProfile.structureName || qualifyingStructureName,
|
|
20067
|
+
structureId: structureId || uuids?.pop(),
|
|
20068
|
+
// qualifyingPositions,
|
|
20069
|
+
stage: QUALIFYING,
|
|
20070
|
+
structureOptions,
|
|
20071
|
+
appliedPolicies,
|
|
20072
|
+
stageSequence,
|
|
20073
|
+
matchUpType,
|
|
20074
|
+
roundTarget,
|
|
20075
|
+
drawSize,
|
|
20076
|
+
idPrefix,
|
|
20077
|
+
isMock,
|
|
20078
|
+
uuids
|
|
20079
|
+
});
|
|
20080
|
+
targetRoundQualifiersCount = groupCount;
|
|
20081
|
+
roundLimit = maxRoundNumber;
|
|
20082
|
+
structure = structures2[0];
|
|
20083
|
+
finishingPositions = [1];
|
|
20084
|
+
} else {
|
|
20085
|
+
({ drawSize, matchUps, roundLimit } = treeMatchUps({
|
|
20086
|
+
qualifyingRoundNumber,
|
|
20087
|
+
qualifyingPositions,
|
|
20088
|
+
matchUpType,
|
|
20089
|
+
drawSize,
|
|
20090
|
+
idPrefix,
|
|
20091
|
+
isMock,
|
|
20092
|
+
uuids
|
|
20093
|
+
}));
|
|
20094
|
+
structure = structureTemplate({
|
|
20095
|
+
structureName: structureProfile.structureName || qualifyingStructureName,
|
|
20096
|
+
structureId: structureId || uuids?.pop(),
|
|
20097
|
+
qualifyingRoundNumber: roundLimit,
|
|
20098
|
+
stage: QUALIFYING,
|
|
20099
|
+
matchUpFormat,
|
|
20100
|
+
stageSequence,
|
|
20101
|
+
matchUpType,
|
|
20102
|
+
roundLimit,
|
|
20103
|
+
// redundant
|
|
20104
|
+
matchUps
|
|
20105
|
+
});
|
|
20106
|
+
if (roundTarget) {
|
|
20107
|
+
addExtension({
|
|
20108
|
+
element: structure,
|
|
20109
|
+
extension: { name: ROUND_TARGET, value: roundTarget }
|
|
20110
|
+
});
|
|
20111
|
+
}
|
|
20112
|
+
targetRoundQualifiersCount = matchUps?.filter((matchUp) => matchUp.roundNumber === roundLimit)?.length || 0;
|
|
20113
|
+
}
|
|
20114
|
+
if (stageSequence > 1) {
|
|
20115
|
+
const { link } = generateQualifyingLink({
|
|
20116
|
+
sourceStructureId: finalQualifyingStructureId,
|
|
20117
|
+
sourceRoundNumber: finalQualifyingRoundNumber,
|
|
20118
|
+
targetStructureId: structure.structureId,
|
|
20119
|
+
finishingPositions: linkType === POSITION ? [1] : void 0,
|
|
20120
|
+
linkType
|
|
20121
|
+
});
|
|
20122
|
+
links.push(link);
|
|
20123
|
+
qualifyingDrawPositionsCount += (drawSize || 0) - targetRoundQualifiersCount;
|
|
20124
|
+
} else {
|
|
20125
|
+
qualifyingDrawPositionsCount += drawSize || 0;
|
|
20126
|
+
}
|
|
20127
|
+
linkType = drawType === ROUND_ROBIN ? POSITION : WINNER;
|
|
20128
|
+
finalQualifyingStructureId = structure.structureId;
|
|
20129
|
+
finalQualifyingRoundNumber = roundLimit;
|
|
20130
|
+
structures.push(structure);
|
|
20131
|
+
stageSequence += 1;
|
|
20132
|
+
}
|
|
20133
|
+
totalQualifiersCount += targetRoundQualifiersCount;
|
|
20134
|
+
qualifyingDetails.push({
|
|
20135
|
+
qualifiersCount: targetRoundQualifiersCount,
|
|
20136
|
+
finalQualifyingRoundNumber,
|
|
20137
|
+
finalQualifyingStructureId,
|
|
20138
|
+
finishingPositions,
|
|
20139
|
+
roundTarget,
|
|
20140
|
+
linkType
|
|
20141
|
+
});
|
|
20142
|
+
targetRoundQualifiersCount = 0;
|
|
20143
|
+
roundTarget += 1;
|
|
20144
|
+
}
|
|
20145
|
+
return {
|
|
20146
|
+
qualifiersCount: totalQualifiersCount,
|
|
20147
|
+
qualifyingDrawPositionsCount,
|
|
20148
|
+
qualifyingDetails,
|
|
20149
|
+
structures,
|
|
20150
|
+
...SUCCESS,
|
|
20151
|
+
links
|
|
20152
|
+
};
|
|
20153
|
+
}
|
|
20154
|
+
|
|
20155
|
+
function generateDrawStructuresAndLinks(params) {
|
|
20156
|
+
const {
|
|
20157
|
+
enforceMinimumDrawSize = true,
|
|
20158
|
+
overwriteExisting,
|
|
20159
|
+
drawTypeCoercion,
|
|
20160
|
+
// coerce to SINGLE_ELIMINATION for drawSize: 2
|
|
20161
|
+
appliedPolicies,
|
|
20162
|
+
staggeredEntry,
|
|
20163
|
+
// optional - specifies main structure FEED_IN for drawTypes CURTIS_CONSOLATION, FEED_IN_CHAMPIONSHIPS, FMLC
|
|
20164
|
+
drawDefinition,
|
|
20165
|
+
tieFormat,
|
|
20166
|
+
drawSize,
|
|
20167
|
+
isMock,
|
|
20168
|
+
uuids
|
|
20169
|
+
} = params || {};
|
|
20170
|
+
const stack = "generateDrawStructuresAndLinks";
|
|
20171
|
+
let drawType = params.drawType ?? SINGLE_ELIMINATION;
|
|
19730
20172
|
const structures = [], links = [];
|
|
19731
20173
|
const matchUpType = params?.matchUpType ?? SINGLES$1;
|
|
19732
20174
|
const existingQualifyingStructures = drawDefinition?.structures?.filter(
|
|
@@ -20351,149 +20793,31 @@ function addDrawDefinition(params) {
|
|
|
20351
20793
|
}
|
|
20352
20794
|
if (incomingMatchUps?.length) {
|
|
20353
20795
|
addMatchUpsNotice({
|
|
20354
|
-
matchUps: incomingMatchUps,
|
|
20355
|
-
tournamentId,
|
|
20356
|
-
eventId
|
|
20357
|
-
});
|
|
20358
|
-
}
|
|
20359
|
-
event.drawDefinitions = event.drawDefinitions.map(
|
|
20360
|
-
(d) => d.drawId === drawId ? drawDefinition : d
|
|
20361
|
-
);
|
|
20362
|
-
const structureIds = drawDefinition.structures?.map(
|
|
20363
|
-
({ structureId }) => structureId
|
|
20364
|
-
);
|
|
20365
|
-
modifyDrawNotice({ drawDefinition, tournamentId, structureIds, eventId });
|
|
20366
|
-
}
|
|
20367
|
-
} else {
|
|
20368
|
-
event.drawDefinitions.push(drawDefinition);
|
|
20369
|
-
if (!suppressNotifications) {
|
|
20370
|
-
const { matchUps } = allDrawMatchUps({ drawDefinition, event });
|
|
20371
|
-
matchUps && addMatchUpsNotice({
|
|
20372
|
-
tournamentId: tournamentRecord?.tournamentId,
|
|
20373
|
-
matchUps
|
|
20374
|
-
});
|
|
20375
|
-
addDrawNotice({ drawDefinition, tournamentId, eventId });
|
|
20376
|
-
}
|
|
20377
|
-
}
|
|
20378
|
-
return { ...SUCCESS, modifiedEventEntryStatusCount };
|
|
20379
|
-
}
|
|
20380
|
-
|
|
20381
|
-
function generateAdHocMatchUps({
|
|
20382
|
-
participantIdPairings,
|
|
20383
|
-
addToStructure = true,
|
|
20384
|
-
tournamentRecord,
|
|
20385
|
-
matchUpIds = [],
|
|
20386
|
-
drawDefinition,
|
|
20387
|
-
matchUpsCount,
|
|
20388
|
-
roundNumber,
|
|
20389
|
-
structureId,
|
|
20390
|
-
newRound
|
|
20391
|
-
}) {
|
|
20392
|
-
if (typeof drawDefinition !== "object")
|
|
20393
|
-
return { error: MISSING_DRAW_DEFINITION };
|
|
20394
|
-
if (!structureId && drawDefinition.structures?.length === 1)
|
|
20395
|
-
structureId = drawDefinition.structures?.[0]?.structureId;
|
|
20396
|
-
if (typeof structureId !== "string")
|
|
20397
|
-
return { error: MISSING_STRUCTURE_ID };
|
|
20398
|
-
if (participantIdPairings && !Array.isArray(participantIdPairings) || matchUpsCount && !isConvertableInteger(matchUpsCount) || matchUpIds && !Array.isArray(matchUpIds) || !participantIdPairings && !matchUpsCount) {
|
|
20399
|
-
return { error: INVALID_VALUES, info: "matchUpsCount or pairings error" };
|
|
20400
|
-
}
|
|
20401
|
-
const structure = drawDefinition?.structures?.find(
|
|
20402
|
-
(structure2) => structure2.structureId === structureId
|
|
20403
|
-
);
|
|
20404
|
-
let structureHasRoundPositions;
|
|
20405
|
-
const existingMatchUps = structure?.matchUps;
|
|
20406
|
-
const lastRoundNumber = existingMatchUps?.reduce(
|
|
20407
|
-
(roundNumber2, matchUp) => {
|
|
20408
|
-
if (matchUp.roundPosition)
|
|
20409
|
-
structureHasRoundPositions = true;
|
|
20410
|
-
return (matchUp?.roundNumber || 0) > roundNumber2 ? matchUp.roundNumber : roundNumber2;
|
|
20411
|
-
},
|
|
20412
|
-
0
|
|
20413
|
-
);
|
|
20414
|
-
if (structure?.structures || structureHasRoundPositions || structure?.finishingPosition === ROUND_OUTCOME) {
|
|
20415
|
-
return { error: INVALID_STRUCTURE };
|
|
20416
|
-
}
|
|
20417
|
-
if (roundNumber && roundNumber - 1 > (lastRoundNumber || 0))
|
|
20418
|
-
return { error: INVALID_VALUES, info: "roundNumber error" };
|
|
20419
|
-
const nextRoundNumber = roundNumber ?? (newRound ? (lastRoundNumber ?? 0) + 1 : lastRoundNumber ?? 1);
|
|
20420
|
-
participantIdPairings = participantIdPairings ?? generateRange(0, matchUpsCount).map(() => ({
|
|
20421
|
-
participantIds: [void 0, void 0]
|
|
20422
|
-
}));
|
|
20423
|
-
const matchUps = participantIdPairings?.map((pairing) => {
|
|
20424
|
-
const idStack = pairing?.participantIds ?? [void 0, void 0];
|
|
20425
|
-
idStack.push(...[void 0, void 0]);
|
|
20426
|
-
const participantIds = idStack.slice(0, 2);
|
|
20427
|
-
const sides = participantIds.map(
|
|
20428
|
-
(participantId, i) => definedAttributes({
|
|
20429
|
-
sideNumber: i + 1,
|
|
20430
|
-
participantId
|
|
20431
|
-
})
|
|
20432
|
-
);
|
|
20433
|
-
return {
|
|
20434
|
-
matchUpStatus: MatchUpStatusEnum.ToBePlayed,
|
|
20435
|
-
matchUpId: matchUpIds.pop() ?? UUID(),
|
|
20436
|
-
roundNumber: nextRoundNumber,
|
|
20437
|
-
sides
|
|
20438
|
-
};
|
|
20439
|
-
});
|
|
20440
|
-
if (addToStructure) {
|
|
20441
|
-
const result = addAdHocMatchUps({
|
|
20442
|
-
tournamentRecord,
|
|
20443
|
-
drawDefinition,
|
|
20444
|
-
structureId,
|
|
20445
|
-
matchUps
|
|
20446
|
-
});
|
|
20447
|
-
if (result.error)
|
|
20448
|
-
return result;
|
|
20449
|
-
}
|
|
20450
|
-
return { matchUpsCount: matchUps.length, matchUps, ...SUCCESS };
|
|
20451
|
-
}
|
|
20452
|
-
function addAdHocMatchUps({
|
|
20453
|
-
tournamentRecord,
|
|
20454
|
-
drawDefinition,
|
|
20455
|
-
structureId,
|
|
20456
|
-
matchUps
|
|
20457
|
-
}) {
|
|
20458
|
-
if (typeof drawDefinition !== "object")
|
|
20459
|
-
return { error: MISSING_DRAW_DEFINITION };
|
|
20460
|
-
if (!structureId && drawDefinition.structures?.length === 1)
|
|
20461
|
-
structureId = drawDefinition.structures?.[0]?.structureId;
|
|
20462
|
-
if (typeof structureId !== "string")
|
|
20463
|
-
return { error: MISSING_STRUCTURE_ID };
|
|
20464
|
-
if (!validMatchUps(matchUps))
|
|
20465
|
-
return { error: INVALID_VALUES, info: mustBeAnArray("matchUps") };
|
|
20466
|
-
const structure = drawDefinition.structures?.find(
|
|
20467
|
-
(structure2) => structure2.structureId === structureId
|
|
20468
|
-
);
|
|
20469
|
-
if (!structure)
|
|
20470
|
-
return { error: STRUCTURE_NOT_FOUND };
|
|
20471
|
-
const existingMatchUps = structure?.matchUps;
|
|
20472
|
-
const structureHasRoundPositions = existingMatchUps.find(
|
|
20473
|
-
(matchUp) => !!matchUp.roundPosition
|
|
20474
|
-
);
|
|
20475
|
-
if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
|
|
20476
|
-
return { error: INVALID_STRUCTURE };
|
|
20477
|
-
}
|
|
20478
|
-
const existingMatchUpIds = allTournamentMatchUps({
|
|
20479
|
-
tournamentRecord,
|
|
20480
|
-
inContext: false
|
|
20481
|
-
})?.matchUps?.map(getMatchUpId) ?? [];
|
|
20482
|
-
const newMatchUpIds = matchUps.map(getMatchUpId);
|
|
20483
|
-
if (overlap(existingMatchUpIds, newMatchUpIds)) {
|
|
20484
|
-
return {
|
|
20485
|
-
error: EXISTING_MATCHUP_ID,
|
|
20486
|
-
info: "One or more matchUpIds already present in tournamentRecord"
|
|
20487
|
-
};
|
|
20796
|
+
matchUps: incomingMatchUps,
|
|
20797
|
+
tournamentId,
|
|
20798
|
+
eventId
|
|
20799
|
+
});
|
|
20800
|
+
}
|
|
20801
|
+
event.drawDefinitions = event.drawDefinitions.map(
|
|
20802
|
+
(d) => d.drawId === drawId ? drawDefinition : d
|
|
20803
|
+
);
|
|
20804
|
+
const structureIds = drawDefinition.structures?.map(
|
|
20805
|
+
({ structureId }) => structureId
|
|
20806
|
+
);
|
|
20807
|
+
modifyDrawNotice({ drawDefinition, tournamentId, structureIds, eventId });
|
|
20808
|
+
}
|
|
20809
|
+
} else {
|
|
20810
|
+
event.drawDefinitions.push(drawDefinition);
|
|
20811
|
+
if (!suppressNotifications) {
|
|
20812
|
+
const { matchUps } = allDrawMatchUps({ drawDefinition, event });
|
|
20813
|
+
matchUps && addMatchUpsNotice({
|
|
20814
|
+
tournamentId: tournamentRecord?.tournamentId,
|
|
20815
|
+
matchUps
|
|
20816
|
+
});
|
|
20817
|
+
addDrawNotice({ drawDefinition, tournamentId, eventId });
|
|
20818
|
+
}
|
|
20488
20819
|
}
|
|
20489
|
-
|
|
20490
|
-
addMatchUpsNotice({
|
|
20491
|
-
tournamentId: tournamentRecord?.tournamentId,
|
|
20492
|
-
drawDefinition,
|
|
20493
|
-
matchUps
|
|
20494
|
-
});
|
|
20495
|
-
modifyDrawNotice({ drawDefinition, structureIds: [structureId] });
|
|
20496
|
-
return { ...SUCCESS };
|
|
20820
|
+
return { ...SUCCESS, modifiedEventEntryStatusCount };
|
|
20497
20821
|
}
|
|
20498
20822
|
|
|
20499
20823
|
function attachPolicies({ drawDefinition, policyDefinitions }) {
|
|
@@ -20558,543 +20882,163 @@ function checkValidEntries({
|
|
|
20558
20882
|
const entryStatus = entryStatusMap[participant.participantId];
|
|
20559
20883
|
const ungroupedParticipant = eventType && [TypeEnum.Doubles, TypeEnum.Team].includes(eventType) && participant.participantType === INDIVIDUAL && (isUngrouped(entryStatus) || entryStatus === WITHDRAWN);
|
|
20560
20884
|
const mismatch = participant.participantType !== participantType && !ungroupedParticipant;
|
|
20561
|
-
const personGender = participant?.person?.sex;
|
|
20562
|
-
const wrongGender = !ignoreGender && eventGender && eventType === TypeEnum.Singles && [GenderEnum.Male, GenderEnum.Female].includes(eventGender) && personGender !== eventGender;
|
|
20563
|
-
return mismatch || wrongGender;
|
|
20564
|
-
});
|
|
20565
|
-
if (invalidEntries.length) {
|
|
20566
|
-
const invalidParticipantIds = invalidEntries.map(
|
|
20567
|
-
(participant) => participant.participantId
|
|
20568
|
-
);
|
|
20569
|
-
return { error: INVALID_ENTRIES, invalidParticipantIds };
|
|
20570
|
-
}
|
|
20571
|
-
return { ...SUCCESS };
|
|
20572
|
-
}
|
|
20573
|
-
|
|
20574
|
-
function getValidStage({ stage, drawDefinition }) {
|
|
20575
|
-
return Boolean(
|
|
20576
|
-
stage === VOLUNTARY_CONSOLATION || stageExists({ stage, drawDefinition }) && getStageDrawPositionsCount({ stage, drawDefinition })
|
|
20577
|
-
);
|
|
20578
|
-
}
|
|
20579
|
-
|
|
20580
|
-
function getStageSpace({
|
|
20581
|
-
entryStatus = DIRECT_ACCEPTANCE,
|
|
20582
|
-
drawDefinition,
|
|
20583
|
-
stageSequence,
|
|
20584
|
-
stage
|
|
20585
|
-
}) {
|
|
20586
|
-
if (entryStatus === ALTERNATE) {
|
|
20587
|
-
if (stageAlternatesCount({ stage, drawDefinition })) {
|
|
20588
|
-
return { positionsAvailable: Infinity, ...SUCCESS };
|
|
20589
|
-
} else {
|
|
20590
|
-
return { error: ENTRY_STATUS_NOT_ALLOWED_IN_STAGE };
|
|
20591
|
-
}
|
|
20592
|
-
}
|
|
20593
|
-
const stageDrawPositionsAvailable = getStageDrawPositionsAvailable({
|
|
20594
|
-
drawDefinition,
|
|
20595
|
-
stageSequence,
|
|
20596
|
-
stage
|
|
20597
|
-
});
|
|
20598
|
-
const wildcardPositions = getStageWildcardsCount({
|
|
20599
|
-
drawDefinition,
|
|
20600
|
-
stage
|
|
20601
|
-
});
|
|
20602
|
-
const wildcardEntriesCount = getStageEntryTypeCount({
|
|
20603
|
-
entryStatus: WILDCARD,
|
|
20604
|
-
drawDefinition,
|
|
20605
|
-
stage
|
|
20606
|
-
});
|
|
20607
|
-
const directEntriesCount = getStageEntryTypeCount({
|
|
20608
|
-
entryStatus: DIRECT_ACCEPTANCE,
|
|
20609
|
-
drawDefinition,
|
|
20610
|
-
stage
|
|
20611
|
-
});
|
|
20612
|
-
const totalEntriesCount = wildcardEntriesCount + directEntriesCount;
|
|
20613
|
-
const stageFull = totalEntriesCount >= stageDrawPositionsAvailable;
|
|
20614
|
-
const positionsAvailable = stageDrawPositionsAvailable - totalEntriesCount;
|
|
20615
|
-
if (stage !== VOLUNTARY_CONSOLATION && stageFull) {
|
|
20616
|
-
return { error: NO_STAGE_SPACE_AVAILABLE_FOR_ENTRY_STATUS };
|
|
20617
|
-
}
|
|
20618
|
-
if (entryStatus === WILDCARD) {
|
|
20619
|
-
if (wildcardEntriesCount < wildcardPositions)
|
|
20620
|
-
return { ...SUCCESS };
|
|
20621
|
-
return { error: NO_STAGE_SPACE_AVAILABLE_FOR_ENTRY_STATUS };
|
|
20622
|
-
}
|
|
20623
|
-
return { positionsAvailable, ...SUCCESS };
|
|
20624
|
-
}
|
|
20625
|
-
|
|
20626
|
-
function addDrawEntry(params) {
|
|
20627
|
-
const {
|
|
20628
|
-
entryStatus = EntryStatusEnum.DirectAcceptance,
|
|
20629
|
-
entryStageSequence,
|
|
20630
|
-
entryStage = MAIN,
|
|
20631
|
-
ignoreStageSpace,
|
|
20632
|
-
drawDefinition,
|
|
20633
|
-
entryPosition,
|
|
20634
|
-
participant,
|
|
20635
|
-
roundTarget,
|
|
20636
|
-
extensions,
|
|
20637
|
-
extension,
|
|
20638
|
-
drawType
|
|
20639
|
-
} = params;
|
|
20640
|
-
const stack = "addDrawEntry";
|
|
20641
|
-
if (!drawDefinition)
|
|
20642
|
-
return { error: MISSING_DRAW_DEFINITION };
|
|
20643
|
-
if (!entryStage)
|
|
20644
|
-
return { error: MISSING_STAGE };
|
|
20645
|
-
if (drawType !== AD_HOC && !getValidStage({ stage: entryStage, drawDefinition })) {
|
|
20646
|
-
return decorateResult({ result: { error: INVALID_STAGE }, stack });
|
|
20647
|
-
}
|
|
20648
|
-
const spaceAvailable = getStageSpace({
|
|
20649
|
-
stageSequence: entryStageSequence,
|
|
20650
|
-
stage: entryStage,
|
|
20651
|
-
drawDefinition,
|
|
20652
|
-
entryStatus
|
|
20653
|
-
});
|
|
20654
|
-
if (!ignoreStageSpace && !spaceAvailable.success) {
|
|
20655
|
-
return { error: spaceAvailable.error };
|
|
20656
|
-
}
|
|
20657
|
-
if (extension && !isValidExtension({ extension }))
|
|
20658
|
-
return decorateResult({
|
|
20659
|
-
result: { error: INVALID_VALUES },
|
|
20660
|
-
info: "Invalid extension",
|
|
20661
|
-
context: { extension },
|
|
20662
|
-
stack
|
|
20663
|
-
});
|
|
20664
|
-
const participantId = params.participantId || participant?.participantId;
|
|
20665
|
-
if (!participantId)
|
|
20666
|
-
return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
|
|
20667
|
-
const invalidLuckyLoser = entryStatus === EntryStatusEnum.LuckyLoser && participantInEntries({ participantId, drawDefinition, entryStatus });
|
|
20668
|
-
const invalidVoluntaryConsolation = entryStage === VOLUNTARY_CONSOLATION && participantInEntries({
|
|
20669
|
-
participantId,
|
|
20670
|
-
drawDefinition,
|
|
20671
|
-
entryStage
|
|
20672
|
-
});
|
|
20673
|
-
const invalidEntry = entryStatus !== EntryStatusEnum.LuckyLoser && entryStage !== VOLUNTARY_CONSOLATION && participantInEntries({ drawDefinition, participantId });
|
|
20674
|
-
if (invalidEntry || invalidLuckyLoser || invalidVoluntaryConsolation) {
|
|
20675
|
-
return decorateResult({
|
|
20676
|
-
context: { invalidEntry, invalidLuckyLoser, invalidVoluntaryConsolation },
|
|
20677
|
-
result: { error: EXISTING_PARTICIPANT },
|
|
20678
|
-
stack
|
|
20679
|
-
});
|
|
20680
|
-
}
|
|
20681
|
-
const entry = definedAttributes({
|
|
20682
|
-
entryStageSequence,
|
|
20683
|
-
participantId,
|
|
20684
|
-
entryPosition,
|
|
20685
|
-
entryStatus,
|
|
20686
|
-
entryStage,
|
|
20687
|
-
extensions
|
|
20688
|
-
});
|
|
20689
|
-
if (extension) {
|
|
20690
|
-
addExtension({ element: entry, extension });
|
|
20691
|
-
}
|
|
20692
|
-
if (roundTarget) {
|
|
20693
|
-
addExtension({
|
|
20694
|
-
extension: { name: "roundEntry", value: roundTarget },
|
|
20695
|
-
element: entry
|
|
20696
|
-
});
|
|
20697
|
-
}
|
|
20698
|
-
if (!drawDefinition.entries)
|
|
20699
|
-
drawDefinition.entries = [];
|
|
20700
|
-
drawDefinition.entries.push(entry);
|
|
20701
|
-
modifyDrawNotice({ drawDefinition });
|
|
20702
|
-
return { ...SUCCESS };
|
|
20703
|
-
}
|
|
20704
|
-
|
|
20705
|
-
function getAllowedDrawTypes({
|
|
20706
|
-
tournamentRecord,
|
|
20707
|
-
categoryName,
|
|
20708
|
-
categoryType
|
|
20709
|
-
}) {
|
|
20710
|
-
if (!tournamentRecord)
|
|
20711
|
-
return { error: MISSING_TOURNAMENT_RECORD };
|
|
20712
|
-
const { appliedPolicies } = getAppliedPolicies({ tournamentRecord });
|
|
20713
|
-
const drawTypesPolicy = appliedPolicies?.[POLICY_TYPE_DRAWS];
|
|
20714
|
-
const drawTypes = drawTypesPolicy?.allowedDrawTypes || [];
|
|
20715
|
-
return drawTypes.filter(
|
|
20716
|
-
({ categoryNames, categoryTypes }) => !categoryName && !categoryTypes || categoryName && categoryNames?.includes(categoryName) || categoryType && categoryTypes?.includes(categoryType)
|
|
20717
|
-
);
|
|
20718
|
-
}
|
|
20719
|
-
|
|
20720
|
-
function generateCandidate({
|
|
20721
|
-
maxIterations = 5e3,
|
|
20722
|
-
// cap the processing intensity of the candidate generator
|
|
20723
|
-
valueSortedPairings,
|
|
20724
|
-
// pairings sorted by value from low to high
|
|
20725
|
-
pairingValues,
|
|
20726
|
-
deltaObjects
|
|
20727
|
-
}) {
|
|
20728
|
-
const rankedMatchUpValues = Object.assign(
|
|
20729
|
-
{},
|
|
20730
|
-
...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
|
|
20731
|
-
);
|
|
20732
|
-
let candidate = roundCandidate({
|
|
20733
|
-
rankedMatchUpValues,
|
|
20734
|
-
valueSortedPairings,
|
|
20735
|
-
deltaObjects
|
|
20736
|
-
});
|
|
20737
|
-
let deltaCandidate = candidate;
|
|
20738
|
-
const actors = Object.keys(pairingValues);
|
|
20739
|
-
let candidatesCount = 0;
|
|
20740
|
-
let iterations;
|
|
20741
|
-
let opponentCount = actors.length;
|
|
20742
|
-
do {
|
|
20743
|
-
opponentCount -= 1;
|
|
20744
|
-
iterations = actors.length * opponentCount * valueSortedPairings.length / 2;
|
|
20745
|
-
} while (iterations > maxIterations && opponentCount > 2);
|
|
20746
|
-
const stipulatedPairs = [];
|
|
20747
|
-
actors.forEach((actor) => {
|
|
20748
|
-
const participantIdPairings = pairingValues[actor];
|
|
20749
|
-
participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
|
|
20750
|
-
const stipulatedPair = pairingHash(actor, pairing.opponent);
|
|
20751
|
-
if (!stipulatedPairs.includes(stipulatedPair)) {
|
|
20752
|
-
const proposed = roundCandidate({
|
|
20753
|
-
// each roundCandidate starts with stipulated pairings
|
|
20754
|
-
stipulated: [[actor, pairing.opponent]],
|
|
20755
|
-
rankedMatchUpValues,
|
|
20756
|
-
valueSortedPairings,
|
|
20757
|
-
deltaObjects
|
|
20758
|
-
});
|
|
20759
|
-
if (proposed.maxDelta < deltaCandidate.maxDelta)
|
|
20760
|
-
deltaCandidate = proposed;
|
|
20761
|
-
if (proposed.value < candidate.value)
|
|
20762
|
-
candidate = proposed;
|
|
20763
|
-
stipulatedPairs.push(stipulatedPair);
|
|
20764
|
-
candidatesCount += 1;
|
|
20765
|
-
}
|
|
20766
|
-
});
|
|
20767
|
-
});
|
|
20768
|
-
return { candidate, deltaCandidate, candidatesCount, iterations };
|
|
20769
|
-
}
|
|
20770
|
-
function roundCandidate({
|
|
20771
|
-
rankedMatchUpValues,
|
|
20772
|
-
valueSortedPairings,
|
|
20773
|
-
stipulated = [],
|
|
20774
|
-
deltaObjects
|
|
20775
|
-
}) {
|
|
20776
|
-
const roundPlayers = [].concat(...stipulated);
|
|
20777
|
-
const participantIdPairings = [];
|
|
20778
|
-
let candidateValue = 0;
|
|
20779
|
-
stipulated.filter(Boolean).forEach((participantIds) => {
|
|
20780
|
-
const [p1, p2] = participantIds;
|
|
20781
|
-
const pairing = pairingHash(p1, p2);
|
|
20782
|
-
const value = rankedMatchUpValues[pairing];
|
|
20783
|
-
participantIdPairings.push({ participantIds, value });
|
|
20784
|
-
candidateValue += rankedMatchUpValues[pairing];
|
|
20885
|
+
const personGender = participant?.person?.sex;
|
|
20886
|
+
const wrongGender = !ignoreGender && eventGender && eventType === TypeEnum.Singles && [GenderEnum.Male, GenderEnum.Female].includes(eventGender) && personGender !== eventGender;
|
|
20887
|
+
return mismatch || wrongGender;
|
|
20785
20888
|
});
|
|
20786
|
-
|
|
20787
|
-
const
|
|
20788
|
-
|
|
20789
|
-
(p, c) => roundPlayers.includes(c) || p,
|
|
20790
|
-
false
|
|
20889
|
+
if (invalidEntries.length) {
|
|
20890
|
+
const invalidParticipantIds = invalidEntries.map(
|
|
20891
|
+
(participant) => participant.participantId
|
|
20791
20892
|
);
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
candidateValue += value;
|
|
20796
|
-
participantIdPairings.push({ participantIds, value });
|
|
20797
|
-
}
|
|
20798
|
-
});
|
|
20799
|
-
participantIdPairings.sort((a, b) => a.value - b.value);
|
|
20800
|
-
const maxDelta = participantIdPairings.reduce((p, c) => {
|
|
20801
|
-
const [p1, p2] = c.participantIds;
|
|
20802
|
-
const hash = pairingHash(p1, p2);
|
|
20803
|
-
const delta = deltaObjects[hash];
|
|
20804
|
-
return delta > p ? delta : p;
|
|
20805
|
-
}, 0);
|
|
20806
|
-
return { value: candidateValue, participantIdPairings, maxDelta };
|
|
20893
|
+
return { error: INVALID_ENTRIES, invalidParticipantIds };
|
|
20894
|
+
}
|
|
20895
|
+
return { ...SUCCESS };
|
|
20807
20896
|
}
|
|
20808
|
-
|
|
20809
|
-
|
|
20897
|
+
|
|
20898
|
+
function getValidStage({ stage, drawDefinition }) {
|
|
20899
|
+
return Boolean(
|
|
20900
|
+
stage === VOLUNTARY_CONSOLATION || stageExists({ stage, drawDefinition }) && getStageDrawPositionsCount({ stage, drawDefinition })
|
|
20901
|
+
);
|
|
20810
20902
|
}
|
|
20811
20903
|
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
const DEFAULT_RATING = 0;
|
|
20815
|
-
const MAX_ITERATIONS = 5e3;
|
|
20816
|
-
function generateDrawMaticRound({
|
|
20817
|
-
maxIterations = MAX_ITERATIONS,
|
|
20818
|
-
generateMatchUps = true,
|
|
20819
|
-
tournamentParticipants,
|
|
20820
|
-
tournamentRecord,
|
|
20821
|
-
participantIds,
|
|
20822
|
-
addToStructure,
|
|
20904
|
+
function getStageSpace({
|
|
20905
|
+
entryStatus = DIRECT_ACCEPTANCE,
|
|
20823
20906
|
drawDefinition,
|
|
20824
|
-
|
|
20825
|
-
|
|
20826
|
-
matchUpIds,
|
|
20827
|
-
eventType,
|
|
20828
|
-
structure
|
|
20907
|
+
stageSequence,
|
|
20908
|
+
stage
|
|
20829
20909
|
}) {
|
|
20830
|
-
if (
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
for (const pairing of encounters) {
|
|
20836
|
-
if (!valueObjects[pairing])
|
|
20837
|
-
valueObjects[pairing] = 0;
|
|
20838
|
-
valueObjects[pairing] += ENCOUNTER_VALUE;
|
|
20839
|
-
}
|
|
20840
|
-
const teamParticipants = tournamentParticipants?.filter(
|
|
20841
|
-
({ participantType }) => participantType === TEAM
|
|
20842
|
-
);
|
|
20843
|
-
if (teamParticipants) {
|
|
20844
|
-
for (const teamParticipant of teamParticipants) {
|
|
20845
|
-
const participantIds2 = teamParticipant.individualParticipantIds || [];
|
|
20846
|
-
const { uniquePairings: uniquePairings2 } = getPairingsData({ participantIds: participantIds2 });
|
|
20847
|
-
for (const pairing of uniquePairings2) {
|
|
20848
|
-
if (!valueObjects[pairing])
|
|
20849
|
-
valueObjects[pairing] = 0;
|
|
20850
|
-
valueObjects[pairing] += SAME_TEAM_VALUE;
|
|
20851
|
-
}
|
|
20910
|
+
if (entryStatus === ALTERNATE) {
|
|
20911
|
+
if (stageAlternatesCount({ stage, drawDefinition })) {
|
|
20912
|
+
return { positionsAvailable: Infinity, ...SUCCESS };
|
|
20913
|
+
} else {
|
|
20914
|
+
return { error: ENTRY_STATUS_NOT_ALLOWED_IN_STAGE };
|
|
20852
20915
|
}
|
|
20853
20916
|
}
|
|
20854
|
-
const
|
|
20855
|
-
participantIds
|
|
20856
|
-
});
|
|
20857
|
-
const params = {
|
|
20858
|
-
tournamentParticipants,
|
|
20859
|
-
possiblePairings,
|
|
20917
|
+
const stageDrawPositionsAvailable = getStageDrawPositionsAvailable({
|
|
20860
20918
|
drawDefinition,
|
|
20861
|
-
|
|
20862
|
-
|
|
20863
|
-
maxIterations,
|
|
20864
|
-
adHocRatings,
|
|
20865
|
-
deltaObjects,
|
|
20866
|
-
valueObjects,
|
|
20867
|
-
eventType,
|
|
20868
|
-
structure
|
|
20869
|
-
};
|
|
20870
|
-
const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
|
|
20871
|
-
if (!candidatesCount)
|
|
20872
|
-
return { error: NO_CANDIDATES };
|
|
20873
|
-
let matchUps;
|
|
20874
|
-
if (generateMatchUps) {
|
|
20875
|
-
const result = generateAdHocMatchUps({
|
|
20876
|
-
participantIdPairings,
|
|
20877
|
-
tournamentRecord,
|
|
20878
|
-
addToStructure,
|
|
20879
|
-
newRound: true,
|
|
20880
|
-
drawDefinition,
|
|
20881
|
-
structureId,
|
|
20882
|
-
matchUpIds
|
|
20883
|
-
});
|
|
20884
|
-
if (result.error)
|
|
20885
|
-
return result;
|
|
20886
|
-
matchUps = result.matchUps;
|
|
20887
|
-
}
|
|
20888
|
-
return {
|
|
20889
|
-
...SUCCESS,
|
|
20890
|
-
participantIdPairings,
|
|
20891
|
-
candidatesCount,
|
|
20892
|
-
iterations,
|
|
20893
|
-
matchUps
|
|
20894
|
-
};
|
|
20895
|
-
}
|
|
20896
|
-
function getSideRatings({
|
|
20897
|
-
tournamentParticipants,
|
|
20898
|
-
adHocRatings,
|
|
20899
|
-
eventType,
|
|
20900
|
-
pairing
|
|
20901
|
-
}) {
|
|
20902
|
-
return pairing.split("|").map((participantId) => {
|
|
20903
|
-
if (eventType === DOUBLES) {
|
|
20904
|
-
const individualParticipantIds = tournamentParticipants?.find(
|
|
20905
|
-
(participant) => participant.participantId === participantId
|
|
20906
|
-
)?.individualParticipantIds;
|
|
20907
|
-
return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
|
|
20908
|
-
(participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
|
|
20909
|
-
);
|
|
20910
|
-
} else {
|
|
20911
|
-
return adHocRatings[participantId] || DEFAULT_RATING;
|
|
20912
|
-
}
|
|
20919
|
+
stageSequence,
|
|
20920
|
+
stage
|
|
20913
20921
|
});
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
adHocRatings = {},
|
|
20918
|
-
possiblePairings,
|
|
20919
|
-
// participant keyed; provides array of possible opponents
|
|
20920
|
-
uniquePairings,
|
|
20921
|
-
// hashes of all possible participantId pairings
|
|
20922
|
-
maxIterations,
|
|
20923
|
-
deltaObjects,
|
|
20924
|
-
// difference in rating between paired participants
|
|
20925
|
-
valueObjects,
|
|
20926
|
-
// calculated value of a pairing of participants, used for sorting pairings
|
|
20927
|
-
eventType
|
|
20928
|
-
}) {
|
|
20929
|
-
uniquePairings.forEach((pairing) => {
|
|
20930
|
-
const ratings = getSideRatings({
|
|
20931
|
-
tournamentParticipants,
|
|
20932
|
-
adHocRatings,
|
|
20933
|
-
eventType,
|
|
20934
|
-
pairing
|
|
20935
|
-
});
|
|
20936
|
-
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
|
|
20937
|
-
deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
|
|
20938
|
-
if (!valueObjects[pairing])
|
|
20939
|
-
valueObjects[pairing] = 0;
|
|
20940
|
-
valueObjects[pairing] += Math.pow(ratingsDifference, 2);
|
|
20922
|
+
const wildcardPositions = getStageWildcardsCount({
|
|
20923
|
+
drawDefinition,
|
|
20924
|
+
stage
|
|
20941
20925
|
});
|
|
20942
|
-
const
|
|
20943
|
-
|
|
20944
|
-
|
|
20945
|
-
|
|
20926
|
+
const wildcardEntriesCount = getStageEntryTypeCount({
|
|
20927
|
+
entryStatus: WILDCARD,
|
|
20928
|
+
drawDefinition,
|
|
20929
|
+
stage
|
|
20946
20930
|
});
|
|
20947
|
-
const
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
|
|
20951
|
-
deltaObjects
|
|
20931
|
+
const directEntriesCount = getStageEntryTypeCount({
|
|
20932
|
+
entryStatus: DIRECT_ACCEPTANCE,
|
|
20933
|
+
drawDefinition,
|
|
20934
|
+
stage
|
|
20952
20935
|
});
|
|
20953
|
-
const
|
|
20954
|
-
|
|
20936
|
+
const totalEntriesCount = wildcardEntriesCount + directEntriesCount;
|
|
20937
|
+
const stageFull = totalEntriesCount >= stageDrawPositionsAvailable;
|
|
20938
|
+
const positionsAvailable = stageDrawPositionsAvailable - totalEntriesCount;
|
|
20939
|
+
if (stage !== VOLUNTARY_CONSOLATION && stageFull) {
|
|
20940
|
+
return { error: NO_STAGE_SPACE_AVAILABLE_FOR_ENTRY_STATUS };
|
|
20941
|
+
}
|
|
20942
|
+
if (entryStatus === WILDCARD) {
|
|
20943
|
+
if (wildcardEntriesCount < wildcardPositions)
|
|
20944
|
+
return { ...SUCCESS };
|
|
20945
|
+
return { error: NO_STAGE_SPACE_AVAILABLE_FOR_ENTRY_STATUS };
|
|
20946
|
+
}
|
|
20947
|
+
return { positionsAvailable, ...SUCCESS };
|
|
20955
20948
|
}
|
|
20956
|
-
|
|
20957
|
-
|
|
20958
|
-
const
|
|
20959
|
-
|
|
20960
|
-
|
|
20961
|
-
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
|
|
20965
|
-
|
|
20966
|
-
|
|
20949
|
+
|
|
20950
|
+
function addDrawEntry(params) {
|
|
20951
|
+
const {
|
|
20952
|
+
entryStatus = EntryStatusEnum.DirectAcceptance,
|
|
20953
|
+
entryStageSequence,
|
|
20954
|
+
entryStage = MAIN,
|
|
20955
|
+
ignoreStageSpace,
|
|
20956
|
+
drawDefinition,
|
|
20957
|
+
entryPosition,
|
|
20958
|
+
participant,
|
|
20959
|
+
roundTarget,
|
|
20960
|
+
extensions,
|
|
20961
|
+
extension,
|
|
20962
|
+
drawType
|
|
20963
|
+
} = params;
|
|
20964
|
+
const stack = "addDrawEntry";
|
|
20965
|
+
if (!drawDefinition)
|
|
20966
|
+
return { error: MISSING_DRAW_DEFINITION };
|
|
20967
|
+
if (!entryStage)
|
|
20968
|
+
return { error: MISSING_STAGE };
|
|
20969
|
+
if (drawType !== AD_HOC && !getValidStage({ stage: entryStage, drawDefinition })) {
|
|
20970
|
+
return decorateResult({ result: { error: INVALID_STAGE }, stack });
|
|
20971
|
+
}
|
|
20972
|
+
const spaceAvailable = getStageSpace({
|
|
20973
|
+
stageSequence: entryStageSequence,
|
|
20974
|
+
stage: entryStage,
|
|
20975
|
+
drawDefinition,
|
|
20976
|
+
entryStatus
|
|
20977
|
+
});
|
|
20978
|
+
if (!ignoreStageSpace && !spaceAvailable.success) {
|
|
20979
|
+
return { error: spaceAvailable.error };
|
|
20980
|
+
}
|
|
20981
|
+
if (extension && !isValidExtension({ extension }))
|
|
20982
|
+
return decorateResult({
|
|
20983
|
+
result: { error: INVALID_VALUES },
|
|
20984
|
+
info: "Invalid extension",
|
|
20985
|
+
context: { extension },
|
|
20986
|
+
stack
|
|
20967
20987
|
});
|
|
20988
|
+
const participantId = params.participantId || participant?.participantId;
|
|
20989
|
+
if (!participantId)
|
|
20990
|
+
return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
|
|
20991
|
+
const invalidLuckyLoser = entryStatus === EntryStatusEnum.LuckyLoser && participantInEntries({ participantId, drawDefinition, entryStatus });
|
|
20992
|
+
const invalidVoluntaryConsolation = entryStage === VOLUNTARY_CONSOLATION && participantInEntries({
|
|
20993
|
+
participantId,
|
|
20994
|
+
drawDefinition,
|
|
20995
|
+
entryStage
|
|
20968
20996
|
});
|
|
20969
|
-
const
|
|
20970
|
-
|
|
20971
|
-
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
const encounters = [];
|
|
20977
|
-
for (const matchUp of matchUps) {
|
|
20978
|
-
const participantIds = matchUp.sides.map(getParticipantId);
|
|
20979
|
-
if (participantIds.length === 2) {
|
|
20980
|
-
const [p1, p2] = participantIds;
|
|
20981
|
-
const pairing = pairingHash(p1, p2);
|
|
20982
|
-
if (!encounters.includes(pairing))
|
|
20983
|
-
encounters.push(pairing);
|
|
20984
|
-
}
|
|
20997
|
+
const invalidEntry = entryStatus !== EntryStatusEnum.LuckyLoser && entryStage !== VOLUNTARY_CONSOLATION && participantInEntries({ drawDefinition, participantId });
|
|
20998
|
+
if (invalidEntry || invalidLuckyLoser || invalidVoluntaryConsolation) {
|
|
20999
|
+
return decorateResult({
|
|
21000
|
+
context: { invalidEntry, invalidLuckyLoser, invalidVoluntaryConsolation },
|
|
21001
|
+
result: { error: EXISTING_PARTICIPANT },
|
|
21002
|
+
stack
|
|
21003
|
+
});
|
|
20985
21004
|
}
|
|
20986
|
-
|
|
20987
|
-
|
|
20988
|
-
|
|
20989
|
-
|
|
20990
|
-
|
|
20991
|
-
|
|
20992
|
-
|
|
20993
|
-
|
|
20994
|
-
|
|
20995
|
-
|
|
20996
|
-
);
|
|
21005
|
+
const entry = definedAttributes({
|
|
21006
|
+
entryStageSequence,
|
|
21007
|
+
participantId,
|
|
21008
|
+
entryPosition,
|
|
21009
|
+
entryStatus,
|
|
21010
|
+
entryStage,
|
|
21011
|
+
extensions
|
|
21012
|
+
});
|
|
21013
|
+
if (extension) {
|
|
21014
|
+
addExtension({ element: entry, extension });
|
|
20997
21015
|
}
|
|
20998
|
-
|
|
20999
|
-
|
|
21000
|
-
|
|
21016
|
+
if (roundTarget) {
|
|
21017
|
+
addExtension({
|
|
21018
|
+
extension: { name: "roundEntry", value: roundTarget },
|
|
21019
|
+
element: entry
|
|
21020
|
+
});
|
|
21001
21021
|
}
|
|
21002
|
-
|
|
21022
|
+
if (!drawDefinition.entries)
|
|
21023
|
+
drawDefinition.entries = [];
|
|
21024
|
+
drawDefinition.entries.push(entry);
|
|
21025
|
+
modifyDrawNotice({ drawDefinition });
|
|
21026
|
+
return { ...SUCCESS };
|
|
21003
21027
|
}
|
|
21004
21028
|
|
|
21005
|
-
function
|
|
21006
|
-
tournamentParticipants,
|
|
21007
|
-
restrictEntryStatus,
|
|
21029
|
+
function getAllowedDrawTypes({
|
|
21008
21030
|
tournamentRecord,
|
|
21009
|
-
|
|
21010
|
-
|
|
21011
|
-
participantIds,
|
|
21012
|
-
drawDefinition,
|
|
21013
|
-
maxIterations,
|
|
21014
|
-
structureId,
|
|
21015
|
-
matchUpIds,
|
|
21016
|
-
scaleName,
|
|
21017
|
-
// custom rating name to seed dynamic ratings
|
|
21018
|
-
eventType,
|
|
21019
|
-
event
|
|
21031
|
+
categoryName,
|
|
21032
|
+
categoryType
|
|
21020
21033
|
}) {
|
|
21021
|
-
if (
|
|
21022
|
-
return { error:
|
|
21023
|
-
}
|
|
21024
|
-
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
const enteredParticipantIds = drawDefinition?.entries?.filter((entry) => {
|
|
21029
|
-
const entryStatus = entry.entryStatus;
|
|
21030
|
-
return !restrictEntryStatus || STRUCTURE_SELECTED_STATUSES.includes(entryStatus);
|
|
21031
|
-
}).map(getParticipantId);
|
|
21032
|
-
if (participantIds) {
|
|
21033
|
-
const invalidParticipantIds = participantIds.filter(
|
|
21034
|
-
(participantId) => !enteredParticipantIds?.includes(participantId)
|
|
21035
|
-
);
|
|
21036
|
-
if (invalidParticipantIds?.length)
|
|
21037
|
-
return {
|
|
21038
|
-
error: INVALID_PARTICIPANT_ID,
|
|
21039
|
-
invalidParticipantIds
|
|
21040
|
-
};
|
|
21041
|
-
} else {
|
|
21042
|
-
participantIds = enteredParticipantIds;
|
|
21043
|
-
}
|
|
21044
|
-
if (!structureId) {
|
|
21045
|
-
const targetStructure = drawDefinition?.structures?.filter((structure2) => structure2.stageSequence === 1)?.reduce((targetStructure2, structure2) => {
|
|
21046
|
-
const orderNumber = structure2.stage && stageOrder[structure2.stage];
|
|
21047
|
-
const structureIsAdHoc2 = isAdHoc({ drawDefinition, structure: structure2 });
|
|
21048
|
-
return structureIsAdHoc2 && orderNumber > (stageOrder[targetStructure2?.stage] || 1) ? structure2 : targetStructure2;
|
|
21049
|
-
}, void 0);
|
|
21050
|
-
structureId = targetStructure?.structureId;
|
|
21051
|
-
}
|
|
21052
|
-
const structure = drawDefinition?.structures?.find(
|
|
21053
|
-
(structure2) => structure2.structureId === structureId
|
|
21034
|
+
if (!tournamentRecord)
|
|
21035
|
+
return { error: MISSING_TOURNAMENT_RECORD };
|
|
21036
|
+
const { appliedPolicies } = getAppliedPolicies({ tournamentRecord });
|
|
21037
|
+
const drawTypesPolicy = appliedPolicies?.[POLICY_TYPE_DRAWS];
|
|
21038
|
+
const drawTypes = drawTypesPolicy?.allowedDrawTypes || [];
|
|
21039
|
+
return drawTypes.filter(
|
|
21040
|
+
({ categoryNames, categoryTypes }) => !categoryName && !categoryTypes || categoryName && categoryNames?.includes(categoryName) || categoryType && categoryTypes?.includes(categoryType)
|
|
21054
21041
|
);
|
|
21055
|
-
if (!structure)
|
|
21056
|
-
return { error: STRUCTURE_NOT_FOUND };
|
|
21057
|
-
const structureIsAdHoc = isAdHoc({ drawDefinition, structure });
|
|
21058
|
-
if (!structureIsAdHoc)
|
|
21059
|
-
return { error: INVALID_DRAW_DEFINITION };
|
|
21060
|
-
const adHocRatings = {};
|
|
21061
|
-
for (const participantId of participantIds ?? []) {
|
|
21062
|
-
const participant = tournamentParticipants?.find(
|
|
21063
|
-
(participant2) => participant2.participantId === participantId
|
|
21064
|
-
);
|
|
21065
|
-
let scaleValue = getScaleValue({ eventType, participant });
|
|
21066
|
-
if (!scaleValue && scaleName) {
|
|
21067
|
-
scaleValue = getScaleValue({ scaleName, eventType, participant });
|
|
21068
|
-
}
|
|
21069
|
-
if (scaleValue)
|
|
21070
|
-
adHocRatings[participantId] = scaleValue;
|
|
21071
|
-
}
|
|
21072
|
-
return generateDrawMaticRound({
|
|
21073
|
-
tournamentParticipants,
|
|
21074
|
-
tournamentRecord,
|
|
21075
|
-
generateMatchUps,
|
|
21076
|
-
participantIds,
|
|
21077
|
-
addToStructure,
|
|
21078
|
-
drawDefinition,
|
|
21079
|
-
maxIterations,
|
|
21080
|
-
adHocRatings,
|
|
21081
|
-
structureId,
|
|
21082
|
-
matchUpIds,
|
|
21083
|
-
structure,
|
|
21084
|
-
eventType
|
|
21085
|
-
});
|
|
21086
|
-
}
|
|
21087
|
-
function getScaleValue({ scaleName = "dynamic", eventType, participant }) {
|
|
21088
|
-
const scaleAttributes = {
|
|
21089
|
-
eventType: eventType || TypeEnum.Singles,
|
|
21090
|
-
scaleType: RATING,
|
|
21091
|
-
scaleName
|
|
21092
|
-
};
|
|
21093
|
-
const result = participant && participantScaleItem({
|
|
21094
|
-
scaleAttributes,
|
|
21095
|
-
participant
|
|
21096
|
-
});
|
|
21097
|
-
return result?.scaleItem?.scaleValue;
|
|
21098
21042
|
}
|
|
21099
21043
|
|
|
21100
21044
|
const definitionTemplate = () => ({
|
|
@@ -22572,6 +22516,113 @@ function prepareStage(params) {
|
|
|
22572
22516
|
};
|
|
22573
22517
|
}
|
|
22574
22518
|
|
|
22519
|
+
function drawMatic({
|
|
22520
|
+
tournamentParticipants,
|
|
22521
|
+
restrictEntryStatus,
|
|
22522
|
+
tournamentRecord,
|
|
22523
|
+
generateMatchUps,
|
|
22524
|
+
addToStructure,
|
|
22525
|
+
participantIds,
|
|
22526
|
+
drawDefinition,
|
|
22527
|
+
scaleAccessor,
|
|
22528
|
+
maxIterations,
|
|
22529
|
+
structureId,
|
|
22530
|
+
matchUpIds,
|
|
22531
|
+
scaleName,
|
|
22532
|
+
// custom rating name to seed dynamic ratings
|
|
22533
|
+
eventType,
|
|
22534
|
+
event
|
|
22535
|
+
}) {
|
|
22536
|
+
if (typeof drawDefinition !== "object" || drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) {
|
|
22537
|
+
return { error: INVALID_DRAW_DEFINITION };
|
|
22538
|
+
}
|
|
22539
|
+
if (!Array.isArray(drawDefinition?.entries) && participantIds && !Array.isArray(participantIds)) {
|
|
22540
|
+
return { error: INVALID_VALUES, info: "Missing Entries" };
|
|
22541
|
+
}
|
|
22542
|
+
eventType = eventType ?? event?.eventType;
|
|
22543
|
+
const enteredParticipantIds = drawDefinition?.entries?.filter((entry) => {
|
|
22544
|
+
const entryStatus = entry.entryStatus;
|
|
22545
|
+
return !restrictEntryStatus || STRUCTURE_SELECTED_STATUSES.includes(entryStatus);
|
|
22546
|
+
}).map(getParticipantId);
|
|
22547
|
+
if (participantIds) {
|
|
22548
|
+
const invalidParticipantIds = participantIds.filter(
|
|
22549
|
+
(participantId) => !enteredParticipantIds?.includes(participantId)
|
|
22550
|
+
);
|
|
22551
|
+
if (invalidParticipantIds?.length)
|
|
22552
|
+
return {
|
|
22553
|
+
error: INVALID_PARTICIPANT_ID,
|
|
22554
|
+
invalidParticipantIds
|
|
22555
|
+
};
|
|
22556
|
+
} else {
|
|
22557
|
+
participantIds = enteredParticipantIds;
|
|
22558
|
+
}
|
|
22559
|
+
if (!structureId) {
|
|
22560
|
+
const targetStructure = drawDefinition?.structures?.filter((structure2) => structure2.stageSequence === 1)?.reduce((targetStructure2, structure2) => {
|
|
22561
|
+
const orderNumber = structure2.stage && stageOrder[structure2.stage];
|
|
22562
|
+
const structureIsAdHoc2 = isAdHoc({ drawDefinition, structure: structure2 });
|
|
22563
|
+
return structureIsAdHoc2 && orderNumber > (stageOrder[targetStructure2?.stage] || 1) ? structure2 : targetStructure2;
|
|
22564
|
+
}, void 0);
|
|
22565
|
+
structureId = targetStructure?.structureId;
|
|
22566
|
+
}
|
|
22567
|
+
const structure = drawDefinition?.structures?.find(
|
|
22568
|
+
(structure2) => structure2.structureId === structureId
|
|
22569
|
+
);
|
|
22570
|
+
if (!structure)
|
|
22571
|
+
return { error: STRUCTURE_NOT_FOUND };
|
|
22572
|
+
const structureIsAdHoc = isAdHoc({ drawDefinition, structure });
|
|
22573
|
+
if (!structureIsAdHoc)
|
|
22574
|
+
return { error: INVALID_DRAW_DEFINITION };
|
|
22575
|
+
tournamentParticipants = tournamentParticipants ?? tournamentRecord.participants ?? [];
|
|
22576
|
+
const adHocRatings = {};
|
|
22577
|
+
for (const participantId of participantIds ?? []) {
|
|
22578
|
+
const participant = tournamentParticipants?.find(
|
|
22579
|
+
(participant2) => participant2.participantId === participantId
|
|
22580
|
+
);
|
|
22581
|
+
let scaleValue = getScaleValue({ eventType, participant });
|
|
22582
|
+
if (!scaleValue && scaleName) {
|
|
22583
|
+
scaleValue = getScaleValue({
|
|
22584
|
+
scaleAccessor,
|
|
22585
|
+
participant,
|
|
22586
|
+
scaleName,
|
|
22587
|
+
eventType
|
|
22588
|
+
});
|
|
22589
|
+
}
|
|
22590
|
+
if (scaleValue)
|
|
22591
|
+
adHocRatings[participantId] = scaleValue;
|
|
22592
|
+
}
|
|
22593
|
+
return generateDrawMaticRound({
|
|
22594
|
+
tournamentParticipants,
|
|
22595
|
+
tournamentRecord,
|
|
22596
|
+
generateMatchUps,
|
|
22597
|
+
participantIds,
|
|
22598
|
+
addToStructure,
|
|
22599
|
+
drawDefinition,
|
|
22600
|
+
maxIterations,
|
|
22601
|
+
adHocRatings,
|
|
22602
|
+
matchUpIds,
|
|
22603
|
+
structure,
|
|
22604
|
+
eventType
|
|
22605
|
+
});
|
|
22606
|
+
}
|
|
22607
|
+
function getScaleValue({
|
|
22608
|
+
eventType = TypeEnum.Singles,
|
|
22609
|
+
scaleName = "dynamic",
|
|
22610
|
+
scaleAccessor,
|
|
22611
|
+
participant
|
|
22612
|
+
}) {
|
|
22613
|
+
const scaleAttributes = {
|
|
22614
|
+
eventType: eventType || TypeEnum.Singles,
|
|
22615
|
+
scaleType: RATING,
|
|
22616
|
+
scaleName
|
|
22617
|
+
};
|
|
22618
|
+
const result = participant && participantScaleItem({
|
|
22619
|
+
scaleAttributes,
|
|
22620
|
+
participant
|
|
22621
|
+
});
|
|
22622
|
+
const scaleValue = result?.scaleItem?.scaleValue;
|
|
22623
|
+
return scaleAccessor && isObject(scaleValue) ? scaleValue[scaleAccessor] : scaleValue;
|
|
22624
|
+
}
|
|
22625
|
+
|
|
22575
22626
|
const POLICY_SEEDING_USTA = {
|
|
22576
22627
|
[POLICY_TYPE_SEEDING]: {
|
|
22577
22628
|
validSeedPositions: { ignore: true },
|
|
@@ -22899,12 +22950,28 @@ function generateDrawDefinition(params) {
|
|
|
22899
22950
|
const matchUpsCount = entries2 ? Math.floor(entries2.length / 2) : 0;
|
|
22900
22951
|
generateRange(1, params.roundsCount + 1).forEach(() => {
|
|
22901
22952
|
if (params.automated) {
|
|
22953
|
+
const {
|
|
22954
|
+
restrictEntryStatus,
|
|
22955
|
+
generateMatchUps,
|
|
22956
|
+
addToStructure,
|
|
22957
|
+
maxIterations,
|
|
22958
|
+
structureId: structureId2,
|
|
22959
|
+
matchUpIds,
|
|
22960
|
+
scaleName
|
|
22961
|
+
} = params.drawMatic ?? {};
|
|
22902
22962
|
drawMatic({
|
|
22903
|
-
generateMatchUps: true,
|
|
22904
|
-
eventType: matchUpType,
|
|
22905
22963
|
tournamentRecord,
|
|
22906
22964
|
participantIds,
|
|
22907
|
-
drawDefinition
|
|
22965
|
+
drawDefinition,
|
|
22966
|
+
eventType: params.drawMatic?.eventType ?? matchUpType,
|
|
22967
|
+
generateMatchUps: generateMatchUps ?? true,
|
|
22968
|
+
restrictEntryStatus,
|
|
22969
|
+
addToStructure,
|
|
22970
|
+
maxIterations,
|
|
22971
|
+
structureId: structureId2,
|
|
22972
|
+
matchUpIds,
|
|
22973
|
+
scaleName
|
|
22974
|
+
// custom rating name to seed dynamic ratings
|
|
22908
22975
|
});
|
|
22909
22976
|
} else {
|
|
22910
22977
|
generateAdHocMatchUps({
|
|
@@ -23146,5 +23213,5 @@ function generateFlightProfile(params) {
|
|
|
23146
23213
|
}
|
|
23147
23214
|
}
|
|
23148
23215
|
|
|
23149
|
-
export { automatedPlayoffPositioning, automatedPositioning, createGroupParticipant, generateAndPopulatePlayoffStructures, generateDrawDefinition, generateFlightProfile, generateVoluntaryConsolation };
|
|
23216
|
+
export { automatedPlayoffPositioning, automatedPositioning, createGroupParticipant, generateAndPopulatePlayoffStructures, generateDrawDefinition, generateDrawMaticRound, generateFlightProfile, generateVoluntaryConsolation };
|
|
23150
23217
|
//# sourceMappingURL=generate.mjs.map
|