Vibe fix to work on PC

This commit is contained in:
2026-09-29 18:21:21 +00:00
committed by JonathanMcCaffrey
parent ab14955434
commit 4e7fc73ebb
87 changed files with 122767 additions and 43 deletions
File diff suppressed because one or more lines are too long
+61660
View File
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="Telerik Blazor 13.0.0" value="C:\Program Files (x86)\Progress\Telerik UI for Blazor 13.0.0" />
</packageSources>
</configuration>
+5 -1
View File
@@ -7,6 +7,10 @@ public partial class App : Application
public App()
{
InitializeComponent();
MainPage = new MapEditorPage();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new MapEditorPage());
}
}
@@ -0,0 +1,8 @@
<maui:MauiWinUIApplication
x:Class="ZeroSpace.MapEditor.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:ZeroSpace.MapEditor.WinUI">
</maui:MauiWinUIApplication>
@@ -0,0 +1,13 @@
using Microsoft.UI.Xaml;
namespace ZeroSpace.MapEditor.WinUI;
public partial class App : MauiWinUIApplication
{
public App()
{
this.InitializeComponent();
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="ZeroSpace.MapEditor.WinUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
@@ -1,5 +1,5 @@
using System.Globalization;
using Microsoft.Maui.Storage;
using CommunityToolkit.Maui.Storage;
using ZeroSpace.MapEditor.Models;
using ZeroSpace.MapEditor.Services;
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-windows10.0.19041.0;net10.0-maccatalyst17.0</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">net10.0-windows10.0.19041.0</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('windows'))">net10.0-maccatalyst</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>ZeroSpace.MapEditor</RootNamespace>
<UseMaui>true</UseMaui>
@@ -13,6 +14,17 @@
<ApplicationId>ca.jonathanmccaffrey.zerospace.mapeditor</ApplicationId>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<!-- Unpackaged Windows desktop execution -->
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.110" />
<PackageReference Include="CommunityToolkit.Maui.Core" Version="15.0.1" />
</ItemGroup>
</Project>
+5 -7
View File
@@ -1,22 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.9" PrivateAssets="all"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.9" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.12" />
<PackageReference Include="Markdig" Version="1.4.0" />
<PackageReference Include="Telerik.UI.for.Blazor" Version="14.0.0" />
<PackageReference Include="Telerik.UI.for.Blazor">
<Version>13.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ZeroSpace.Model\ZeroSpace.Model.csproj" />
</ItemGroup>
</Project>
+6 -3
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
@@ -10,7 +10,9 @@
<link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/app.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<link href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" rel="stylesheet"/>
<link href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" rel="stylesheet" type="text/css" />
<link href="ZeroSpace.Web.styles.css" rel="stylesheet" />
<script type="importmap"></script>
</head>
@@ -29,7 +31,8 @@
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>
<script defer src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"></script>
<script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js" defer></script>
<script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
</body>
@@ -0,0 +1,6 @@
<Router AppAssembly="@typeof(App).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
</Router>
@@ -0,0 +1,10 @@
@using Markdig
@using ZeroSpace.Web.Services
@((MarkupString)Markdig.Markdown.ToHtml(ZeroSpaceLinks.ResolveWikiLinks(Markdown), Pipeline, null))
@code {
private static readonly MarkdownPipeline Pipeline = new MarkdownPipelineBuilder().Build();
[Parameter, EditorRequired]
public string Markdown { get; set; } = string.Empty;
}
@@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
# Copy project files for caching restore layer
COPY ["ZeroSpace.Web/ZeroSpace.Web.csproj", "ZeroSpace.Web/"]
COPY ["ZeroSpace.Model/ZeroSpace.Model.csproj", "ZeroSpace.Model/"]
RUN dotnet restore "ZeroSpace.Web/ZeroSpace.Web.csproj"
# Copy source code and build
COPY . .
WORKDIR "/src/ZeroSpace.Web"
RUN dotnet publish "ZeroSpace.Web.csproj" -c Release -o /app/publish
FROM nginx:alpine AS final
WORKDIR /usr/share/nginx/html
COPY --from=build /app/publish/wwwroot .
COPY ZeroSpace.Web/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
@@ -0,0 +1,15 @@
@using Telerik.Blazor.Components
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu/>
</div>
<main>
<article class="content px-4">
<TelerikRootComponent>
@Body
</TelerikRootComponent>
</article>
</main>
</div>
@@ -0,0 +1,77 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, #0d1117 0%, #161b22 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;
}
}
@@ -0,0 +1,45 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">ZeroSpace</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<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="units">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Units
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="StarSystem">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Star Systems
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="SystemMastery">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Masteries
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
@@ -0,0 +1,83 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.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 a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item ::deep a.active {
background-color: rgba(88, 166, 255, 0.2);
color: #58a6ff;
}
.nav-item ::deep a:hover {
background-color: rgba(88, 166, 255, 0.1);
color: #58a6ff;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
.nav-scrollable {
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}
@@ -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,111 @@
@page "/StarSystem/{Id}"
<PageTitle>@(system?.Name ?? "Star System")</PageTitle>
@if (system is null)
{
<div class="alert alert-warning" role="alert">
Unknown star system. <a href="/StarSystem">Back to all star systems</a>.
</div>
}
else
{
<div class="section-header d-flex align-items-center mb-4">
<h1 class="mb-0">@system.Name</h1>
<span class="badge bg-primary ms-3">@system.Kind</span>
<div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>
<dl class="row">
<dt class="col-sm-3">Occupation buff</dt>
<dd class="col-sm-9">@(system.OccupationBuff ?? "—")</dd>
<dt class="col-sm-3">System mastery</dt>
<dd class="col-sm-9">
@if (system.SystemMastery is null)
{
@:—
}
else
{
var masteryUrl = ZeroSpaceLinks.UrlFor(system.SystemMastery);
if (masteryUrl is null)
{
@system.SystemMastery
}
else
{
<a href="@masteryUrl">@system.SystemMastery</a>
}
}
</dd>
<dt class="col-sm-3">Yields</dt>
<dd class="col-sm-9">@YieldText(system)</dd>
<dt class="col-sm-3">Connected systems</dt>
<dd class="col-sm-9">
@for (var i = 0; i < system.ConnectedSystems.Count; i++)
{
var name = system.ConnectedSystems[i];
var url = ZeroSpaceLinks.UrlFor(name);
if (url is null)
{
<span>@name</span>
}
else
{
<a href="@url">@name</a>
}
@if (i < system.ConnectedSystems.Count - 1)
{
@:,&nbsp;
}
}
</dd>
</dl>
@if (!string.IsNullOrWhiteSpace(system.Body))
{
<h2>Notes</h2>
<MarkdownView Markdown="@system.Body" />
}
}
@code {
[Parameter]
public string Id { get; set; } = string.Empty;
private StarSystemData? system;
protected override void OnParametersSet()
{
system = StarSystems.All.FirstOrDefault(s => s.Id.Equals(Id, StringComparison.OrdinalIgnoreCase));
}
private static string YieldText(StarSystemData s)
{
var yields = new List<string>();
if (s.HigherInfluenceYield)
{
yields.Add("Influence");
}
if (s.HigherCreditYield)
{
yields.Add("Credits");
}
if (s.HigherEnergyYield)
{
yields.Add("Energy");
}
if (s.HigherChanceForItems)
{
yields.Add("Items");
}
return yields.Count == 0 ? "Standard" : "Higher " + string.Join(", ", yields);
}
}
@@ -0,0 +1,22 @@
@page "/StarSystem"
<PageTitle>Star Systems</PageTitle>
<div class="section-header d-flex align-items-center mb-4">
<h1 class="mb-0">Star Systems</h1>
<div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>
@foreach (var kind in Enum.GetValues<StarSystemKind>())
{
var systems = StarSystems.All.Where(s => s.Kind == kind).OrderBy(s => s.Name).ToList();
<h2>@kind <span class="text-muted fs-5">(@systems.Count)</span></h2>
<ul class="list-unstyled row mb-4">
@foreach (var system in systems)
{
<li class="col-md-4 col-lg-3 mb-1">
<a href="/StarSystem/@system.Id">@system.Name</a>
</li>
}
</ul>
}
@@ -0,0 +1,79 @@
@page "/SystemMastery/{Id}"
<PageTitle>@(mastery?.Name ?? "System Mastery")</PageTitle>
@if (mastery is null)
{
<div class="alert alert-warning" role="alert">
Unknown system mastery. <a href="/SystemMastery">Back to all masteries</a>.
</div>
}
else
{
<div class="section-header d-flex align-items-center mb-4">
<h1 class="mb-0">@mastery.Name</h1>
<div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>
<h2>Levels</h2>
<ol>
@for (var i = 0; i < mastery.Levels.Count; i++)
{
<li><strong>Level @(i + 1):</strong> @mastery.Levels[i]</li>
}
</ol>
@if (mastery.Stats.Count > 0)
{
<h2>Totals</h2>
<table class="table table-sm w-auto">
<tbody>
@foreach (var stat in mastery.Stats)
{
<tr>
<td>@ZeroSpaceLinks.Humanize(stat.Key)</td>
<td class="text-end">@stat.Value</td>
</tr>
}
</tbody>
</table>
}
<h2>Available on</h2>
<ul class="list-unstyled row">
@foreach (var name in mastery.AvailableSystems.OrderBy(n => n))
{
<li class="col-md-4 col-lg-3 mb-1">
@{
var url = ZeroSpaceLinks.UrlFor(name);
}
@if (url is null)
{
@name
}
else
{
<a href="@url">@name</a>
}
</li>
}
</ul>
@if (!string.IsNullOrWhiteSpace(mastery.Body))
{
<h2>Notes</h2>
<MarkdownView Markdown="@mastery.Body" />
}
}
@code {
[Parameter]
public string Id { get; set; } = string.Empty;
private SystemMasteryData? mastery;
protected override void OnParametersSet()
{
mastery = SystemMasteries.All.FirstOrDefault(m => m.Id.Equals(Id, StringComparison.OrdinalIgnoreCase));
}
}
@@ -0,0 +1,18 @@
@page "/SystemMastery"
<PageTitle>System Masteries</PageTitle>
<div class="section-header d-flex align-items-center mb-4">
<h1 class="mb-0">System Masteries</h1>
<div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>
<div class="list-group">
@foreach (var mastery in SystemMasteries.All.OrderBy(m => m.Name))
{
<a class="list-group-item list-group-item-action" href="/SystemMastery/@mastery.Id">
<div class="fw-bold">@mastery.Name</div>
<small class="text-muted">@mastery.Levels[0] · available on @mastery.AvailableSystems.Count systems</small>
</a>
}
</div>
@@ -0,0 +1,100 @@
@page "/units"
@using ZeroSpace.Model
@using ZeroSpace.Web.Services
@using Telerik.Blazor
@using Telerik.Blazor.Components
@inject IUnitsApiClient UnitsApiClient
<PageTitle>Units</PageTitle>
<div class="section-header d-flex align-items-center mb-4">
<h1 class="mb-0">Units</h1>
<div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>
@if (isLoading)
{
<div class="d-flex justify-content-center py-5">
<div class="spinner-border text-success" role="status">
<span class="visually-hidden">Loading units...</span>
</div>
</div>
}
else if (errorMessage != null)
{
<div class="alert alert-danger d-flex align-items-center justify-content-between" role="alert">
<div>
<strong>Error:</strong> @errorMessage
</div>
<button class="btn btn-outline-danger btn-sm" @onclick="LoadUnitsAsync">Retry</button>
</div>
}
else if (gearNotes == null || gearNotes.Count == 0)
{
<div class="alert alert-warning" role="alert">
No units found.
</div>
}
else
{
<div class="grid-container">
<TelerikGrid Data="@gearNotes" Pageable="true" PageSize="50" Sortable="true" FilterMode="@GridFilterMode.FilterRow"
Height="calc(100vh - 250px)">
<GridColumns>
<GridColumn Field="@(nameof(UnitData.Name))" Title="Name" Width="200px"/>
<GridColumn Field="@(nameof(UnitData.Hexite))" Title="Hexite" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Flux))" Title="Flux" Width="90px" />
<GridColumn Field="@(nameof(UnitData.DpsPerTotalCost))" Title="DpsPerTotalCost" Width="90px" />
<GridColumn Field="@(nameof(UnitData.HealthPerTotalCost))" Title="HealthPerTotalCost" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Supply))" Title="Supply" Width="90px" />
<GridColumn Field="@(nameof(UnitData.ProductionTime))" Title="Production Time" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Health))" Title="Health" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Shields))" Title="Shields" Width="90px" />
<GridColumn Field="@(nameof(UnitData.ArmorRating))" Title="Armor Rating" Width="90px" />
<GridColumn Field="@(nameof(UnitData.MovementSpeed))" Title="Movement Speed" Width="90px" />
<GridColumn Field="@(nameof(UnitData.DamagePerSecond))" Title="Damage Per Second" Width="90px" />
<GridColumn Field="@(nameof(UnitData.AttackRange))" Title="Attack Range" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Attributes))" Title="Attributes" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Tier))" Title="Tier" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Faction))" Title="Faction" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Hotkey))" Title="Hotkey" Width="90px" />
<GridColumn Field="@(nameof(UnitData.BuildAtSameTime))" Title="Build At Same Time" Width="90px" />
<GridColumn Field="@(nameof(UnitData.Limit))" Title="Limit" Width="90px" />
</GridColumns>
</TelerikGrid>
</div>
}
@code {
private List<UnitData>? gearNotes;
private bool isLoading = true;
private string? errorMessage;
protected override async Task OnInitializedAsync()
{
await LoadUnitsAsync();
}
private async Task LoadUnitsAsync()
{
isLoading = true;
errorMessage = null;
try
{
var units = await UnitsApiClient.GetUnitsAsync();
gearNotes = units.ToList();
}
catch (Exception ex)
{
errorMessage = $"Failed to load units: {ex.Message}";
}
finally
{
isLoading = false;
}
}
}
@@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using ZeroSpace.Web;
using ZeroSpace.Web.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddHttpClient<IUnitsApiClient, UnitsApiClient>(client =>
{
var apiBaseUrl = builder.Configuration["services:apiservice:https:0"]
?? builder.Configuration["services:apiservice:http:0"]
?? builder.Configuration["ApiServiceUrl"]
?? builder.HostEnvironment.BaseAddress;
if (!apiBaseUrl.EndsWith('/'))
{
apiBaseUrl += "/";
}
client.BaseAddress = new Uri(apiBaseUrl);
});
builder.Services.AddTelerikBlazor();
await builder.Build().RunAsync();
@@ -0,0 +1,25 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "http://localhost:5114",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7205;http://localhost:5114",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,11 @@
using ZeroSpace.Model;
namespace ZeroSpace.Web.Services;
public interface IUnitsApiClient
{
Task<IReadOnlyList<UnitData>> GetUnitsAsync(string? faction = null, int? tier = null, CancellationToken cancellationToken = default);
Task<UnitData?> GetUnitByIdAsync(string id, CancellationToken cancellationToken = default);
Task<UnitData?> CreateUnitAsync(UnitData unit, CancellationToken cancellationToken = default);
Task<bool> DeleteUnitAsync(string id, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,278 @@
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
using ZeroSpace.Model;
namespace ZeroSpace.Web.Services;
public class UnitsApiClient : IUnitsApiClient
{
private readonly HttpClient _httpClient;
private readonly ILogger<UnitsApiClient> _logger;
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
};
private const string AllUnitFields = @"
id
name
hexite
flux
supply
productionTime
health
energy
shields
armorRating
movementSpeed
damagePerSecond
attackRange
attributes
tier
faction
hotkey
buildAtSameTime
limit";
public UnitsApiClient(HttpClient httpClient, ILogger<UnitsApiClient> logger)
{
_httpClient = httpClient;
_logger = logger;
}
public async Task<IReadOnlyList<UnitData>> GetUnitsAsync(string? faction = null, int? tier = null, CancellationToken cancellationToken = default)
{
try
{
Dictionary<string, object?>? whereFilter = null;
if (!string.IsNullOrWhiteSpace(faction) || tier.HasValue)
{
whereFilter = new Dictionary<string, object?>();
if (!string.IsNullOrWhiteSpace(faction))
{
whereFilter["faction"] = new Dictionary<string, object?> { ["eq"] = faction };
}
if (tier.HasValue)
{
whereFilter["tier"] = new Dictionary<string, object?> { ["eq"] = tier.Value };
}
}
var query = $@"
query GetUnits($where: UnitDataFilterInput) {{
units(where: $where) {{
{AllUnitFields}
}}
}}";
var requestBody = new
{
query,
variables = new
{
where = whereFilter
}
};
var response = await _httpClient.PostAsJsonAsync("graphql", requestBody, cancellationToken);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<GraphQLResponse<UnitsQueryResult>>(JsonOptions, cancellationToken);
if (result?.Data?.Units is not null && result.Data.Units.Count > 0)
{
return result.Data.Units;
}
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to load units via GraphQL API service. Falling back to static units list.");
}
// Fallback to static model data if GraphQL call fails
var fallback = Units.All.AsEnumerable();
if (!string.IsNullOrWhiteSpace(faction))
{
fallback = fallback.Where(u => u.Faction.Equals(faction, StringComparison.OrdinalIgnoreCase));
}
if (tier.HasValue)
{
fallback = fallback.Where(u => u.Tier == tier.Value);
}
return fallback.ToList();
}
public async Task<UnitData?> GetUnitByIdAsync(string id, CancellationToken cancellationToken = default)
{
try
{
var query = $@"
query GetUnitById($id: String!) {{
unitById(id: $id) {{
{AllUnitFields}
}}
}}";
var requestBody = new
{
query,
variables = new
{
id
}
};
var response = await _httpClient.PostAsJsonAsync("graphql", requestBody, cancellationToken);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<GraphQLResponse<UnitByIdQueryResult>>(JsonOptions, cancellationToken);
if (result?.Data?.UnitById is not null)
{
return result.Data.UnitById;
}
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to get unit '{Id}' via GraphQL API.", id);
}
return Units.All.FirstOrDefault(u => u.Id == id);
}
public async Task<UnitData?> CreateUnitAsync(UnitData unit, CancellationToken cancellationToken = default)
{
try
{
var mutation = $@"
mutation CreateUnit($input: CreateUnitInput!) {{
createUnit(input: $input) {{
{AllUnitFields}
}}
}}";
var input = new
{
id = unit.Id,
name = unit.Name,
hexite = unit.Hexite,
flux = unit.Flux,
supply = unit.Supply,
productionTime = unit.ProductionTime,
health = unit.Health,
energy = unit.Energy,
shields = unit.Shields,
armorRating = unit.ArmorRating,
movementSpeed = unit.MovementSpeed,
damagePerSecond = unit.DamagePerSecond,
attackRange = unit.AttackRange,
attributes = unit.Attributes,
tier = unit.Tier,
faction = unit.Faction,
hotkey = unit.Hotkey,
buildAtSameTime = unit.BuildAtSameTime,
limit = unit.Limit
};
var requestBody = new
{
query = mutation,
variables = new
{
input
}
};
var response = await _httpClient.PostAsJsonAsync("graphql", requestBody, cancellationToken);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<GraphQLResponse<CreateUnitMutationResult>>(JsonOptions, cancellationToken);
return result?.Data?.CreateUnit;
}
_logger.LogError("Failed to create unit via GraphQL. Status: {StatusCode}", response.StatusCode);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating unit via GraphQL.");
}
return null;
}
public async Task<bool> DeleteUnitAsync(string id, CancellationToken cancellationToken = default)
{
try
{
var mutation = @"
mutation DeleteUnit($id: String!) {
deleteUnit(id: $id)
}";
var requestBody = new
{
query = mutation,
variables = new
{
id
}
};
var response = await _httpClient.PostAsJsonAsync("graphql", requestBody, cancellationToken);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<GraphQLResponse<DeleteUnitMutationResult>>(JsonOptions, cancellationToken);
return result?.Data?.DeleteUnit ?? false;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting unit '{Id}' via GraphQL.", id);
}
return false;
}
private sealed class GraphQLResponse<T>
{
[JsonPropertyName("data")]
public T? Data { get; set; }
[JsonPropertyName("errors")]
public List<GraphQLErrorItem>? Errors { get; set; }
}
private sealed class GraphQLErrorItem
{
[JsonPropertyName("message")]
public string Message { get; set; } = string.Empty;
}
private sealed class UnitsQueryResult
{
[JsonPropertyName("units")]
public List<UnitData>? Units { get; set; }
}
private sealed class UnitByIdQueryResult
{
[JsonPropertyName("unitById")]
public UnitData? UnitById { get; set; }
}
private sealed class CreateUnitMutationResult
{
[JsonPropertyName("createUnit")]
public UnitData? CreateUnit { get; set; }
}
private sealed class DeleteUnitMutationResult
{
[JsonPropertyName("deleteUnit")]
public bool DeleteUnit { get; set; }
}
}
@@ -0,0 +1,45 @@
using System.Text.RegularExpressions;
using ZeroSpace.Model;
namespace ZeroSpace.Web.Services;
public static partial class ZeroSpaceLinks
{
private static readonly IReadOnlyDictionary<string, string> SystemUrls = StarSystems.All
.ToDictionary(static system => system.Name, static system => $"/StarSystem/{system.Id}", StringComparer.OrdinalIgnoreCase);
private static readonly IReadOnlyDictionary<string, string> MasteryUrls = SystemMasteries.All
.ToDictionary(static mastery => mastery.Name, static mastery => $"/SystemMastery/{mastery.Id}", StringComparer.OrdinalIgnoreCase);
public static string? UrlFor(string name)
{
if (SystemUrls.TryGetValue(name, out var systemUrl))
{
return systemUrl;
}
return MasteryUrls.TryGetValue(name, out var masteryUrl) ? masteryUrl : null;
}
public static string ResolveWikiLinks(string markdown)
{
return WikiLinkPattern().Replace(markdown, match =>
{
var name = match.Groups[1].Value.Trim();
var url = UrlFor(name);
return url is null ? name : $"[{name}]({url})";
});
}
public static string Humanize(string camelCase)
{
var spaced = CamelCasePattern().Replace(camelCase, " ");
return spaced.Length == 0 ? spaced : char.ToUpperInvariant(spaced[0]) + spaced[1..];
}
[GeneratedRegex(@"\[\[([^\]]+)\]\]")]
private static partial Regex WikiLinkPattern();
[GeneratedRegex("(?<=[a-z0-9])(?=[A-Z])")]
private static partial Regex CamelCasePattern();
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.9" PrivateAssets="all"/>
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.12" />
<PackageReference Include="Markdig" Version="1.4.0" />
<PackageReference Include="Telerik.UI.for.Blazor" Version="14.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ZeroSpace.Model\ZeroSpace.Model.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,13 @@
@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 Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using ZeroSpace.Web
@using ZeroSpace.Web.Layout
@using ZeroSpace.Web.Components
@using ZeroSpace.Web.Services
@using ZeroSpace.Model
@@ -0,0 +1,27 @@
events { }
http {
include mime.types;
types {
application/wasm wasm;
}
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(?:ico|css|js|gif|jpe?g|png|wasm|woff2?|eot|ttf|svg)$ {
root /usr/share/nginx/html;
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
}
}
@@ -0,0 +1,3 @@
{
"ApiServiceUrl": "https://localhost:7142"
}
@@ -0,0 +1,3 @@
{
"ApiServiceUrl": "https://localhost:7142"
}
@@ -0,0 +1,125 @@
html, body {
font-family: 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif;
background-color: #0d1117;
color: #c9d1d9;
}
h1:focus {
outline: none;
}
h1, h2, h3, h4, h5, h6 {
color: #e6edf3;
}
a, .btn-link {
color: #58a6ff;
}
p {
color: #8b949e;
}
.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;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid red;
}
.validation-message {
color: red;
}
#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;
}
.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."
}
.loading-progress {
position: absolute;
display: block;
width: 8rem;
height: 8rem;
inset: 20vh 0 auto 0;
margin: 0 auto 0 auto;
}
.loading-progress circle {
fill: none;
stroke: #e0e0e0;
stroke-width: 0.6rem;
transform-origin: 50% 50%;
transform: rotate(-90deg);
}
.loading-progress circle:last-child {
stroke: #1b6ec2;
stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
transition: stroke-dasharray 0.05s ease-in-out;
}
.loading-progress-text {
position: absolute;
text-align: center;
font-weight: bold;
inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}
.loading-progress-text:after {
content: var(--blazor-load-percentage-text, "Loading");
}
code {
color: #c02d76;
}
.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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web</title>
<base href="/" />
<link rel="preload" id="webassembly" />
<link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/app.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<link href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" rel="stylesheet"/>
<link href="ZeroSpace.Web.styles.css" rel="stylesheet" />
<script type="importmap"></script>
</head>
<body>
<div id="app">
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
<circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>
<script defer src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"></script>
<script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
</body>
</html>
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 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 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 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 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 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 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,27 @@
[
{
"date": "2022-01-06",
"temperatureC": 1,
"summary": "Freezing"
},
{
"date": "2022-01-07",
"temperatureC": 14,
"summary": "Bracing"
},
{
"date": "2022-01-08",
"temperatureC": -13,
"summary": "Freezing"
},
{
"date": "2022-01-09",
"temperatureC": -16,
"summary": "Balmy"
},
{
"date": "2022-01-10",
"temperatureC": -2,
"summary": "Chilly"
}
]
@@ -0,0 +1,110 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Telerik UI for Blazor Upgrade Wizard Log</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
top: 0;
left: 0;
width: 100%;
background-color: #fff;
font: normal 12px Arial, sans-serif;
line-height: 1.5;
}
#header {
display: block;
margin: 0;
padding: 20px;
height: 60px;
min-width: 600px;
background: url('file:///c:/users/jonmc/appdata/local/microsoft/visualstudio/18.0_5c8aff0c/extensions/x3krtzi4.coo/Resources/T4Templates/UpgradeLog/Logo.png') no-repeat right 30px top 30px;
background-color: #0e0e0e;
color: #909090;
font: normal 10px Arial, sans-serif;
}
#header span {
display: block;
color: #fff;
font: normal 22px Arial, sans-serif;
}
#legend {
display: block;
height: 20px;
margin: 0;
padding: 0;
background-color: #0e0e0e;
font: normal 12px Arial, sans-serif;
}
#legend span {
display: block;
float: left;
height: 18px;
margin: 0;
padding: 2px 10px 0 10px;
background-color: #8e8e8e;
font: normal 12px Arial, sans-serif;
}
table#logTable {
border: 1px solid #999;
border-collapse: collapse;
}
table#logTable th, table#logTable td {
border: 1px solid #999;
padding: 5px 10px;
text-align: left;
}
table#logTable th {
border: 0;
padding: 5px 10px;
background-color: #8e8e8e;
height: 20px;
font: bold 14px Arial, sans-serif;
color: #fff;
}
</style>
</head>
<body>
<div>
<table id="logTable" cellpadding="0px" cellspacing="0px">
<tbody>
<tr>
<td colspan="5" style="padding: 0;">
<div id="header">
Telerik UI for Blazor <span>Upgrade Wizard Log</span>
</div>
<div id="legend">
<span style="background-color: #0e0e0e; color: #fff;">Processed: 1</span>
<span style="background-color: green; color: #fff;">Succeeded: 1</span>
<span style="background-color: blue; color: #fff;">Info: 0</span>
<span style="background-color: gold; color: #fff;">Warnings: 0</span>
<span style="background-color: red; color: #fff;">Failed: 0</span>
</div>
</td>
</tr>
<tr>
<th>&nbsp;</th>
<th>Project</th>
<th>Title</th>
<th>Details</th>
<th>Result</th>
</tr>
<tr>
<tr>
<td><img alt="Success" src="file:///c:/users/jonmc/appdata/local/microsoft/visualstudio/18.0_5c8aff0c/extensions/x3krtzi4.coo/Resources/T4Templates/UpgradeLog/Success.gif" /></td>
<td>ZeroSpace.Web</td>
<td>Backup</td>
<td>Create backup C:\Users\jonmc\ZeroSpace\ZeroSpace\ZeroSpace.Web_Backup_2026.09.28_11.24.30.</td>
<td>Success</td>
</tr>
</tr>
</tbody>
</table>
</div>
</body>
</html>
+2 -2
View File
@@ -11,6 +11,6 @@ connectedSystems:
- "[[Xenon Abyss]]"
- "[[Inferno's Edge Stronghold]]"
- "[[Tartarus Expanse]]"
x: 230.0
y: 140.6
x: 813.8
y: 93.6
---
+2 -2
View File
@@ -8,6 +8,6 @@ connectedSystems:
- "[[Void Star]]"
- "[[Inferno's Edge Stronghold]]"
- "[[Shattered Light]]"
x: 623.3
y: 58.5
x: 663.3
y: 0.0
---