tods-competition-factory 2.2.41 → 2.2.43

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.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  function factoryVersion() {
6
- return '2.2.41';
6
+ return '2.2.43';
7
7
  }
8
8
 
9
9
  const SINGLES_MATCHUP = 'SINGLES';
@@ -1982,13 +1982,15 @@ const setTypes$1 = {
1982
1982
  };
1983
1983
 
1984
1984
  function stringify(matchUpFormatObject, preserveRedundant) {
1985
+ if (!isObject(matchUpFormatObject))
1986
+ return undefined;
1985
1987
  if ((matchUpFormatObject?.bestOf || matchUpFormatObject?.exactly) && matchUpFormatObject?.setFormat) {
1986
1988
  return getSetFormat(matchUpFormatObject, preserveRedundant);
1987
1989
  }
1988
1990
  return undefined;
1989
1991
  }
1990
1992
  function getNumber$1(formatstring) {
1991
- return !isNaN(Number(formatstring)) && Number(formatstring);
1993
+ return !Number.isNaN(Number(formatstring)) && Number(formatstring);
1992
1994
  }
1993
1995
  function timedSetFormat(matchUpFormatObject) {
1994
1996
  let value = `T${matchUpFormatObject.minutes}`;
@@ -2025,7 +2027,7 @@ function getSetFormat(matchUpFormatObject, preserveRedundant) {
2025
2027
  '';
2026
2028
  const valid = setLimitCode && setCountValue;
2027
2029
  if (valid) {
2028
- return [setLimitCode, setCode, finalSetCode].filter((f) => f).join('-');
2030
+ return [setLimitCode, setCode, finalSetCode].filter(Boolean).join('-');
2029
2031
  }
2030
2032
  return undefined;
2031
2033
  }
@@ -10343,7 +10345,7 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10343
10345
  const sourceDrawPositionRoundRanges = sourceDrawPositionRanges?.[roundNumber];
10344
10346
  const matchUpCategory = collectionDefinition?.category
10345
10347
  ? {
10346
- ...(context?.category || {}),
10348
+ ...context?.category,
10347
10349
  ...collectionDefinition.category,
10348
10350
  }
10349
10351
  : (context?.category ?? event?.category);
@@ -10361,7 +10363,7 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10361
10363
  ...onlyDefined(context),
10362
10364
  ...onlyDefined({
10363
10365
  matchUpFormat: matchUpType === TEAM$1 ? undefined : matchUpFormat,
10364
- tieFormat: matchUpType !== TEAM$1 ? undefined : tieFormat,
10366
+ tieFormat: matchUpType === TEAM$1 ? tieFormat : undefined,
10365
10367
  gender: collectionDefinition?.gender ?? event?.gender,
10366
10368
  endDate: matchUp.endDate ?? endDate,
10367
10369
  discipline: event?.discipline,
@@ -10402,16 +10404,19 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10402
10404
  .sort((a, b) => a.setNumber - b.setNumber)
10403
10405
  .map((set, i) => {
10404
10406
  const setNumber = i + 1;
10405
- if (setNumber === bestOf) {
10406
- if (finalSetFormat?.tiebreakSet || finalSetFormat?.timed)
10407
- set.tiebreakSet = true;
10408
- }
10409
- else if (setFormat?.tiebreakSet || setFormat?.timed) {
10407
+ const isDecidingSet = setNumber === bestOf;
10408
+ const currentSetFormat = isDecidingSet && finalSetFormat ? finalSetFormat : setFormat;
10409
+ const isTiebreakOnly = currentSetFormat?.tiebreakSet && !currentSetFormat?.timed;
10410
+ const isTimed = currentSetFormat?.timed;
10411
+ if (isTiebreakOnly) {
10410
10412
  set.tiebreakSet = true;
10413
+ if ([1, 2].includes(set.winningSide)) {
10414
+ set.side1Score = set.winningSide === 1 ? 1 : 0;
10415
+ set.side2Score = set.winningSide === 2 ? 1 : 0;
10416
+ }
10411
10417
  }
10412
- if (set.tiebreakSet && [1, 2].includes(set.winningSide)) {
10413
- set.side1Score = set.winningSide === 1 ? 1 : 0;
10414
- set.side2Score = set.winningSide === 2 ? 1 : 0;
10418
+ else if (isTimed) {
10419
+ set.timed = true;
10415
10420
  }
10416
10421
  return set;
10417
10422
  });
@@ -21620,7 +21625,7 @@ function processPlayoffGroups({ requireSequential = true, playoffMatchUpFormat,
21620
21625
  }
21621
21626
  for (const playoffGroup of playoffGroups) {
21622
21627
  const finishingPositions = playoffGroup.finishingPositions;
21623
- const positionsPlayedOff = positionRangeMap && finishingPositions.map((p) => positionRangeMap[p]?.finishingPositions).flat();
21628
+ const positionsPlayedOff = positionRangeMap && finishingPositions.flatMap((p) => positionRangeMap[p]?.finishingPositions ?? []);
21624
21629
  const participantsInDraw = groupCount * finishingPositions.length;
21625
21630
  const drawSize = nextPowerOf2(participantsInDraw);
21626
21631
  const playoffDrawType = (drawSize === 2 && SINGLE_ELIMINATION) || playoffGroup.drawType || SINGLE_ELIMINATION;
@@ -32184,7 +32189,7 @@ var help = {
32184
32189
  tidyScore: tidyScore
32185
32190
  };
32186
32191
 
32187
- function validateTiebreakOnlySet(winnerScore, loserScore, scoreDiff, tiebreakSetTo, allowIncomplete) {
32192
+ function validateTiebreakOnlySet(winnerScore, loserScore, scoreDiff, tiebreakSetTo, allowIncomplete, NoAD = false) {
32188
32193
  if (allowIncomplete) {
32189
32194
  return { isValid: true };
32190
32195
  }
@@ -32197,12 +32202,18 @@ function validateTiebreakOnlySet(winnerScore, loserScore, scoreDiff, tiebreakSet
32197
32202
  error: `Tiebreak-only set winner must reach at least ${tiebreakSetTo}, got ${winnerScore}`,
32198
32203
  };
32199
32204
  }
32200
- if (scoreDiff < 2) {
32205
+ const requiredWinBy = NoAD ? 1 : 2;
32206
+ if (scoreDiff < requiredWinBy) {
32201
32207
  return {
32202
32208
  isValid: false,
32203
- error: `Tiebreak-only set must be won by at least 2 points, got ${winnerScore}-${loserScore}`,
32209
+ error: NoAD
32210
+ ? `Tiebreak-only set (NoAD) must be won by at least 1 point, got ${winnerScore}-${loserScore}`
32211
+ : `Tiebreak-only set must be won by at least 2 points, got ${winnerScore}-${loserScore}`,
32204
32212
  };
32205
32213
  }
32214
+ if (NoAD) {
32215
+ return { isValid: true };
32216
+ }
32206
32217
  if (winnerScore === tiebreakSetTo && loserScore > tiebreakSetTo - 2) {
32207
32218
  return {
32208
32219
  isValid: false,
@@ -32393,7 +32404,8 @@ function validateSetScore(set, matchUpFormat, isDecidingSet, allowIncomplete) {
32393
32404
  const loserScore = Math.min(side1Score, side2Score);
32394
32405
  const scoreDiff = winnerScore - loserScore;
32395
32406
  if (isTiebreakOnlyFormat) {
32396
- return validateTiebreakOnlySet(winnerScore, loserScore, scoreDiff, tiebreakSetTo, allowIncomplete ?? false);
32407
+ const NoAD = setFormat.tiebreakSet?.NoAD ?? false;
32408
+ return validateTiebreakOnlySet(winnerScore, loserScore, scoreDiff, tiebreakSetTo, allowIncomplete ?? false, NoAD);
32397
32409
  }
32398
32410
  const hasExplicitTiebreak = side1TiebreakScore !== undefined || side2TiebreakScore !== undefined;
32399
32411
  const isImplicitTiebreak = setTo && winnerScore === setTo + 1 && loserScore === setTo;
@@ -32427,6 +32439,62 @@ function validateMatchUpScore(sets, matchUpFormat, matchUpStatus) {
32427
32439
  return { isValid: true };
32428
32440
  }
32429
32441
 
32442
+ function validateTiebreak(tiebreakFormat, side1TiebreakScore, side2TiebreakScore, setWinningSide, isLastSet, irregularEnding) {
32443
+ const { tiebreakTo, NoAD } = tiebreakFormat || {};
32444
+ const maxTiebreakScore = Math.max(side1TiebreakScore ?? 0, side2TiebreakScore ?? 0);
32445
+ if (NoAD && maxTiebreakScore > tiebreakTo)
32446
+ return false;
32447
+ if (maxTiebreakScore < tiebreakTo && setWinningSide) {
32448
+ if (isLastSet && !irregularEnding)
32449
+ return false;
32450
+ if (!isLastSet)
32451
+ return false;
32452
+ }
32453
+ return true;
32454
+ }
32455
+ function validateSet(set, i, matchUpScoringFormat, totalSets, isLastSet, irregularEnding) {
32456
+ const setNumber = i + 1;
32457
+ const isFinalSet = setNumber === totalSets;
32458
+ const { side1Score, side2Score, side1TiebreakScore, side2TiebreakScore, winningSide: setWinningSide } = set;
32459
+ const maxSetScore = Math.max(side1Score ?? 0, side2Score ?? 0);
32460
+ const hasTiebreak = side1TiebreakScore ?? side2TiebreakScore;
32461
+ const { finalSetFormat, setFormat } = matchUpScoringFormat;
32462
+ const setValues = isFinalSet ? finalSetFormat || setFormat : setFormat;
32463
+ if (hasTiebreak) {
32464
+ const isValidTiebreak = validateTiebreak(setValues?.tiebreakFormat, side1TiebreakScore, side2TiebreakScore, setWinningSide, isLastSet, irregularEnding);
32465
+ if (!isValidTiebreak)
32466
+ return false;
32467
+ }
32468
+ if (!setValues.setTo)
32469
+ return true;
32470
+ const excessiveSetScore = !setValues.noTiebreak && maxSetScore > setValues.setTo + 1;
32471
+ return !excessiveSetScore;
32472
+ }
32473
+ function calculateAggregateWinner(sets) {
32474
+ const aggregateTotals = sets.reduce((totals, set) => {
32475
+ if (set.side1Score !== undefined || set.side2Score !== undefined) {
32476
+ totals[0] += set.side1Score ?? 0;
32477
+ totals[1] += set.side2Score ?? 0;
32478
+ }
32479
+ return totals;
32480
+ }, [0, 0]);
32481
+ if (aggregateTotals[0] > aggregateTotals[1]) {
32482
+ return 1;
32483
+ }
32484
+ else if (aggregateTotals[1] > aggregateTotals[0]) {
32485
+ return 2;
32486
+ }
32487
+ else {
32488
+ const tiebreakSet = sets.find((set) => set.side1TiebreakScore !== undefined || set.side2TiebreakScore !== undefined);
32489
+ return tiebreakSet?.winningSide;
32490
+ }
32491
+ }
32492
+ function calculateStandardWinner(maxSetsCount, setsToWin, maxSetsInstances, setsWinCounts, matchUpFormat) {
32493
+ return (((!matchUpFormat || maxSetsCount === setsToWin) &&
32494
+ maxSetsInstances === 1 &&
32495
+ setsWinCounts.indexOf(maxSetsCount) + 1) ||
32496
+ undefined);
32497
+ }
32430
32498
  function analyzeScore({ existingMatchUpStatus, matchUpFormat, matchUpStatus, winningSide, score, }) {
32431
32499
  const sets = score?.sets ?? [];
32432
32500
  const completedSets = sets?.filter((set) => set?.winningSide) || [];
@@ -32448,71 +32516,23 @@ function analyzeScore({ existingMatchUpStatus, matchUpFormat, matchUpStatus, win
32448
32516
  const maxSetsCount = Math.max(...setsWinCounts);
32449
32517
  const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
32450
32518
  const timed = matchUpScoringFormat?.setFormat?.timed || matchUpScoringFormat?.finalSetFormat?.timed;
32451
- const bestOf = matchUpScoringFormat?.bestOf;
32452
- const setsToWin = (bestOf && Math.ceil(bestOf / 2)) || 1;
32519
+ const totalSets = matchUpScoringFormat?.bestOf || matchUpScoringFormat?.exactly;
32520
+ const setsToWin = (totalSets && Math.ceil(totalSets / 2)) || 1;
32453
32521
  const relevantMatchUpStatus = matchUpStatus ?? existingMatchUpStatus;
32454
- const irregularEnding = relevantMatchUpStatus && [DEFAULTED, RETIRED$1, WALKOVER$2].includes(relevantMatchUpStatus);
32522
+ const irregularEnding = !!(relevantMatchUpStatus && [DEFAULTED, RETIRED$1, WALKOVER$2].includes(relevantMatchUpStatus));
32455
32523
  const validSets = !matchUpScoringFormat ||
32456
32524
  !sets.length ||
32457
- sets.every((set, i) => {
32458
- const setNumber = i + 1;
32459
- const isFinalSet = setNumber === bestOf;
32460
- const isLastSet = setNumber === sets.length;
32461
- const { side1Score, side2Score, side1TiebreakScore, side2TiebreakScore, winningSide: setWinningSide } = set;
32462
- const maxSetScore = Math.max(side1Score ?? 0, side2Score ?? 0);
32463
- const hasTiebreak = side1TiebreakScore ?? side2TiebreakScore;
32464
- const { finalSetFormat, setFormat } = matchUpScoringFormat;
32465
- const setValues = isFinalSet ? finalSetFormat || setFormat : setFormat;
32466
- if (hasTiebreak) {
32467
- const { tiebreakTo, NoAD } = setValues?.tiebreakFormat || {};
32468
- const maxTiebreakScore = Math.max(side1TiebreakScore ?? 0, side2TiebreakScore ?? 0);
32469
- if (NoAD && maxTiebreakScore > tiebreakTo)
32470
- return false;
32471
- if (maxTiebreakScore < tiebreakTo && setWinningSide) {
32472
- if (isLastSet && !irregularEnding)
32473
- return false;
32474
- if (!isLastSet)
32475
- return false;
32476
- }
32477
- }
32478
- if (!setValues.setTo)
32479
- return true;
32480
- const excessiveSetScore = !setValues.noTiebreak && maxSetScore > setValues.setTo + 1;
32481
- return !excessiveSetScore;
32482
- });
32525
+ sets.every((set, i) => validateSet(set, i, matchUpScoringFormat, totalSets ?? 0, i === sets.length - 1, irregularEnding));
32483
32526
  const isAggregateScoring = matchUpScoringFormat?.setFormat?.based === 'A' || matchUpScoringFormat?.finalSetFormat?.based === 'A';
32484
- let calculatedWinningSide;
32485
- if (isAggregateScoring && sets.length > 0) {
32486
- const aggregateTotals = sets.reduce((totals, set) => {
32487
- if (set.side1Score !== undefined || set.side2Score !== undefined) {
32488
- totals[0] += set.side1Score ?? 0;
32489
- totals[1] += set.side2Score ?? 0;
32490
- }
32491
- return totals;
32492
- }, [0, 0]);
32493
- if (aggregateTotals[0] > aggregateTotals[1]) {
32494
- calculatedWinningSide = 1;
32495
- }
32496
- else if (aggregateTotals[1] > aggregateTotals[0]) {
32497
- calculatedWinningSide = 2;
32498
- }
32499
- else {
32500
- const tiebreakSet = sets.find((set) => set.side1TiebreakScore !== undefined || set.side2TiebreakScore !== undefined);
32501
- if (tiebreakSet) {
32502
- calculatedWinningSide = tiebreakSet.winningSide;
32503
- }
32504
- }
32505
- }
32506
- else {
32507
- calculatedWinningSide =
32508
- ((!matchUpFormat || maxSetsCount === setsToWin) &&
32509
- maxSetsInstances === 1 &&
32510
- setsWinCounts.indexOf(maxSetsCount) + 1) ||
32511
- undefined;
32512
- }
32527
+ const calculatedWinningSide = isAggregateScoring && sets.length > 0
32528
+ ? calculateAggregateWinner(sets)
32529
+ : calculateStandardWinner(maxSetsCount, setsToWin, maxSetsInstances, setsWinCounts, matchUpFormat);
32513
32530
  const valid = !!(validSets &&
32514
32531
  ((winningSide && isAggregateScoring && winningSide === calculatedWinningSide) ||
32515
- (winningSide && !isAggregateScoring && winningSideSetsCount > losingSideSetsCount && winningSide === calculatedWinningSide) ||
32532
+ (winningSide &&
32533
+ !isAggregateScoring &&
32534
+ winningSideSetsCount > losingSideSetsCount &&
32535
+ winningSide === calculatedWinningSide) ||
32516
32536
  (winningSide && irregularEnding) ||
32517
32537
  (!winningSide &&
32518
32538
  !calculatedWinningSide &&
@@ -32631,94 +32651,115 @@ function getHighTiebreakValue(params) {
32631
32651
  return tiebreakTo;
32632
32652
  }
32633
32653
 
32654
+ function determineWinningSide(score1, score2) {
32655
+ return (score1 > score2 && 1) || (score1 < score2 && 2) || undefined;
32656
+ }
32657
+ function parseTiebreakOnlySet(bracketedScores, isTiebreakOnlyFormat) {
32658
+ if (isTiebreakOnlyFormat) {
32659
+ return {
32660
+ side1Score: bracketedScores[0],
32661
+ side2Score: bracketedScores[1],
32662
+ winningSide: determineWinningSide(bracketedScores[0], bracketedScores[1]),
32663
+ };
32664
+ }
32665
+ return {
32666
+ side1TiebreakScore: bracketedScores[0],
32667
+ side2TiebreakScore: bracketedScores[1],
32668
+ winningSide: determineWinningSide(bracketedScores[0], bracketedScores[1]),
32669
+ };
32670
+ }
32634
32671
  function parseScoreString({ tiebreakTo = 7, scoreString = '', matchUpFormat }) {
32635
32672
  let parsedFormat;
32636
32673
  let bestOfSets = 3;
32637
32674
  if (matchUpFormat) {
32638
32675
  try {
32639
32676
  parsedFormat = parse(matchUpFormat);
32640
- const bestOfMatch = matchUpFormat?.match(/SET(\d+)/)?.[1];
32677
+ const bestOfMatch = /SET(\d+)/.exec(matchUpFormat)?.[1];
32641
32678
  bestOfSets = bestOfMatch ? Number.parseInt(bestOfMatch) : 3;
32642
32679
  }
32643
- catch (_e) {
32680
+ catch {
32644
32681
  }
32645
32682
  }
32646
32683
  return scoreString
32647
32684
  ?.split(' ')
32648
32685
  .filter(Boolean)
32649
32686
  .map((set, index) => parseSet({ set, setNumber: index + 1 }));
32687
+ function checkIsTiebreakOnlyFormat(setNumber, isTiebreakOnlySet) {
32688
+ if (!parsedFormat || !isTiebreakOnlySet)
32689
+ return false;
32690
+ const isDecidingSet = setNumber === bestOfSets;
32691
+ const setFormat = isDecidingSet && parsedFormat.finalSetFormat ? parsedFormat.finalSetFormat : parsedFormat.setFormat;
32692
+ if (!setFormat)
32693
+ return false;
32694
+ const tiebreakSetTo = setFormat.tiebreakSet?.tiebreakTo;
32695
+ const regularSetTo = setFormat.setTo;
32696
+ return !!tiebreakSetTo && !regularSetTo;
32697
+ }
32698
+ function getTiebreakToForSet(setNumber) {
32699
+ if (!parsedFormat)
32700
+ return tiebreakTo;
32701
+ const isDecidingSet = setNumber === bestOfSets;
32702
+ const setFormat = isDecidingSet && parsedFormat.finalSetFormat ? parsedFormat.finalSetFormat : parsedFormat.setFormat;
32703
+ return setFormat?.tiebreakFormat?.tiebreakTo ?? tiebreakTo;
32704
+ }
32705
+ function parseTiebreakGame(tiebreakMatch, winningSide, setNumber) {
32706
+ const setTiebreakLowScore = tiebreakMatch[1];
32707
+ const setSpecificTiebreakTo = getTiebreakToForSet(setNumber);
32708
+ const side1TiebreakPerspective = getTiebreakComplement({
32709
+ lowValue: setTiebreakLowScore,
32710
+ isSide1: winningSide === 2,
32711
+ tiebreakTo: setSpecificTiebreakTo,
32712
+ });
32713
+ if (Array.isArray(side1TiebreakPerspective)) {
32714
+ return [side1TiebreakPerspective[0], side1TiebreakPerspective[1]];
32715
+ }
32716
+ return [undefined, undefined];
32717
+ }
32718
+ function parseRegularSet(set, tiebreak, bracketed, setNumber) {
32719
+ const setString = (tiebreak && set.replace(tiebreak[0], '')) || (bracketed && set.replace(bracketed[0], '')) || set;
32720
+ const setScores = setString.split('-').map((score) => Number.parseInt(score));
32721
+ const side1Score = setScores[0];
32722
+ const side2Score = setScores[1];
32723
+ const winningSide = determineWinningSide(side1Score, side2Score);
32724
+ let side1TiebreakScore;
32725
+ let side2TiebreakScore;
32726
+ if (tiebreak) {
32727
+ [side1TiebreakScore, side2TiebreakScore] = parseTiebreakGame(tiebreak, winningSide, setNumber);
32728
+ }
32729
+ if (bracketed) {
32730
+ const matchTiebreakScores = bracketed[1].split('-').map((score) => Number.parseInt(score));
32731
+ side1TiebreakScore = matchTiebreakScores[0];
32732
+ side2TiebreakScore = matchTiebreakScores[1];
32733
+ }
32734
+ return {
32735
+ side1Score,
32736
+ side2Score,
32737
+ side1TiebreakScore,
32738
+ side2TiebreakScore,
32739
+ winningSide,
32740
+ };
32741
+ }
32650
32742
  function parseSet({ set, setNumber }) {
32651
32743
  const inParentheses = /\(([^)]+)\)/;
32652
32744
  const inBrackets = /\[([^\]]+)\]/;
32653
32745
  const tiebreak = inParentheses.exec(set);
32654
32746
  const bracketed = inBrackets.exec(set);
32655
32747
  const isTiebreakOnlySet = set?.startsWith('[') && bracketed;
32656
- let isTiebreakOnlyFormat = false;
32657
- if (parsedFormat && isTiebreakOnlySet) {
32658
- const isDecidingSet = setNumber === bestOfSets;
32659
- const setFormat = isDecidingSet && parsedFormat.finalSetFormat ? parsedFormat.finalSetFormat : parsedFormat.setFormat;
32660
- if (setFormat) {
32661
- const tiebreakSetTo = setFormat.tiebreakSet?.tiebreakTo;
32662
- const regularSetTo = setFormat.setTo;
32663
- isTiebreakOnlyFormat = !!tiebreakSetTo && !regularSetTo;
32664
- }
32665
- }
32666
- let side1Score;
32667
- let side2Score;
32668
- let side1TiebreakScore;
32669
- let side2TiebreakScore;
32670
- let winningSide;
32748
+ const isTiebreakOnlyFormat = checkIsTiebreakOnlyFormat(setNumber, !!isTiebreakOnlySet);
32749
+ let result;
32671
32750
  if (isTiebreakOnlySet) {
32672
- const bracketedScores = bracketed[1].split('-').map((score) => parseInt(score));
32673
- if (isTiebreakOnlyFormat) {
32674
- side1Score = bracketedScores[0];
32675
- side2Score = bracketedScores[1];
32676
- winningSide = (side1Score > side2Score && 1) || (side1Score < side2Score && 2) || undefined;
32677
- }
32678
- else {
32679
- side1TiebreakScore = bracketedScores[0];
32680
- side2TiebreakScore = bracketedScores[1];
32681
- winningSide =
32682
- (side1TiebreakScore > side2TiebreakScore && 1) || (side1TiebreakScore < side2TiebreakScore && 2) || undefined;
32683
- }
32751
+ const bracketedScores = bracketed[1].split('-').map((score) => Number.parseInt(score));
32752
+ result = parseTiebreakOnlySet(bracketedScores, isTiebreakOnlyFormat);
32684
32753
  }
32685
32754
  else {
32686
- const setString = (tiebreak && set.replace(tiebreak[0], '')) || (bracketed && set.replace(bracketed[0], '')) || set;
32687
- const setScores = setString.split('-').map((score) => Number.parseInt(score));
32688
- side1Score = setScores[0];
32689
- side2Score = setScores[1];
32690
- winningSide = (side1Score > side2Score && 1) || (side1Score < side2Score && 2) || undefined;
32691
- if (tiebreak) {
32692
- const setTiebreakLowScore = tiebreak[1];
32693
- let setSpecificTiebreakTo = tiebreakTo;
32694
- if (parsedFormat) {
32695
- const isDecidingSet = setNumber === bestOfSets;
32696
- const setFormat = isDecidingSet && parsedFormat.finalSetFormat ? parsedFormat.finalSetFormat : parsedFormat.setFormat;
32697
- if (setFormat?.tiebreakFormat?.tiebreakTo) {
32698
- setSpecificTiebreakTo = setFormat.tiebreakFormat.tiebreakTo;
32699
- }
32700
- }
32701
- const side1TiebreakPerspective = getTiebreakComplement({
32702
- lowValue: setTiebreakLowScore,
32703
- isSide1: winningSide === 2,
32704
- tiebreakTo: setSpecificTiebreakTo,
32705
- });
32706
- if (Array.isArray(side1TiebreakPerspective)) {
32707
- [side1TiebreakScore, side2TiebreakScore] = side1TiebreakPerspective;
32708
- }
32709
- }
32710
- if (bracketed && !isTiebreakOnlySet) {
32711
- const matchTiebreakScores = bracketed[1].split('-').map((score) => Number.parseInt(score));
32712
- side1TiebreakScore = matchTiebreakScores[0];
32713
- side2TiebreakScore = matchTiebreakScores[1];
32714
- }
32755
+ result = parseRegularSet(set, tiebreak, bracketed, setNumber);
32715
32756
  }
32716
32757
  return {
32717
- side1Score,
32718
- side2Score,
32719
- side1TiebreakScore,
32720
- side2TiebreakScore,
32721
- winningSide,
32758
+ side1Score: result.side1Score,
32759
+ side2Score: result.side2Score,
32760
+ side1TiebreakScore: result.side1TiebreakScore,
32761
+ side2TiebreakScore: result.side2TiebreakScore,
32762
+ winningSide: result.winningSide,
32722
32763
  setNumber,
32723
32764
  };
32724
32765
  }
@@ -47239,6 +47280,67 @@ var index$9 = {
47239
47280
  validMatchUps: validMatchUps
47240
47281
  };
47241
47282
 
47283
+ function inferWinningSideFromAggregate(neutralParsedSets) {
47284
+ const aggregateTotals = neutralParsedSets.reduce((totals, set) => {
47285
+ if (set.side1Score !== undefined || set.side2Score !== undefined) {
47286
+ totals.side1 += set.side1Score ?? 0;
47287
+ totals.side2 += set.side2Score ?? 0;
47288
+ }
47289
+ return totals;
47290
+ }, { side1: 0, side2: 0 });
47291
+ if (aggregateTotals.side1 > aggregateTotals.side2)
47292
+ return 1;
47293
+ if (aggregateTotals.side2 > aggregateTotals.side1)
47294
+ return 2;
47295
+ const tiebreakSet = neutralParsedSets.find((set) => set.side1TiebreakScore !== undefined || set.side2TiebreakScore !== undefined);
47296
+ return tiebreakSet?.winningSide;
47297
+ }
47298
+ function inferWinningSideFromSets(neutralParsedSets) {
47299
+ const setsWon = { side1: 0, side2: 0 };
47300
+ neutralParsedSets.forEach((set) => {
47301
+ if (set.winningSide === 1)
47302
+ setsWon.side1++;
47303
+ else if (set.winningSide === 2)
47304
+ setsWon.side2++;
47305
+ });
47306
+ if (setsWon.side1 > setsWon.side2)
47307
+ return 1;
47308
+ if (setsWon.side2 > setsWon.side1)
47309
+ return 2;
47310
+ return undefined;
47311
+ }
47312
+ function inferWinningSide(winningSide, matchUpFormat, neutralParsedSets) {
47313
+ if (winningSide || !matchUpFormat || !neutralParsedSets)
47314
+ return winningSide;
47315
+ const parsedFormat = parse(matchUpFormat);
47316
+ const isAggregateScoring = parsedFormat?.setFormat?.based === 'A' || parsedFormat?.finalSetFormat?.based === 'A';
47317
+ return isAggregateScoring
47318
+ ? inferWinningSideFromAggregate(neutralParsedSets)
47319
+ : inferWinningSideFromSets(neutralParsedSets);
47320
+ }
47321
+ function generateScoreForSideOrder(scoreString, matchUpFormat, setTBlast) {
47322
+ const sets = parseScoreString({ scoreString, matchUpFormat });
47323
+ return {
47324
+ sets,
47325
+ scoreStringSide1: generateScoreString({ sets, matchUpFormat, setTBlast }),
47326
+ scoreStringSide2: generateScoreString({ sets, reversed: true, matchUpFormat, setTBlast }),
47327
+ };
47328
+ }
47329
+ function generateScoreForWinnerOrder(neutralParsedSets, inferredWinningSide, matchUpFormat, setTBlast) {
47330
+ const winningScoreString = generateScoreString({ sets: neutralParsedSets, matchUpFormat, setTBlast });
47331
+ const losingScoreString = generateScoreString({ sets: neutralParsedSets, reversed: true, matchUpFormat, setTBlast });
47332
+ if (typeof winningScoreString !== 'string')
47333
+ return winningScoreString;
47334
+ if (typeof losingScoreString !== 'string')
47335
+ return losingScoreString;
47336
+ const scoreStringSide1 = inferredWinningSide === 2 ? losingScoreString : winningScoreString;
47337
+ const scoreStringSide2 = inferredWinningSide === 2 ? winningScoreString : losingScoreString;
47338
+ return {
47339
+ sets: parseScoreString({ scoreString: scoreStringSide1, matchUpFormat }),
47340
+ scoreStringSide1,
47341
+ scoreStringSide2,
47342
+ };
47343
+ }
47242
47344
  function generateOutcomeFromScoreString(params) {
47243
47345
  const { matchUpFormat, matchUpStatus, winningSide, scoreString, setTBlast } = params;
47244
47346
  if (!scoreString)
@@ -47253,81 +47355,12 @@ function generateOutcomeFromScoreString(params) {
47253
47355
  return { error: INVALID_VALUES, winningSide };
47254
47356
  const neutralParsedSets = scoreString && parseScoreString({ scoreString, matchUpFormat });
47255
47357
  const isBracketNotation = scoreString?.trim().startsWith('[');
47256
- let inferredWinningSide = winningSide;
47257
- if (!inferredWinningSide && matchUpFormat && neutralParsedSets) {
47258
- const parsedFormat = parse(matchUpFormat);
47259
- const isAggregateScoring = parsedFormat?.setFormat?.based === 'A' || parsedFormat?.finalSetFormat?.based === 'A';
47260
- if (isAggregateScoring) {
47261
- const aggregateTotals = neutralParsedSets.reduce((totals, set) => {
47262
- if (set.side1Score !== undefined || set.side2Score !== undefined) {
47263
- totals.side1 += set.side1Score ?? 0;
47264
- totals.side2 += set.side2Score ?? 0;
47265
- }
47266
- return totals;
47267
- }, { side1: 0, side2: 0 });
47268
- if (aggregateTotals.side1 > aggregateTotals.side2)
47269
- inferredWinningSide = 1;
47270
- else if (aggregateTotals.side2 > aggregateTotals.side1)
47271
- inferredWinningSide = 2;
47272
- else {
47273
- const tiebreakSet = neutralParsedSets.find((set) => set.side1TiebreakScore !== undefined || set.side2TiebreakScore !== undefined);
47274
- if (tiebreakSet)
47275
- inferredWinningSide = tiebreakSet.winningSide;
47276
- }
47277
- }
47278
- else {
47279
- const setsWon = { side1: 0, side2: 0 };
47280
- neutralParsedSets.forEach((set) => {
47281
- if (set.winningSide === 1)
47282
- setsWon.side1++;
47283
- else if (set.winningSide === 2)
47284
- setsWon.side2++;
47285
- });
47286
- if (setsWon.side1 > setsWon.side2)
47287
- inferredWinningSide = 1;
47288
- else if (setsWon.side2 > setsWon.side1)
47289
- inferredWinningSide = 2;
47290
- }
47291
- }
47292
- const score = {};
47358
+ const inferredWinningSide = inferWinningSide(winningSide, matchUpFormat, neutralParsedSets);
47293
47359
  const parsedFormat = parse(matchUpFormat);
47294
47360
  const isAggregateScoring = parsedFormat?.setFormat?.based === 'A' || parsedFormat?.finalSetFormat?.based === 'A';
47295
- if (isBracketNotation || isAggregateScoring) {
47296
- score.sets = parseScoreString({ scoreString, matchUpFormat });
47297
- score.scoreStringSide1 = generateScoreString({
47298
- sets: score.sets,
47299
- matchUpFormat,
47300
- setTBlast,
47301
- });
47302
- score.scoreStringSide2 = generateScoreString({
47303
- sets: score.sets,
47304
- reversed: true,
47305
- matchUpFormat,
47306
- setTBlast,
47307
- });
47308
- }
47309
- else {
47310
- const winningScoreString = generateScoreString({
47311
- sets: neutralParsedSets,
47312
- matchUpFormat,
47313
- setTBlast,
47314
- });
47315
- const losingScoreString = generateScoreString({
47316
- sets: neutralParsedSets,
47317
- reversed: true,
47318
- matchUpFormat,
47319
- setTBlast,
47320
- });
47321
- if (inferredWinningSide === 2) {
47322
- score.scoreStringSide1 = losingScoreString;
47323
- score.scoreStringSide2 = winningScoreString;
47324
- }
47325
- else {
47326
- score.scoreStringSide1 = winningScoreString;
47327
- score.scoreStringSide2 = losingScoreString;
47328
- }
47329
- score.sets = parseScoreString({ scoreString: score.scoreStringSide1, matchUpFormat });
47330
- }
47361
+ const score = isBracketNotation || isAggregateScoring
47362
+ ? generateScoreForSideOrder(scoreString, matchUpFormat, setTBlast)
47363
+ : generateScoreForWinnerOrder(neutralParsedSets, inferredWinningSide, matchUpFormat, setTBlast);
47331
47364
  return definedAttributes({
47332
47365
  outcome: {
47333
47366
  matchUpStatus,
@@ -59583,7 +59616,7 @@ async function asyncExecutionQueue(engine, directives, rollbackOnError) {
59583
59616
  if (!methods[methodName])
59584
59617
  return logMethodNotFound({ methodName, start, params });
59585
59618
  if (pipe) {
59586
- const lastResult = results[results.length - 1];
59619
+ const lastResult = results.at(-1);
59587
59620
  const pipeKeys = Object.keys(pipe);
59588
59621
  for (const pipeKey of pipeKeys) {
59589
59622
  if (lastResult[pipeKey])
@@ -59765,7 +59798,7 @@ function executionQueue(engine, directives, rollbackOnError) {
59765
59798
  if (!methods[methodName])
59766
59799
  return logMethodNotFound({ methodName, start, params });
59767
59800
  if (pipe) {
59768
- const lastResult = results[results.length - 1];
59801
+ const lastResult = results.at(-1);
59769
59802
  const pipeKeys = Object.keys(pipe);
59770
59803
  for (const pipeKey of pipeKeys) {
59771
59804
  if (lastResult[pipeKey])