@ethlete/cdk 4.47.0 → 4.48.0

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.
@@ -1,10 +1,10 @@
1
1
  import * as i1 from '@angular/cdk/portal';
2
2
  import { CdkPortal, PortalModule, ComponentPortal, TemplatePortal, CdkPortalOutlet } from '@angular/cdk/portal';
3
- import { AsyncPipe, NgClass, NgTemplateOutlet, NgComponentOutlet, JsonPipe, DOCUMENT, Location } from '@angular/common';
3
+ import { AsyncPipe, NgClass, NgTemplateOutlet, isPlatformBrowser, NgComponentOutlet, JsonPipe, DOCUMENT, Location } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
5
- import { Component, ViewEncapsulation, ChangeDetectionStrategy, InjectionToken, Directive, booleanAttribute, Input, ContentChild, ContentChildren, inject, ElementRef, Injector, HostBinding, input, numberAttribute, computed, signal, contentChildren, viewChild, viewChildren, isDevMode, Injectable, ChangeDetectorRef, TemplateRef, ViewContainerRef, ViewChild, assertInInjectionContext, forwardRef, EventEmitter, Output, ViewChildren, runInInjectionContext, Optional, Inject, SkipSelf, HostListener, contentChild, effect, untracked, NgZone, NgModule, DestroyRef, isSignal, Attribute } from '@angular/core';
5
+ import { Component, ViewEncapsulation, ChangeDetectionStrategy, InjectionToken, Directive, booleanAttribute, Input, ContentChild, ContentChildren, inject, ElementRef, Injector, HostBinding, input, numberAttribute, computed, PLATFORM_ID, Renderer2, effect, DestroyRef, signal, contentChildren, viewChild, viewChildren, isDevMode, Injectable, ChangeDetectorRef, TemplateRef, ViewContainerRef, ViewChild, assertInInjectionContext, forwardRef, EventEmitter, Output, ViewChildren, runInInjectionContext, Optional, Inject, SkipSelf, HostListener, contentChild, untracked, NgZone, NgModule, isSignal, Attribute } from '@angular/core';
6
6
  import * as i1$1 from '@ethlete/core';
7
- import { LetDirective, createDestroy, Memo, signalHostAttributes, signalHostClasses, previousSignalValue, signalHostStyles, nextFrame, syncSignal, signalStyles, injectHostElement, ObserveVisibilityDirective, signalVisibilityChangeClasses, IS_EMAIL, MUST_MATCH, IS_ARRAY_NOT_EMPTY, AT_LEAST_ONE_REQUIRED, equal, switchQueryListChanges, controlValueSignal, signalAttributes, ResizeObserverService, createFlipAnimation, AnimatedOverlayDirective, RuntimeError, SelectionModel, ActiveSelectionModel, KeyPressManager, signalClasses, scrollToElement, isEmptyArray, isObjectArray, isPrimitiveArray, createComponentId, ClickOutsideDirective, ANIMATED_LIFECYCLE_TOKEN, AnimatedLifecycleDirective, ObserveContentDirective, clamp, DELAYABLE_TOKEN, ObserveResizeDirective, SmartBlockScrollStrategy, signalElementDimensions, signalElementScrollState, createIsRenderedSignal, createCanAnimateSignal, useCursorDragScroll, signalElementIntersection, signalElementChildren, getIntersectionInfo, getElementScrollCoordinates, ObserveScrollStateDirective, ClickObserverService, RootBoundaryDirective, elementCanScroll, cloneFormGroup, getFormGroupValue, ViewportService, injectRoute, ROOT_BOUNDARY_TOKEN, injectQueryParam, RouterStateService, fromNextFrame, isElementVisible, AnimatedIfDirective, FocusVisibleService, inferMimeType, ScrollObserverIgnoreTargetDirective, TypedQueryList } from '@ethlete/core';
7
+ import { LetDirective, createDestroy, Memo, createComponentId, signalHostAttributes, signalHostClasses, previousSignalValue, signalHostStyles, nextFrame, syncSignal, signalStyles, injectHostElement, ObserveVisibilityDirective, signalVisibilityChangeClasses, IS_EMAIL, MUST_MATCH, IS_ARRAY_NOT_EMPTY, AT_LEAST_ONE_REQUIRED, equal, switchQueryListChanges, controlValueSignal, signalAttributes, ResizeObserverService, createFlipAnimation, AnimatedOverlayDirective, RuntimeError, SelectionModel, ActiveSelectionModel, KeyPressManager, signalClasses, scrollToElement, isEmptyArray, isObjectArray, isPrimitiveArray, ClickOutsideDirective, ANIMATED_LIFECYCLE_TOKEN, AnimatedLifecycleDirective, ObserveContentDirective, clamp, DELAYABLE_TOKEN, ObserveResizeDirective, SmartBlockScrollStrategy, signalElementDimensions, signalElementScrollState, createIsRenderedSignal, createCanAnimateSignal, useCursorDragScroll, signalElementIntersection, signalElementChildren, getIntersectionInfo, getElementScrollCoordinates, ObserveScrollStateDirective, ClickObserverService, RootBoundaryDirective, elementCanScroll, cloneFormGroup, getFormGroupValue, ViewportService, injectRoute, ROOT_BOUNDARY_TOKEN, injectQueryParam, RouterStateService, fromNextFrame, isElementVisible, AnimatedIfDirective, FocusVisibleService, inferMimeType, ScrollObserverIgnoreTargetDirective, TypedQueryList } from '@ethlete/core';
8
8
  import { BehaviorSubject, startWith, map, switchMap, combineLatest, pairwise, tap, takeUntil, skip, of, merge, timer, takeWhile, filter, fromEvent, Subject, Observable, debounceTime, withLatestFrom, distinctUntilChanged, take, skipUntil, skipWhile, catchError, throwError, defer, partition, from, finalize, Subscription } from 'rxjs';
9
9
  import { trigger, state, style, transition, animate } from '@angular/animations';
