@page "/decks/{Name}" @deck?.Name
Back to Decks @if (deck == null) {

Deck not found.

} else {

@deck.Name

Deck Code:
@deck.DeckCode
@if (deck.Factions.Count > 0) {
@foreach (var f in deck.Factions) { @f }
}
@deck.Cards.Count cards @(deck.IsValid ? "Valid" : "Invalid") @if (!deck.IsValid) { @deck.ValidationMessage }
@if (deck.Keycards.Count > 0) {

Keycards

@foreach (var cardName in deck.Keycards) { var card = LookupCard(cardName); }
} @if (deck.Divers.Count > 0) {

Divers

@foreach (var cardName in deck.Divers) { var card = LookupCard(cardName); }
}

Cards

@foreach (var group in deck.Cards.GroupBy(x => x)) { var cardName = group.Key; var count = group.Count(); var card = LookupCard(cardName); }
@if (deck.Description != null) {

Description

@RenderDescription(deck.Description)
}
}
@if (selectedCard != null) {
@selectedCard.Name

@selectedCard.Name

@selectedCard.Category @if (selectedCard.Cost.HasValue) { @selectedCard.Cost } @if (selectedCard.Attack.HasValue) { @selectedCard.Attack } @if (selectedCard.Health.HasValue) { @selectedCard.Health } @if (selectedCard.Speed != null) { @selectedCard.Speed }
@if (selectedCard.Faction != null) {
Faction @selectedCard.Faction
} @if (selectedCard.Description != null) {
@selectedCard.Description
} @if (selectedCard.Set != null) {
Set @selectedCard.Set
} @if (selectedCard.Archetypes is { Count: > 0 }) {
Archetypes @string.Join(", ", selectedCard.Archetypes)
} @if (selectedCard.ImmortalizeWhen != null) {
Immortalize When @selectedCard.ImmortalizeWhen
} @if (selectedCard.HasImmortalize) {
Immortalizes To @string.Join(", ", selectedCard.ImmortalizeTo!)
} @if (selectedCard.ImmortalizeFrom != null) {
Immortalizes From @selectedCard.ImmortalizeFrom
}
} @code { [Parameter] public string Name { get; set; } = ""; private DeckData? deck; private CardData? selectedCard; protected override void OnParametersSet() { var decoded = Uri.UnescapeDataString(Name); deck = DeckDatabase.Decks.FirstOrDefault(d => d.IsVisible && d.Name == decoded); } private CardData? LookupCard(string cardName) { return CardDatabase.Cards.FirstOrDefault(c => string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase)); } private void SelectCard(CardData? card) { selectedCard = card; } private void CloseDetail() { selectedCard = null; } private RenderFragment RenderDescription(string description) { return builder => { var cardNames = CardDatabase.Cards .Select(c => c.Name) .Where(n => !string.IsNullOrWhiteSpace(n)) .OrderByDescending(n => n.Length) .ToList(); int sequence = 0; var paragraphs = description.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var paragraph in paragraphs) { builder.OpenElement(sequence++, "p"); var currentText = paragraph; while (!string.IsNullOrEmpty(currentText)) { int bestMatchIndex = -1; string? bestMatchName = null; foreach (var name in cardNames) { int index = currentText.IndexOf(name, StringComparison.OrdinalIgnoreCase); if (index != -1 && (bestMatchIndex == -1 || index < bestMatchIndex)) { bestMatchIndex = index; bestMatchName = name; } } if (bestMatchIndex != -1 && bestMatchName != null) { if (bestMatchIndex > 0) { builder.AddContent(sequence++, currentText.Substring(0, bestMatchIndex)); } var card = LookupCard(bestMatchName); builder.OpenElement(sequence++, "button"); builder.AddAttribute(sequence++, "class", "inline-card-btn"); builder.AddAttribute(sequence++, "onclick", EventCallback.Factory.Create(this, () => SelectCard(card))); builder.AddContent(sequence++, bestMatchName); builder.CloseElement(); currentText = currentText.Substring(bestMatchIndex + bestMatchName.Length); } else { builder.AddContent(sequence++, currentText); currentText = string.Empty; } } builder.CloseElement(); } }; } }