tods-competition-factory 1.7.3 → 1.7.5
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 +15 -3
- package/dist/forge/generate.mjs +356 -226
- package/dist/forge/generate.mjs.map +1 -1
- package/dist/forge/query.mjs +3 -2
- package/dist/forge/query.mjs.map +1 -1
- package/dist/forge/transform.mjs +3 -2
- package/dist/forge/transform.mjs.map +1 -1
- package/dist/index.mjs +302 -185
- package/dist/index.mjs.map +1 -1
- package/dist/tods-competition-factory.development.cjs.js +315 -225
- 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.5";
|
|
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";
|
|
@@ -4428,14 +4429,15 @@ function getScaleValues({ participant }) {
|
|
|
4428
4429
|
for (const itemType of itemTypes) {
|
|
4429
4430
|
const scaleItem = latestScaleItem(itemType);
|
|
4430
4431
|
if (scaleItem) {
|
|
4431
|
-
const [, type, format, scaleName] = scaleItem.itemType.split(".");
|
|
4432
|
+
const [, type, format, scaleName, modifier] = scaleItem.itemType.split(".");
|
|
4433
|
+
const namedScale = modifier ? `${scaleName}.${modifier}` : scaleName;
|
|
4432
4434
|
const scaleType = type === SEEDING$1 && "seedings" || type === RANKING$1 && "rankings" || "ratings";
|
|
4433
4435
|
if (!scales[scaleType][format])
|
|
4434
4436
|
scales[scaleType][format] = [];
|
|
4435
4437
|
scales[scaleType][format].push({
|
|
4436
4438
|
scaleValue: scaleItem.itemValue,
|
|
4437
4439
|
scaleDate: scaleItem.itemDate,
|
|
4438
|
-
scaleName
|
|
4440
|
+
scaleName: namedScale
|
|
4439
4441
|
});
|
|
4440
4442
|
}
|
|
4441
4443
|
}
|
|
@@ -13381,21 +13383,27 @@ const ratingConstants = {
|
|
|
13381
13383
|
const ratingsParameters = {
|
|
13382
13384
|
[ELO]: { range: [0, 3e3], decimalsCount: 0, defaultInitialization: 1500 },
|
|
13383
13385
|
[NTRP]: {
|
|
13384
|
-
range: [1, 7],
|
|
13385
|
-
decimalsCount: 1,
|
|
13386
|
-
defaultInitialization: 3,
|
|
13387
|
-
accessor: "dntrpRatingHundredths",
|
|
13388
13386
|
accessors: ["ntrpRating", "dntrpRatingHundredths"],
|
|
13389
|
-
attributes: { ustaRatingType: "" }
|
|
13387
|
+
attributes: { ustaRatingType: "" },
|
|
13388
|
+
accessor: "dntrpRatingHundredths",
|
|
13389
|
+
defaultInitialization: 3,
|
|
13390
|
+
decimalsCount: 1,
|
|
13391
|
+
range: [1, 7]
|
|
13390
13392
|
},
|
|
13391
|
-
[UTR]: {
|
|
13392
|
-
|
|
13393
|
-
|
|
13393
|
+
[UTR]: {
|
|
13394
|
+
defaultInitialization: 6,
|
|
13395
|
+
accessors: ["utrRating"],
|
|
13396
|
+
accessor: "utrRating",
|
|
13394
13397
|
decimalsCount: 2,
|
|
13398
|
+
range: [1, 16]
|
|
13399
|
+
},
|
|
13400
|
+
[WTN]: {
|
|
13401
|
+
attributes: { confidence: { generator: true, range: [60, 100] } },
|
|
13402
|
+
accessors: ["wtnRating", "confidence"],
|
|
13395
13403
|
defaultInitialization: 23,
|
|
13396
13404
|
accessor: "wtnRating",
|
|
13397
|
-
|
|
13398
|
-
|
|
13405
|
+
decimalsCount: 2,
|
|
13406
|
+
range: [40, 1]
|
|
13399
13407
|
}
|
|
13400
13408
|
};
|
|
13401
13409
|
|
|
@@ -38815,7 +38823,7 @@ function treeMatchUps({
|
|
|
38815
38823
|
uuids
|
|
38816
38824
|
}));
|
|
38817
38825
|
roundNumber++;
|
|
38818
|
-
roundLimit = roundLimit || qualifyingRoundNumber
|
|
38826
|
+
roundLimit = roundLimit || qualifyingRoundNumber;
|
|
38819
38827
|
while (roundNodes.length > 1) {
|
|
38820
38828
|
if (qualifyingPositions && roundNodes.length === qualifyingPositions) {
|
|
38821
38829
|
roundLimit = roundNumber - 1;
|
|
@@ -39656,6 +39664,7 @@ function generateCurtisConsolation(params) {
|
|
|
39656
39664
|
finishingPositionOffset,
|
|
39657
39665
|
structureName = MAIN,
|
|
39658
39666
|
stageSequence = 1,
|
|
39667
|
+
structureNameMap,
|
|
39659
39668
|
staggeredEntry,
|
|
39660
39669
|
stage = MAIN,
|
|
39661
39670
|
matchUpType,
|
|
@@ -39689,8 +39698,9 @@ function generateCurtisConsolation(params) {
|
|
|
39689
39698
|
const consolationItems = feedRoundOffsets.map((roundOffset, index) => {
|
|
39690
39699
|
const stageSequence2 = index + 1;
|
|
39691
39700
|
const { consolationStructure } = consolationFeedStructure({
|
|
39692
|
-
structureId: uuids?.pop(),
|
|
39693
39701
|
idPrefix: idPrefix && `${idPrefix}-c${index}`,
|
|
39702
|
+
structureId: uuids?.pop(),
|
|
39703
|
+
structureNameMap,
|
|
39694
39704
|
stageSequence: stageSequence2,
|
|
39695
39705
|
roundOffset,
|
|
39696
39706
|
matchUpType,
|
|
@@ -39719,9 +39729,9 @@ function generateCurtisConsolation(params) {
|
|
|
39719
39729
|
isMock
|
|
39720
39730
|
});
|
|
39721
39731
|
const playoffStructure = structureTemplate({
|
|
39732
|
+
structureName: structureNameMap?.[PLAY_OFF] || PLAY_OFF,
|
|
39722
39733
|
structureId: uuids?.pop(),
|
|
39723
39734
|
matchUps: playoffMatchUps,
|
|
39724
|
-
structureName: PLAY_OFF,
|
|
39725
39735
|
stageSequence: 2,
|
|
39726
39736
|
stage: PLAY_OFF,
|
|
39727
39737
|
matchUpType
|
|
@@ -39746,6 +39756,7 @@ function generateCurtisConsolation(params) {
|
|
|
39746
39756
|
}
|
|
39747
39757
|
function consolationFeedStructure({
|
|
39748
39758
|
stageSequence = 1,
|
|
39759
|
+
structureNameMap,
|
|
39749
39760
|
roundOffset = 0,
|
|
39750
39761
|
matchUpType,
|
|
39751
39762
|
structureId,
|
|
@@ -39766,7 +39777,8 @@ function consolationFeedStructure({
|
|
|
39766
39777
|
isMock,
|
|
39767
39778
|
uuids
|
|
39768
39779
|
});
|
|
39769
|
-
const
|
|
39780
|
+
const defaultName = `${CONSOLATION} ${index + 1}`;
|
|
39781
|
+
const structureName = structureNameMap?.[defaultName] || defaultName;
|
|
39770
39782
|
const consolationStructure = structureTemplate({
|
|
39771
39783
|
matchUps: consolationMatchUps,
|
|
39772
39784
|
stage: CONSOLATION,
|
|
@@ -40051,6 +40063,7 @@ function processPlayoffGroups({
|
|
|
40051
40063
|
}
|
|
40052
40064
|
const params = {
|
|
40053
40065
|
structureId: playoffGroup.structureId ?? uuids?.pop(),
|
|
40066
|
+
structureNameMap: playoffGroup.structureNameMap,
|
|
40054
40067
|
structureName: playoffGroup.structureName,
|
|
40055
40068
|
idPrefix: idPrefix && `${idPrefix}-po`,
|
|
40056
40069
|
appliedPolicies: policyDefinitions,
|
|
@@ -46712,60 +46725,93 @@ function removeDelegatedOutcome$1({ drawDefinition, event, matchUpId }) {
|
|
|
46712
46725
|
}
|
|
46713
46726
|
|
|
46714
46727
|
function generateCandidate({
|
|
46715
|
-
maxIterations =
|
|
46728
|
+
maxIterations = 4e3,
|
|
46716
46729
|
// cap the processing intensity of the candidate generator
|
|
46717
46730
|
valueSortedPairings,
|
|
46718
46731
|
// pairings sorted by value from low to high
|
|
46719
46732
|
pairingValues,
|
|
46733
|
+
valueObjects,
|
|
46720
46734
|
deltaObjects
|
|
46721
46735
|
}) {
|
|
46722
|
-
const
|
|
46736
|
+
const pairingValueMap = Object.assign(
|
|
46723
46737
|
{},
|
|
46724
46738
|
...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
|
|
46725
46739
|
);
|
|
46726
|
-
|
|
46727
|
-
|
|
46740
|
+
const actors = Object.keys(pairingValues);
|
|
46741
|
+
let proposedCandidates = [];
|
|
46742
|
+
const initialProposal = roundCandidate({
|
|
46743
|
+
actorsCount: actors.length,
|
|
46728
46744
|
valueSortedPairings,
|
|
46729
|
-
|
|
46745
|
+
pairingValueMap,
|
|
46746
|
+
deltaObjects,
|
|
46747
|
+
valueObjects
|
|
46730
46748
|
});
|
|
46731
|
-
|
|
46732
|
-
|
|
46749
|
+
const candidateHashes = [candidateHash(initialProposal)];
|
|
46750
|
+
proposedCandidates.push(initialProposal);
|
|
46751
|
+
let lowCandidateValue = initialProposal.value;
|
|
46752
|
+
let deltaCandidate = initialProposal;
|
|
46733
46753
|
let candidatesCount = 0;
|
|
46734
|
-
let iterations;
|
|
46754
|
+
let iterations = 0;
|
|
46735
46755
|
let opponentCount = actors.length;
|
|
46756
|
+
let calculatedIterations;
|
|
46736
46757
|
do {
|
|
46737
46758
|
opponentCount -= 1;
|
|
46738
|
-
|
|
46739
|
-
} while (
|
|
46759
|
+
calculatedIterations = actors.length * pairingValues[actors[0]].length;
|
|
46760
|
+
} while (calculatedIterations > maxIterations && opponentCount > 5);
|
|
46740
46761
|
const stipulatedPairs = [];
|
|
46741
46762
|
actors.forEach((actor) => {
|
|
46742
46763
|
const participantIdPairings = pairingValues[actor];
|
|
46743
46764
|
participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
|
|
46765
|
+
iterations += 1;
|
|
46744
46766
|
const stipulatedPair = pairingHash(actor, pairing.opponent);
|
|
46745
46767
|
if (!stipulatedPairs.includes(stipulatedPair)) {
|
|
46746
46768
|
const proposed = roundCandidate({
|
|
46747
46769
|
// each roundCandidate starts with stipulated pairings
|
|
46748
46770
|
stipulated: [[actor, pairing.opponent]],
|
|
46749
|
-
|
|
46771
|
+
actorsCount: actors.length,
|
|
46750
46772
|
valueSortedPairings,
|
|
46751
|
-
|
|
46773
|
+
pairingValueMap,
|
|
46774
|
+
deltaObjects,
|
|
46775
|
+
valueObjects
|
|
46752
46776
|
});
|
|
46753
|
-
if (proposed
|
|
46754
|
-
|
|
46755
|
-
|
|
46756
|
-
|
|
46757
|
-
|
|
46758
|
-
|
|
46777
|
+
if (!candidateHashes.includes(candidateHash(proposed))) {
|
|
46778
|
+
candidateHashes.push(candidateHash(proposed));
|
|
46779
|
+
proposedCandidates.push(proposed);
|
|
46780
|
+
const { maxDelta, value } = proposed;
|
|
46781
|
+
if (maxDelta < deltaCandidate.maxDelta)
|
|
46782
|
+
deltaCandidate = proposed;
|
|
46783
|
+
if (value < lowCandidateValue || value === lowCandidateValue && Math.round(Math.random())) {
|
|
46784
|
+
lowCandidateValue = value;
|
|
46785
|
+
}
|
|
46786
|
+
stipulatedPairs.push(stipulatedPair);
|
|
46787
|
+
candidatesCount += 1;
|
|
46788
|
+
}
|
|
46759
46789
|
}
|
|
46760
46790
|
});
|
|
46791
|
+
proposedCandidates = proposedCandidates.filter(
|
|
46792
|
+
(proposed) => Math.abs(proposed.value - lowCandidateValue) < 5
|
|
46793
|
+
);
|
|
46761
46794
|
});
|
|
46762
|
-
|
|
46795
|
+
proposedCandidates.sort((a, b) => a.maxDiff - b.maxDiff);
|
|
46796
|
+
const candidate = randomPop(proposedCandidates);
|
|
46797
|
+
return {
|
|
46798
|
+
candidatesCount,
|
|
46799
|
+
deltaCandidate,
|
|
46800
|
+
maxIterations,
|
|
46801
|
+
iterations,
|
|
46802
|
+
candidate
|
|
46803
|
+
};
|
|
46804
|
+
}
|
|
46805
|
+
function candidateHash(candidate) {
|
|
46806
|
+
return candidate.participantIdPairings.map(({ participantIds }) => participantIds.sort().join("|")).sort().join("/");
|
|
46763
46807
|
}
|
|
46764
46808
|
function roundCandidate({
|
|
46765
|
-
rankedMatchUpValues,
|
|
46766
46809
|
valueSortedPairings,
|
|
46767
46810
|
stipulated = [],
|
|
46768
|
-
|
|
46811
|
+
pairingValueMap,
|
|
46812
|
+
deltaObjects,
|
|
46813
|
+
valueObjects,
|
|
46814
|
+
actorsCount
|
|
46769
46815
|
}) {
|
|
46770
46816
|
const roundPlayers = [].concat(...stipulated);
|
|
46771
46817
|
const participantIdPairings = [];
|
|
@@ -46773,11 +46819,17 @@ function roundCandidate({
|
|
|
46773
46819
|
stipulated.filter(Boolean).forEach((participantIds) => {
|
|
46774
46820
|
const [p1, p2] = participantIds;
|
|
46775
46821
|
const pairing = pairingHash(p1, p2);
|
|
46776
|
-
const value =
|
|
46822
|
+
const value = pairingValueMap[pairing];
|
|
46777
46823
|
participantIdPairings.push({ participantIds, value });
|
|
46778
|
-
candidateValue +=
|
|
46824
|
+
candidateValue += pairingValueMap[pairing];
|
|
46779
46825
|
});
|
|
46780
|
-
valueSortedPairings.
|
|
46826
|
+
const consideredPairings = chunkArray(valueSortedPairings, actorsCount).map(
|
|
46827
|
+
(pairings) => shuffleArray(pairings).map((pairing) => ({
|
|
46828
|
+
...pairing,
|
|
46829
|
+
value: pairing.value + Math.random() * Math.round(Math.random())
|
|
46830
|
+
}))
|
|
46831
|
+
).flat();
|
|
46832
|
+
consideredPairings.forEach((rankedPairing) => {
|
|
46781
46833
|
const participantIds = rankedPairing.pairing.split("|");
|
|
46782
46834
|
const opponentExists = participantIds.reduce(
|
|
46783
46835
|
(p, c) => roundPlayers.includes(c) || p,
|
|
@@ -46797,17 +46849,158 @@ function roundCandidate({
|
|
|
46797
46849
|
const delta = deltaObjects[hash];
|
|
46798
46850
|
return delta > p ? delta : p;
|
|
46799
46851
|
}, 0);
|
|
46800
|
-
|
|
46852
|
+
const maxDiff = participantIdPairings.reduce((p, c) => {
|
|
46853
|
+
const [p1, p2] = c.participantIds;
|
|
46854
|
+
const hash = pairingHash(p1, p2);
|
|
46855
|
+
const diff = valueObjects[hash];
|
|
46856
|
+
return diff > p ? diff : p;
|
|
46857
|
+
}, 0);
|
|
46858
|
+
return { value: candidateValue, participantIdPairings, maxDelta, maxDiff };
|
|
46801
46859
|
}
|
|
46802
46860
|
function pairingHash(id1, id2) {
|
|
46803
46861
|
return [id1, id2].sort().join("|");
|
|
46804
46862
|
}
|
|
46805
46863
|
|
|
46806
|
-
|
|
46807
|
-
const
|
|
46864
|
+
function getPairingsData({ participantIds }) {
|
|
46865
|
+
const possiblePairings = {};
|
|
46866
|
+
const uniquePairings = [];
|
|
46867
|
+
participantIds.forEach((participantId) => {
|
|
46868
|
+
possiblePairings[participantId] = participantIds.filter(
|
|
46869
|
+
(id) => id !== participantId
|
|
46870
|
+
);
|
|
46871
|
+
possiblePairings[participantId].forEach((id) => {
|
|
46872
|
+
const pairing = pairingHash(id, participantId);
|
|
46873
|
+
if (!uniquePairings.includes(pairing))
|
|
46874
|
+
uniquePairings.push(pairing);
|
|
46875
|
+
});
|
|
46876
|
+
});
|
|
46877
|
+
const deltaObjects = Object.assign(
|
|
46878
|
+
{},
|
|
46879
|
+
...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
|
|
46880
|
+
);
|
|
46881
|
+
return { uniquePairings, possiblePairings, deltaObjects };
|
|
46882
|
+
}
|
|
46883
|
+
|
|
46884
|
+
function getEncounters({ matchUps }) {
|
|
46885
|
+
const encounters = [];
|
|
46886
|
+
for (const matchUp of matchUps) {
|
|
46887
|
+
const participantIds = matchUp.sides.map(
|
|
46888
|
+
extractAttributes("participantId")
|
|
46889
|
+
);
|
|
46890
|
+
if (participantIds.length === 2) {
|
|
46891
|
+
const [p1, p2] = participantIds;
|
|
46892
|
+
const pairing = pairingHash(p1, p2);
|
|
46893
|
+
if (!encounters.includes(pairing))
|
|
46894
|
+
encounters.push(pairing);
|
|
46895
|
+
}
|
|
46896
|
+
}
|
|
46897
|
+
return { encounters };
|
|
46898
|
+
}
|
|
46899
|
+
|
|
46900
|
+
function getParticipantPairingValues({
|
|
46901
|
+
possiblePairings,
|
|
46902
|
+
valueObjects
|
|
46903
|
+
}) {
|
|
46904
|
+
const pairingValues = {};
|
|
46905
|
+
for (const participantId of Object.keys(possiblePairings)) {
|
|
46906
|
+
const participantValues = possiblePairings[participantId].map(
|
|
46907
|
+
(opponent) => pairingValue(participantId, opponent)
|
|
46908
|
+
);
|
|
46909
|
+
pairingValues[participantId] = participantValues.sort(
|
|
46910
|
+
(a, b) => a.value - b.value
|
|
46911
|
+
);
|
|
46912
|
+
}
|
|
46913
|
+
function pairingValue(participantId, opponent) {
|
|
46914
|
+
const key = pairingHash(participantId, opponent);
|
|
46915
|
+
return { opponent, value: valueObjects[key] };
|
|
46916
|
+
}
|
|
46917
|
+
return { pairingValues };
|
|
46918
|
+
}
|
|
46919
|
+
|
|
46808
46920
|
const DEFAULT_RATING = 0;
|
|
46809
|
-
|
|
46921
|
+
function getSideRatings({
|
|
46922
|
+
tournamentParticipants,
|
|
46923
|
+
adHocRatings,
|
|
46924
|
+
eventType,
|
|
46925
|
+
scaleName,
|
|
46926
|
+
pairing
|
|
46927
|
+
}) {
|
|
46928
|
+
const defaultRating = ratingsParameters[scaleName]?.defaultInitialization ?? DEFAULT_RATING;
|
|
46929
|
+
return pairing.split("|").map((participantId) => {
|
|
46930
|
+
if (eventType === DOUBLES) {
|
|
46931
|
+
const individualParticipantIds = tournamentParticipants?.find(
|
|
46932
|
+
(participant) => participant.participantId === participantId
|
|
46933
|
+
)?.individualParticipantIds;
|
|
46934
|
+
return !individualParticipantIds ? defaultRating * 2 : individualParticipantIds?.map(
|
|
46935
|
+
(participantId2) => adHocRatings[participantId2] || defaultRating
|
|
46936
|
+
);
|
|
46937
|
+
} else {
|
|
46938
|
+
return adHocRatings[participantId] || defaultRating;
|
|
46939
|
+
}
|
|
46940
|
+
});
|
|
46941
|
+
}
|
|
46942
|
+
|
|
46943
|
+
function getPairings({
|
|
46944
|
+
tournamentParticipants,
|
|
46945
|
+
adHocRatings = {},
|
|
46946
|
+
possiblePairings,
|
|
46947
|
+
// participant keyed; provides array of possible opponents
|
|
46948
|
+
uniquePairings,
|
|
46949
|
+
// hashes of all possible participantId pairings
|
|
46950
|
+
maxIterations,
|
|
46951
|
+
deltaObjects,
|
|
46952
|
+
// difference in rating between paired participants
|
|
46953
|
+
valueObjects,
|
|
46954
|
+
// calculated value of a pairing of participants, used for sorting pairings
|
|
46955
|
+
eventType,
|
|
46956
|
+
scaleName,
|
|
46957
|
+
salted
|
|
46958
|
+
}) {
|
|
46959
|
+
uniquePairings.forEach((pairing) => {
|
|
46960
|
+
const ratings = getSideRatings({
|
|
46961
|
+
tournamentParticipants,
|
|
46962
|
+
adHocRatings,
|
|
46963
|
+
scaleName,
|
|
46964
|
+
eventType,
|
|
46965
|
+
pairing
|
|
46966
|
+
});
|
|
46967
|
+
const salting = typeof salted === "number" && salted || 0.5;
|
|
46968
|
+
const salt = salted && (Math.round(Math.random()) ? salting : salting * -1) || 0;
|
|
46969
|
+
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + salt;
|
|
46970
|
+
const pairingDelta = Math.abs(ratings[0] - ratings[1]);
|
|
46971
|
+
deltaObjects[pairing] = pairingDelta;
|
|
46972
|
+
if (!valueObjects[pairing])
|
|
46973
|
+
valueObjects[pairing] = 0;
|
|
46974
|
+
valueObjects[pairing] += ratingsDifference ? Math.pow(ratingsDifference, 2) : 0;
|
|
46975
|
+
});
|
|
46976
|
+
const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
|
|
46977
|
+
const { pairingValues } = getParticipantPairingValues({
|
|
46978
|
+
possiblePairings,
|
|
46979
|
+
valueObjects
|
|
46980
|
+
});
|
|
46981
|
+
const { candidate, candidatesCount, deltaCandidate, iterations } = generateCandidate({
|
|
46982
|
+
valueSortedPairings,
|
|
46983
|
+
maxIterations,
|
|
46984
|
+
pairingValues,
|
|
46985
|
+
deltaObjects,
|
|
46986
|
+
valueObjects
|
|
46987
|
+
});
|
|
46988
|
+
const { participantIdPairings } = candidate;
|
|
46989
|
+
return {
|
|
46990
|
+
participantIdPairings,
|
|
46991
|
+
candidatesCount,
|
|
46992
|
+
deltaCandidate,
|
|
46993
|
+
iterations,
|
|
46994
|
+
candidate
|
|
46995
|
+
};
|
|
46996
|
+
}
|
|
46997
|
+
|
|
46998
|
+
const ENCOUNTER_VALUE = 100;
|
|
46999
|
+
const SAME_TEAM_VALUE = 100;
|
|
47000
|
+
const MAX_ITERATIONS = 4e3;
|
|
46810
47001
|
function generateDrawMaticRound({
|
|
47002
|
+
encounterValue = ENCOUNTER_VALUE,
|
|
47003
|
+
sameTeamValue = SAME_TEAM_VALUE,
|
|
46811
47004
|
maxIterations = MAX_ITERATIONS,
|
|
46812
47005
|
generateMatchUps = true,
|
|
46813
47006
|
tournamentParticipants,
|
|
@@ -46817,9 +47010,11 @@ function generateDrawMaticRound({
|
|
|
46817
47010
|
drawDefinition,
|
|
46818
47011
|
adHocRatings,
|
|
46819
47012
|
structureId,
|
|
47013
|
+
salted = 0.5,
|
|
46820
47014
|
matchUpIds,
|
|
46821
47015
|
eventType,
|
|
46822
|
-
structure
|
|
47016
|
+
structure,
|
|
47017
|
+
scaleName
|
|
46823
47018
|
}) {
|
|
46824
47019
|
if (!drawDefinition)
|
|
46825
47020
|
return { error: MISSING_DRAW_DEFINITION };
|
|
@@ -46838,7 +47033,7 @@ function generateDrawMaticRound({
|
|
|
46838
47033
|
for (const pairing of encounters) {
|
|
46839
47034
|
if (!valueObjects[pairing])
|
|
46840
47035
|
valueObjects[pairing] = 0;
|
|
46841
|
-
valueObjects[pairing] +=
|
|
47036
|
+
valueObjects[pairing] += encounterValue;
|
|
46842
47037
|
}
|
|
46843
47038
|
const teamParticipants = tournamentParticipants?.filter(
|
|
46844
47039
|
({ participantType }) => participantType === TEAM
|
|
@@ -46850,7 +47045,7 @@ function generateDrawMaticRound({
|
|
|
46850
47045
|
for (const pairing of uniquePairings2) {
|
|
46851
47046
|
if (!valueObjects[pairing])
|
|
46852
47047
|
valueObjects[pairing] = 0;
|
|
46853
|
-
valueObjects[pairing] +=
|
|
47048
|
+
valueObjects[pairing] += sameTeamValue;
|
|
46854
47049
|
}
|
|
46855
47050
|
}
|
|
46856
47051
|
}
|
|
@@ -46868,9 +47063,11 @@ function generateDrawMaticRound({
|
|
|
46868
47063
|
deltaObjects,
|
|
46869
47064
|
valueObjects,
|
|
46870
47065
|
eventType,
|
|
46871
|
-
|
|
47066
|
+
scaleName,
|
|
47067
|
+
structure,
|
|
47068
|
+
salted
|
|
46872
47069
|
};
|
|
46873
|
-
const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
|
|
47070
|
+
const { candidatesCount, participantIdPairings, iterations, candidate } = getPairings(params);
|
|
46874
47071
|
if (!candidatesCount)
|
|
46875
47072
|
return { error: NO_CANDIDATES };
|
|
46876
47073
|
let matchUps;
|
|
@@ -46888,130 +47085,28 @@ function generateDrawMaticRound({
|
|
|
46888
47085
|
return result;
|
|
46889
47086
|
matchUps = result.matchUps;
|
|
46890
47087
|
}
|
|
47088
|
+
const { maxDelta, maxDiff } = candidate;
|
|
46891
47089
|
return {
|
|
46892
47090
|
...SUCCESS,
|
|
46893
47091
|
participantIdPairings,
|
|
46894
47092
|
candidatesCount,
|
|
46895
47093
|
iterations,
|
|
46896
|
-
matchUps
|
|
47094
|
+
matchUps,
|
|
47095
|
+
maxDelta,
|
|
47096
|
+
maxDiff
|
|
46897
47097
|
};
|
|
46898
47098
|
}
|
|
46899
|
-
function getSideRatings({
|
|
46900
|
-
tournamentParticipants,
|
|
46901
|
-
adHocRatings,
|
|
46902
|
-
eventType,
|
|
46903
|
-
pairing
|
|
46904
|
-
}) {
|
|
46905
|
-
return pairing.split("|").map((participantId) => {
|
|
46906
|
-
if (eventType === DOUBLES) {
|
|
46907
|
-
const individualParticipantIds = tournamentParticipants?.find(
|
|
46908
|
-
(participant) => participant.participantId === participantId
|
|
46909
|
-
)?.individualParticipantIds;
|
|
46910
|
-
return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
|
|
46911
|
-
(participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
|
|
46912
|
-
);
|
|
46913
|
-
} else {
|
|
46914
|
-
return adHocRatings[participantId] || DEFAULT_RATING;
|
|
46915
|
-
}
|
|
46916
|
-
});
|
|
46917
|
-
}
|
|
46918
|
-
function getPairings({
|
|
46919
|
-
tournamentParticipants,
|
|
46920
|
-
adHocRatings = {},
|
|
46921
|
-
possiblePairings,
|
|
46922
|
-
// participant keyed; provides array of possible opponents
|
|
46923
|
-
uniquePairings,
|
|
46924
|
-
// hashes of all possible participantId pairings
|
|
46925
|
-
maxIterations,
|
|
46926
|
-
deltaObjects,
|
|
46927
|
-
// difference in rating between paired participants
|
|
46928
|
-
valueObjects,
|
|
46929
|
-
// calculated value of a pairing of participants, used for sorting pairings
|
|
46930
|
-
eventType
|
|
46931
|
-
}) {
|
|
46932
|
-
uniquePairings.forEach((pairing) => {
|
|
46933
|
-
const ratings = getSideRatings({
|
|
46934
|
-
tournamentParticipants,
|
|
46935
|
-
adHocRatings,
|
|
46936
|
-
eventType,
|
|
46937
|
-
pairing
|
|
46938
|
-
});
|
|
46939
|
-
const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
|
|
46940
|
-
deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
|
|
46941
|
-
if (!valueObjects[pairing])
|
|
46942
|
-
valueObjects[pairing] = 0;
|
|
46943
|
-
valueObjects[pairing] += Math.pow(ratingsDifference, 2);
|
|
46944
|
-
});
|
|
46945
|
-
const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
|
|
46946
|
-
const { pairingValues } = getParticipantPairingValues({
|
|
46947
|
-
possiblePairings,
|
|
46948
|
-
valueObjects
|
|
46949
|
-
});
|
|
46950
|
-
const { candidate, candidatesCount, iterations } = generateCandidate({
|
|
46951
|
-
valueSortedPairings,
|
|
46952
|
-
maxIterations,
|
|
46953
|
-
pairingValues,
|
|
46954
|
-
deltaObjects
|
|
46955
|
-
});
|
|
46956
|
-
const { participantIdPairings } = candidate;
|
|
46957
|
-
return { candidatesCount, participantIdPairings, iterations };
|
|
46958
|
-
}
|
|
46959
|
-
function getPairingsData({ participantIds }) {
|
|
46960
|
-
const possiblePairings = {};
|
|
46961
|
-
const uniquePairings = [];
|
|
46962
|
-
participantIds.forEach((participantId) => {
|
|
46963
|
-
possiblePairings[participantId] = participantIds.filter(
|
|
46964
|
-
(id) => id !== participantId
|
|
46965
|
-
);
|
|
46966
|
-
possiblePairings[participantId].forEach((id) => {
|
|
46967
|
-
const pairing = pairingHash(id, participantId);
|
|
46968
|
-
if (!uniquePairings.includes(pairing))
|
|
46969
|
-
uniquePairings.push(pairing);
|
|
46970
|
-
});
|
|
46971
|
-
});
|
|
46972
|
-
const deltaObjects = Object.assign(
|
|
46973
|
-
{},
|
|
46974
|
-
...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
|
|
46975
|
-
);
|
|
46976
|
-
return { uniquePairings, possiblePairings, deltaObjects };
|
|
46977
|
-
}
|
|
46978
|
-
function getEncounters({ matchUps }) {
|
|
46979
|
-
const encounters = [];
|
|
46980
|
-
for (const matchUp of matchUps) {
|
|
46981
|
-
const participantIds = matchUp.sides.map(getParticipantId);
|
|
46982
|
-
if (participantIds.length === 2) {
|
|
46983
|
-
const [p1, p2] = participantIds;
|
|
46984
|
-
const pairing = pairingHash(p1, p2);
|
|
46985
|
-
if (!encounters.includes(pairing))
|
|
46986
|
-
encounters.push(pairing);
|
|
46987
|
-
}
|
|
46988
|
-
}
|
|
46989
|
-
return { encounters };
|
|
46990
|
-
}
|
|
46991
|
-
function getParticipantPairingValues({ possiblePairings, valueObjects }) {
|
|
46992
|
-
const pairingValues = {};
|
|
46993
|
-
for (const participantId of Object.keys(possiblePairings)) {
|
|
46994
|
-
const participantValues = possiblePairings[participantId].map(
|
|
46995
|
-
(opponent) => pairingValue(participantId, opponent)
|
|
46996
|
-
);
|
|
46997
|
-
pairingValues[participantId] = participantValues.sort(
|
|
46998
|
-
(a, b) => a.value - b.value
|
|
46999
|
-
);
|
|
47000
|
-
}
|
|
47001
|
-
function pairingValue(participantId, opponent) {
|
|
47002
|
-
const key = pairingHash(participantId, opponent);
|
|
47003
|
-
return { opponent, value: valueObjects[key] };
|
|
47004
|
-
}
|
|
47005
|
-
return { pairingValues };
|
|
47006
|
-
}
|
|
47007
47099
|
|
|
47008
47100
|
function drawMatic$1({
|
|
47009
47101
|
tournamentParticipants,
|
|
47010
47102
|
restrictEntryStatus,
|
|
47011
|
-
|
|
47103
|
+
adHocRatings = {},
|
|
47012
47104
|
generateMatchUps,
|
|
47105
|
+
tournamentRecord,
|
|
47013
47106
|
addToStructure,
|
|
47014
47107
|
participantIds,
|
|
47108
|
+
encounterValue,
|
|
47109
|
+
sameTeamValue,
|
|
47015
47110
|
drawDefinition,
|
|
47016
47111
|
scaleAccessor,
|
|
47017
47112
|
maxIterations,
|
|
@@ -47020,6 +47115,7 @@ function drawMatic$1({
|
|
|
47020
47115
|
scaleName,
|
|
47021
47116
|
// custom rating name to seed dynamic ratings
|
|
47022
47117
|
eventType,
|
|
47118
|
+
salted,
|
|
47023
47119
|
event
|
|
47024
47120
|
}) {
|
|
47025
47121
|
if (typeof drawDefinition !== "object" || drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) {
|
|
@@ -47062,12 +47158,16 @@ function drawMatic$1({
|
|
|
47062
47158
|
if (!structureIsAdHoc)
|
|
47063
47159
|
return { error: INVALID_DRAW_DEFINITION };
|
|
47064
47160
|
tournamentParticipants = tournamentParticipants ?? tournamentRecord.participants ?? [];
|
|
47065
|
-
const adHocRatings = {};
|
|
47066
47161
|
for (const participantId of participantIds ?? []) {
|
|
47067
47162
|
const participant = tournamentParticipants?.find(
|
|
47068
47163
|
(participant2) => participant2.participantId === participantId
|
|
47069
47164
|
);
|
|
47070
|
-
let scaleValue = getScaleValue({
|
|
47165
|
+
let scaleValue = getScaleValue({
|
|
47166
|
+
scaleName: `${scaleName}.${DYNAMIC}`,
|
|
47167
|
+
scaleAccessor,
|
|
47168
|
+
participant,
|
|
47169
|
+
eventType
|
|
47170
|
+
});
|
|
47071
47171
|
if (!scaleValue && scaleName) {
|
|
47072
47172
|
scaleValue = getScaleValue({
|
|
47073
47173
|
scaleAccessor,
|
|
@@ -47076,32 +47176,36 @@ function drawMatic$1({
|
|
|
47076
47176
|
eventType
|
|
47077
47177
|
});
|
|
47078
47178
|
}
|
|
47079
|
-
if (scaleValue)
|
|
47179
|
+
if (scaleValue && !adHocRatings[participantId])
|
|
47080
47180
|
adHocRatings[participantId] = scaleValue;
|
|
47081
47181
|
}
|
|
47082
47182
|
return generateDrawMaticRound({
|
|
47083
47183
|
tournamentParticipants,
|
|
47084
|
-
tournamentRecord,
|
|
47085
47184
|
generateMatchUps,
|
|
47086
|
-
|
|
47185
|
+
tournamentRecord,
|
|
47087
47186
|
addToStructure,
|
|
47187
|
+
participantIds,
|
|
47188
|
+
encounterValue,
|
|
47189
|
+
sameTeamValue,
|
|
47088
47190
|
drawDefinition,
|
|
47089
47191
|
maxIterations,
|
|
47090
47192
|
adHocRatings,
|
|
47091
47193
|
matchUpIds,
|
|
47092
47194
|
structure,
|
|
47093
|
-
eventType
|
|
47195
|
+
eventType,
|
|
47196
|
+
salted
|
|
47094
47197
|
});
|
|
47095
47198
|
}
|
|
47096
47199
|
function getScaleValue({
|
|
47097
|
-
|
|
47098
|
-
scaleName = "dynamic",
|
|
47200
|
+
scaleType = RATING$2,
|
|
47099
47201
|
scaleAccessor,
|
|
47100
|
-
participant
|
|
47202
|
+
participant,
|
|
47203
|
+
scaleName,
|
|
47204
|
+
eventType
|
|
47101
47205
|
}) {
|
|
47102
47206
|
const scaleAttributes = {
|
|
47103
47207
|
eventType: eventType || TypeEnum.Singles,
|
|
47104
|
-
scaleType
|
|
47208
|
+
scaleType,
|
|
47105
47209
|
scaleName
|
|
47106
47210
|
};
|
|
47107
47211
|
const result = participant && participantScaleItem({
|
|
@@ -59475,11 +59579,15 @@ function calculateNewRatings(params) {
|
|
|
59475
59579
|
targetRange: consideredRange
|
|
59476
59580
|
});
|
|
59477
59581
|
const updatedWinnerRating = invertedScale ? ratingRange[0] - convertedUpdatedWinnerRating : convertedUpdatedWinnerRating;
|
|
59478
|
-
let newWinnerRating = parseFloat(
|
|
59582
|
+
let newWinnerRating = parseFloat(
|
|
59583
|
+
parseFloat(updatedWinnerRating).toFixed(decimalPlaces)
|
|
59584
|
+
);
|
|
59479
59585
|
const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
|
|
59480
|
-
let newLoserRating = parseFloat(
|
|
59586
|
+
let newLoserRating = parseFloat(
|
|
59587
|
+
parseFloat(updatedLoserRating).toFixed(decimalPlaces)
|
|
59588
|
+
);
|
|
59481
59589
|
const percentageDifference = Math.max(...ratingRange) ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange) : 0;
|
|
59482
|
-
if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold ||
|
|
59590
|
+
if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || newWinnerRating < 0 || newLoserRating < 0) {
|
|
59483
59591
|
newWinnerRating = winnerRating;
|
|
59484
59592
|
newLoserRating = loserRating;
|
|
59485
59593
|
}
|
|
@@ -59497,7 +59605,8 @@ const aggregateSets = (sets) => {
|
|
|
59497
59605
|
) || [0, 0];
|
|
59498
59606
|
};
|
|
59499
59607
|
|
|
59500
|
-
function
|
|
59608
|
+
function generateDynamicRatings({
|
|
59609
|
+
removePriorValues = true,
|
|
59501
59610
|
tournamentRecord,
|
|
59502
59611
|
ratingType = ELO,
|
|
59503
59612
|
considerGames,
|
|
@@ -59528,7 +59637,7 @@ function processMatchUps({
|
|
|
59528
59637
|
scaleName: ratingType,
|
|
59529
59638
|
scaleType: RATING$2
|
|
59530
59639
|
};
|
|
59531
|
-
const dynamicScaleName = `${ratingType}
|
|
59640
|
+
const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
|
|
59532
59641
|
const dynamicScaleAttributes = {
|
|
59533
59642
|
scaleName: dynamicScaleName,
|
|
59534
59643
|
eventType: matchUpType,
|
|
@@ -59564,9 +59673,9 @@ function processMatchUps({
|
|
|
59564
59673
|
return participantId && {
|
|
59565
59674
|
[participantId]: dynamicScaleItem ?? scaleItem ?? {
|
|
59566
59675
|
scaleName: outputScaleName,
|
|
59567
|
-
scaleType: RATING$2,
|
|
59568
59676
|
eventType: matchUpType,
|
|
59569
59677
|
scaleDate: endDate,
|
|
59678
|
+
scaleType: RATING$2,
|
|
59570
59679
|
scaleValue
|
|
59571
59680
|
}
|
|
59572
59681
|
};
|
|
@@ -59595,27 +59704,35 @@ function processMatchUps({
|
|
|
59595
59704
|
loserRating,
|
|
59596
59705
|
ratingType
|
|
59597
59706
|
});
|
|
59598
|
-
const newWinnerScaleValue = accessor ? {
|
|
59599
|
-
|
|
59707
|
+
const newWinnerScaleValue = accessor ? {
|
|
59708
|
+
...winnerScaleValue,
|
|
59709
|
+
[accessor]: newWinnerRating
|
|
59710
|
+
} : newWinnerRating;
|
|
59711
|
+
const newLoserScaleValue = accessor ? {
|
|
59712
|
+
...loserScaleValue,
|
|
59713
|
+
[accessor]: newLoserRating
|
|
59714
|
+
} : newLoserRating;
|
|
59600
59715
|
scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
|
|
59601
59716
|
scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
|
|
59602
59717
|
let result = setParticipantScaleItem({
|
|
59718
|
+
participantId: winnerParticipantId,
|
|
59719
|
+
removePriorValues,
|
|
59720
|
+
tournamentRecord,
|
|
59603
59721
|
scaleItem: {
|
|
59604
59722
|
...scaleItemMap[winnerParticipantId],
|
|
59605
59723
|
scaleName: outputScaleName
|
|
59606
|
-
}
|
|
59607
|
-
participantId: winnerParticipantId,
|
|
59608
|
-
tournamentRecord
|
|
59724
|
+
}
|
|
59609
59725
|
});
|
|
59610
59726
|
if (result.error)
|
|
59611
59727
|
return result;
|
|
59612
59728
|
result = setParticipantScaleItem({
|
|
59729
|
+
participantId: loserParticipantId,
|
|
59730
|
+
removePriorValues,
|
|
59731
|
+
tournamentRecord,
|
|
59613
59732
|
scaleItem: {
|
|
59614
59733
|
...scaleItemMap[loserParticipantId],
|
|
59615
59734
|
scaleName: outputScaleName
|
|
59616
|
-
}
|
|
59617
|
-
participantId: loserParticipantId,
|
|
59618
|
-
tournamentRecord
|
|
59735
|
+
}
|
|
59619
59736
|
});
|
|
59620
59737
|
if (result.error)
|
|
59621
59738
|
return result;
|
|
@@ -59629,7 +59746,7 @@ function processMatchUps({
|
|
|
59629
59746
|
|
|
59630
59747
|
const governor = {
|
|
59631
59748
|
calculateNewRatings,
|
|
59632
|
-
|
|
59749
|
+
generateDynamicRatings
|
|
59633
59750
|
};
|
|
59634
59751
|
|
|
59635
59752
|
const scaleEngine = (() => {
|