More notes and added store precons
This commit is contained in:
@@ -154,7 +154,8 @@ foreach (var file in deckFiles)
|
||||
.Replace("\r", "\n").Replace("\n\n", "\n").Replace("\n\n", "\n"),
|
||||
Factions = ParseList(yaml, "factions").Select(s => StripWikiLink(s) ?? "").Where(s => s != "").ToList(),
|
||||
IsVisible = isVisible,
|
||||
DeckCode = deckCode
|
||||
DeckCode = deckCode,
|
||||
DeckType = yaml.GetValueOrDefault("deckType")
|
||||
};
|
||||
|
||||
decks.Add(deck);
|
||||
@@ -189,6 +190,7 @@ for (var i = 0; i < decks.Count; i++)
|
||||
WriteListProp(deckWriter, "Factions", d.Factions, 3);
|
||||
deckWriter.WriteLine($" IsVisible = {(d.IsVisible ? "true" : "false")},");
|
||||
WriteStrProp(deckWriter, "DeckCode", d.DeckCode, 3);
|
||||
WriteStrProp(deckWriter, "DeckType", d.DeckType, 3);
|
||||
var comma = i < decks.Count - 1 ? "," : "";
|
||||
deckWriter.WriteLine($" }}{comma}");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csp
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cloud", "Cloud\Cloud.csproj", "{378D4271-55B8-4E77-92F0-65C7DA26ABD3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -108,6 +110,18 @@ Global
|
||||
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Release|x64.Build.0 = Release|Any CPU
|
||||
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Release|x86.Build.0 = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{378D4271-55B8-4E77-92F0-65C7DA26ABD3}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Model\Model.csproj" />
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<base href="/"/>
|
||||
<ResourcePreloader/>
|
||||
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]"/>
|
||||
<link rel="stylesheet" href="@Assets["app.css"]"/>
|
||||
<link rel="stylesheet" href="@Assets["Cloud.styles.css"]"/>
|
||||
<ImportMap/>
|
||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||
<HeadOutlet/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Routes/>
|
||||
<ReconnectModal/>
|
||||
<script src="@Assets["_framework/blazor.web.js"]"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu/>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui" data-nosnippet>
|
||||
An unhandled error has occurred.
|
||||
<a href="." class="reload">Reload</a>
|
||||
<span class="dismiss">🗙</span>
|
||||
</div>
|
||||
@@ -0,0 +1,98 @@
|
||||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
color-scheme: light only;
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">Cloud</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="checkbox" title="Navigation menu" class="navbar-toggler"/>
|
||||
|
||||
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
|
||||
<nav class="nav flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="weather">
|
||||
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -0,0 +1,105 @@
|
||||
.navbar-toggler {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
width: 3.5rem;
|
||||
height: 2.5rem;
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 1rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.navbar-toggler:checked {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
min-height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.75rem;
|
||||
top: -1px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link {
|
||||
color: #d7d7d7;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-toggler:checked ~ .nav-scrollable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<script type="module" src="@Assets["Components/Layout/ReconnectModal.razor.js"]"></script>
|
||||
|
||||
<dialog id="components-reconnect-modal" data-nosnippet>
|
||||
<div class="components-reconnect-container">
|
||||
<div class="components-rejoining-animation" aria-hidden="true">
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p class="components-reconnect-first-attempt-visible">
|
||||
Rejoining the server...
|
||||
</p>
|
||||
<p class="components-reconnect-repeated-attempt-visible">
|
||||
Rejoin failed... trying again in <span id="components-seconds-to-next-attempt"></span> seconds.
|
||||
</p>
|
||||
<p class="components-reconnect-failed-visible">
|
||||
Failed to rejoin.<br/>Please retry or reload the page.
|
||||
</p>
|
||||
<button id="components-reconnect-button" class="components-reconnect-failed-visible">
|
||||
Retry
|
||||
</button>
|
||||
<p class="components-pause-visible">
|
||||
The session has been paused by the server.
|
||||
</p>
|
||||
<p class="components-resume-failed-visible">
|
||||
Failed to resume the session.<br/>Please retry or reload the page.
|
||||
</p>
|
||||
<button id="components-resume-button" class="components-pause-visible components-resume-failed-visible">
|
||||
Resume
|
||||
</button>
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -0,0 +1,157 @@
|
||||
.components-reconnect-first-attempt-visible,
|
||||
.components-reconnect-repeated-attempt-visible,
|
||||
.components-reconnect-failed-visible,
|
||||
.components-pause-visible,
|
||||
.components-resume-failed-visible,
|
||||
.components-rejoining-animation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible,
|
||||
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation,
|
||||
#components-reconnect-modal.components-reconnect-paused .components-pause-visible,
|
||||
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible,
|
||||
#components-reconnect-modal.components-reconnect-retrying,
|
||||
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible,
|
||||
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation,
|
||||
#components-reconnect-modal.components-reconnect-failed,
|
||||
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#components-reconnect-modal {
|
||||
background-color: white;
|
||||
width: 20rem;
|
||||
margin: 20vh auto;
|
||||
padding: 2rem;
|
||||
border: 0;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
|
||||
opacity: 0;
|
||||
transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
|
||||
animation: components-reconnect-modal-fadeOutOpacity 0.5s both;
|
||||
&[open]
|
||||
|
||||
{
|
||||
animation: components-reconnect-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity 0.5s ease-in-out 0.3s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#components-reconnect-modal::backdrop {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
animation: components-reconnect-modal-fadeInOpacity 0.5s ease-in-out;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@keyframes components-reconnect-modal-slideUp {
|
||||
0% {
|
||||
transform: translateY(30px) scale(0.95);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes components-reconnect-modal-fadeInOpacity {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes components-reconnect-modal-fadeOutOpacity {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.components-reconnect-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
#components-reconnect-modal p {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#components-reconnect-modal button {
|
||||
border: 0;
|
||||
background-color: #6b9ed2;
|
||||
color: white;
|
||||
padding: 4px 24px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#components-reconnect-modal button:hover {
|
||||
background-color: #3b6ea2;
|
||||
}
|
||||
|
||||
#components-reconnect-modal button:active {
|
||||
background-color: #6b9ed2;
|
||||
}
|
||||
|
||||
.components-rejoining-animation {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.components-rejoining-animation div {
|
||||
position: absolute;
|
||||
border: 3px solid #0087ff;
|
||||
opacity: 1;
|
||||
border-radius: 50%;
|
||||
animation: components-rejoining-animation 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
||||
}
|
||||
|
||||
.components-rejoining-animation div:nth-child(2) {
|
||||
animation-delay: -0.5s;
|
||||
}
|
||||
|
||||
@keyframes components-rejoining-animation {
|
||||
0% {
|
||||
top: 40px;
|
||||
left: 40px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
4.9% {
|
||||
top: 40px;
|
||||
left: 40px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
5% {
|
||||
top: 40px;
|
||||
left: 40px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Set up event handlers
|
||||
const reconnectModal = document.getElementById("components-reconnect-modal");
|
||||
reconnectModal.addEventListener("components-reconnect-state-changed", handleReconnectStateChanged);
|
||||
|
||||
const retryButton = document.getElementById("components-reconnect-button");
|
||||
retryButton.addEventListener("click", retry);
|
||||
|
||||
const resumeButton = document.getElementById("components-resume-button");
|
||||
resumeButton.addEventListener("click", resume);
|
||||
|
||||
function handleReconnectStateChanged(event) {
|
||||
if (event.detail.state === "show") {
|
||||
reconnectModal.showModal();
|
||||
} else if (event.detail.state === "hide") {
|
||||
reconnectModal.close();
|
||||
} else if (event.detail.state === "failed") {
|
||||
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||
} else if (event.detail.state === "rejected") {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
async function retry() {
|
||||
document.removeEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||
|
||||
try {
|
||||
// Reconnect will asynchronously return:
|
||||
// - true to mean success
|
||||
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
|
||||
// - exception to mean we didn't reach the server (this can be sync or async)
|
||||
const successful = await Blazor.reconnect();
|
||||
if (!successful) {
|
||||
// We have been able to reach the server, but the circuit is no longer available.
|
||||
// We'll reload the page so the user can continue using the app as quickly as possible.
|
||||
const resumeSuccessful = await Blazor.resumeCircuit();
|
||||
if (!resumeSuccessful) {
|
||||
location.reload();
|
||||
} else {
|
||||
reconnectModal.close();
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// We got an exception, server is currently unavailable
|
||||
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||
}
|
||||
}
|
||||
|
||||
async function resume() {
|
||||
try {
|
||||
const successful = await Blazor.resumeCircuit();
|
||||
if (!successful) {
|
||||
location.reload();
|
||||
}
|
||||
} catch {
|
||||
reconnectModal.classList.replace("components-reconnect-paused", "components-reconnect-resume-failed");
|
||||
}
|
||||
}
|
||||
|
||||
async function retryWhenDocumentBecomesVisible() {
|
||||
if (document.visibilityState === "visible") {
|
||||
await retry();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
@page "/counter"
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<PageTitle>Counter</PageTitle>
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
@page "/Error"
|
||||
@using System.Diagnostics
|
||||
|
||||
<PageTitle>Error</PageTitle>
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
|
||||
@code{
|
||||
[CascadingParameter] private HttpContext? HttpContext { get; set; }
|
||||
|
||||
private string? RequestId { get; set; }
|
||||
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
protected override void OnInitialized() =>
|
||||
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@page "/"
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
@@ -0,0 +1,5 @@
|
||||
@page "/not-found"
|
||||
@layout MainLayout
|
||||
|
||||
<h3>Not Found</h3>
|
||||
<p>Sorry, the content you are looking for does not exist.</p>
|
||||
@@ -0,0 +1,5 @@
|
||||
@page "/weather"
|
||||
@using Shared.Pages
|
||||
@attribute [StreamRendering]
|
||||
|
||||
<Decks></Decks>
|
||||
@@ -0,0 +1,7 @@
|
||||
@using Shared.Pages
|
||||
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly }" NotFoundPage="typeof(Pages.NotFound)">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)"/>
|
||||
<FocusOnNavigate RouteData="routeData" Selector="h1"/>
|
||||
</Found>
|
||||
</Router>
|
||||
@@ -0,0 +1,11 @@
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using Cloud
|
||||
@using Cloud.Components
|
||||
@using Cloud.Components.Layout
|
||||
@@ -0,0 +1,28 @@
|
||||
using Cloud.Components;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapStaticAssets();
|
||||
app.MapRazorComponents<App>()
|
||||
.AddInteractiveServerRenderMode();
|
||||
|
||||
app.Run();
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5230",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7086;http://localhost:5230",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a, .btn-link {
|
||||
color: #006bb7;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 1.1rem;
|
||||
}
|
||||
|
||||
h1:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.valid.modified:not([type=checkbox]) {
|
||||
outline: 1px solid #26b050;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
outline: 1px solid #e50000;
|
||||
}
|
||||
|
||||
.validation-message {
|
||||
color: #e50000;
|
||||
}
|
||||
|
||||
.blazor-error-boundary {
|
||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
||||
padding: 1rem 1rem 1rem 3.7rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.blazor-error-boundary::after {
|
||||
content: "An error has occurred."
|
||||
}
|
||||
|
||||
.darker-border-checkbox.form-check-input {
|
||||
border-color: #929292;
|
||||
}
|
||||
|
||||
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
|
||||
text-align: start;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,597 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text-emphasis: #052c65;
|
||||
--bs-secondary-text-emphasis: #2b2f32;
|
||||
--bs-success-text-emphasis: #0a3622;
|
||||
--bs-info-text-emphasis: #055160;
|
||||
--bs-warning-text-emphasis: #664d03;
|
||||
--bs-danger-text-emphasis: #58151c;
|
||||
--bs-light-text-emphasis: #495057;
|
||||
--bs-dark-text-emphasis: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #e2e3e5;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #c4c8cb;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-color: #212529;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-xxl: 2rem;
|
||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
--bs-focus-ring-width: 0.25rem;
|
||||
--bs-focus-ring-opacity: 0.25;
|
||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||
--bs-form-valid-color: #198754;
|
||||
--bs-form-valid-border-color: #198754;
|
||||
--bs-form-invalid-color: #dc3545;
|
||||
--bs-form-invalid-border-color: #dc3545;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bs-body-color: #dee2e6;
|
||||
--bs-body-color-rgb: 222, 226, 230;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-primary-text-emphasis: #6ea8fe;
|
||||
--bs-secondary-text-emphasis: #a7acb1;
|
||||
--bs-success-text-emphasis: #75b798;
|
||||
--bs-info-text-emphasis: #6edff6;
|
||||
--bs-warning-text-emphasis: #ffda6a;
|
||||
--bs-danger-text-emphasis: #ea868f;
|
||||
--bs-light-text-emphasis: #f8f9fa;
|
||||
--bs-dark-text-emphasis: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #161719;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #41464b;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #087990;
|
||||
--bs-warning-border-subtle: #997404;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #8bb9fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-highlight-color: #dee2e6;
|
||||
--bs-highlight-bg: #664d03;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
--bs-form-valid-color: #75b798;
|
||||
--bs-form-valid-border-color: #75b798;
|
||||
--bs-form-invalid-color: #ea868f;
|
||||
--bs-form-invalid-border-color: #ea868f;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
color: var(--bs-highlight-color);
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/* rtl:raw:
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,594 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text-emphasis: #052c65;
|
||||
--bs-secondary-text-emphasis: #2b2f32;
|
||||
--bs-success-text-emphasis: #0a3622;
|
||||
--bs-info-text-emphasis: #055160;
|
||||
--bs-warning-text-emphasis: #664d03;
|
||||
--bs-danger-text-emphasis: #58151c;
|
||||
--bs-light-text-emphasis: #495057;
|
||||
--bs-dark-text-emphasis: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #e2e3e5;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #c4c8cb;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-color: #212529;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-xxl: 2rem;
|
||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
--bs-focus-ring-width: 0.25rem;
|
||||
--bs-focus-ring-opacity: 0.25;
|
||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||
--bs-form-valid-color: #198754;
|
||||
--bs-form-valid-border-color: #198754;
|
||||
--bs-form-invalid-color: #dc3545;
|
||||
--bs-form-invalid-border-color: #dc3545;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bs-body-color: #dee2e6;
|
||||
--bs-body-color-rgb: 222, 226, 230;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-primary-text-emphasis: #6ea8fe;
|
||||
--bs-secondary-text-emphasis: #a7acb1;
|
||||
--bs-success-text-emphasis: #75b798;
|
||||
--bs-info-text-emphasis: #6edff6;
|
||||
--bs-warning-text-emphasis: #ffda6a;
|
||||
--bs-danger-text-emphasis: #ea868f;
|
||||
--bs-light-text-emphasis: #f8f9fa;
|
||||
--bs-dark-text-emphasis: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #161719;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #41464b;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #087990;
|
||||
--bs-warning-border-subtle: #997404;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #8bb9fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-highlight-color: #dee2e6;
|
||||
--bs-highlight-bg: #664d03;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
--bs-form-valid-color: #75b798;
|
||||
--bs-form-valid-border-color: #75b798;
|
||||
--bs-form-invalid-color: #ea868f;
|
||||
--bs-form-invalid-border-color: #ea868f;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
color: var(--bs-highlight-color);
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+12057
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4494
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -9,6 +9,7 @@ public class DeckData
|
||||
public string? Description { get; init; }
|
||||
|
||||
public string? DeckCode { get; init; }
|
||||
public string? DeckType { get; init; }
|
||||
|
||||
public List<string> Factions { get; init; } = [];
|
||||
public bool IsVisible { get; init; }
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
@page "/test"
|
||||
<h1>Test Page</h1>
|
||||
<p>This is a test page.</p>
|
||||
@@ -1,6 +1,12 @@
|
||||
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Shared.Pages.Home).Assembly }" NotFoundPage="typeof(NotFound)">
|
||||
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Shared.Pages.Home).Assembly }">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
|
||||
@@ -6,6 +6,7 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
|
||||
builder.Services.AddTelerikBlazor();
|
||||
|
||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||
builder.Services.AddDbContext<AppDbContext>(options =>
|
||||
@@ -39,6 +40,8 @@ app.UseStaticFiles();
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapControllers();
|
||||
app.MapRazorComponents<Server.Components.App>().AddInteractiveServerRenderMode();
|
||||
app.MapRazorComponents<Server.Components.App>()
|
||||
.AddInteractiveServerRenderMode()
|
||||
.AddAdditionalAssemblies(typeof(Shared.Pages.Home).Assembly);
|
||||
|
||||
app.Run();
|
||||
|
||||
@@ -226,6 +226,14 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Overflow",
|
||||
Category = "Keyword",
|
||||
Description = "Adding more energy then your reserves increase this passive stack by 1.",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Overpower",
|
||||
Category = "Keyword",
|
||||
@@ -330,6 +338,20 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Beta Season 1 Track",
|
||||
Category = "Pass",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Onboarding Track",
|
||||
Category = "Pass",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Daily Wins",
|
||||
Category = "Quest",
|
||||
@@ -430,6 +452,14 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Energy Reserves",
|
||||
Category = "Rule",
|
||||
Description = "Up to three unused mana can be banked per turn for spell usage only.",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Fast",
|
||||
Category = "Rule",
|
||||
|
||||
@@ -7,6 +7,66 @@ public static class DeckDatabase
|
||||
{
|
||||
public static readonly System.Collections.Generic.List<DeckData> Decks =
|
||||
[
|
||||
new()
|
||||
{
|
||||
Name = "Aggro",
|
||||
Cards = [
|
||||
"Headbanging",
|
||||
"Headbanging",
|
||||
"Chronal Scan",
|
||||
"Chronal Scan",
|
||||
"Gilded Behemoth",
|
||||
"Gilded Behemoth",
|
||||
"Bathe in Flames",
|
||||
"Bathe in Flames",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Enhanced Retriever",
|
||||
"Enhanced Retriever",
|
||||
"Enhanced Retriever",
|
||||
"Fractal Phantasm",
|
||||
"Fractal Phantasm",
|
||||
"Fractal Phantasm",
|
||||
"Denizen of Flames",
|
||||
"Denizen of Flames",
|
||||
"Denizen of Flames",
|
||||
"Glittering Gladiator",
|
||||
"Glittering Gladiator",
|
||||
"Glittering Gladiator",
|
||||
"Desperate Primordial",
|
||||
"Desperate Primordial",
|
||||
"Desperate Primordial",
|
||||
"Blazing Shifter",
|
||||
"Blazing Shifter",
|
||||
"Blazing Shifter",
|
||||
"Devoted Bloodletter",
|
||||
"Devoted Bloodletter",
|
||||
"Devoted Bloodletter",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Bloodbolt",
|
||||
"Bloodbolt",
|
||||
"Bloodbolt",
|
||||
"Go for the Heart",
|
||||
"Go for the Heart",
|
||||
"Go for the Heart",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Efficient Scrapbot",
|
||||
"Bloodline Tracker",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Splintergleam",
|
||||
"Singularity",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Big Energy",
|
||||
@@ -69,6 +129,83 @@ public static class DeckDatabase
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "AUHUE2LHEBCW4ZLSM54SAQ3POB4QWY3PNZZXI4TVMN2GKZBTAADACASPCICESCQCAUFDCAYGAMCAGAQDDYBQCAYBAOTQCAYQAMDQG",
|
||||
DeckType = "custom",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Example",
|
||||
Cards = [
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
],
|
||||
IsVisible = false,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Kyln Control",
|
||||
Cards = [
|
||||
"Devourer Spawn",
|
||||
"Devourer Spawn",
|
||||
"Radiant Channeling",
|
||||
"Radiant Channeling",
|
||||
"Brilliant Martyr",
|
||||
"Brilliant Martyr",
|
||||
"Brilliant Martyr",
|
||||
"Hidden Locus",
|
||||
"Hidden Locus",
|
||||
"Hidden Locus",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Sunshock",
|
||||
"Sunshock",
|
||||
"Sunshock",
|
||||
"Throw into the Sun",
|
||||
"Throw into the Sun",
|
||||
"Throw into the Sun",
|
||||
"Enlightened Refugee",
|
||||
"Enlightened Refugee",
|
||||
"Enlightened Refugee",
|
||||
"Scuttling Spares",
|
||||
"Scuttling Spares",
|
||||
"Scuttling Spares",
|
||||
"Nascent Clone",
|
||||
"Nascent Clone",
|
||||
"Nascent Clone",
|
||||
"Recycler",
|
||||
"Recycler",
|
||||
"Recycler",
|
||||
"Rapid Iteration",
|
||||
"Rapid Iteration",
|
||||
"Rapid Iteration",
|
||||
"Frontline Fellowship",
|
||||
"Frontline Fellowship",
|
||||
"Frontline Fellowship",
|
||||
"Timestop",
|
||||
"Timestop",
|
||||
"Timestop",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Planet Seeder",
|
||||
"Traffic Conductor",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Sungrace",
|
||||
"Singularity",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
@@ -97,6 +234,246 @@ public static class DeckDatabase
|
||||
Factions = [
|
||||
],
|
||||
IsVisible = false,
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Rewind",
|
||||
Cards = [
|
||||
"Holder of the Instruments",
|
||||
"Holder of the Instruments",
|
||||
"Invigorating Balm",
|
||||
"Invigorating Balm",
|
||||
"Fervent Mycologist",
|
||||
"Fervent Mycologist",
|
||||
"Fervent Mycologist",
|
||||
"Pterosaur Rider",
|
||||
"Pterosaur Rider",
|
||||
"Pterosaur Rider",
|
||||
"Scent the Prey",
|
||||
"Scent the Prey",
|
||||
"Scent the Prey",
|
||||
"Curious Acolyte",
|
||||
"Curious Acolyte",
|
||||
"Curious Acolyte",
|
||||
"Temple Analyst",
|
||||
"Temple Analyst",
|
||||
"Temple Analyst",
|
||||
"Holy Cleaner",
|
||||
"Holy Cleaner",
|
||||
"Holy Cleaner",
|
||||
"Karmic Debtor",
|
||||
"Karmic Debtor",
|
||||
"Karmic Debtor",
|
||||
"Divergence Assassin",
|
||||
"Divergence Assassin",
|
||||
"Divergence Assassin",
|
||||
"Chronicle of the One",
|
||||
"Chronicle of the One",
|
||||
"Chronicle of the One",
|
||||
"Prayer of Rescue",
|
||||
"Prayer of Rescue",
|
||||
"Prayer of Rescue",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Rescind Authorization",
|
||||
"Rescind Authorization",
|
||||
"Rescind Authorization",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Zealot of the Hunt",
|
||||
"Nonlethal Special Forces",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Phasetide",
|
||||
"Lifeblood",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Somnus Spam",
|
||||
Cards = [
|
||||
"Return to Stillness",
|
||||
"Pressure Spike",
|
||||
"Pressure Spike",
|
||||
"Bury the Evidence",
|
||||
"Bury the Evidence",
|
||||
"Hush Now",
|
||||
"Hush Now",
|
||||
"Quiet Repose",
|
||||
"Quiet Repose",
|
||||
"Spirit's Lament",
|
||||
"Spirit's Lament",
|
||||
"Stern Arbiter",
|
||||
"Stern Arbiter",
|
||||
"Braindead Bouncer",
|
||||
"Braindead Bouncer",
|
||||
"Braindead Bouncer",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Nameless Spirit",
|
||||
"Nameless Spirit",
|
||||
"Nameless Spirit",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Sensory Deprivation Pod",
|
||||
"Sensory Deprivation Pod",
|
||||
"Sensory Deprivation Pod",
|
||||
"Mind Over Matter",
|
||||
"Mind Over Matter",
|
||||
"Mind Over Matter",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Snap Back",
|
||||
"Snap Back",
|
||||
"Snap Back",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Librarian's Assistant",
|
||||
"Bareknuckle Inquisitor",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Silence",
|
||||
"Phasetide",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Sunbleed",
|
||||
Cards = [
|
||||
"Chaos Control",
|
||||
"Chaos Control",
|
||||
"Chaos Control",
|
||||
"Persistent Squire",
|
||||
"Persistent Squire",
|
||||
"Persistent Squire",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Red Reaper",
|
||||
"Red Reaper",
|
||||
"Red Reaper",
|
||||
"Hungry Engine",
|
||||
"Hungry Engine",
|
||||
"Hungry Engine",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Kintsu-Kai",
|
||||
"Kintsu-Kai",
|
||||
"Kintsu-Kai",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Ironblood Elixir",
|
||||
"Ironblood Elixir",
|
||||
"Ironblood Elixir",
|
||||
"Rippling Resplendence",
|
||||
"Rippling Resplendence",
|
||||
"Rippling Resplendence",
|
||||
"Soothing Glow",
|
||||
"Soothing Glow",
|
||||
"BREAK AND SHATTER!",
|
||||
"BREAK AND SHATTER!",
|
||||
"Kinetic Absorber",
|
||||
"Kinetic Absorber",
|
||||
"Kinetic Absorber",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Containment Breach",
|
||||
"Devoted Bloodletter",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Sungrace",
|
||||
"Splintergleam",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Tempo Deplete",
|
||||
Cards = [
|
||||
"Cascading Serenity",
|
||||
"Mulch",
|
||||
"Mulch",
|
||||
"Unstoppable Growth",
|
||||
"Unstoppable Growth",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Forest Recluse",
|
||||
"Forest Recluse",
|
||||
"The Forgotten Tale",
|
||||
"The Forgotten Tale",
|
||||
"Gnosis",
|
||||
"Gnosis",
|
||||
"Muffle",
|
||||
"Muffle",
|
||||
"Hush Now",
|
||||
"Hush Now",
|
||||
"Sleepy Druid",
|
||||
"Sleepy Druid",
|
||||
"Sleepy Druid",
|
||||
"Zealot of the Hunt",
|
||||
"Zealot of the Hunt",
|
||||
"Zealot of the Hunt",
|
||||
"Bloom",
|
||||
"Bloom",
|
||||
"Bloom",
|
||||
"Focused Adaptation",
|
||||
"Focused Adaptation",
|
||||
"Focused Adaptation",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Telepathic Scavenger",
|
||||
"Telepathic Scavenger",
|
||||
"Telepathic Scavenger",
|
||||
"Not so Fast",
|
||||
"Not so Fast",
|
||||
"Not so Fast",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Egg Tender",
|
||||
"Redactionist",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Lifeblood",
|
||||
"Silence",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public static class DocDatabase
|
||||
{
|
||||
Title = "Splintergleam",
|
||||
Category = "Faction",
|
||||
Content = "Concepts:\n- Self Damage\n- Bleed\n-",
|
||||
Content = "# Self Damage\n\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\n\n# Core Damage \n\nCan hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Faction" },
|
||||
@@ -204,7 +204,7 @@ public static class DocDatabase
|
||||
{
|
||||
Title = "Sungrace",
|
||||
Category = "Faction",
|
||||
Content = "Concepts:\n- Ramp\n- Using and Replenishing Reserved Energy\n-",
|
||||
Content = "# Energy Reserves\n\nCare about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is you [[Overflow]] your energy reserve.\n\nConcepts:\n- Ramp\n- Using and Replenishing Reserved Energy\n-",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Faction" },
|
||||
@@ -310,6 +310,17 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Overflow",
|
||||
Category = "Keyword",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Keyword" },
|
||||
{ "description", "Adding more energy then your reserves increase this passive stack by 1." },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Overpower",
|
||||
Category = "Keyword",
|
||||
@@ -453,6 +464,30 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Beta Season 1 Track",
|
||||
Category = "Pass",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Pass" },
|
||||
{ "expPer", "500" },
|
||||
{ "size", "30" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Onboarding Track",
|
||||
Category = "Pass",
|
||||
Content = "| Tier | Reward |\n| ---- | -------------------------------- |\n| 1 | Sprouts Record |\n| 2 | 120 Core Charges |\n| 3 | Burn Precon |\n| 4 | 120 Core Charges, 25 Flux |\n| 5 | Profile Pictures |\n| 6 | Emotes |\n| 7 | 120 Core Charges |\n| 8 | Profile Pictures |\n| 9 | 60 Core Charges, 50 Flux |\n| 10 | 240 Core Charges, 1 Draft Ticket |\n\n| Core Charges | Flux |\n| ------------ | ---- |\n| 660 | 75 |",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "expPer", "30" },
|
||||
{ "size", "10" },
|
||||
{ "category", "Pass" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Daily Wins",
|
||||
Category = "Quest",
|
||||
@@ -596,6 +631,17 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Energy Reserves",
|
||||
Category = "Rule",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Rule" },
|
||||
{ "description", "Up to three unused mana can be banked per turn for spell usage only." },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Fast",
|
||||
Category = "Rule",
|
||||
|
||||
@@ -6,8 +6,13 @@
|
||||
<div class="decks-page">
|
||||
<div class="decks-header">
|
||||
<h1>Decks</h1>
|
||||
<div class="decks-header-row">
|
||||
<p class="text-secondary">@decks.Count deck@(decks.Count != 1 ? "s" : "")</p>
|
||||
<p class="text-primary">Please note these are my crafted decks. They are probably not optimal or good. See <a href="https://runeterra.ar/chrono/home">Runeterra.ar</a> and check out the decks from recognizable names there. This is not an ad, just common sense.</p>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="showPrecons" @bind="showPrecons" @bind:after="RefreshDecks">
|
||||
<label class="form-check-label" for="showPrecons">Show Precons</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="deck-list">
|
||||
@@ -25,6 +30,11 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="deck-card-factions">
|
||||
<span class="faction-badge">@deck.DeckType</span>
|
||||
</div>
|
||||
|
||||
<div class="deck-card-meta">
|
||||
<span>@deck.Cards.Distinct().Count() unique, @deck.Cards.Count total</span>
|
||||
@if (deck.Keycards.Count > 0)
|
||||
@@ -56,10 +66,22 @@
|
||||
|
||||
@code {
|
||||
private List<DeckData> decks = [];
|
||||
private bool showPrecons = false;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
decks = DeckDatabase.Decks.Where(d => d.IsVisible).ToList();
|
||||
RefreshDecks();
|
||||
}
|
||||
|
||||
private void RefreshDecks()
|
||||
{
|
||||
decks = DeckDatabase.Decks
|
||||
.Where(d => d.IsVisible)
|
||||
.Where(d =>
|
||||
showPrecons
|
||||
? d.DeckType is "precon" or "store" :
|
||||
d.DeckType is "custom")
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static string Truncate(string text, int maxLength)
|
||||
|
||||
@@ -8,6 +8,16 @@
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.decks-header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.decks-header-row p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.decks-header h1 {
|
||||
margin: 0 0 0.25rem;
|
||||
}
|
||||
|
||||
+38
-122
@@ -39,10 +39,7 @@
|
||||
<div class="doc-card" @onclick="() => SelectDoc(doc)">
|
||||
<div class="doc-card-category">@doc.Category</div>
|
||||
<h3 class="doc-card-title">@doc.Title</h3>
|
||||
@{
|
||||
var desc = GetDescription(doc);
|
||||
}
|
||||
@if (desc != null)
|
||||
@if (GetField(doc, "description") is { Length: > 0 } desc)
|
||||
{
|
||||
<p class="doc-card-desc">@desc</p>
|
||||
}
|
||||
@@ -67,37 +64,34 @@
|
||||
<header class="doc-header">
|
||||
<div class="doc-meta">@selectedDoc.Category</div>
|
||||
<h1>@selectedDoc.Title</h1>
|
||||
@{
|
||||
var desc = GetDescription(selectedDoc);
|
||||
}
|
||||
@if (desc != null)
|
||||
{
|
||||
<p class="doc-description">@desc</p>
|
||||
}
|
||||
</header>
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(selectedDoc.Content))
|
||||
{
|
||||
<div class="doc-body">
|
||||
@((MarkupString)FormatContent(selectedDoc.Content))
|
||||
</div>
|
||||
<div class="doc-fields">
|
||||
@{
|
||||
var fm = selectedDoc.Frontmatter;
|
||||
}
|
||||
|
||||
@if (HasExtraFrontmatter(selectedDoc))
|
||||
@foreach (var kvp in fm)
|
||||
{
|
||||
<div class="doc-extra">
|
||||
<h3>Details</h3>
|
||||
<div class="doc-frontmatter">
|
||||
@foreach (var kvp in selectedDoc.Frontmatter.Where(kvp => kvp.Key != "category" && kvp.Key != "description"))
|
||||
var key = kvp.Key;
|
||||
var val = kvp.Value;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(val)) continue;
|
||||
|
||||
<div class="doc-field">
|
||||
<span class="doc-field-key">@GetLabel(key)</span>
|
||||
|
||||
@if (key == "description")
|
||||
{
|
||||
<div class="fm-item">
|
||||
<span class="fm-key">@kvp.Key</span>
|
||||
<span class="fm-value">@kvp.Value</span>
|
||||
<p class="doc-field-desc">@val</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="doc-field-val">@val</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</article>
|
||||
}
|
||||
</main>
|
||||
@@ -122,8 +116,7 @@
|
||||
.Where(d => (selectedCategory == null || d.Category == selectedCategory) &&
|
||||
(string.IsNullOrWhiteSpace(searchQuery) ||
|
||||
d.Title.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
(GetDescription(d)?.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||
d.Content.Contains(searchQuery, StringComparison.OrdinalIgnoreCase)));
|
||||
(GetField(d, "description")?.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ?? false)));
|
||||
|
||||
private void SelectCategory(string? category)
|
||||
{
|
||||
@@ -136,102 +129,25 @@
|
||||
selectedDoc = doc;
|
||||
}
|
||||
|
||||
private static string? GetDescription(DocData doc)
|
||||
private static string? GetField(DocData doc, string key)
|
||||
{
|
||||
return doc.Frontmatter.TryGetValue("description", out var desc) && !string.IsNullOrWhiteSpace(desc) ? desc : null;
|
||||
return doc.Frontmatter.TryGetValue(key, out var val) && !string.IsNullOrWhiteSpace(val) ? val : null;
|
||||
}
|
||||
|
||||
private static bool HasExtraFrontmatter(DocData doc)
|
||||
private static string GetLabel(string key) => key switch
|
||||
{
|
||||
var count = doc.Frontmatter.Count;
|
||||
if (count == 0) return false;
|
||||
if (count == 1 && doc.Frontmatter.ContainsKey("category")) return false;
|
||||
if (count == 2 && doc.Frontmatter.ContainsKey("category") && doc.Frontmatter.ContainsKey("description")) return false;
|
||||
return doc.Frontmatter.Any(kvp => kvp.Key != "category" && kvp.Key != "description");
|
||||
}
|
||||
|
||||
private string FormatContent(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content)) return "";
|
||||
|
||||
var lines = content.Replace("\r\n", "\n").Split('\n');
|
||||
var html = new System.Text.StringBuilder();
|
||||
var inList = false;
|
||||
|
||||
foreach (var rawLine in lines)
|
||||
{
|
||||
var line = rawLine.TrimEnd();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (inList) { html.AppendLine("</ul>"); inList = false; }
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.StartsWith("- "))
|
||||
{
|
||||
var item = line[2..].Trim();
|
||||
if (item.Length > 0)
|
||||
{
|
||||
if (!inList) { html.AppendLine("<ul class=\"doc-list-items\">"); inList = true; }
|
||||
html.Append("<li>");
|
||||
html.Append(EncodeInline(item));
|
||||
html.AppendLine("</li>");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inList) { html.AppendLine("</ul>"); inList = false; }
|
||||
|
||||
if (line.EndsWith(":") || line.Contains(":\n"))
|
||||
{
|
||||
var trimmed = line.TrimEnd(':');
|
||||
if (trimmed.Length > 0)
|
||||
{
|
||||
html.Append("<p class=\"doc-label\">");
|
||||
html.Append(System.Web.HttpUtility.HtmlEncode(trimmed));
|
||||
html.AppendLine("</p>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.Append("<p>");
|
||||
html.Append(EncodeInline(line));
|
||||
html.AppendLine("</p>");
|
||||
}
|
||||
}
|
||||
|
||||
if (inList) html.AppendLine("</ul>");
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
private string EncodeInline(string text)
|
||||
{
|
||||
var result = new System.Text.StringBuilder();
|
||||
var remaining = text;
|
||||
|
||||
while (remaining.Length > 0)
|
||||
{
|
||||
var boldIdx = remaining.IndexOf("**", StringComparison.Ordinal);
|
||||
if (boldIdx >= 0)
|
||||
{
|
||||
var endBold = remaining.IndexOf("**", boldIdx + 2, StringComparison.Ordinal);
|
||||
if (endBold >= 0)
|
||||
{
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining[..boldIdx]));
|
||||
result.Append("<strong>");
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining[(boldIdx + 2)..endBold]));
|
||||
result.Append("</strong>");
|
||||
remaining = remaining[(endBold + 2)..];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining));
|
||||
break;
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
"category" => "Category",
|
||||
"description" => "Description",
|
||||
"essencePrice" => "Essence Price",
|
||||
"crytalPrice" => "Crystal Price",
|
||||
"coreChargesPrice" => "Core Charges Price",
|
||||
"pricePerPack" => "Price per Pack",
|
||||
"codeCharges" => "Code Charges",
|
||||
"coreCharges" => "Core Charges",
|
||||
"currency" => "Currency",
|
||||
"faction" => "Faction",
|
||||
"exp" => "EXP Reward",
|
||||
"see" => "See Also",
|
||||
_ => string.Concat(key.Select((c, i) => i > 0 && char.IsUpper(c) ? " " + c : c.ToString())),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,119 +171,45 @@
|
||||
}
|
||||
|
||||
.doc-header h1 {
|
||||
margin: 0 0 0.75rem;
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.doc-description {
|
||||
.doc-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.doc-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.doc-field-key {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.doc-field-val {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.doc-field-desc {
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.doc-body {
|
||||
line-height: 1.7;
|
||||
font-size: 1rem;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.doc-body p {
|
||||
margin: 0 0 0.6rem;
|
||||
}
|
||||
|
||||
.doc-body p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.doc-label {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.doc-list-items {
|
||||
margin: 0 0 0.8rem;
|
||||
padding-left: 1.5rem;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.doc-list-items li {
|
||||
position: relative;
|
||||
padding: 0.2rem 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.doc-list-items li::before {
|
||||
content: "▸";
|
||||
position: absolute;
|
||||
left: -1.2rem;
|
||||
color: var(--accent);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.doc-extra {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.doc-extra h3 {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.75rem;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.doc-frontmatter {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.4rem 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--bg-elevated);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.fm-item {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.fm-key {
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
font-size: 0.85rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fm-value {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.doc-link-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
text-decoration-color: rgba(108, 99, 255, 0.3);
|
||||
transition: color var(--transition), text-decoration-color var(--transition);
|
||||
}
|
||||
|
||||
.doc-link-btn:hover {
|
||||
color: #7b73ff;
|
||||
text-decoration-color: #7b73ff;
|
||||
border-left: 3px solid var(--accent);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Microsoft.Playwright;
|
||||
using Microsoft.Playwright.NUnit;
|
||||
|
||||
namespace Tests;
|
||||
@@ -6,4 +7,36 @@ namespace Tests;
|
||||
[TestFixture]
|
||||
public class PlaywrightTests : PageTest
|
||||
{
|
||||
private const string BaseUrl = "http://localhost:5256";
|
||||
|
||||
[Test]
|
||||
public async Task HomePage_ShouldLoad()
|
||||
{
|
||||
await Page.GotoAsync(BaseUrl);
|
||||
await Expect(Page).ToHaveTitleAsync(new System.Text.RegularExpressions.Regex("Chrono CCG"));
|
||||
|
||||
// Check for some content that should be on the home page
|
||||
var heading = Page.Locator("h1");
|
||||
await Expect(heading).ToBeVisibleAsync();
|
||||
await Expect(heading).ToContainTextAsync("Slop Game Reference - Chrono CCG");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DocsPage_ShouldLoad()
|
||||
{
|
||||
await Page.GotoAsync($"{BaseUrl}/docs");
|
||||
var heading = Page.Locator("h1");
|
||||
await Expect(heading).ToBeVisibleAsync();
|
||||
await Expect(heading).ToContainTextAsync("Documentation");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AgentsPage_ShouldLoad()
|
||||
{
|
||||
await Page.GotoAsync($"{BaseUrl}/agents");
|
||||
// Agents page uses Telerik Grid, let's wait for it
|
||||
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
||||
var grid = Page.Locator(".agents-grid");
|
||||
await Expect(grid).ToBeVisibleAsync();
|
||||
}
|
||||
}
|
||||
Vendored
+3
-1
@@ -15,6 +15,8 @@
|
||||
"factions": "multitext",
|
||||
"essencePrice": "number",
|
||||
"codeCharges": "number",
|
||||
"exp": "number"
|
||||
"exp": "number",
|
||||
"expPer": "number",
|
||||
"size": "number"
|
||||
}
|
||||
}
|
||||
Vendored
+60
-32
@@ -10,18 +10,46 @@
|
||||
{
|
||||
"id": "852a1aaf6b54ec43",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bases",
|
||||
"state": {
|
||||
"file": "_Store.base",
|
||||
"viewName": "Table"
|
||||
},
|
||||
"icon": "lucide-table",
|
||||
"title": "_Store"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "711239c069fbdec8",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Rule/Slow.md",
|
||||
"file": "Rule/Energy Reserves.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Slow"
|
||||
"title": "Energy Reserves"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a2a9bf0db5bd1fb6",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Pass/Beta Season 1 Track.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Beta Season 1 Track"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"currentTab": 2
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
@@ -53,7 +81,7 @@
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "The Ripper",
|
||||
"query": "deckType: store",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
@@ -183,45 +211,45 @@
|
||||
"bases:Create new base": false
|
||||
}
|
||||
},
|
||||
"active": "852a1aaf6b54ec43",
|
||||
"active": "a2a9bf0db5bd1fb6",
|
||||
"lastOpenFiles": [
|
||||
"Rule/Immediate.md",
|
||||
"Rule/Fast.md",
|
||||
"Pass",
|
||||
"Pass/Onboarding Track.md",
|
||||
"Pass/Beta Season 1 Track.md",
|
||||
"Rule/Energy Reserves.md",
|
||||
"Keyword/Overflow.md",
|
||||
"_Store.base",
|
||||
"Untitled.md",
|
||||
"Faction/Sungrace.md",
|
||||
"Overload.md",
|
||||
"Faction/Splintergleam.md",
|
||||
"Faction/Phasetide.md",
|
||||
"Faction/Lifeblood.md",
|
||||
"Deck/Example.md",
|
||||
"Deck/Big Energy.md",
|
||||
"_Timeline.base",
|
||||
"Store/Core Set Packs x1.md",
|
||||
"Store/Core Set Packs x5.md",
|
||||
"Store/Core Set Packs x10.md",
|
||||
"Deck/Aggro.md",
|
||||
"Deck/Kyln Control.md",
|
||||
"Deck/Rewind.md",
|
||||
"Deck/Somnus Spam.md",
|
||||
"Deck/Sunbleed.md",
|
||||
"Deck/Untitled.md",
|
||||
"Deck/Tempo Deplete.md",
|
||||
"Deck/Rewind Me.md",
|
||||
"Store/Core Set Packs x50.md",
|
||||
"Store/Card Backs.md",
|
||||
"Store/Text Emote.md",
|
||||
"Store/Common.md",
|
||||
"Store/Rare.md",
|
||||
"Store/Divergent.md",
|
||||
"Store/Core Set Packs x1.md",
|
||||
"_Spells.base",
|
||||
"Rule/Slow.md",
|
||||
"Speed/Slow.md",
|
||||
"Speed/Immediate.md",
|
||||
"Speed/Fast.md",
|
||||
"Speed",
|
||||
"_Quests.base",
|
||||
"Quest",
|
||||
"Quest/Overflow 10 Times.md",
|
||||
"exp.md",
|
||||
"Quest/Deal 30 Damage with Overpower Agents.md",
|
||||
"Quest/Deal 50 Damage with Specific Faction.md",
|
||||
"Quest/Erase 7 Cards.md",
|
||||
"Quest/Deplete 10 Agents.md",
|
||||
"Quest/Deal 200 Damage.md",
|
||||
"Quest/Weekly Wins.md",
|
||||
"Quest/Daily Wins.md",
|
||||
"Currency/Draft Ticket.md",
|
||||
"Store/Lost.md",
|
||||
"Currency/Flux.md",
|
||||
"Store",
|
||||
"Currency",
|
||||
"Currency/Core Charges.md",
|
||||
"Currency/Crystals.md",
|
||||
"_Factions.base",
|
||||
"Decks/Rewind Me.canvas",
|
||||
"_Debuff.base",
|
||||
"_Keyword.base",
|
||||
"Agent/[[Lifeblood]]/1",
|
||||
"images/Wolf.png",
|
||||
"images/Seedling.png",
|
||||
"images/Pocket Scout.png",
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Headbanging]]"
|
||||
- "[[Headbanging]]"
|
||||
- "[[Chronal Scan]]"
|
||||
- "[[Chronal Scan]]"
|
||||
- "[[Gilded Behemoth]]"
|
||||
- "[[Gilded Behemoth]]"
|
||||
- "[[Bathe in Flames]]"
|
||||
- "[[Bathe in Flames]]"
|
||||
- "[[Paradox Cacophony]]"
|
||||
- "[[Paradox Cacophony]]"
|
||||
- "[[Enhanced Retriever]]"
|
||||
- "[[Enhanced Retriever]]"
|
||||
- "[[Enhanced Retriever]]"
|
||||
- "[[Fractal Phantasm]]"
|
||||
- "[[Fractal Phantasm]]"
|
||||
- "[[Fractal Phantasm]]"
|
||||
- "[[Denizen of Flames]]"
|
||||
- "[[Denizen of Flames]]"
|
||||
- "[[Denizen of Flames]]"
|
||||
- "[[Glittering Gladiator]]"
|
||||
- "[[Glittering Gladiator]]"
|
||||
- "[[Glittering Gladiator]]"
|
||||
- "[[Desperate Primordial]]"
|
||||
- "[[Desperate Primordial]]"
|
||||
- "[[Desperate Primordial]]"
|
||||
- "[[Blazing Shifter]]"
|
||||
- "[[Blazing Shifter]]"
|
||||
- "[[Blazing Shifter]]"
|
||||
- "[[Devoted Bloodletter]]"
|
||||
- "[[Devoted Bloodletter]]"
|
||||
- "[[Devoted Bloodletter]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Bloodbolt]]"
|
||||
- "[[Bloodbolt]]"
|
||||
- "[[Bloodbolt]]"
|
||||
- "[[Go for the Heart]]"
|
||||
- "[[Go for the Heart]]"
|
||||
- "[[Go for the Heart]]"
|
||||
divers:
|
||||
- "[[Efficient Scrapbot]]
|
||||
- "[[Bloodline Tracker]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Splintergleam]]"
|
||||
- "[[Singularity]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -72,16 +72,13 @@ factions:
|
||||
- "[[Sungrace]]"
|
||||
- "[[Phasetide]]"
|
||||
deckCode: AUHUE2LHEBCW4ZLSM54SAQ3POB4QWY3PNZZXI4TVMN2GKZBTAADACASPCICESCQCAUFDCAYGAMCAGAQDDYBQCAYBAOTQCAYQAMDQG
|
||||
deckType: custom
|
||||
---
|
||||
The idea of this deck is to go heavy on stat-efficient cards. Like 2 for a 2/3 [[Kinetic Absorber]], 5/6 [[Lumbering Starseeker]], and 8 for a 9/14 [[Lightsteel Colossus]].
|
||||
|
||||
You got [[Devourer Spawn]] to help push for lethal. It's going to have a bunch of keywords on it, given how popular timelines are in the meta.
|
||||
|
||||
You need to Overflow your mana once in a while, or some of your [[Supernova]] removal will be useless. Be pass heavy.
|
||||
|
||||
You're going to win on very low health if you win. Such is life.
|
||||
|
||||
No strong card draw, so [[Army of the Sun]] is your hope if things go long. At the worst, it's a spell that summons a big unit right away if it goes off.
|
||||
You need to Overflow your mana once in a while, or some of your [[Supernova]] removal will be useless. Be pass heavy. And if you do end up overflowing many times [[Supernova]] can refill for mana bar, and it's worth adding some [[Snap Back]]s to the deck to use that spell multiple times.
|
||||
|
||||
Attack aggressively with [[Brilliant Martyr]]. You really want [[Star Siphon]] to ramp.
|
||||
|
||||
@@ -91,3 +88,6 @@ So ya, [[Curb the Anomalies]] can weaken the enemy board, by shutting off all th
|
||||
|
||||
And I suppose [[Bearer of the Broth]]. Since the deck has so much raw stats, you will probably find somewhere to heal. Like healing [[Kinetic Absorber]] so it can keep killing after it Immortalizes.
|
||||
|
||||
Also in practice [[Bearer of the Broth]] has proven to be an insane and reliable draw engine for this deck.
|
||||
|
||||
[[Gunnery Captain]] helps clear up the board. Tokens are just 1 to 2 cost units that grew to absurd sizes. And [[Army of the Sun]] helps in the mirror match, given how common this deck is due to the precon.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[]]"
|
||||
- "[[]]"
|
||||
divers:
|
||||
- "[[]]
|
||||
- "[[]]"
|
||||
isVisible: false
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[]]"
|
||||
- "[[]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Devourer Spawn]]"
|
||||
- "[[Devourer Spawn]]"
|
||||
- "[[Radiant Channeling]]"
|
||||
- "[[Radiant Channeling]]"
|
||||
- "[[Brilliant Martyr]]"
|
||||
- "[[Brilliant Martyr]]"
|
||||
- "[[Brilliant Martyr]]"
|
||||
- "[[Hidden Locus]]"
|
||||
- "[[Hidden Locus]]"
|
||||
- "[[Hidden Locus]]"
|
||||
- "[[Debris Collector]]"
|
||||
- "[[Debris Collector]]"
|
||||
- "[[Debris Collector]]"
|
||||
- "[[Sunshock]]"
|
||||
- "[[Sunshock]]"
|
||||
- "[[Sunshock]]"
|
||||
- "[[Throw into the Sun]]"
|
||||
- "[[Throw into the Sun]]"
|
||||
- "[[Throw into the Sun]]"
|
||||
- "[[Enlightened Refugee]]"
|
||||
- "[[Enlightened Refugee]]"
|
||||
- "[[Enlightened Refugee]]"
|
||||
- "[[Scuttling Spares]]"
|
||||
- "[[Scuttling Spares]]"
|
||||
- "[[Scuttling Spares]]"
|
||||
- "[[Nascent Clone]]"
|
||||
- "[[Nascent Clone]]"
|
||||
- "[[Nascent Clone]]"
|
||||
- "[[Recycler]]"
|
||||
- "[[Recycler]]"
|
||||
- "[[Recycler]]"
|
||||
- "[[Rapid Iteration]]"
|
||||
- "[[Rapid Iteration]]"
|
||||
- "[[Rapid Iteration]]"
|
||||
- "[[Frontline Fellowship]]"
|
||||
- "[[Frontline Fellowship]]"
|
||||
- "[[Frontline Fellowship]]"
|
||||
- "[[Timestop]]"
|
||||
- "[[Timestop]]"
|
||||
- "[[Timestop]]"
|
||||
divers:
|
||||
- "[[Planet Seeder]]
|
||||
- "[[Traffic Conductor]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Sungrace]]"
|
||||
- "[[Singularity]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Holder of the Instruments]]"
|
||||
- "[[Holder of the Instruments]]"
|
||||
- "[[Invigorating Balm]]"
|
||||
- "[[Invigorating Balm]]"
|
||||
- "[[Fervent Mycologist]]"
|
||||
- "[[Fervent Mycologist]]"
|
||||
- "[[Fervent Mycologist]]"
|
||||
- "[[Pterosaur Rider]]"
|
||||
- "[[Pterosaur Rider]]"
|
||||
- "[[Pterosaur Rider]]"
|
||||
- "[[Scent the Prey]]"
|
||||
- "[[Scent the Prey]]"
|
||||
- "[[Scent the Prey]]"
|
||||
- "[[Curious Acolyte]]"
|
||||
- "[[Curious Acolyte]]"
|
||||
- "[[Curious Acolyte]]"
|
||||
- "[[Temple Analyst]]"
|
||||
- "[[Temple Analyst]]"
|
||||
- "[[Temple Analyst]]"
|
||||
- "[[Holy Cleaner]]"
|
||||
- "[[Holy Cleaner]]"
|
||||
- "[[Holy Cleaner]]"
|
||||
- "[[Karmic Debtor]]"
|
||||
- "[[Karmic Debtor]]"
|
||||
- "[[Karmic Debtor]]"
|
||||
- "[[Divergence Assassin]]"
|
||||
- "[[Divergence Assassin]]"
|
||||
- "[[Divergence Assassin]]"
|
||||
- "[[Chronicle of the One]]"
|
||||
- "[[Chronicle of the One]]"
|
||||
- "[[Chronicle of the One]]"
|
||||
- "[[Prayer of Rescue]]"
|
||||
- "[[Prayer of Rescue]]"
|
||||
- "[[Prayer of Rescue]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Rescind Authorization]]"
|
||||
- "[[Rescind Authorization]]"
|
||||
- "[[Rescind Authorization]]"
|
||||
divers:
|
||||
- "[[Zealot of the Hunt]]"
|
||||
- "[[Nonlethal Special Forces]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Phasetide]]"
|
||||
- "[[Lifeblood]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Return to Stillness]]
|
||||
- "[[Pressure Spike]]""
|
||||
- "[[Pressure Spike]]""
|
||||
- "[[Bury the Evidence]]"
|
||||
- "[[Bury the Evidence]]"
|
||||
- "[[Hush Now]]"
|
||||
- "[[Hush Now]]"
|
||||
- "[[Quiet Repose]]"
|
||||
- "[[Quiet Repose]]"
|
||||
- "[[Spirit's Lament]]"
|
||||
- "[[Spirit's Lament]]"
|
||||
- "[[Stern Arbiter]]"
|
||||
- "[[Stern Arbiter]]"
|
||||
- "[[Braindead Bouncer]]"
|
||||
- "[[Braindead Bouncer]]"
|
||||
- "[[Braindead Bouncer]]"
|
||||
- "[[Somber Astronomer]]"
|
||||
- "[[Somber Astronomer]]"
|
||||
- "[[Somber Astronomer]]"
|
||||
- "[[Nameless Spirit]]"
|
||||
- "[[Nameless Spirit]]"
|
||||
- "[[Nameless Spirit]]"
|
||||
- "[[Destiny Ripper]]"
|
||||
- "[[Destiny Ripper]]"
|
||||
- "[[Destiny Ripper]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Sensory Deprivation Pod]]"
|
||||
- "[[Sensory Deprivation Pod]]"
|
||||
- "[[Sensory Deprivation Pod]]"
|
||||
- "[[Mind Over Matter]]"
|
||||
- "[[Mind Over Matter]]"
|
||||
- "[[Mind Over Matter]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Backhand]]"
|
||||
- "[[Snap Back]]"
|
||||
- "[[Snap Back]]"
|
||||
- "[[Snap Back]]"
|
||||
divers:
|
||||
- "[[Librarian's Assistant]]"
|
||||
- "[[Bareknuckle Inquisitor]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Silence]]"
|
||||
- "[[Phasetide]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Chaos Control]]"
|
||||
- "[[Chaos Control]]"
|
||||
- "[[Chaos Control]]"
|
||||
- "[[Persistent Squire]]"
|
||||
- "[[Persistent Squire]]"
|
||||
- "[[Persistent Squire]]"
|
||||
- "[[Bright-Eyed Supplicant]]"
|
||||
- "[[Bright-Eyed Supplicant]]"
|
||||
- "[[Bright-Eyed Supplicant]]"
|
||||
- "[[Red Reaper]]"
|
||||
- "[[Red Reaper]]"
|
||||
- "[[Red Reaper]]"
|
||||
- "[[Hungry Engine]]"
|
||||
- "[[Hungry Engine]]"
|
||||
- "[[Hungry Engine]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Channel Vigor]]"
|
||||
- "[[Kintsu-Kai]]"
|
||||
- "[[Kintsu-Kai]]"
|
||||
- "[[Kintsu-Kai]]"
|
||||
- "[[Paradox Cacophony]]"
|
||||
- "[[Paradox Cacophony]]"
|
||||
- "[[Paradox Cacophony]]"
|
||||
- "[[Ironblood Elixir]]"
|
||||
- "[[Ironblood Elixir]]"
|
||||
- "[[Ironblood Elixir]]"
|
||||
- "[[Rippling Resplendence]]"
|
||||
- "[[Rippling Resplendence]]"
|
||||
- "[[Rippling Resplendence]]"
|
||||
- "[[Soothing Glow]]"
|
||||
- "[[Soothing Glow]]"
|
||||
- "[[BREAK AND SHATTER!]]"
|
||||
- "[[BREAK AND SHATTER!]]"
|
||||
- "[[Kinetic Absorber]]"
|
||||
- "[[Kinetic Absorber]]"
|
||||
- "[[Kinetic Absorber]]"
|
||||
- "[[Debris Collector]]"
|
||||
- "[[Debris Collector]]"
|
||||
- "[[Debris Collector]]"
|
||||
divers:
|
||||
- "[[Containment Breach]]"
|
||||
- "[[Devoted Bloodletter]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Sungrace]]"
|
||||
- "[[Splintergleam]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
category: Deck
|
||||
cards:
|
||||
- "[[Cascading Serenity]]"
|
||||
- "[[Mulch]]"
|
||||
- "[[Mulch]]"
|
||||
- "[[Unstoppable Growth]]"
|
||||
- "[[Unstoppable Growth]]"
|
||||
- "[[Somber Astronomer]]"
|
||||
- "[[Somber Astronomer]]"
|
||||
- "[[Destiny Ripper]]"
|
||||
- "[[Destiny Ripper]]"
|
||||
- "[[Forest Recluse]]"
|
||||
- "[[Forest Recluse]]"
|
||||
- "[[The Forgotten Tale]]"
|
||||
- "[[The Forgotten Tale]]"
|
||||
- "[[Gnosis]]"
|
||||
- "[[Gnosis]]"
|
||||
- "[[Muffle]]"
|
||||
- "[[Muffle]]"
|
||||
- "[[Hush Now]]"
|
||||
- "[[Hush Now]]"
|
||||
- "[[Sleepy Druid]]"
|
||||
- "[[Sleepy Druid]]"
|
||||
- "[[Sleepy Druid]]"
|
||||
- "[[Zealot of the Hunt]]"
|
||||
- "[[Zealot of the Hunt]]"
|
||||
- "[[Zealot of the Hunt]]"
|
||||
- "[[Bloom]]"
|
||||
- "[[Bloom]]"
|
||||
- "[[Bloom]]"
|
||||
- "[[Focused Adaptation]]"
|
||||
- "[[Focused Adaptation]]"
|
||||
- "[[Focused Adaptation]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Rotting Rocker]]"
|
||||
- "[[Telepathic Scavenger]]"
|
||||
- "[[Telepathic Scavenger]]"
|
||||
- "[[Telepathic Scavenger]]"
|
||||
- "[[Not so Fast]]"
|
||||
- "[[Not so Fast]]"
|
||||
- "[[Not so Fast]]"
|
||||
divers:
|
||||
- "[[Egg Tender]]"
|
||||
- "[[Redactionist]]"
|
||||
isVisible: true
|
||||
keycards:
|
||||
description:
|
||||
factions:
|
||||
- "[[Lifeblood]]"
|
||||
- "[[Silence]]"
|
||||
deckCode:
|
||||
deckType: store
|
||||
---
|
||||
@@ -1,7 +1,11 @@
|
||||
---
|
||||
category: Faction
|
||||
---
|
||||
Concepts:
|
||||
- Self Damage
|
||||
- Bleed
|
||||
-
|
||||
|
||||
# Self Damage
|
||||
|
||||
Can hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.
|
||||
|
||||
# Core Damage
|
||||
|
||||
Can hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
category: Faction
|
||||
---
|
||||
# Energy Reserves
|
||||
|
||||
Care about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is you [[Overflow]] your energy reserve.
|
||||
|
||||
Concepts:
|
||||
- Ramp
|
||||
- Using and Replenishing Reserved Energy
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: Keyword
|
||||
description: Adding more energy then your reserves increase this passive stack by 1.
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: Pass
|
||||
expPer: 500
|
||||
size: 30
|
||||
---
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
expPer: 30
|
||||
size: 10
|
||||
category: Pass
|
||||
---
|
||||
|
||||
| Tier | Reward |
|
||||
| ---- | -------------------------------- |
|
||||
| 1 | Sprouts Record |
|
||||
| 2 | 120 Core Charges |
|
||||
| 3 | Burn Precon |
|
||||
| 4 | 120 Core Charges, 25 Flux |
|
||||
| 5 | Profile Pictures |
|
||||
| 6 | Emotes |
|
||||
| 7 | 120 Core Charges |
|
||||
| 8 | Profile Pictures |
|
||||
| 9 | 60 Core Charges, 50 Flux |
|
||||
| 10 | 240 Core Charges, 1 Draft Ticket |
|
||||
|
||||
| Core Charges | Flux |
|
||||
| ------------ | ---- |
|
||||
| 660 | 75 |
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: Rule
|
||||
description: Up to three unused mana can be banked per turn for spell usage only.
|
||||
---
|
||||
Reference in New Issue
Block a user