10
10
  import { __decorate, __metadata } from 'tslib';
@@ -1040,12 +1040,18 @@ const BRACKET_ROUND_MIRROR_TYPE = {
1040
1040
  LEFT: 'left',
1041
1041
  RIGHT: 'right',
1042
1042
  };
1043
- const generateRoundTypeFromEthleteRoundType = (type, tournamentMode) => {
1043
+ const generateRoundTypeFromEthleteRoundType = (type, tournamentMode, roundMatchCount) => {
1044
1044
  switch (type) {
1045
1045
  case 'normal':
1046
1046
  switch (tournamentMode) {
1047
1047
  case 'single-elimination':
1048
- return SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET;
1048
+ // This might break if the single elimination contains a 3rd place match + round
1049
+ if (roundMatchCount === 1) {
1050
+ return COMMON_BRACKET_ROUND_TYPE.FINAL;
1051
+ }
1052
+ else {
1053
+ return SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET;
1054
+ }
1049
1055
  case 'group':
1050
1056
  return GROUP_BRACKET_ROUND_TYPE.GROUP;
1051
1057
  case 'swiss':
@@ -1164,13 +1170,18 @@ const generateRoundRelations = (bracketData) => {
1164
1170
  const hasLowerRounds = lowerRounds.length > 0;
1165
1171
  const lastLowerRound = lowerRounds[lowerRounds.length - 1] || null;
1166
1172
  for (const [currentUpperRoundIndex, currentUpperRound] of upperRounds.entries()) {
1167
- const previousUpperRound = upperRounds[currentUpperRoundIndex - 1] || null;
1168
- const nextUpperRound = upperRounds[currentUpperRoundIndex + 1] || null;
1173
+ const isLeftToRight = currentUpperRound.mirrorRoundType === null ||
1174
+ currentUpperRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.LEFT;
1175
+ const relativePreviousUpperRound = upperRounds[currentUpperRoundIndex - 1] || null;
1176
+ const relativeNextUpperRound = upperRounds[currentUpperRoundIndex + 1] || null;
1177
+ const previousUpperRound = isLeftToRight ? relativePreviousUpperRound : relativeNextUpperRound;
1178
+ const nextUpperRound = isLeftToRight ? relativeNextUpperRound : relativePreviousUpperRound;
1169
1179
  const currentLowerRound = lowerRounds[currentUpperRoundIndex] || null;
1170
1180
  const previousLowerRound = lowerRounds[currentUpperRoundIndex - 1] || null;
1171
1181
  const nextLowerRound = lowerRounds[currentUpperRoundIndex + 1] || null;
1172
- const isFirstRound = currentUpperRoundIndex === 0;
1173
- const isLastUpperRound = currentUpperRoundIndex === upperRounds.length - 1;
1182
+ const isLastUpperRound = !nextUpperRound ||
1183
+ (nextUpperRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT &&
1184
+ currentUpperRound.mirrorRoundType === null);
1174
1185
  const isFinal = currentUpperRound.type === COMMON_BRACKET_ROUND_TYPE.FINAL;
1175
1186
  if (isFinal && hasLowerRounds) {
1176
1187
  // two to one relation
@@ -1286,7 +1297,7 @@ const generateRoundRelations = (bracketData) => {
1286
1297
  rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
1287
1298
  });
1288
1299
  }
1289
- else if (isFirstRound) {
1300
+ else if (currentUpperRound.isFirstRound) {
1290
1301
  // nothing to one relation
1291
1302
  if (!nextUpperRound)
1292
1303
  throw new Error('nextUpperRound is null');
@@ -1351,10 +1362,10 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
1351
1362
  const currentRelation = roundRelations.get(match.round.id);
1352
1363
  if (!currentRelation)
1353
1364
  throw new Error('Match round not found');
1354
- const { nextUpperRoundMatchPosition, nextLowerRoundMatchPosition, previousLowerRoundMatchPosition, previousUpperRoundMatchPosition, } = generateMatchRelationPositions(currentRelation, match);
1365
+ const { nextRoundMatchPosition, previousLowerRoundMatchPosition, previousUpperRoundMatchPosition } = generateMatchRelationPositions(currentRelation, match);
1355
1366
  switch (currentRelation.type) {
1356
1367
  case 'nothing-to-one': {
1357
- const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextUpperRoundMatchPosition);
1368
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1358
1369
  if (!nextMatch)
1359
1370
  throw new Error('Next round match not found');
1360
1371
  // means left is nothing. right is one
@@ -1403,7 +1414,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
1403
1414
  break;
1404
1415
  }
1405
1416
  case 'one-to-one': {
1406
- const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextUpperRoundMatchPosition);
1417
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1407
1418
  const previousUpperMatch = matchPositionMaps
1408
1419
  .get(currentRelation.previousRound.id)
1409
1420
  ?.get(previousUpperRoundMatchPosition);
@@ -1418,12 +1429,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
1418
1429
  throw new Error('Previous lower round match not found');
1419
1430
  // can be either one to one or two to one
1420
1431
  const isLeftOne = previousUpperRoundMatchPosition === previousLowerRoundMatchPosition;
1421
- const isRightOne = nextUpperRoundMatchPosition === nextLowerRoundMatchPosition;
1422
- if (currentRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT) {
1423
- console.log(match, generateMatchRelationPositions(currentRelation, match));
1424
- }
1425
- // TODO: Implement one to two
1426
- if (isLeftOne && isRightOne) {
1432
+ if (isLeftOne) {
1427
1433
  // one-to-one
1428
1434
  matchRelations.set(match.id, {
1429
1435
  type: 'one-to-one',
@@ -1435,7 +1441,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
1435
1441
  nextRound: currentRelation.nextRound,
1436
1442
  });
1437
1443
  }
1438
- else if (!isLeftOne) {
1444
+ else {
1439
1445
  // two-to-one
1440
1446
  matchRelations.set(match.id, {
1441
1447
  type: 'two-to-one',
@@ -1449,27 +1455,10 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
1449
1455
  nextRound: currentRelation.nextRound,
1450
1456
  });
1451
1457
  }
1452
- else if (!isRightOne) {
1453
- const nextLowerMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextLowerRoundMatchPosition);
1454
- if (!nextLowerMatch)
1455
- throw new Error('Next lower round match not found');
1456
- // one-to-two
1457
- matchRelations.set(match.id, {
1458
- type: 'one-to-two',
1459
- currentMatch: match,
1460
- currentRound: currentRelation.currentRound,
1461
- previousMatch: previousUpperMatch,
1462
- previousRound: currentRelation.previousRound,
1463
- nextUpperMatch: nextMatch,
1464
- nextUpperRound: currentRelation.nextRound,
1465
- nextLowerMatch,
1466
- nextLowerRound: nextLowerMatch.round,
1467
- });
1468
- }
1469
1458
  break;
1470
1459
  }
1471
1460
  case 'two-to-one': {
1472
- const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextUpperRoundMatchPosition);
1461
+ const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
1473
1462
  const previousUpperMatch = matchPositionMaps
1474
1463
  .get(currentRelation.previousUpperRound.id)
1475
1464
  ?.get(previousUpperRoundMatchPosition);
@@ -1525,8 +1514,7 @@ const generateMatchRelationPositions = (currentRelation, match) => {
1525
1514
  switch (currentRelation.type) {
1526
1515
  case 'nothing-to-one': {
1527
1516
  return {
1528
- nextUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1529
- nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1517
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1530
1518
  previousUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
1531
1519
  previousLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1532
1520
  };
@@ -1535,8 +1523,7 @@ const generateMatchRelationPositions = (currentRelation, match) => {
1535
1523
  const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
1536
1524
  const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
1537
1525
  return {
1538
- nextUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
1539
- nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1526
+ nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
1540
1527
  previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
1541
1528
  doubleUpperMatchCountShift),
1542
1529
  previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
@@ -1544,13 +1531,9 @@ const generateMatchRelationPositions = (currentRelation, match) => {
1544
1531
  }
1545
1532
  case 'one-to-one': {
1546
1533
  const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
1547
- const nextRoundHasDoubleTheMatchCount = currentRelation.nextRoundMatchFactor === 2;
1548
1534
  const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
1549
- const doubleLowerMatchCountShift = nextRoundHasDoubleTheMatchCount ? 1 : 0;
1550
1535
  return {
1551
- nextUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.nextRoundMatchFactor) -
1552
- doubleLowerMatchCountShift),
1553
- nextLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1536
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1554
1537
  previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
1555
1538
  doubleUpperMatchCountShift),
1556
1539
  previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
@@ -1558,16 +1541,14 @@ const generateMatchRelationPositions = (currentRelation, match) => {
1558
1541
  }
1559
1542
  case 'two-to-one': {
1560
1543
  return {
1561
- nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1562
- nextUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1544
+ nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
1563
1545
  previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
1564
1546
  previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
1565
1547
  };
1566
1548
  }
1567
1549
  case 'two-to-nothing': {
1568
1550
  return {
1569
- nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
1570
- nextUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
1551
+ nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
1571
1552
  previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
1572
1553
  previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
1573
1554
  };
@@ -1613,9 +1594,9 @@ const generateMatchParticipantMap = (bracketData) => {
1613
1594
  let lossesTilNow = 0;
1614
1595
  let tiesTilNow = 0;
1615
1596
  for (const matchParticipantMatch of participant.matches.values()) {
1616
- const isWinner = matchParticipantMatch.bracketMatch.winner === matchParticipantMatch.side;
1617
- const isLooser = matchParticipantMatch.bracketMatch.winner &&
1618
- matchParticipantMatch.bracketMatch.winner !== matchParticipantMatch.side;
1597
+ const isWinner = matchParticipantMatch.bracketMatch.winnerSide === matchParticipantMatch.side;
1598
+ const isLooser = matchParticipantMatch.bracketMatch.winnerSide &&
1599
+ matchParticipantMatch.bracketMatch.winnerSide !== matchParticipantMatch.side;
1619
1600
  const isTie = matchParticipantMatch.bracketMatch.status === 'completed' && !matchParticipantMatch.bracketMatch.winner;
1620
1601
  if (isWinner) {
1621
1602
  winsTilNow++;
@@ -1724,8 +1705,8 @@ const generateBracketRoundSwissGroupMaps = (bracketData, matchParticipantMap) =>
1724
1705
  }
1725
1706
  const emptyMatchIds = [];
1726
1707
  for (const match of bracketRound.matches.values()) {
1727
- const participantHome = match.home ? (matchParticipantMap.get(match.home) ?? null) : null;
1728
- const participantAway = match.away ? (matchParticipantMap.get(match.away) ?? null) : null;
1708
+ const participantHome = match.home ? (matchParticipantMap.get(match.home.id) ?? null) : null;
1709
+ const participantAway = match.away ? (matchParticipantMap.get(match.away.id) ?? null) : null;
1729
1710
  const anyParticipant = participantHome || participantAway;
1730
1711
  if (!anyParticipant) {
1731
1712
  emptyMatchIds.push(match.id);
@@ -1772,7 +1753,7 @@ const generateBracketDataForEthlete = (source) => {
1772
1753
  if (bracketData.rounds.some((r) => r.id === currentItem.round.id)) {
1773
1754
  throw new Error(`Round with id ${currentItem.round.id} already exists in the bracket data.`);
1774
1755
  }
1775
- const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode);
1756
+ const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode, currentItem.matches.length);
1776
1757
  const bracketRound = {
1777
1758
  type: roundType,
1778
1759
  id: currentItem.round.id,
@@ -1800,39 +1781,46 @@ const generateBracketDataForEthlete = (source) => {
1800
1781
  };
1801
1782
  const generateAndSetBracketMatchWithParticipants = (match, options) => {
1802
1783
  const matchId = match.id;
1803
- const { bracketData, bracketRound, currentIndexInRound } = options;
1784
+ const { bracketData, bracketRound, currentIndexInRound, participantCounter } = options;
1785
+ let localParticipantCounter = participantCounter;
1804
1786
  const bracketMatch = {
1805
1787
  id: matchId,
1806
1788
  indexInRound: currentIndexInRound,
1807
1789
  position: (currentIndexInRound + 1),
1808
1790
  data: match.data,
1809
1791
  round: bracketRound,
1810
- home: match.home,
1811
- away: match.away,
1812
- winner: match.winner,
1792
+ home: null,
1793
+ away: null,
1813
1794
  status: match.status,
1795
+ winnerSide: match.winner,
1796
+ winner: null,
1814
1797
  };
1815
1798
  bracketData.matches.set(matchId, bracketMatch);
1816
1799
  bracketRound.matches.set(matchId, bracketMatch);
1817
- const participants = [bracketMatch.home, bracketMatch.away];
1818
- for (const [participantIndex, participant] of participants.entries()) {
1819
- if (!participant)
1800
+ const participantIds = [match.home, match.away];
1801
+ for (const [participantIndex, participantId] of participantIds.entries()) {
1802
+ if (!participantId)
1820
1803
  continue;
1821
- const side = participantIndex === 0 ? 'Homeside' : 'Awayside';
1822
- if (!bracketData.participants.has(participant)) {
1823
- bracketData.participants.set(participant, {
1824
- id: participant,
1804
+ const side = participantIndex === 0 ? 'home' : 'away';
1805
+ if (!bracketData.participants.has(participantId)) {
1806
+ bracketData.participants.set(participantId, {
1807
+ id: participantId,
1808
+ shortId: `p${localParticipantCounter++}`,
1825
1809
  name: `${side} ${currentIndexInRound}`,
1826
1810
  matches: new Map(),
1827
1811
  });
1828
1812
  }
1829
- const participantData = bracketData.participants.get(participant);
1813
+ const participantData = bracketData.participants.get(participantId);
1830
1814
  if (!participantData.matches.has(bracketMatch.id)) {
1831
1815
  participantData.matches.set(bracketMatch.id, {
1832
- side: bracketMatch.home === participant ? 'home' : 'away',
1816
+ side: match.home === participantId ? 'home' : 'away',
1833
1817
  bracketMatch,
1834
1818
  });
1835
1819
  }
1820
+ bracketMatch[side] = participantData;
1821
+ if (bracketMatch.winnerSide === side) {
1822
+ bracketMatch.winner = participantData;
1823
+ }
1836
1824
  }
1837
1825
  return bracketMatch;
1838
1826
  };
@@ -1852,11 +1840,12 @@ const generateBracketData = (source, options) => {
1852
1840
  let currentUpperBracketIndex = 0;
1853
1841
  let currentLowerBracketIndex = 0;
1854
1842
  const splitRoundsRest = [];
1855
- for (const round of source.rounds) {
1843
+ for (const [roundIndex, round] of source.rounds.entries()) {
1856
1844
  const isLowerBracket = round.type === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
1857
1845
  const matches = source.matches.filter((m) => m.roundId === round.id);
1858
1846
  const roundId = round.id;
1859
1847
  const shouldSplitRound = shouldSplitRoundsInTwo && matches.length % 2 === 0;
1848
+ const isFirstRound = roundIndex === 0;
1860
1849
  if (shouldSplitRound) {
1861
1850
  const firstHalfMatchesMaxIndex = matches.length / 2 - 1;
1862
1851
  const firstHalfRoundId = `${roundId}--half-1`;
@@ -1871,6 +1860,7 @@ const generateBracketData = (source, options) => {
1871
1860
  matchCount: matches.length / 2,
1872
1861
  matches: new Map(),
1873
1862
  mirrorRoundType: BRACKET_ROUND_MIRROR_TYPE.LEFT,
1863
+ isFirstRound,
1874
1864
  };
1875
1865
  const bracketRoundSecondHalf = {
1876
1866
  type: round.type,
@@ -1882,6 +1872,7 @@ const generateBracketData = (source, options) => {
1882
1872
  matchCount: matches.length / 2,
1883
1873
  matches: new Map(),
1884
1874
  mirrorRoundType: BRACKET_ROUND_MIRROR_TYPE.RIGHT,
1875
+ isFirstRound,
1885
1876
  };
1886
1877
  bracketData.roundIds.push(firstHalfRoundId);
1887
1878
  bracketData.rounds.set(firstHalfRoundId, bracketRoundFirstHalf);
@@ -1891,15 +1882,20 @@ const generateBracketData = (source, options) => {
1891
1882
  const matchSecond = matches[firstHalfMatchesMaxIndex + 1 + index];
1892
1883
  if (!matchFirst || !matchSecond)
1893
1884
  throw new Error('Match not found');
1885
+ const participantCounter = bracketData.participants.size;
1894
1886
  const bracketMatchFirst = generateAndSetBracketMatchWithParticipants(matchFirst, {
1895
1887
  bracketData,
1896
1888
  bracketRound: bracketRoundFirstHalf,
1897
1889
  currentIndexInRound: index,
1890
+ participantCounter,
1898
1891
  });
1892
+ // The participant counter might have changed after the first half
1893
+ const updatedParticipantCounter = bracketData.participants.size;
1899
1894
  const bracketMatchSecond = generateAndSetBracketMatchWithParticipants(matchSecond, {
1900
1895
  bracketData,
1901
1896
  bracketRound: bracketRoundSecondHalf,
1902
1897
  currentIndexInRound: index,
1898
+ participantCounter: updatedParticipantCounter,
1903
1899
  });
1904
1900
  bracketData.matchIds.push(bracketMatchFirst.id, bracketMatchSecond.id);
1905
1901
  }
@@ -1915,15 +1911,18 @@ const generateBracketData = (source, options) => {
1915
1911
  matchCount: matches.length,
1916
1912
  matches: new Map(),
1917
1913
  mirrorRoundType: null,
1914
+ isFirstRound,
1918
1915
  };
1919
1916
  bracketData.roundIds.push(roundId);
1920
1917
  bracketData.rounds.set(roundId, bracketRound);
1921
1918
  let currentIndexInRound = 0;
1922
1919
  for (const match of matches) {
1920
+ const participantCounter = bracketData.participants.size;
1923
1921
  const bracketMatch = generateAndSetBracketMatchWithParticipants(match, {
1924
1922
  bracketData,
1925
1923
  bracketRound,
1926
1924
  currentIndexInRound,
1925
+ participantCounter,
1927
1926
  });
1928
1927
  bracketData.matchIds.push(bracketMatch.id);
1929
1928
  currentIndexInRound++;
@@ -1953,29 +1952,30 @@ const generateBracketData = (source, options) => {
1953
1952
  return bracketData;
1954
1953
  };
1955
1954
 
1956
- const path = (d, options) => `<path d="${d}" stroke="currentColor" fill="none" stroke-width="${options.width}" stroke-dasharray="${options.dashArray}" stroke-dashoffset="${options.dashOffset}" />`;
1955
+ const path = (d, options) => `<path d="${d.replace(/\s+/g, ' ').trim()}" stroke="currentColor" fill="none" stroke-width="${options.width}" stroke-dasharray="${options.dashArray}" stroke-dashoffset="${options.dashOffset}" class="${options.className}" />`;
1957
1956
  const curve = (from, to, direction, options) => {
1958
1957
  const fromInline = from.inline.end;
1959
- const fromBlock = from.block.center;
1960
1958
  const toInline = to.inline.start;
1961
1959
  const toBlock = to.block.center;
1962
- const curveAmount = options.curveAmount;
1960
+ const fromBlock = from.block.center;
1961
+ const startingCurveAmount = options.lineStartingCurveAmount;
1962
+ const endingCurveAmount = options.lineEndingCurveAmount;
1963
1963
  const totalSpace = toInline - fromInline;
1964
- const totalSpaceMinusCurve = totalSpace - curveAmount * 2;
1964
+ const totalSpaceMinusCurve = totalSpace - startingCurveAmount - endingCurveAmount;
1965
1965
  const lineLength = totalSpaceMinusCurve / 2;
1966
1966
  const straightLeftEnd = fromInline + lineLength;
1967
1967
  const straightRightStart = toInline - lineLength;
1968
1968
  // first 90 degree curve down
1969
1969
  const firstCurveStartX = straightLeftEnd;
1970
- const firstCurveEndX = straightLeftEnd + curveAmount;
1971
- const firstCurveEndY = direction === 'down' ? fromBlock + curveAmount : fromBlock - curveAmount;
1972
- const firstCurveBezierX = straightLeftEnd + curveAmount;
1970
+ const firstCurveEndX = straightLeftEnd + startingCurveAmount;
1971
+ const firstCurveEndY = direction === 'down' ? fromBlock + startingCurveAmount : fromBlock - startingCurveAmount;
1972
+ const firstCurveBezierX = straightLeftEnd + startingCurveAmount;
1973
1973
  const firstCurveBezierY = fromBlock;
1974
1974
  // second 90 degree curve to the right
1975
- const secondCurveStartY = direction === 'down' ? toBlock - curveAmount : toBlock + curveAmount;
1975
+ const secondCurveStartY = direction === 'down' ? toBlock - endingCurveAmount : toBlock + endingCurveAmount;
1976
1976
  const secondCurveEndX = straightRightStart;
1977
1977
  const secondCurveEndY = toBlock;
1978
- const secondCurveBezierX = straightRightStart - curveAmount;
1978
+ const secondCurveBezierX = straightRightStart - endingCurveAmount;
1979
1979
  const secondCurveBezierY = toBlock;
1980
1980
  const pathStr = `
1981
1981
  M ${fromInline} ${fromBlock}
@@ -1984,7 +1984,40 @@ const curve = (from, to, direction, options) => {
1984
1984
  V ${secondCurveStartY}
1985
1985
  Q ${secondCurveBezierX} ${secondCurveBezierY}, ${secondCurveEndX} ${secondCurveEndY}
1986
1986
  H ${toInline}
1987
- `.replace(/\s+/g, ' ');
1987
+ `;
1988
+ return path(pathStr, options.path);
1989
+ };
1990
+ const curveInverted = (from, to, direction, options) => {
1991
+ const fromInline = from.inline.start;
1992
+ const fromBlock = from.block.center;
1993
+ const toInline = to.inline.end;
1994
+ const toBlock = to.block.center;
1995
+ const startingCurveAmount = options.lineStartingCurveAmount;
1996
+ const endingCurveAmount = options.lineEndingCurveAmount;
1997
+ const totalSpace = fromInline - toInline;
1998
+ const totalSpaceMinusCurve = totalSpace - startingCurveAmount - endingCurveAmount;
1999
+ const lineLength = totalSpaceMinusCurve / 2;
2000
+ const straightRightEnd = fromInline - lineLength;
2001
+ const straightLeftStart = toInline + lineLength;
2002
+ const firstCurveStartX = straightRightEnd;
2003
+ const firstCurveEndX = straightRightEnd - startingCurveAmount;
2004
+ const firstCurveEndY = direction === 'down' ? fromBlock + startingCurveAmount : fromBlock - startingCurveAmount;
2005
+ const firstCurveBezierX = straightRightEnd - startingCurveAmount;
2006
+ const firstCurveBezierY = fromBlock;
2007
+ // second 90 degree curve to the right
2008
+ const secondCurveStartY = direction === 'down' ? toBlock - endingCurveAmount : toBlock + endingCurveAmount;
2009
+ const secondCurveEndX = straightLeftStart;
2010
+ const secondCurveEndY = toBlock;
2011
+ const secondCurveBezierX = straightLeftStart + endingCurveAmount;
2012
+ const secondCurveBezierY = toBlock;
2013
+ const pathStr = `
2014
+ M ${fromInline} ${fromBlock}
2015
+ H ${firstCurveStartX}
2016
+ Q ${firstCurveBezierX} ${firstCurveBezierY}, ${firstCurveEndX} ${firstCurveEndY}
2017
+ V ${secondCurveStartY}
2018
+ Q ${secondCurveBezierX} ${secondCurveBezierY}, ${secondCurveEndX} ${secondCurveEndY}
2019
+ H ${toInline}
2020
+ `;
1988
2021
  return path(pathStr, options.path);
1989
2022
  };
1990
2023
  const line = (from, to, options) => {
@@ -2062,10 +2095,14 @@ const drawMan = (items, firstRounds, dimensions) => {
2062
2095
  matchHeight,
2063
2096
  rowGap,
2064
2097
  };
2065
- // TODO: No lines for now
2066
- if (item.matchRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT) {
2067
- continue;
2068
- }
2098
+ const currentMatchParticipantsShortIds = [
2099
+ item.matchRelation.currentMatch.home?.shortId,
2100
+ item.matchRelation.currentMatch.away?.shortId,
2101
+ ]
2102
+ .filter((id) => !!id)
2103
+ .join(' ');
2104
+ const pathOptions = { ...dimensions.path, className: currentMatchParticipantsShortIds };
2105
+ const currentMatchPosition = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
2069
2106
  // We only draw the left side of the match relation
2070
2107
  switch (item.matchRelation.type) {
2071
2108
  case 'nothing-to-one': {
@@ -2073,31 +2110,36 @@ const drawMan = (items, firstRounds, dimensions) => {
2073
2110
  }
2074
2111
  case 'one-to-nothing':
2075
2112
  case 'one-to-one': {
2076
- const previous = getMatchPosition(items.get(item.matchRelation.previousRound.id), item.matchRelation.previousMatch.id, staticMeasurements);
2077
- const current = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
2113
+ const previousMatchPosition = getMatchPosition(items.get(item.matchRelation.previousRound.id), item.matchRelation.previousMatch.id, staticMeasurements);
2078
2114
  // draw a straight line
2079
- svgParts.push(line(previous, current, { path: dimensions.path }));
2080
- break;
2081
- }
2082
- case 'one-to-two': {
2083
- const nextUpper = getMatchPosition(items.get(item.matchRelation.nextUpperRound.id), item.matchRelation.nextUpperMatch.id, staticMeasurements);
2084
- const nextLower = getMatchPosition(items.get(item.matchRelation.nextLowerRound.id), item.matchRelation.nextLowerMatch.id, staticMeasurements);
2085
- const current = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
2086
- // const curveOptions: CurveOptions = { ...dimensions.curve, path: dimensions.path };
2087
- // // draw two lines that merge into one in the middle
2088
- // svgParts.push(curve(nextUpper, current, 'down', curveOptions));
2089
- // svgParts.push(curve(nextLower, current, 'up', curveOptions));
2115
+ svgParts.push(line(previousMatchPosition, currentMatchPosition, { path: pathOptions }));
2090
2116
  break;
2091
2117
  }
2092
2118
  case 'two-to-nothing':
2093
2119
  case 'two-to-one': {
2094
2120
  const previousUpper = getMatchPosition(items.get(item.matchRelation.previousUpperRound.id), item.matchRelation.previousUpperMatch.id, staticMeasurements);
2095
2121
  const previousLower = getMatchPosition(items.get(item.matchRelation.previousLowerRound.id), item.matchRelation.previousLowerMatch.id, staticMeasurements);
2096
- const current = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
2097
- const curveOptions = { ...dimensions.curve, path: dimensions.path };
2122
+ const curveOptions = {
2123
+ ...dimensions.curve,
2124
+ path: { ...dimensions.path, className: '' },
2125
+ };
2126
+ const curveFn = item.roundRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT ? curveInverted : curve;
2098
2127
  // draw two lines that merge into one in the middle
2099
- svgParts.push(curve(previousUpper, current, 'down', curveOptions));
2100
- svgParts.push(curve(previousLower, current, 'up', curveOptions));
2128
+ svgParts.push(curveFn(previousUpper, currentMatchPosition, 'down', {
2129
+ ...curveOptions,
2130
+ path: { ...curveOptions.path, className: item.matchRelation.previousUpperMatch.winner?.shortId || '' },
2131
+ }));
2132
+ svgParts.push(curveFn(previousLower, currentMatchPosition, 'up', {
2133
+ ...curveOptions,
2134
+ path: { ...curveOptions.path, className: item.matchRelation.previousLowerMatch.winner?.shortId || '' },
2135
+ }));
2136
+ if (item.matchRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT &&
2137
+ item.matchRelation.type === 'two-to-one' &&
2138
+ item.matchRelation.nextRound.mirrorRoundType === null) {
2139
+ // draw a straight line for the special case of connecting the final match to the mirrored semi final match
2140
+ const next = getMatchPosition(items.get(item.matchRelation.nextRound.id), item.matchRelation.nextMatch.id, staticMeasurements);
2141
+ svgParts.push(line(next, currentMatchPosition, { path: pathOptions }));
2142
+ }
2101
2143
  break;
2102
2144
  }
2103
2145
  }
@@ -2184,10 +2226,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
2184
2226
  const generateBracketGridItems = (bracketData, roundTypeMap, swissGroups, roundRelations, matchRelations, options) => {
2185
2227
  const roundHeaderComponent = options.headerComponent ?? NewBracketDefaultRoundHeaderComponent;
2186
2228
  const matchComponent = options.matchComponent ?? NewBracketDefaultMatchComponent;
2229
+ const finalMatchComponent = options.finalMatchComponent ?? matchComponent;
2187
2230
  const optionsWithDefaults = {
2188
2231
  ...options,
2189
2232
  headerComponent: roundHeaderComponent,
2190
2233
  matchComponent: matchComponent,
2234
+ finalMatchComponent: finalMatchComponent,
2191
2235
  };
2192
2236
  switch (bracketData.mode) {
2193
2237
  case TOURNAMENT_MODE.DOUBLE_ELIMINATION:
@@ -2234,6 +2278,7 @@ const generateGenericGridPlacements = (bracketData, roundTypeMap, roundRelations
2234
2278
  rowStart: currentMatchRow,
2235
2279
  rowEnd: ++currentMatchRow,
2236
2280
  component: options.headerComponent,
2281
+ className: 'et-bracket-new-item et-bracket-round-header-container',
2237
2282
  roundRelation,
2238
2283
  data: {
2239
2284
  bracketRound: round,
@@ -2249,15 +2294,17 @@ const generateGenericGridPlacements = (bracketData, roundTypeMap, roundRelations
2249
2294
  throw new Error('Match relation is missing');
2250
2295
  }
2251
2296
  const baseRow = match.indexInRound * matchHeight;
2297
+ const participantShortIds = [match.home?.shortId, match.away?.shortId].filter((id) => !!id).join(' ');
2252
2298
  const matchItem = {
2253
2299
  type: 'match',
2254
2300
  id: match.id,
2255
2301
  layoutId: `${match.id}-layout`,
2256
2302
  rowStart: baseRow + currentMatchRow,
2257
2303
  rowEnd: baseRow + currentMatchRow + matchHeight,
2258
- component: options.matchComponent,
2304
+ component: round.type === COMMON_BRACKET_ROUND_TYPE.FINAL ? options.finalMatchComponent : options.matchComponent,
2259
2305
  matchRelation,
2260
2306
  roundRelation,
2307
+ className: `et-bracket-new-item et-bracket-match-container ${participantShortIds}`,
2261
2308
  data: {
2262
2309
  bracketRound: round,
2263
2310
  bracketMatch: match,
@@ -2278,23 +2325,47 @@ const generateSwissWithEliminationGridPlacements = (bracketData, roundTypeMap, s
2278
2325
  return gridItems;
2279
2326
  };
2280
2327
 
2328
+ const createJourneyHighlight = (bracketData) => {
2329
+ let styles = '';
2330
+ for (const participant of bracketData.participants.values()) {
2331
+ styles += `
2332
+ .et-new-bracket-host:has(.${participant.shortId}:hover) {
2333
+ path, .et-bracket-match-container {
2334
+ opacity: 0.5;
2335
+ }
2336
+
2337
+ .${participant.shortId} {
2338
+ opacity: 1 !important;
2339
+ }
2340
+ }
2341
+ `;
2342
+ }
2343
+ return styles.replace(/\s+/g, ' ').trim();
2344
+ };
2345
+
2281
2346
  class NewBracketComponent {
2347
+ #domSanitizer;
2348
+ #elementId;
2282
2349
  constructor() {
2283
2350
  this.#domSanitizer = inject(DomSanitizer);
2351
+ this.#elementId = createComponentId('et-new-bracket');
2284
2352
  this.source = input.required();
2285
2353
  this.columnWidth = input(250, { transform: numberAttribute });
2286
2354
  this.matchHeight = input(75, { transform: numberAttribute });
2287
2355
  this.roundHeaderHeight = input(50, { transform: numberAttribute });
2288
2356
  this.columnGap = input(60, { transform: numberAttribute });
2289
2357
  this.rowGap = input(30, { transform: numberAttribute });
2290
- this.curveAmount = input(20, { transform: numberAttribute });
2358
+ this.lineStartingCurveAmount = input(10, { transform: numberAttribute });
2359
+ this.lineEndingCurveAmount = input(0, { transform: numberAttribute });
2291
2360
  this.lineWidth = input(2, { transform: numberAttribute });
2292
2361
  this.lineDashArray = input(0, { transform: numberAttribute });
2293
2362
  this.lineDashOffset = input(0, { transform: numberAttribute });
2363
+ this.disableJourneyHighlight = input(false, { transform: booleanAttribute });
2294
2364
  this.layout = input(BRACKET_DATA_LAYOUT.LEFT_TO_RIGHT);
2295
2365
  this.hideRoundHeaders = input(false, { transform: booleanAttribute });
2296
2366
  this.roundHeaderComponent = input();
2297
2367
  this.matchComponent = input();
2368
+ this.finalMatchComponent = input();
2298
2369
  this.bracketData = computed(() => generateBracketData(this.source(), { layout: this.layout() }));
2299
2370
  this.roundTypeMap = computed(() => generateBracketRoundTypeMap(this.bracketData()));
2300
2371
  this.matchParticipantMap = computed(() => generateMatchParticipantMap(this.bracketData()));
@@ -2306,6 +2377,7 @@ class NewBracketComponent {
2306
2377
  includeRoundHeaders: !this.hideRoundHeaders(),
2307
2378
  headerComponent: this.roundHeaderComponent(),
2308
2379
  matchComponent: this.matchComponent(),
2380
+ finalMatchComponent: this.finalMatchComponent(),
2309
2381
  }));
2310
2382
  this.definitions = computed(() => generateBracketGridDefinitions(this.bracketData(), this.roundTypeMap(), {
2311
2383
  includeRoundHeaders: !this.hideRoundHeaders(),
@@ -2319,7 +2391,8 @@ class NewBracketComponent {
2319
2391
  rowGap: this.rowGap(),
2320
2392
  gridDefinitions: this.definitions(),
2321
2393
  curve: {
2322
- curveAmount: this.curveAmount(),
2394
+ lineEndingCurveAmount: this.lineEndingCurveAmount(),
2395
+ lineStartingCurveAmount: this.lineStartingCurveAmount(),
2323
2396
  },
2324
2397
  path: {
2325
2398
  dashArray: this.lineDashArray(),
@@ -2327,17 +2400,45 @@ class NewBracketComponent {
2327
2400
  width: this.lineWidth(),
2328
2401
  },
2329
2402
  })));
2403
+ this.journeyHighlight = computed(() => this.disableJourneyHighlight() ? null : createJourneyHighlight(this.bracketData()));
2404
+ const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
2405
+ if (!isBrowser)
2406
+ return;
2407
+ const renderer = inject(Renderer2);
2408
+ const styleId = `et-new-bracket-journey-highlight--${this.#elementId}`;
2409
+ let oldStyleEl = null;
2410
+ effect(() => {
2411
+ const newHighlightStyle = this.journeyHighlight();
2412
+ const head = document.head;
2413
+ if (oldStyleEl) {
2414
+ renderer.removeChild(head, oldStyleEl);
2415
+ }
2416
+ if (newHighlightStyle) {
2417
+ const el = renderer.createElement('style');
2418
+ renderer.setAttribute(el, 'id', styleId);
2419
+ renderer.appendChild(el, renderer.createText(newHighlightStyle));
2420
+ renderer.appendChild(head, el);
2421
+ oldStyleEl = el;
2422
+ }
2423
+ else {
2424
+ oldStyleEl = null;
2425
+ }
2426
+ });
2427
+ inject(DestroyRef).onDestroy(() => {
2428
+ if (oldStyleEl) {
2429
+ renderer.removeChild(document.head, oldStyleEl);
2430
+ }
2431
+ });
2330
2432
  }
2331
- #domSanitizer;
2332
2433
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NewBracketComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2333
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: NewBracketComponent, isStandalone: true, selector: "et-new-bracket", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, columnWidth: { classPropertyName: "columnWidth", publicName: "columnWidth", isSignal: true, isRequired: false, transformFunction: null }, matchHeight: { classPropertyName: "matchHeight", publicName: "matchHeight", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderHeight: { classPropertyName: "roundHeaderHeight", publicName: "roundHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, columnGap: { classPropertyName: "columnGap", publicName: "columnGap", isSignal: true, isRequired: false, transformFunction: null }, rowGap: { classPropertyName: "rowGap", publicName: "rowGap", isSignal: true, isRequired: false, transformFunction: null }, curveAmount: { classPropertyName: "curveAmount", publicName: "curveAmount", isSignal: true, isRequired: false, transformFunction: null }, lineWidth: { classPropertyName: "lineWidth", publicName: "lineWidth", isSignal: true, isRequired: false, transformFunction: null }, lineDashArray: { classPropertyName: "lineDashArray", publicName: "lineDashArray", isSignal: true, isRequired: false, transformFunction: null }, lineDashOffset: { classPropertyName: "lineDashOffset", publicName: "lineDashOffset", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, hideRoundHeaders: { classPropertyName: "hideRoundHeaders", publicName: "hideRoundHeaders", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderComponent: { classPropertyName: "roundHeaderComponent", publicName: "roundHeaderComponent", isSignal: true, isRequired: false, transformFunction: null }, matchComponent: { classPropertyName: "matchComponent", publicName: "matchComponent", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-new-bracket-host" }, ngImport: i0, template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" class=\"et-bracket-new-item\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color)}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2434
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: NewBracketComponent, isStandalone: true, selector: "et-new-bracket", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, columnWidth: { classPropertyName: "columnWidth", publicName: "columnWidth", isSignal: true, isRequired: false, transformFunction: null }, matchHeight: { classPropertyName: "matchHeight", publicName: "matchHeight", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderHeight: { classPropertyName: "roundHeaderHeight", publicName: "roundHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, columnGap: { classPropertyName: "columnGap", publicName: "columnGap", isSignal: true, isRequired: false, transformFunction: null }, rowGap: { classPropertyName: "rowGap", publicName: "rowGap", isSignal: true, isRequired: false, transformFunction: null }, lineStartingCurveAmount: { classPropertyName: "lineStartingCurveAmount", publicName: "lineStartingCurveAmount", isSignal: true, isRequired: false, transformFunction: null }, lineEndingCurveAmount: { classPropertyName: "lineEndingCurveAmount", publicName: "lineEndingCurveAmount", isSignal: true, isRequired: false, transformFunction: null }, lineWidth: { classPropertyName: "lineWidth", publicName: "lineWidth", isSignal: true, isRequired: false, transformFunction: null }, lineDashArray: { classPropertyName: "lineDashArray", publicName: "lineDashArray", isSignal: true, isRequired: false, transformFunction: null }, lineDashOffset: { classPropertyName: "lineDashOffset", publicName: "lineDashOffset", isSignal: true, isRequired: false, transformFunction: null }, disableJourneyHighlight: { classPropertyName: "disableJourneyHighlight", publicName: "disableJourneyHighlight", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, hideRoundHeaders: { classPropertyName: "hideRoundHeaders", publicName: "hideRoundHeaders", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderComponent: { classPropertyName: "roundHeaderComponent", publicName: "roundHeaderComponent", isSignal: true, isRequired: false, transformFunction: null }, matchComponent: { classPropertyName: "matchComponent", publicName: "matchComponent", isSignal: true, isRequired: false, transformFunction: null }, finalMatchComponent: { classPropertyName: "finalMatchComponent", publicName: "finalMatchComponent", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-new-bracket-host" }, ngImport: i0, template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"hideRoundHeaders() ? matchHeight() : roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" [class]=\"item.className\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center;transition:opacity .2s}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color);transition:opacity .2s}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2334
2435
  }
2335
2436
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NewBracketComponent, decorators: [{
2336
2437
  type: Component,
2337
2438
  args: [{ selector: 'et-new-bracket', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2338
2439
  class: 'et-new-bracket-host',
2339
- }, imports: [NgComponentOutlet], template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" class=\"et-bracket-new-item\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color)}\n"] }]
2340
- }] });
2440
+ }, imports: [NgComponentOutlet], template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"hideRoundHeaders() ? matchHeight() : roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" [class]=\"item.className\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center;transition:opacity .2s}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color);transition:opacity .2s}\n"] }]
2441
+ }], ctorParameters: () => [] });
2341
2442
 
2342
2443
  var index = /*#__PURE__*/Object.freeze({
2343
2444
  __proto__: null,