tods-competition-factory 1.7.2 → 1.7.4
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 +7 -2
- package/dist/forge/generate.mjs +350 -223
- package/dist/forge/generate.mjs.map +1 -1
- package/dist/forge/query.mjs +1 -1
- package/dist/forge/query.mjs.map +1 -1
- package/dist/forge/transform.mjs +1 -1
- package/dist/forge/transform.mjs.map +1 -1
- package/dist/index.mjs +303 -187
- package/dist/index.mjs.map +1 -1
- package/dist/tods-competition-factory.development.cjs.js +336 -233
- 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 +4 -4
package/dist/index.mjs
CHANGED
|
@@ -333,7 +333,7 @@ const matchUpFormatCode = {
|
|
|
333
333
|
};
|
|
334
334
|
|
|
335
335
|
function factoryVersion() {
|
|
336
|
-
return "1.7.
|
|
336
|
+
return "1.7.4";
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
function getObjectTieFormat(obj) {
|
|
@@ -4404,6 +4404,7 @@ function getMatchUpFormatAverageTimes({
|
|
|
4404
4404
|
});
|
|
4405
4405
|
}
|
|
4406
4406
|
|
|
4407
|
+
const DYNAMIC = "DYNAMIC";
|
|
4407
4408
|
const RANKING$1 = "RANKING";
|
|
4408
4409
|
const RATING$2 = "RATING";
|
|
4409
4410
|
const SCALE$1 = "SCALE";
|
|
@@ -6183,7 +6184,7 @@ function getRoundMatchUps$1({
|
|
|
6183
6184
|
roundProfile[roundNumber].finishingRound = finishingRoundMap[roundNumber]?.finishingRound;
|
|
6184
6185
|
roundProfile[roundNumber].roundName = finishingRoundMap[roundNumber]?.roundName;
|
|
6185
6186
|
roundProfile[roundNumber].abbreviatedRoundName = finishingRoundMap[roundNumber]?.abbreviatedRoundName;
|
|
6186
|
-
roundProfile[roundNumber].finishingPositionRange = roundMatchUps[roundNumber][0]
|
|
6187
|
+
roundProfile[roundNumber].finishingPositionRange = roundMatchUps[roundNumber]?.[0]?.finishingPositionRange;
|
|
6187
6188
|
if (roundNumber === 1 || !roundProfile[roundNumber - 1]) {
|
|
6188
6189
|
const orderedDrawPositions = currentRoundDrawPositions.sort(numericSort);
|
|
6189
6190
|
const pairedDrawPositions = chunkArray(orderedDrawPositions, 2);
|
|
@@ -13381,21 +13382,27 @@ const ratingConstants = {
|
|
|
13381
13382
|
const ratingsParameters = {
|
|
13382
13383
|
[ELO]: { range: [0, 3e3], decimalsCount: 0, defaultInitialization: 1500 },
|
|
13383
13384
|
[NTRP]: {
|
|
13384
|
-
range: [1, 7],
|
|
13385
|
-
decimalsCount: 1,
|
|
13386
|
-
defaultInitialization: 3,
|
|
13387
|
-
accessor: "dntrpRatingHundredths",
|
|
13388
13385
|
accessors: ["ntrpRating", "dntrpRatingHundredths"],
|
|
13389
|
-
attributes: { ustaRatingType: "" }
|
|
13386
|
+
attributes: { ustaRatingType: "" },
|
|
13387
|
+
accessor: "dntrpRatingHundredths",
|
|
13388
|
+
defaultInitialization: 3,
|
|
13389
|
+
decimalsCount: 1,
|
|
13390
|
+
range: [1, 7]
|
|
13390
13391
|
},
|
|
13391
|
-
[UTR]: {
|
|
13392
|
-
|
|
13393
|
-
|
|
13392
|
+
[UTR]: {
|
|
13393
|
+
defaultInitialization: 6,
|
|
13394
|
+
accessors: ["utrRating"],
|
|
13395
|
+
accessor: "utrRating",
|
|
13394
13396
|
decimalsCount: 2,
|
|
13397
|
+
range: [1, 16]
|
|
13398
|
+
},
|
|
13399
|
+
[WTN]: {
|
|
13400
|
+
attributes: { confidence: { generator: true, range: [60, 100] } },
|
|
13401
|
+
accessors: ["wtnRating", "confidence"],
|
|
13395
13402
|
defaultInitialization: 23,
|
|
13396
13403
|
accessor: "wtnRating",
|
|
13397
|
-
|
|
13398
|
-
|
|
13404
|
+
decimalsCount: 2,
|
|
13405
|
+
range: [40, 1]
|
|
13399
13406
|
}
|
|
13400
13407
|
};
|
|
13401
13408
|
|
|
@@ -28916,9 +28923,9 @@ function getParticipantEntries(params) {
|
|
|
28916
28923
|
if (!participation)
|
|
28917
28924
|
return;
|
|
28918
28925
|
if (!finishingPositionRange)
|
|
28919
|
-
finishingPositionRange = participation
|
|
28920
|
-
if (diff(finishingPositionRange) > diff(participation
|
|
28921
|
-
finishingPositionRange = participation
|
|
28926
|
+
finishingPositionRange = participation?.finishingPositionRange;
|
|
28927
|
+
if (diff(finishingPositionRange) > diff(participation?.finishingPositionRange))
|
|
28928
|
+
finishingPositionRange = participation?.finishingPositionRange;
|
|
28922
28929
|
const notQualifying = participation.stage !== QUALIFYING;
|
|
28923
28930
|
if (notQualifying)
|
|
28924
28931
|
nonQualifyingOrder += 1;
|
|
@@ -28929,8 +28936,10 @@ function getParticipantEntries(params) {
|
|
|
28929
28936
|
flightNumber
|
|
28930
28937
|
});
|
|
28931
28938
|
}).filter(Boolean);
|
|
28932
|
-
participantAggregator.draws[drawId]
|
|
28933
|
-
|
|
28939
|
+
if (participantAggregator.draws[drawId]) {
|
|
28940
|
+
participantAggregator.draws[drawId].finishingPositionRange = finishingPositionRange;
|
|
28941
|
+
participantAggregator.draws[drawId].structureParticipation = orderedParticipation;
|
|
28942
|
+
}
|
|
28934
28943
|
}
|
|
28935
28944
|
}
|
|
28936
28945
|
}
|
|
@@ -39654,6 +39663,7 @@ function generateCurtisConsolation(params) {
|
|
|
39654
39663
|
finishingPositionOffset,
|
|
39655
39664
|
structureName = MAIN,
|
|
39656
39665
|
stageSequence = 1,
|
|
39666
|
+
structureNameMap,
|
|
39657
39667
|
staggeredEntry,
|
|
39658
39668
|
stage = MAIN,
|
|
39659
39669
|
matchUpType,
|
|
@@ -39687,8 +39697,9 @@ function generateCurtisConsolation(params) {
|
|
|
39687
39697
|
const consolationItems = feedRoundOffsets.map((roundOffset, index) => {
|
|
39688
39698
|
const stageSequence2 = index + 1;
|
|
39689
39699
|
const { consolationStructure } = consolationFeedStructure({
|
|
39690
|
-
structureId: uuids?.pop(),
|
|
39691
39700
|
idPrefix: idPrefix && `${idPrefix}-c${index}`,
|
|
39701
|
+
structureId: uuids?.pop(),
|
|
39702
|
+
structureNameMap,
|
|
39692
39703
|
stageSequence: stageSequence2,
|
|
39693
39704
|
roundOffset,
|
|
39694
39705
|
matchUpType,
|
|
@@ -39717,9 +39728,9 @@ function generateCurtisConsolation(params) {
|
|
|
39717
39728
|
isMock
|
|
39718
39729
|
});
|
|
39719
39730
|
const playoffStructure = structureTemplate({
|
|
39731
|
+
structureName: structureNameMap?.[PLAY_OFF] || PLAY_OFF,
|
|
39720
39732
|
structureId: uuids?.pop(),
|
|
39721
39733
|
matchUps: playoffMatchUps,
|
|
39722
|
-
structureName: PLAY_OFF,
|
|
39723
39734
|
stageSequence: 2,
|
|
39724
39735
|
stage: PLAY_OFF,
|
|
39725
39736
|
matchUpType
|
|
@@ -39744,6 +39755,7 @@ function generateCurtisConsolation(params) {
|
|
|
39744
39755
|
}
|
|
39745
39756
|
function consolationFeedStructure({
|
|
39746
39757
|
stageSequence = 1,
|
|
39758
|
+
structureNameMap,
|
|
39747
39759
|
roundOffset = 0,
|
|
39748
39760
|
matchUpType,
|
|
39749
39761
|
structureId,
|
|
@@ -39764,7 +39776,8 @@ function consolationFeedStructure({
|
|
|
39764
39776
|
isMock,
|
|
39765
39777
|
uuids
|
|
39766
39778
|
});
|
|
39767
|
-
const
|
|
39779
|
+
const defaultName = `${CONSOLATION} ${index + 1}`;
|
|
39780
|
+
const structureName = structureNameMap?.[defaultName] || defaultName;
|
|
39768
39781
|
const consolationStructure = structureTemplate({
|
|
39769
39782
|
matchUps: consolationMatchUps,
|
|
39770
39783
|
stage: CONSOLATION,
|
|
@@ -40049,6 +40062,7 @@ function processPlayoffGroups({
|
|
|
40049
40062
|
}
|
|
40050
40063
|
const params = {
|
|
40051
40064
|
structureId: playoffGroup.structureId ?? uuids?.pop(),
|
|
40065
|
+
structureNameMap: playoffGroup.structureNameMap,
|
|
40052
40066
|
structureName: playoffGroup.structureName,
|
|
40053
40067
|
idPrefix: idPrefix && `${idPrefix}-po`,
|
|
40054
40068
|
appliedPolicies: policyDefinitions,
|
|
@@ -44332,21 +44346,30 @@ function generateAdHocMatchUps$1({
|
|
|
44332
44346
|
structureId = drawDefinition.structures?.[0]?.structureId;
|
|
44333
44347
|
if (typeof structureId !== "string")
|
|
44334
44348
|
return { error: MISSING_STRUCTURE_ID };
|
|
44335
|
-
|
|
44349
|
+
const structure = drawDefinition.structures?.find(
|
|
44350
|
+
(structure2) => structure2.structureId === structureId
|
|
44351
|
+
);
|
|
44352
|
+
if (!structure)
|
|
44353
|
+
return { error: STRUCTURE_NOT_FOUND };
|
|
44354
|
+
if (!matchUpsCount) {
|
|
44336
44355
|
const selectedEntries = drawDefinition?.entries?.filter((entry) => {
|
|
44337
44356
|
const entryStatus = entry.entryStatus;
|
|
44338
44357
|
return STRUCTURE_SELECTED_STATUSES.includes(entryStatus);
|
|
44339
44358
|
}) ?? [];
|
|
44340
|
-
|
|
44359
|
+
const roundMatchUpsCount = Math.floor(selectedEntries?.length / 2) || 1;
|
|
44360
|
+
if (newRound) {
|
|
44361
|
+
matchUpsCount = roundMatchUpsCount;
|
|
44362
|
+
} else {
|
|
44363
|
+
const maxRemaining = roundMatchUpsCount - (structure.matchUps?.length || 0);
|
|
44364
|
+
if (maxRemaining > 0)
|
|
44365
|
+
matchUpsCount = maxRemaining;
|
|
44366
|
+
}
|
|
44341
44367
|
}
|
|
44342
44368
|
if (participantIdPairings && !Array.isArray(participantIdPairings) || matchUpsCount && !isConvertableInteger(matchUpsCount) || matchUpIds && !Array.isArray(matchUpIds) || !participantIdPairings && !matchUpsCount) {
|
|
44343
44369
|
return { error: INVALID_VALUES, info: "matchUpsCount or pairings error" };
|
|
44344
44370
|
}
|
|
44345
|
-
const structure = drawDefinition?.structures?.find(
|
|
44346
|
-
(structure2) => structure2.structureId === structureId
|
|
44347
|
-
);
|
|
44348
44371
|
let structureHasRoundPositions;
|
|
44349
|
-
const existingMatchUps = structure
|
|
44372
|
+
const existingMatchUps = structure.matchUps ?? [];
|
|
44350
44373
|
const lastRoundNumber = existingMatchUps?.reduce(
|
|
44351
44374
|
(roundNumber2, matchUp) => {
|
|
44352
44375
|
if (matchUp.roundPosition)
|
|
@@ -44355,12 +44378,12 @@ function generateAdHocMatchUps$1({
|
|
|
44355
44378
|
},
|
|
44356
44379
|
0
|
|
44357
44380
|
);
|
|
44358
|
-
if (structure
|
|
44381
|
+
if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
|
|
44359
44382
|
return { error: INVALID_STRUCTURE };
|
|
44360
44383
|
}
|
|
44361
44384
|
if (roundNumber && roundNumber - 1 > (lastRoundNumber || 0))
|
|
44362
44385
|
return { error: INVALID_VALUES, info: "roundNumber error" };
|
|
44363
|
-
const nextRoundNumber = roundNumber ?? (newRound
|
|
44386
|
+
const nextRoundNumber = roundNumber ?? (newRound && (lastRoundNumber ?? 0) + 1 || lastRoundNumber || 1);
|
|
44364
44387
|
participantIdPairings = participantIdPairings ?? generateRange(0, matchUpsCount).map(() => ({
|
|
44365
44388
|
participantIds: [void 0, void 0]
|
|
44366
44389
|
}));
|
|
@@ -46701,60 +46724,93 @@ function removeDelegatedOutcome$1({ drawDefinition, event, matchUpId }) {
|
|
|
46701
46724
|
}
|
|
46702
46725
|
|
|
46703
46726
|
function generateCandidate({
|
|
46704
|
-
maxIterations =
|
|
46727
|
+
maxIterations = 4e3,
|
|
46705
46728
|
// cap the processing intensity of the candidate generator
|
|
46706
46729
|
valueSortedPairings,
|
|
46707
46730
|
// pairings sorted by value from low to high
|
|
46708
46731
|
pairingValues,
|
|
46732
|
+
valueObjects,
|
|
46709
46733
|
deltaObjects
|
|
46710
46734
|
}) {
|
|
46711
|
-
const
|
|
46735
|
+
const pairingValueMap = Object.assign(
|
|
46712
46736
|
{},
|
|
46713
46737
|
...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
|
|
46714
46738
|
);
|
|
46715
|
-
|
|
46716
|
-
|
|
46739
|
+
const actors = Object.keys(pairingValues);
|
|
46740
|
+
let proposedCandidates = [];
|
|
46741
|
+
const initialProposal = roundCandidate({
|
|
46742
|
+
actorsCount: actors.length,
|
|
46717
46743
|
valueSortedPairings,
|
|
46718
|
-
|
|
46744
|
+
pairingValueMap,
|
|
46745
|
+
deltaObjects,
|
|
46746
|
+
valueObjects
|
|
46719
46747
|
});
|
|
46720
|
-
|
|
46721
|
-
|
|
46748
|
+
const candidateHashes = [candidateHash(initialProposal)];
|
|
46749
|
+
proposedCandidates.push(initialProposal);
|
|
46750
|
+
let lowCandidateValue = initialProposal.value;
|
|
46751
|
+
let deltaCandidate = initialProposal;
|
|
46722
46752
|
let candidatesCount = 0;
|
|
46723
|
-
let iterations;
|
|
46753
|
+
let iterations = 0;
|
|
46724
46754
|
let opponentCount = actors.length;
|
|
46755
|
+
let calculatedIterations;
|
|
46725
46756
|
do {
|
|
46726
46757
|
opponentCount -= 1;
|
|
46727
|
-
|
|
46728
|
-
} while (
|
|
46758
|
+
calculatedIterations = actors.length * pairingValues[actors[0]].length;
|
|
46759
|
+
} while (calculatedIterations > maxIterations && opponentCount > 5);
|
|
46729
46760
|
const stipulatedPairs = [];
|
|
46730
46761
|
actors.forEach((actor) => {
|
|
46731
46762
|
const participantIdPairings = pairingValues[actor];
|
|
46732
46763
|
participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
|
|
46764
|
+
iterations += 1;
|
|
46733
46765
|
const stipulatedPair = pairingHash(actor, pairing.opponent);
|
|
46734
46766
|
if (!stipulatedPairs.includes(stipulatedPair)) {
|
|
46735
46767
|
const proposed = roundCandidate({
|
|
46736
46768
|
// each roundCandidate starts with stipulated pairings
|
|
46737
46769
|
stipulated: [[actor, pairing.opponent]],
|
|
46738
|
-
|
|
46770
|
+
actorsCount: actors.length,
|
|
46739
46771
|
valueSortedPairings,
|
|
46740
|
-
|
|
46772
|
+
pairingValueMap,
|
|
46773
|
+
deltaObjects,
|
|
46774
|
+
valueObjects
|
|
46741
46775
|
});
|
|
46742
|
-
if (proposed
|
|
46743
|
-
|
|
46744
|
-
|
|
46745
|
-
|
|
46746
|
-
|
|
46747
|
-
|
|
46776
|
+
if (!candidateHashes.includes(candidateHash(proposed))) {
|
|
46777
|
+
candidateHashes.push(candidateHash(proposed));
|
|
46778
|
+
proposedCandidates.push(proposed);
|
|
46779
|
+
const { maxDelta, value } = proposed;
|
|
46780
|
+
if (maxDelta < deltaCandidate.maxDelta)
|
|
46781
|
+
deltaCandidate = proposed;
|
|
46782
|
+
if (value < lowCandidateValue || value === lowCandidateValue && Math.round(Math.random())) {
|
|
46783
|
+
lowCandidateValue = value;
|
|
46784
|
+
}
|
|
46785
|
+
stipulatedPairs.push(stipulatedPair);
|
|
46786
|
+
candidatesCount += 1;
|
|
46787
|
+
}
|
|
46748
46788
|
}
|
|
46749
46789
|
});
|
|
46790
|
+
proposedCandidates = proposedCandidates.filter(
|
|
46791
|
+
(proposed) => Math.abs(proposed.value - lowCandidateValue) < 5
|
|
46792
|
+
);
|
|
46750
46793
|
});
|
|
46751
|
-
|
|
46794
|
+
proposedCandidates.sort((a, b) => a.maxDiff - b.maxDiff);
|
|
46795
|
+
const candidate = randomPop(proposedCandidates);
|
|
46796
|
+
return {
|
|
46797
|
+
candidatesCount,
|
|
46798
|
+
deltaCandidate,
|
|
46799
|
+
maxIterations,
|
|
46800
|
+
iterations,
|
|
46801
|
+
candidate
|
|
46802
|
+
};
|
|
46803
|
+
}
|
|
46804
|
+
function candidateHash(candidate) {
|
|
46805
|
+
return candidate.participantIdPairings.map(({ participantIds }) => participantIds.sort().join("|")).sort().join("/");
|
|
46752
46806
|
}
|
|
46753
46807
|
function roundCandidate({
|
|
46754
|
-
rankedMatchUpValues,
|
|
46755
46808
|
valueSortedPairings,
|
|
46756
46809
|
stipulated = [],
|
|
46757
|
-
|
|
46810
|
+
pairingValueMap,
|
|
46811
|
+
deltaObjects,
|
|
46812
|
+
valueObjects,
|
|
46813
|
+
actorsCount
|
|
46758
46814
|
}) {
|
|
46759
46815
|
const roundPlayers = [].concat(...stipulated);
|
|
46760
46816
|
const participantIdPairings = [];
|
|
@@ -46762,11 +46818,17 @@ function roundCandidate({
|
|
|
46762
46818
|
stipulated.filter(Boolean).forEach((participantIds) => {
|
|
46763
46819
|
const [p1, p2] = participantIds;
|
|
46764
46820
|
const pairing = pairingHash(p1, p2);
|
|
46765
|
-
const value =
|
|
46821
|
+
const value = pairingValueMap[pairing];
|
|
46766
46822
|
participantIdPairings.push({ participantIds, value });
|
|
46767
|
-
candidateValue +=
|
|
46823
|
+
candidateValue += pairingValueMap[pairing];
|
|
46768
46824
|
});
|
|
46769
|
-
valueSortedPairings.
|
|
46825
|
+
const consideredPairings = chunkArray(valueSortedPairings, actorsCount).map(
|
|
46826
|
+
(pairings) => shuffleArray(pairings).map((pairing) => ({
|
|
46827
|
+
...pairing,
|
|
46828
|
+
value: pairing.value + Math.random() * Math.round(Math.random())
|
|
46829
|
+
}))
|
|
46830
|
+
).flat();
|
|
46831
|
+
consideredPairings.forEach((rankedPairing) => {
|
|
46770
46832
|
const participantIds = rankedPairing.pairing.split("|");
|
|
46771
46833
|
const opponentExists = participantIds.reduce(
|
|
46772
46834
|
(p, c) => roundPlayers.includes(c) || p,
|
|
@@ -46786,15 +46848,154 @@ function roundCandidate({
|
|
|
46786
46848
|
const delta = deltaObjects[hash];
|
|
46787
46849
|
return delta > p ? delta : p;
|
|
46788
46850
|
}, 0);
|
|
46789
|
-
|
|
46851
|
+
const maxDiff = participantIdPairings.reduce((p, c) => {
|
|
46852
|
+
const [p1, p2] = c.participantIds;
|
|
46853
|
+
const hash = pairingHash(p1, p2);
|
|
46854
|
+
const diff = valueObjects[hash];
|
|
46855
|
+
return diff > p ? diff : p;
|
|
46856
|
+
}, 0);
|
|
46857
|
+
return { value: candidateValue, participantIdPairings, maxDelta, maxDiff };
|
|
46790
46858
|
}
|
|
46791
46859
|
function pairingHash(id1, id2) {
|
|
46792
46860
|
return [id1, id2].sort().join("|");
|
|
46793
46861
|
}
|
|
46794
46862
|
|
|
46795
|
-
|
|
46796
|
-
const
|
|
46863
|
+
function getPairingsData({ participantIds }) {
|
|
46864
|
+
const possiblePairings = {};
|
|
46865
|
+
const uniquePairings = [];
|
|
46866
|
+
participantIds.forEach((participantId) => {
|
|
46867
|
+
possiblePairings[participantId] = participantIds.filter(
|
|
46868
|
+
(id) => id !== participantId
|
|
46869
|
+
);
|
|
46870
|
+
possiblePairings[participantId].forEach((id) => {
|
|
46871
|
+
const pairing = pairingHash(id, participantId);
|
|
46872
|
+
if (!uniquePairings.includes(pairing))
|
|
46873
|
+
uniquePairings.push(pairing);
|
|
46874
|
+
});
|
|
46875
|
+
});
|
|
46876
|
+
const deltaObjects = Object.assign(
|
|
46877
|
+
{},
|
|
46878
|
+
...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
|
|
46879
|
+
);
|
|
46880
|
+
return { uniquePairings, possiblePairings, deltaObjects };
|
|
46881
|
+
}
|
|
46882
|
+
|
|
46883
|
+
function getEncounters({ matchUps }) {
|
|
46884
|
+
const encounters = [];
|
|
46885
|
+
for (const matchUp of matchUps) {
|
|
46886
|
+
const participantIds = matchUp.sides.map(
|
|
46887
|
+
extractAttributes("participantId")
|
|
46888
|
+
);
|
|
46889
|
+
if (participantIds.length === 2) {
|
|
46890
|
+
const [p1, p2] = participantIds;
|
|
46891
|
+
const pairing = pairingHash(p1, p2);
|
|
46892
|
+
if (!encounters.includes(pairing))
|
|
46893
|
+
encounters.push(pairing);
|
|
46894
|
+
}
|
|
46895
|
+
}
|
|
46896
|
+
return { encounters };
|
|
46897
|
+
}
|
|
46898
|
+
|
|
46899
|
+
function getParticipantPairingValues({
|
|
46900
|
+
possiblePairings,
|
|
46901
|
+
valueObjects
|
|
46902
|
+
}) {
|
|
46903
|
+
const pairingValues = {};
|
|
46904
|
+
for (const participantId of Object.keys(possiblePairings)) {
|
|
46905
|
+
const participantValues = possiblePairings[participantId].map(
|
|
46906
|
+
(opponent) => pairingValue(participantId, opponent)
|
|
46907
|
+
);
|
|
46908
|
+
pairingValues[participantId] = participantValues.sort(
|
|
46909
|
+
(a, b) => a.value - b.value
|
|
46910
|
+
);
|
|
46911
|
+
}
|
|
46912
|
+
function pairingValue(participantId, opponent) {
|
|
46913
|
+
const key = pairingHash(participantId, opponent);
|
|
46914
|
+
return { opponent, value: valueObjects[key] };
|
|
46915
|
+
}
|
|
46916
|
+
return { pairingValues };
|
|
46917
|
+
}
|
|
46918
|
+
|
|
46797
46919
|
const DEFAULT_RATING = 0;
|
|
46920
|
+
function getSideRatings({
|
|
46921
|
+
tournamentParticipants,
|
|
46922
|
+
adHocRatings,
|
|
46923
|
+
eventType,
|
|
46924
|
+
scaleName,
|
|
46925
|
+
pairing
|
|
46926
|
+
}) {
|
|
46927
|
+
const defaultRating = ratingsParameters[scaleName]?.defaultInitialization ?? DEFAULT_RATING;
|
|
46928
|
+
return pairing.split("|").map((participantId) => {
|
|
46929
|
+
if (eventType === DOUBLES) {
|
|
46930
|
+
const individualParticipantIds = tournamentParticipants?.find(
|
|
46931
|
+
(participant) => participant.participantId === participantId
|
|
46932
|
+
)?.individualParticipantIds;
|
|
46933
|
+
return !individualParticipantIds ? defaultRating * 2 : individualParticipantIds?.map(
|
|
46934
|
+
(participantId2) => adHocRatings[participantId2] || defaultRating
|
|
46935
|
+
);
|
|
46936
|
+
} else {
|
|
46937
|
+
return adHocRatings[participantId] || defaultRating;
|
|
46938
|
+
}
|
|
46939
|
+
});
|
|
46940
|
+
}
|
|
46941
|
+
|
|
46942
|
+
function getPairings({
|
|
46943
|
+
tournamentParticipants,
|
|
46944
|
+
adHocRatings = {},
|
|
46945
|
+
possiblePairings,
|
|
46946
|
+
// participant keyed; provides array of possible opponents
|
|
46947
|
+
uniquePairings,
|
|
46948
|
+
// hashes of all possible participantId pairings
|
|
46949
|
+
maxIterations,
|
|
46950
|
+
deltaObjects,
|
|
46951
|
+
// difference in rating between paired participants
|
|
46952
|
+
valueObjects,
|
|
46953
|
+
// calculated value of a pairing of participants, used for sorting pairings
|
|
46954
|
+
eventType,
|
|
46955
|
+
scaleName,
|
|
46956
|
+
salted
|
|
46957
|
+
}) {
|
|
46958
|
+
uniquePairings.forEach((pairing) => {
|
|
46959
|
+
const ratings = getSideRatings({
|
|
46960
|
+
tournamentParticipants,
|
|
46961
|
+
adHocRatings,
|
|
46962
|
+
scaleName,
|
|
46963
|
+
eventType,
|
|
46964
|
+
pairing
|
|
46965
|
+
});
|
|
46966
|
+
const salting = typeof salted === "number" && salted || 0.5;
|
|
46967
|
+
const salt = salted && (Math.round(Math.random()) ? salting : salting * -1) || 0;
|
|
46968
|
+
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + salt;
|
|
46969
|
+
const pairingDelta = Math.abs(ratings[0] - ratings[1]);
|
|
46970
|
+
deltaObjects[pairing] = pairingDelta;
|
|
46971
|
+
if (!valueObjects[pairing])
|
|
46972
|
+
valueObjects[pairing] = 0;
|
|
46973
|
+
valueObjects[pairing] += ratingsDifference ? Math.pow(ratingsDifference, 2) : 0;
|
|
46974
|
+
});
|
|
46975
|
+
const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
|
|
46976
|
+
const { pairingValues } = getParticipantPairingValues({
|
|
46977
|
+
possiblePairings,
|
|
46978
|
+
valueObjects
|
|
46979
|
+
});
|
|
46980
|
+
const { candidate, candidatesCount, deltaCandidate, iterations } = generateCandidate({
|
|
46981
|
+
valueSortedPairings,
|
|
46982
|
+
maxIterations,
|
|
46983
|
+
pairingValues,
|
|
46984
|
+
deltaObjects,
|
|
46985
|
+
valueObjects
|
|
46986
|
+
});
|
|
46987
|
+
const { participantIdPairings } = candidate;
|
|
46988
|
+
return {
|
|
46989
|
+
participantIdPairings,
|
|
46990
|
+
candidatesCount,
|
|
46991
|
+
deltaCandidate,
|
|
46992
|
+
iterations,
|
|
46993
|
+
candidate
|
|
46994
|
+
};
|
|
46995
|
+
}
|
|
46996
|
+
|
|
46997
|
+
const ENCOUNTER_VALUE = 100;
|
|
46998
|
+
const SAME_TEAM_VALUE = 100;
|
|
46798
46999
|
const MAX_ITERATIONS = 5e3;
|
|
46799
47000
|
function generateDrawMaticRound({
|
|
46800
47001
|
maxIterations = MAX_ITERATIONS,
|
|
@@ -46806,9 +47007,11 @@ function generateDrawMaticRound({
|
|
|
46806
47007
|
drawDefinition,
|
|
46807
47008
|
adHocRatings,
|
|
46808
47009
|
structureId,
|
|
47010
|
+
salted = 0.5,
|
|
46809
47011
|
matchUpIds,
|
|
46810
47012
|
eventType,
|
|
46811
|
-
structure
|
|
47013
|
+
structure,
|
|
47014
|
+
scaleName
|
|
46812
47015
|
}) {
|
|
46813
47016
|
if (!drawDefinition)
|
|
46814
47017
|
return { error: MISSING_DRAW_DEFINITION };
|
|
@@ -46857,7 +47060,9 @@ function generateDrawMaticRound({
|
|
|
46857
47060
|
deltaObjects,
|
|
46858
47061
|
valueObjects,
|
|
46859
47062
|
eventType,
|
|
46860
|
-
|
|
47063
|
+
scaleName,
|
|
47064
|
+
structure,
|
|
47065
|
+
salted
|
|
46861
47066
|
};
|
|
46862
47067
|
const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
|
|
46863
47068
|
if (!candidatesCount)
|
|
@@ -46885,118 +47090,11 @@ function generateDrawMaticRound({
|
|
|
46885
47090
|
matchUps
|
|
46886
47091
|
};
|
|
46887
47092
|
}
|
|
46888
|
-
function getSideRatings({
|
|
46889
|
-
tournamentParticipants,
|
|
46890
|
-
adHocRatings,
|
|
46891
|
-
eventType,
|
|
46892
|
-
pairing
|
|
46893
|
-
}) {
|
|
46894
|
-
return pairing.split("|").map((participantId) => {
|
|
46895
|
-
if (eventType === DOUBLES) {
|
|
46896
|
-
const individualParticipantIds = tournamentParticipants?.find(
|
|
46897
|
-
(participant) => participant.participantId === participantId
|
|
46898
|
-
)?.individualParticipantIds;
|
|
46899
|
-
return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
|
|
46900
|
-
(participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
|
|
46901
|
-
);
|
|
46902
|
-
} else {
|
|
46903
|
-
return adHocRatings[participantId] || DEFAULT_RATING;
|
|
46904
|
-
}
|
|
46905
|
-
});
|
|
46906
|
-
}
|
|
46907
|
-
function getPairings({
|
|
46908
|
-
tournamentParticipants,
|
|
46909
|
-
adHocRatings = {},
|
|
46910
|
-
possiblePairings,
|
|
46911
|
-
// participant keyed; provides array of possible opponents
|
|
46912
|
-
uniquePairings,
|
|
46913
|
-
// hashes of all possible participantId pairings
|
|
46914
|
-
maxIterations,
|
|
46915
|
-
deltaObjects,
|
|
46916
|
-
// difference in rating between paired participants
|
|
46917
|
-
valueObjects,
|
|
46918
|
-
// calculated value of a pairing of participants, used for sorting pairings
|
|
46919
|
-
eventType
|
|
46920
|
-
}) {
|
|
46921
|
-
uniquePairings.forEach((pairing) => {
|
|
46922
|
-
const ratings = getSideRatings({
|
|
46923
|
-
tournamentParticipants,
|
|
46924
|
-
adHocRatings,
|
|
46925
|
-
eventType,
|
|
46926
|
-
pairing
|
|
46927
|
-
});
|
|
46928
|
-
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
|
|
46929
|
-
deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
|
|
46930
|
-
if (!valueObjects[pairing])
|
|
46931
|
-
valueObjects[pairing] = 0;
|
|
46932
|
-
valueObjects[pairing] += Math.pow(ratingsDifference, 2);
|
|
46933
|
-
});
|
|
46934
|
-
const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
|
|
46935
|
-
const { pairingValues } = getParticipantPairingValues({
|
|
46936
|
-
possiblePairings,
|
|
46937
|
-
valueObjects
|
|
46938
|
-
});
|
|
46939
|
-
const { candidate, candidatesCount, iterations } = generateCandidate({
|
|
46940
|
-
valueSortedPairings,
|
|
46941
|
-
maxIterations,
|
|
46942
|
-
pairingValues,
|
|
46943
|
-
deltaObjects
|
|
46944
|
-
});
|
|
46945
|
-
const { participantIdPairings } = candidate;
|
|
46946
|
-
return { candidatesCount, participantIdPairings, iterations };
|
|
46947
|
-
}
|
|
46948
|
-
function getPairingsData({ participantIds }) {
|
|
46949
|
-
const possiblePairings = {};
|
|
46950
|
-
const uniquePairings = [];
|
|
46951
|
-
participantIds.forEach((participantId) => {
|
|
46952
|
-
possiblePairings[participantId] = participantIds.filter(
|
|
46953
|
-
(id) => id !== participantId
|
|
46954
|
-
);
|
|
46955
|
-
possiblePairings[participantId].forEach((id) => {
|
|
46956
|
-
const pairing = pairingHash(id, participantId);
|
|
46957
|
-
if (!uniquePairings.includes(pairing))
|
|
46958
|
-
uniquePairings.push(pairing);
|
|
46959
|
-
});
|
|
46960
|
-
});
|
|
46961
|
-
const deltaObjects = Object.assign(
|
|
46962
|
-
{},
|
|
46963
|
-
...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
|
|
46964
|
-
);
|
|
46965
|
-
return { uniquePairings, possiblePairings, deltaObjects };
|
|
46966
|
-
}
|
|
46967
|
-
function getEncounters({ matchUps }) {
|
|
46968
|
-
const encounters = [];
|
|
46969
|
-
for (const matchUp of matchUps) {
|
|
46970
|
-
const participantIds = matchUp.sides.map(getParticipantId);
|
|
46971
|
-
if (participantIds.length === 2) {
|
|
46972
|
-
const [p1, p2] = participantIds;
|
|
46973
|
-
const pairing = pairingHash(p1, p2);
|
|
46974
|
-
if (!encounters.includes(pairing))
|
|
46975
|
-
encounters.push(pairing);
|
|
46976
|
-
}
|
|
46977
|
-
}
|
|
46978
|
-
return { encounters };
|
|
46979
|
-
}
|
|
46980
|
-
function getParticipantPairingValues({ possiblePairings, valueObjects }) {
|
|
46981
|
-
const pairingValues = {};
|
|
46982
|
-
for (const participantId of Object.keys(possiblePairings)) {
|
|
46983
|
-
const participantValues = possiblePairings[participantId].map(
|
|
46984
|
-
(opponent) => pairingValue(participantId, opponent)
|
|
46985
|
-
);
|
|
46986
|
-
pairingValues[participantId] = participantValues.sort(
|
|
46987
|
-
(a, b) => a.value - b.value
|
|
46988
|
-
);
|
|
46989
|
-
}
|
|
46990
|
-
function pairingValue(participantId, opponent) {
|
|
46991
|
-
const key = pairingHash(participantId, opponent);
|
|
46992
|
-
return { opponent, value: valueObjects[key] };
|
|
46993
|
-
}
|
|
46994
|
-
return { pairingValues };
|
|
46995
|
-
}
|
|
46996
47093
|
|
|
46997
47094
|
function drawMatic$1({
|
|
46998
47095
|
tournamentParticipants,
|
|
46999
47096
|
restrictEntryStatus,
|
|
47097
|
+
adHocRatings = {},
|
|
47000
47098
|
tournamentRecord,
|
|
47001
47099
|
generateMatchUps,
|
|
47002
47100
|
addToStructure,
|
|
@@ -47051,12 +47149,16 @@ function drawMatic$1({
|
|
|
47051
47149
|
if (!structureIsAdHoc)
|
|
47052
47150
|
return { error: INVALID_DRAW_DEFINITION };
|
|
47053
47151
|
tournamentParticipants = tournamentParticipants ?? tournamentRecord.participants ?? [];
|
|
47054
|
-
const adHocRatings = {};
|
|
47055
47152
|
for (const participantId of participantIds ?? []) {
|
|
47056
47153
|
const participant = tournamentParticipants?.find(
|
|
47057
47154
|
(participant2) => participant2.participantId === participantId
|
|
47058
47155
|
);
|
|
47059
|
-
let scaleValue = getScaleValue({
|
|
47156
|
+
let scaleValue = getScaleValue({
|
|
47157
|
+
scaleName: `${scaleName}.${DYNAMIC}`,
|
|
47158
|
+
scaleAccessor,
|
|
47159
|
+
participant,
|
|
47160
|
+
eventType
|
|
47161
|
+
});
|
|
47060
47162
|
if (!scaleValue && scaleName) {
|
|
47061
47163
|
scaleValue = getScaleValue({
|
|
47062
47164
|
scaleAccessor,
|
|
@@ -47065,7 +47167,7 @@ function drawMatic$1({
|
|
|
47065
47167
|
eventType
|
|
47066
47168
|
});
|
|
47067
47169
|
}
|
|
47068
|
-
if (scaleValue)
|
|
47170
|
+
if (scaleValue && !adHocRatings[participantId])
|
|
47069
47171
|
adHocRatings[participantId] = scaleValue;
|
|
47070
47172
|
}
|
|
47071
47173
|
return generateDrawMaticRound({
|
|
@@ -47083,14 +47185,15 @@ function drawMatic$1({
|
|
|
47083
47185
|
});
|
|
47084
47186
|
}
|
|
47085
47187
|
function getScaleValue({
|
|
47086
|
-
|
|
47087
|
-
scaleName = "dynamic",
|
|
47188
|
+
scaleType = RATING$2,
|
|
47088
47189
|
scaleAccessor,
|
|
47089
|
-
participant
|
|
47190
|
+
participant,
|
|
47191
|
+
scaleName,
|
|
47192
|
+
eventType
|
|
47090
47193
|
}) {
|
|
47091
47194
|
const scaleAttributes = {
|
|
47092
47195
|
eventType: eventType || TypeEnum.Singles,
|
|
47093
|
-
scaleType
|
|
47196
|
+
scaleType,
|
|
47094
47197
|
scaleName
|
|
47095
47198
|
};
|
|
47096
47199
|
const result = participant && participantScaleItem({
|
|
@@ -59464,11 +59567,15 @@ function calculateNewRatings(params) {
|
|
|
59464
59567
|
targetRange: consideredRange
|
|
59465
59568
|
});
|
|
59466
59569
|
const updatedWinnerRating = invertedScale ? ratingRange[0] - convertedUpdatedWinnerRating : convertedUpdatedWinnerRating;
|
|
59467
|
-
let newWinnerRating = parseFloat(
|
|
59570
|
+
let newWinnerRating = parseFloat(
|
|
59571
|
+
parseFloat(updatedWinnerRating).toFixed(decimalPlaces)
|
|
59572
|
+
);
|
|
59468
59573
|
const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
|
|
59469
|
-
let newLoserRating = parseFloat(
|
|
59574
|
+
let newLoserRating = parseFloat(
|
|
59575
|
+
parseFloat(updatedLoserRating).toFixed(decimalPlaces)
|
|
59576
|
+
);
|
|
59470
59577
|
const percentageDifference = Math.max(...ratingRange) ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange) : 0;
|
|
59471
|
-
if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold ||
|
|
59578
|
+
if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || newWinnerRating < 0 || newLoserRating < 0) {
|
|
59472
59579
|
newWinnerRating = winnerRating;
|
|
59473
59580
|
newLoserRating = loserRating;
|
|
59474
59581
|
}
|
|
@@ -59486,7 +59593,8 @@ const aggregateSets = (sets) => {
|
|
|
59486
59593
|
) || [0, 0];
|
|
59487
59594
|
};
|
|
59488
59595
|
|
|
59489
|
-
function
|
|
59596
|
+
function generateDynamicRatings({
|
|
59597
|
+
removePriorValues = true,
|
|
59490
59598
|
tournamentRecord,
|
|
59491
59599
|
ratingType = ELO,
|
|
59492
59600
|
considerGames,
|
|
@@ -59517,7 +59625,7 @@ function processMatchUps({
|
|
|
59517
59625
|
scaleName: ratingType,
|
|
59518
59626
|
scaleType: RATING$2
|
|
59519
59627
|
};
|
|
59520
|
-
const dynamicScaleName = `${ratingType}
|
|
59628
|
+
const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
|
|
59521
59629
|
const dynamicScaleAttributes = {
|
|
59522
59630
|
scaleName: dynamicScaleName,
|
|
59523
59631
|
eventType: matchUpType,
|
|
@@ -59553,9 +59661,9 @@ function processMatchUps({
|
|
|
59553
59661
|
return participantId && {
|
|
59554
59662
|
[participantId]: dynamicScaleItem ?? scaleItem ?? {
|
|
59555
59663
|
scaleName: outputScaleName,
|
|
59556
|
-
scaleType: RATING$2,
|
|
59557
59664
|
eventType: matchUpType,
|
|
59558
59665
|
scaleDate: endDate,
|
|
59666
|
+
scaleType: RATING$2,
|
|
59559
59667
|
scaleValue
|
|
59560
59668
|
}
|
|
59561
59669
|
};
|
|
@@ -59584,27 +59692,35 @@ function processMatchUps({
|
|
|
59584
59692
|
loserRating,
|
|
59585
59693
|
ratingType
|
|
59586
59694
|
});
|
|
59587
|
-
const newWinnerScaleValue = accessor ? {
|
|
59588
|
-
|
|
59695
|
+
const newWinnerScaleValue = accessor ? {
|
|
59696
|
+
...winnerScaleValue,
|
|
59697
|
+
[accessor]: newWinnerRating
|
|
59698
|
+
} : newWinnerRating;
|
|
59699
|
+
const newLoserScaleValue = accessor ? {
|
|
59700
|
+
...loserScaleValue,
|
|
59701
|
+
[accessor]: newLoserRating
|
|
59702
|
+
} : newLoserRating;
|
|
59589
59703
|
scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
|
|
59590
59704
|
scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
|
|
59591
59705
|
let result = setParticipantScaleItem({
|
|
59706
|
+
participantId: winnerParticipantId,
|
|
59707
|
+
removePriorValues,
|
|
59708
|
+
tournamentRecord,
|
|
59592
59709
|
scaleItem: {
|
|
59593
59710
|
...scaleItemMap[winnerParticipantId],
|
|
59594
59711
|
scaleName: outputScaleName
|
|
59595
|
-
}
|
|
59596
|
-
participantId: winnerParticipantId,
|
|
59597
|
-
tournamentRecord
|
|
59712
|
+
}
|
|
59598
59713
|
});
|
|
59599
59714
|
if (result.error)
|
|
59600
59715
|
return result;
|
|
59601
59716
|
result = setParticipantScaleItem({
|
|
59717
|
+
participantId: loserParticipantId,
|
|
59718
|
+
removePriorValues,
|
|
59719
|
+
tournamentRecord,
|
|
59602
59720
|
scaleItem: {
|
|
59603
59721
|
...scaleItemMap[loserParticipantId],
|
|
59604
59722
|
scaleName: outputScaleName
|
|
59605
|
-
}
|
|
59606
|
-
participantId: loserParticipantId,
|
|
59607
|
-
tournamentRecord
|
|
59723
|
+
}
|
|
59608
59724
|
});
|
|
59609
59725
|
if (result.error)
|
|
59610
59726
|
return result;
|
|
@@ -59618,7 +59734,7 @@ function processMatchUps({
|
|
|
59618
59734
|
|
|
59619
59735
|
const governor = {
|
|
59620
59736
|
calculateNewRatings,
|
|
59621
|
-
|
|
59737
|
+
generateDynamicRatings
|
|
59622
59738
|
};
|
|
59623
59739
|
|
|
59624
59740
|
const scaleEngine = (() => {
|