Compare commits

...

1 Commits

Author SHA1 Message Date
67c72284d5 dev: rubbish 2025-01-16 17:30:34 +08:00
63 changed files with 1179 additions and 323 deletions

3
.gitignore vendored
View File

@ -482,3 +482,6 @@ $RECYCLE.BIN/
# Vim temporary swap files # Vim temporary swap files
*.swp *.swp
# Tailwind auto-generated stylesheet
output.css

View File

@ -1,8 +0,0 @@
@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

View File

@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AngleSharp" Version="1.1.0" />
<PackageReference Include="Markdig" Version="0.38.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="YamlDotNet" Version="16.2.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
</Project>

View File

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YaeBlog.Core", "YaeBlog.Core\YaeBlog.Core.csproj", "{1671A8AE-78F6-4641-B97D-D8ABA5E9CBEF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YaeBlog", "YaeBlog\YaeBlog.csproj", "{20438EFD-8DDE-43AF-92E2-76495C29233C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YaeBlog", "YaeBlog\YaeBlog.csproj", "{20438EFD-8DDE-43AF-92E2-76495C29233C}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".gitea", ".gitea", "{9B5AAA29-37D8-454A-8D8F-3E6B6BCF38E6}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".gitea", ".gitea", "{9B5AAA29-37D8-454A-8D8F-3E6B6BCF38E6}"
@ -29,10 +27,6 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1671A8AE-78F6-4641-B97D-D8ABA5E9CBEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1671A8AE-78F6-4641-B97D-D8ABA5E9CBEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1671A8AE-78F6-4641-B97D-D8ABA5E9CBEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1671A8AE-78F6-4641-B97D-D8ABA5E9CBEF}.Release|Any CPU.Build.0 = Release|Any CPU
{20438EFD-8DDE-43AF-92E2-76495C29233C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {20438EFD-8DDE-43AF-92E2-76495C29233C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20438EFD-8DDE-43AF-92E2-76495C29233C}.Debug|Any CPU.Build.0 = Debug|Any CPU {20438EFD-8DDE-43AF-92E2-76495C29233C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20438EFD-8DDE-43AF-92E2-76495C29233C}.Release|Any CPU.ActiveCfg = Release|Any CPU {20438EFD-8DDE-43AF-92E2-76495C29233C}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@ -1,7 +1,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Abstractions; namespace YaeBlog.Abstraction;
public interface IEssayContentService public interface IEssayContentService
{ {

View File

@ -1,6 +1,6 @@
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Abstractions; namespace YaeBlog.Abstraction;
public interface IEssayScanService public interface IEssayScanService
{ {

View File

@ -1,6 +1,6 @@
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Abstractions; namespace YaeBlog.Abstraction;
public interface IPostRenderProcessor public interface IPostRenderProcessor
{ {

View File

@ -1,6 +1,6 @@
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Abstractions; namespace YaeBlog.Abstraction;
public interface IPreRenderProcessor public interface IPreRenderProcessor
{ {

View File

@ -1,7 +1,7 @@
using System.CommandLine.Binding; using System.CommandLine.Binding;
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Commands.Binders; namespace YaeBlog.Commands.Binders;

View File

@ -1,8 +1,8 @@
using System.CommandLine.Binding; using System.CommandLine.Binding;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Models; using YaeBlog.Models;
using YaeBlog.Core.Services; using YaeBlog.Services;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;

View File

@ -1,15 +1,32 @@
using System.CommandLine; using System.CommandLine;
using YaeBlog.Commands.Binders; using YaeBlog.Commands.Binders;
using YaeBlog.Components; using YaeBlog.Components;
using YaeBlog.Core.Extensions; using YaeBlog.Extensions;
using YaeBlog.Core.Models; using YaeBlog.Models;
using YaeBlog.Core.Services; using YaeBlog.Services;
namespace YaeBlog.Commands; namespace YaeBlog.Commands;
public static class CommandExtensions public sealed class YaeBlogCommand
{ {
public static void AddServeCommand(this RootCommand rootCommand) private readonly RootCommand _rootCommand = new("YaeBlog Cli");
public YaeBlogCommand()
{
AddServeCommand(_rootCommand);
AddWatchCommand(_rootCommand);
AddListCommand(_rootCommand);
AddNewCommand(_rootCommand);
AddPublishCommand(_rootCommand);
AddScanCommand(_rootCommand);
}
public Task<int> RunAsync(string[] args)
{
return _rootCommand.InvokeAsync(args);
}
private static void AddServeCommand(RootCommand rootCommand)
{ {
Command serveCommand = new("serve", "Start http server."); Command serveCommand = new("serve", "Start http server.");
rootCommand.AddCommand(serveCommand); rootCommand.AddCommand(serveCommand);
@ -21,7 +38,6 @@ public static class CommandExtensions
builder.Services.AddRazorComponents() builder.Services.AddRazorComponents()
.AddInteractiveServerComponents(); .AddInteractiveServerComponents();
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddBlazorBootstrap();
builder.AddYaeBlog(); builder.AddYaeBlog();
builder.AddServer(); builder.AddServer();
@ -40,7 +56,7 @@ public static class CommandExtensions
}); });
} }
public static void AddWatchCommand(this RootCommand rootCommand) private static void AddWatchCommand(RootCommand rootCommand)
{ {
Command command = new("watch", "Start a blog watcher that re-render when file changes."); Command command = new("watch", "Start a blog watcher that re-render when file changes.");
rootCommand.AddCommand(command); rootCommand.AddCommand(command);
@ -52,9 +68,9 @@ public static class CommandExtensions
builder.Services.AddRazorComponents() builder.Services.AddRazorComponents()
.AddInteractiveServerComponents(); .AddInteractiveServerComponents();
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddBlazorBootstrap();
builder.AddYaeBlog(); builder.AddYaeBlog();
builder.AddWatcher(); builder.AddWatcher();
builder.AddTailwindWatcher();
WebApplication application = builder.Build(); WebApplication application = builder.Build();
@ -71,7 +87,7 @@ public static class CommandExtensions
}); });
} }
public static void AddNewCommand(this RootCommand rootCommand) private static void AddNewCommand(RootCommand rootCommand)
{ {
Command newCommand = new("new", "Create a new blog file and image directory."); Command newCommand = new("new", "Create a new blog file and image directory.");
rootCommand.AddCommand(newCommand); rootCommand.AddCommand(newCommand);
@ -101,7 +117,7 @@ public static class CommandExtensions
new EssayScanServiceBinder()); new EssayScanServiceBinder());
} }
public static void AddListCommand(this RootCommand rootCommand) private static void AddListCommand(RootCommand rootCommand)
{ {
Command command = new("list", "List all blogs"); Command command = new("list", "List all blogs");
rootCommand.AddCommand(command); rootCommand.AddCommand(command);
@ -124,7 +140,7 @@ public static class CommandExtensions
}, new BlogOptionsBinder(), new LoggerBinder<EssayScanService>(), new EssayScanServiceBinder()); }, new BlogOptionsBinder(), new LoggerBinder<EssayScanService>(), new EssayScanServiceBinder());
} }
public static void AddScanCommand(this RootCommand rootCommand) private static void AddScanCommand(RootCommand rootCommand)
{ {
Command command = new("scan", "Scan unused and not found images."); Command command = new("scan", "Scan unused and not found images.");
rootCommand.AddCommand(command); rootCommand.AddCommand(command);
@ -165,7 +181,7 @@ public static class CommandExtensions
}, new BlogOptionsBinder(), new LoggerBinder<EssayScanService>(), new EssayScanServiceBinder(), removeOption); }, new BlogOptionsBinder(), new LoggerBinder<EssayScanService>(), new EssayScanServiceBinder(), removeOption);
} }
public static void AddPublishCommand(this RootCommand rootCommand) private static void AddPublishCommand(RootCommand rootCommand)
{ {
Command command = new("publish", "Publish a new blog file."); Command command = new("publish", "Publish a new blog file.");
rootCommand.AddCommand(command); rootCommand.AddCommand(command);

View File

@ -7,10 +7,8 @@
<base href="/"/> <base href="/"/>
<link rel="stylesheet" href="YaeBlog.styles.css"/> <link rel="stylesheet" href="YaeBlog.styles.css"/>
<link rel="icon" href="images/favicon.ico"/> <link rel="icon" href="images/favicon.ico"/>
<link rel="stylesheet" href="bootstrap.min.css"/>
<link rel="stylesheet" href="bootstrap-icons.min.css"/>
<link rel="stylesheet" href="_content/Blazor.Bootstrap/blazor.bootstrap.css"/>
<link rel="stylesheet" href="globals.css"/> <link rel="stylesheet" href="globals.css"/>
<link rel="stylesheet" href="output.css"/>
<HeadOutlet/> <HeadOutlet/>
</head> </head>
@ -18,7 +16,6 @@
<Routes/> <Routes/>
<script src="_framework/blazor.web.js"></script> <script src="_framework/blazor.web.js"></script>
<script src="bootstrap.bundle.min.js"></script>
<script src="clipboard.min.js"></script> <script src="clipboard.min.js"></script>
<script> <script>
const clipboard = new ClipboardJS('.btn'); const clipboard = new ClipboardJS('.btn');

View File

@ -1,5 +1,5 @@
@using YaeBlog.Core.Abstractions @using YaeBlog.Abstraction
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject IEssayContentService Contents @inject IEssayContentService Contents
@inject BlogOptions Options @inject BlogOptions Options
@ -7,7 +7,7 @@
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-auto p-4"> <div class="col-auto p-4">
<Image Src="images/avatar.png" Alt="Ricardo's avatar"/> @* <Image Src="images/avatar.png" Alt="Ricardo's avatar"/> *@
</div> </div>
</div> </div>

View File

@ -1,5 +1,5 @@
@using System.Text.Encodings.Web @using System.Text.Encodings.Web
@using YaeBlog.Core.Models @using YaeBlog.Models
<div class="container p-3"> <div class="container p-3">
<div class="row fs-2 fw-bold py-2 essay-title"> <div class="row fs-2 fw-bold py-2 essay-title">

View File

@ -1,5 +1,4 @@
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject BlogOptions Options @inject BlogOptions Options
<div class="row px-2 py-4 copyright border border-primary rounded-1 bg-primary-subtle"> <div class="row px-2 py-4 copyright border border-primary rounded-1 bg-primary-subtle">

View File

@ -0,0 +1,12 @@
namespace YaeBlog.Core.Exceptions;
public sealed class ProcessInteropException : Exception
{
public ProcessInteropException(string message) : base(message)
{
}
public ProcessInteropException(string message, Exception innerException) : base(message, innerException)
{
}
}

View File

@ -1,9 +1,8 @@
using Markdig; using Markdig;
using Microsoft.Extensions.DependencyInjection;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
namespace YaeBlog.Core.Extensions; namespace YaeBlog.Extensions;
public static class ServiceCollectionExtensions public static class ServiceCollectionExtensions
{ {

View File

@ -1,13 +1,11 @@
using AngleSharp; using AngleSharp;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Models; using YaeBlog.Services;
using YaeBlog.Core.Processors; using YaeBlog.Models;
using YaeBlog.Core.Services; using YaeBlog.Processors;
namespace YaeBlog.Core.Extensions; namespace YaeBlog.Extensions;
public static class WebApplicationBuilderExtensions public static class WebApplicationBuilderExtensions
{ {
@ -19,7 +17,7 @@ public static class WebApplicationBuilderExtensions
builder.Services.AddMarkdig(); builder.Services.AddMarkdig();
builder.Services.AddYamlParser(); builder.Services.AddYamlParser();
builder.Services.AddSingleton<IConfiguration>(_ => Configuration.Default); builder.Services.AddSingleton<AngleSharp.IConfiguration>(_ => Configuration.Default);
builder.Services.AddSingleton<IEssayScanService, EssayScanService>(); builder.Services.AddSingleton<IEssayScanService, EssayScanService>();
builder.Services.AddSingleton<RendererService>(); builder.Services.AddSingleton<RendererService>();
builder.Services.AddSingleton<IEssayContentService, EssayContentService>(); builder.Services.AddSingleton<IEssayContentService, EssayContentService>();
@ -47,4 +45,13 @@ public static class WebApplicationBuilderExtensions
return builder; return builder;
} }
public static WebApplicationBuilder AddTailwindWatcher(this WebApplicationBuilder builder)
{
builder.Services.AddSingleton<ProcessInteropService>();
builder.Services.Configure<TailwindOptions>(builder.Configuration.GetSection(TailwindOptions.OptionName));
builder.Services.AddHostedService<TailwindRefreshService>();
return builder;
}
} }

View File

@ -1,10 +1,8 @@
using Microsoft.AspNetCore.Builder; using YaeBlog.Abstraction;
using Microsoft.Extensions.DependencyInjection; using YaeBlog.Processors;
using YaeBlog.Core.Abstractions; using YaeBlog.Services;
using YaeBlog.Core.Processors;
using YaeBlog.Core.Services;
namespace YaeBlog.Core.Extensions; namespace YaeBlog.Extensions;
public static class WebApplicationExtensions public static class WebApplicationExtensions
{ {

View File

@ -2,60 +2,41 @@
@attribute [StreamRendering] @attribute [StreamRendering]
<main class="container"> <main class="container mx-auto">
<div class="row d-none d-xl-flex" style="height: 80px"> <div class="grid grid-cols-3 mx-3">
<div class="px-2 col-9"> <div class="md:col-span-2 col-span-3 my-6">
<a href="/blog/" class="p-2"> <a href="/blog/">
<h4>Ricardo's Blog</h4> <span class="text-blue-600 text-2xl">Ricardo's Blog</span>
</a> </a>
</div> </div>
<div class="col-3 d-flex justify-content-around align-items-center"> <div class="md:col-span-1 col-span-3 my-6">
<a href="/blog/" class="p-2"> <div class="flex flex-row">
<h5>首页</h5> <div class="px-2 ">
</a> <a href="/blog/">
<span class="text-xl text-blue-600">首页</span>
<a href="/blog/archives/" class="p-2"> </a>
<h5>归档</h5> </div>
</a> <div class="px-2 ">
<a href="/blog/archives/">
<a href="/blog/tags/" class="p-2"> <span class="text-xl text-blue-600">归档</span>
<h5>标签</h5> </a>
</a> </div>
<div class="px-2 ">
<a href="/blog/about/" class="p-2"> <a href="/blog/tags/">
<h5>关于</h5> <span class="text-xl text-blue-600">标签</span>
</a> </a>
</div>
<div class="px-2 ">
<a href="/blog/about/">
<span class="text-xl text-blue-600">关于</span>
</a>
</div>
</div>
</div> </div>
</div> </div>
<div class="row d-xl-none"> <div class="px-4 py-2">
<div class="px-2 col-12">
<a href="/blog/" class="p-2">
<h4>Ricardo's Blog</h4>
</a>
</div>
<div class="px-2 col-12 justify-content-end d-flex">
<a href="/blog/" class="p-2">
<h5>首页</h5>
</a>
<a href="/blog/archives/" class="p-2">
<h5>归档</h5>
</a>
<a href="/blog/tags/" class="p-2">
<h5>标签</h5>
</a>
<a href="/blog/about/" class="p-2">
<h5>关于</h5>
</a>
</div>
</div>
<div class="row px-4 py-2">
@Body @Body
</div> </div>

View File

@ -1,21 +1,22 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
<main class="container"> <main class="container mx-auto">
<div class="row" style="height: 80px"> <div class="flex flex-row h-20">
<div class="px-2 col-8"> <div class="px-2 basis-3/4">
<a href="/" class="p-2"> <a href="/" class="text-2xl p-2">
<h4>Ricardo's Index</h4> <h4 class="text-blue-600">Ricardo's Index</h4>
</a> </a>
<h1></h1>
</div> </div>
<div class="col-4 d-flex justify-content-around align-items-center"> <div class="basis-1/4">
<a href="mailto://shicangjuner@outlook.com" class="p-2" target="_blank"> <a href="mailto://shicangjuner@outlook.com" class="p-2 text-xl" target="_blank">
<h5>E-mail</h5> <h5 class="text-blue-600">E-mail</h5>
</a> </a>
</div> </div>
</div> </div>
<div class="row px-4 center"> <div class="px-4 mx-auto">
<div class="py-2"> <div class="py-2">
@Body @Body
</div> </div>

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class AboutInfo public class AboutInfo
{ {

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class BlogContent public class BlogContent
{ {

View File

@ -1,6 +1,6 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public sealed class BlogContents(ConcurrentBag<BlogContent> drafts, ConcurrentBag<BlogContent> posts) public sealed class BlogContents(ConcurrentBag<BlogContent> drafts, ConcurrentBag<BlogContent> posts)
{ {

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class BlogEssay : IComparable<BlogEssay> public class BlogEssay : IComparable<BlogEssay>
{ {

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class BlogHeadline(string title, string selectorId) public class BlogHeadline(string title, string selectorId)
{ {

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class BlogOptions public class BlogOptions
{ {

View File

@ -1,6 +1,6 @@
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class EssayTag(string tagName) : IEquatable<EssayTag> public class EssayTag(string tagName) : IEquatable<EssayTag>
{ {

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
/// <summary> /// <summary>
/// 友链模型类 /// 友链模型类

View File

@ -1,3 +1,3 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public record struct ImageScanResult(List<FileInfo> UnusedImages, List<FileInfo> NotFoundImages); public record struct ImageScanResult(List<FileInfo> UnusedImages, List<FileInfo> NotFoundImages);

View File

@ -1,4 +1,4 @@
namespace YaeBlog.Core.Models; namespace YaeBlog.Models;
public class MarkdownMetadata public class MarkdownMetadata
{ {

View File

@ -0,0 +1,10 @@
namespace YaeBlog.Models;
public class TailwindOptions
{
public const string OptionName = "Tailwind";
public required string InputFile { get; set; }
public required string OutputFile { get; set; }
}

View File

@ -1,5 +1,5 @@
@page "/blog/about" @page "/blog/about"
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject BlogOptions Options @inject BlogOptions Options
@ -116,7 +116,7 @@
<a href="@(link.Link)" target="_blank" class="m-3"> <a href="@(link.Link)" target="_blank" class="m-3">
<div class="row link-item"> <div class="row link-item">
<div class="col-4"> <div class="col-4">
<Image Src="@(link.AvatarImage)" Alt="@(link.Name)" Style="border-radius: 50%"/> @* <Image Src="@(link.AvatarImage)" Alt="@(link.Name)" Style="border-radius: 50%"/> *@
</div> </div>
<div class="col-8"> <div class="col-8">

View File

@ -1,6 +1,6 @@
@page "/blog/archives" @page "/blog/archives"
@using YaeBlog.Core.Abstractions @using YaeBlog.Abstraction
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject IEssayContentService Contents @inject IEssayContentService Contents

View File

@ -1,6 +1,6 @@
@page "/blog" @page "/blog"
@using YaeBlog.Core.Abstractions @using YaeBlog.Abstraction
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject IEssayContentService Contents @inject IEssayContentService Contents
@inject NavigationManager NavigationInstance @inject NavigationManager NavigationInstance

View File

@ -1,7 +1,7 @@
@page "/blog/essays/{BlogKey}" @page "/blog/essays/{BlogKey}"
@using System.Text.Encodings.Web @using System.Text.Encodings.Web
@using YaeBlog.Core.Abstractions @using YaeBlog.Abstraction
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject IEssayContentService Contents @inject IEssayContentService Contents
@inject NavigationManager NavigationInstance @inject NavigationManager NavigationInstance

View File

@ -7,7 +7,7 @@
<div class="container"> <div class="container">
<div class="row py-4"> <div class="row py-4">
<div class="col-lg-4 col-12 p-5 p-lg-0"> <div class="col-lg-4 col-12 p-5 p-lg-0">
<Image Src="images/avatar.png" Alt="Ricardo's Avatar"/> @* <Image Src="images/avatar.png" Alt="Ricardo's Avatar"/> *@
</div> </div>
<div class="col-lg-8 col-12"> <div class="col-lg-8 col-12">

View File

@ -1,7 +1,7 @@
@page "/blog/tags/" @page "/blog/tags/"
@using System.Text.Encodings.Web @using System.Text.Encodings.Web
@using YaeBlog.Core.Abstractions @using YaeBlog.Abstraction
@using YaeBlog.Core.Models @using YaeBlog.Models
@inject IEssayContentService Contents @inject IEssayContentService Contents
@inject NavigationManager NavigationInstance @inject NavigationManager NavigationInstance

View File

@ -1,9 +1,9 @@
using AngleSharp; using AngleSharp;
using AngleSharp.Dom; using AngleSharp.Dom;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Processors; namespace YaeBlog.Processors;
public class CodeBlockPostRenderProcessor : IPostRenderProcessor public class CodeBlockPostRenderProcessor : IPostRenderProcessor
{ {

View File

@ -1,13 +1,12 @@
using AngleSharp; using AngleSharp;
using AngleSharp.Dom; using AngleSharp.Dom;
using Microsoft.Extensions.Logging; using YaeBlog.Abstraction;
using YaeBlog.Core.Abstractions; using YaeBlog.Models;
using YaeBlog.Core.Models;
namespace YaeBlog.Core.Processors; namespace YaeBlog.Processors;
public class HeadlinePostRenderProcessor( public class HeadlinePostRenderProcessor(
IConfiguration angleConfiguration, AngleSharp.IConfiguration angleConfiguration,
IEssayContentService essayContentService, IEssayContentService essayContentService,
ILogger<HeadlinePostRenderProcessor> logger) : IPostRenderProcessor ILogger<HeadlinePostRenderProcessor> logger) : IPostRenderProcessor
{ {

View File

@ -1,18 +1,17 @@
using AngleSharp; using AngleSharp;
using AngleSharp.Dom; using AngleSharp.Dom;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Exceptions; using YaeBlog.Core.Exceptions;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Processors; namespace YaeBlog.Processors;
public class ImagePostRenderProcessor(ILogger<ImagePostRenderProcessor> logger, public class ImagePostRenderProcessor(ILogger<ImagePostRenderProcessor> logger,
IOptions<BlogOptions> options) IOptions<BlogOptions> options)
: IPostRenderProcessor : IPostRenderProcessor
{ {
private static readonly IConfiguration s_configuration = Configuration.Default; private static readonly AngleSharp.IConfiguration s_configuration = Configuration.Default;
private readonly BlogOptions _options = options.Value; private readonly BlogOptions _options = options.Value;

View File

@ -1,10 +1,10 @@
using AngleSharp; using AngleSharp;
using AngleSharp.Dom; using AngleSharp.Dom;
using AngleSharp.Html.Dom; using AngleSharp.Html.Dom;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Processors; namespace YaeBlog.Processors;
public class TablePostRenderProcessor: IPostRenderProcessor public class TablePostRenderProcessor: IPostRenderProcessor
{ {

View File

@ -1,13 +1,4 @@
using System.CommandLine;
using YaeBlog.Commands; using YaeBlog.Commands;
RootCommand rootCommand = new("YaeBlog CLI"); YaeBlogCommand command = new();
await command.RunAsync(args);
rootCommand.AddServeCommand();
rootCommand.AddNewCommand();
rootCommand.AddListCommand();
rootCommand.AddWatchCommand();
rootCommand.AddScanCommand();
rootCommand.AddPublishCommand();
await rootCommand.InvokeAsync(args);

View File

@ -1,8 +1,7 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options; using YaeBlog.Models;
using YaeBlog.Core.Models;
namespace YaeBlog.Core.Services; namespace YaeBlog.Services;
public sealed class BlogChangeWatcher : IDisposable public sealed class BlogChangeWatcher : IDisposable
{ {

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.Hosting; namespace YaeBlog.Services;
using Microsoft.Extensions.Logging;
namespace YaeBlog.Core.Services;
public class BlogHostedService( public class BlogHostedService(
ILogger<BlogHostedService> logger, ILogger<BlogHostedService> logger,

View File

@ -1,8 +1,6 @@
using Microsoft.Extensions.Hosting; using YaeBlog.Abstraction;
using Microsoft.Extensions.Logging;
using YaeBlog.Core.Abstractions;
namespace YaeBlog.Core.Services; namespace YaeBlog.Services;
public sealed class BlogHotReloadService( public sealed class BlogHotReloadService(
RendererService rendererService, RendererService rendererService,

View File

@ -1,9 +1,9 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Services; namespace YaeBlog.Services;
public class EssayContentService : IEssayContentService public class EssayContentService : IEssayContentService
{ {

View File

@ -1,14 +1,13 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using YaeBlog.Core.Abstractions; using YaeBlog.Abstraction;
using YaeBlog.Core.Exceptions; using YaeBlog.Core.Exceptions;
using YaeBlog.Core.Models; using YaeBlog.Models;
using YamlDotNet.Core; using YamlDotNet.Core;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
namespace YaeBlog.Core.Services; namespace YaeBlog.Services;
public partial class EssayScanService( public partial class EssayScanService(
ISerializer yamlSerializer, ISerializer yamlSerializer,

View File

@ -0,0 +1,65 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using YaeBlog.Core.Exceptions;
namespace YaeBlog.Services;
public class ProcessInteropService(ILogger<ProcessInteropService> logger)
{
public Process StartProcess(string command, string arguments)
{
string commandName;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !command.EndsWith(".exe"))
{
commandName = command + ".exe";
}
else
{
commandName = command;
}
try
{
ProcessStartInfo startInfo = new()
{
FileName = commandName,
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
Process? process = Process.Start(startInfo);
if (process is null)
{
throw new ProcessInteropException(
$"Failed to start process: {commandName}, the return process is null.");
}
process.OutputDataReceived += (_, data) =>
{
if (!string.IsNullOrEmpty(data.Data))
{
logger.LogInformation("Receive output from process '{}': '{}'", commandName, data.Data);
}
};
process.ErrorDataReceived += (_, data) =>
{
if (!string.IsNullOrEmpty(data.Data))
{
logger.LogWarning("Receive error from process '{}': '{}'", commandName, data.Data);
}
};
return process;
}
catch (Exception innerException)
{
throw new ProcessInteropException($"Failed to start process '{command}' with arguments '{arguments}",
innerException);
}
}
}

View File

@ -3,12 +3,11 @@ using System.Diagnostics;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Markdig; using Markdig;
using Microsoft.Extensions.Logging; using YaeBlog.Abstraction;
using YaeBlog.Core.Abstractions;
using YaeBlog.Core.Exceptions; using YaeBlog.Core.Exceptions;
using YaeBlog.Core.Models; using YaeBlog.Models;
namespace YaeBlog.Core.Services; namespace YaeBlog.Services;
public partial class RendererService( public partial class RendererService(
ILogger<RendererService> logger, ILogger<RendererService> logger,

View File

@ -0,0 +1,46 @@
using System.Diagnostics;
using Microsoft.Extensions.Options;
using YaeBlog.Models;
namespace YaeBlog.Services;
/// <summary>
/// 在应用程序运行的过程中启动Tailwind watch
/// 在程序退出时自动结束进程
/// 只在Development模式下启动
/// </summary>
public sealed class TailwindRefreshService(
IOptions<TailwindOptions> options,
ProcessInteropService processInteropService,
IHostEnvironment hostEnvironment,
ILogger<TailwindRefreshService> logger) : IHostedService, IDisposable
{
private Process? _tailwindProcess;
public Task StartAsync(CancellationToken cancellationToken)
{
if (!hostEnvironment.IsDevelopment())
{
return Task.CompletedTask;
}
logger.LogInformation("Try to start tailwind watcher with input {} and output {}", options.Value.InputFile,
options.Value.OutputFile);
_tailwindProcess = processInteropService.StartProcess("pnpm",
$"tailwind -i {options.Value.InputFile} -o {options.Value.OutputFile} --watch");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_tailwindProcess?.Kill();
return Task.CompletedTask;
}
public void Dispose()
{
_tailwindProcess?.Dispose();
}
}

View File

@ -1,18 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\YaeBlog.Core\YaeBlog.Core.csproj" /> <PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
</ItemGroup> <PackageReference Include="AngleSharp" Version="1.1.0"/>
<PackageReference Include="Markdig" Version="0.38.0"/>
<PackageReference Include="YamlDotNet" Version="16.2.1"/>
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazor.Bootstrap" Version="3.2.0" /> <Watch Remove="**\*.razor~"/>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" /> </ItemGroup>
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<Target Name="PnpmInstall">
<Exec Command="pnpm install"/>
</Target>
<Target Name="TailwindGenerate" DependsOnTargets="PnpmInstall" BeforeTargets="BeforeBuild">
<Exec Command="pnpm tailwind -i wwwroot/input.css -o wwwroot/output.css"/>
</Target>
</Project> </Project>

View File

@ -6,6 +6,5 @@
@using static Microsoft.AspNetCore.Components.Web.RenderMode @using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using BlazorBootstrap
@using YaeBlog @using YaeBlog
@using YaeBlog.Components @using YaeBlog.Components

View File

@ -6,6 +6,10 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Tailwind": {
"InputFile": "wwwroot/input.css",
"OutputFile": "wwwroot/output.css"
},
"Blog": { "Blog": {
"Root": "source", "Root": "source",
"Announcement": "博客锐意装修中,敬请期待!测试阶段如有问题还请海涵。", "Announcement": "博客锐意装修中,敬请期待!测试阶段如有问题还请海涵。",

12
YaeBlog/package.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "YaeBlog",
"version": "1.0.0",
"description": "",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"tailwindcss": "^3.4.16"
}
}

836
YaeBlog/pnpm-lock.yaml Normal file
View File

@ -0,0 +1,836 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
tailwindcss:
specifier: ^3.4.16
version: 3.4.16
packages:
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
'@jridgewell/gen-mapping@0.3.8':
resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
engines: {node: '>=6.0.0'}
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
'@jridgewell/set-array@1.2.1':
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
'@nodelib/fs.stat@2.0.5':
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
'@nodelib/fs.walk@1.2.8':
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.1.0:
resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.1:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
camelcase-css@2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
hasBin: true
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
foreground-child@3.3.0:
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
engines: {node: '>=14'}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
glob@10.4.5:
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
hasBin: true
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-core-module@2.16.0:
resolution: {integrity: sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==}
engines: {node: '>= 0.4'}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
jiti@1.21.6:
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
hasBin: true
lilconfig@3.1.3:
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
engines: {node: '>=14'}
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
path-scurry@1.11.1:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
postcss-import@15.1.0:
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'}
peerDependencies:
postcss: ^8.0.0
postcss-js@4.0.1:
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.4.21
postcss-load-config@4.0.2:
resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
postcss-nested@6.2.0:
resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
postcss-selector-parser@6.1.2:
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
engines: {node: '>=4'}
postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
postcss@8.4.49:
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
engines: {node: ^10 || ^12 || >=14}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
resolve@1.22.9:
resolution: {integrity: sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==}
hasBin: true
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.1.0:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
sucrase@3.35.0:
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
tailwindcss@3.4.16:
resolution: {integrity: sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==}
engines: {node: '>=14.0.0'}
hasBin: true
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
yaml@2.6.1:
resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
engines: {node: '>= 14'}
hasBin: true
snapshots:
'@alloc/quick-lru@5.2.0': {}
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
strip-ansi: 7.1.0
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
'@jridgewell/gen-mapping@0.3.8':
dependencies:
'@jridgewell/set-array': 1.2.1
'@jridgewell/sourcemap-codec': 1.5.0
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/set-array@1.2.1': {}
'@jridgewell/sourcemap-codec@1.5.0': {}
'@jridgewell/trace-mapping@0.3.25':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
'@nodelib/fs.stat@2.0.5': {}
'@nodelib/fs.walk@1.2.8':
dependencies:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@pkgjs/parseargs@0.11.0':
optional: true
ansi-regex@5.0.1: {}
ansi-regex@6.1.0: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansi-styles@6.2.1: {}
any-promise@1.3.0: {}
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
arg@5.0.2: {}
balanced-match@1.0.2: {}
binary-extensions@2.3.0: {}
brace-expansion@2.0.1:
dependencies:
balanced-match: 1.0.2
braces@3.0.3:
dependencies:
fill-range: 7.1.1
camelcase-css@2.0.1: {}
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
commander@4.1.1: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
cssesc@3.0.0: {}
didyoumean@1.2.2: {}
dlv@1.1.3: {}
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
fast-glob@3.3.2:
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.8
fastq@1.17.1:
dependencies:
reusify: 1.0.4
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
foreground-child@3.3.0:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
glob-parent@6.0.2:
dependencies:
is-glob: 4.0.3
glob@10.4.5:
dependencies:
foreground-child: 3.3.0
jackspeak: 3.4.3
minimatch: 9.0.5
minipass: 7.1.2
package-json-from-dist: 1.0.1
path-scurry: 1.11.1
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-core-module@2.16.0:
dependencies:
hasown: 2.0.2
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
is-number@7.0.0: {}
isexe@2.0.0: {}
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
jiti@1.21.6: {}
lilconfig@3.1.3: {}
lines-and-columns@1.2.4: {}
lru-cache@10.4.3: {}
merge2@1.4.1: {}
micromatch@4.0.8:
dependencies:
braces: 3.0.3
picomatch: 2.3.1
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.1
minipass@7.1.2: {}
mz@2.7.0:
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
nanoid@3.3.8: {}
normalize-path@3.0.0: {}
object-assign@4.1.1: {}
object-hash@3.0.0: {}
package-json-from-dist@1.0.1: {}
path-key@3.1.1: {}
path-parse@1.0.7: {}
path-scurry@1.11.1:
dependencies:
lru-cache: 10.4.3
minipass: 7.1.2
picocolors@1.1.1: {}
picomatch@2.3.1: {}
pify@2.3.0: {}
pirates@4.0.6: {}
postcss-import@15.1.0(postcss@8.4.49):
dependencies:
postcss: 8.4.49
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.9
postcss-js@4.0.1(postcss@8.4.49):
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.49
postcss-load-config@4.0.2(postcss@8.4.49):
dependencies:
lilconfig: 3.1.3
yaml: 2.6.1
optionalDependencies:
postcss: 8.4.49
postcss-nested@6.2.0(postcss@8.4.49):
dependencies:
postcss: 8.4.49
postcss-selector-parser: 6.1.2
postcss-selector-parser@6.1.2:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
postcss-value-parser@4.2.0: {}
postcss@8.4.49:
dependencies:
nanoid: 3.3.8
picocolors: 1.1.1
source-map-js: 1.2.1
queue-microtask@1.2.3: {}
read-cache@1.0.0:
dependencies:
pify: 2.3.0
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
resolve@1.22.9:
dependencies:
is-core-module: 2.16.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
reusify@1.0.4: {}
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
shebang-regex@3.0.0: {}
signal-exit@4.1.0: {}
source-map-js@1.2.1: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string-width@5.1.2:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.1.0
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-ansi@7.1.0:
dependencies:
ansi-regex: 6.1.0
sucrase@3.35.0:
dependencies:
'@jridgewell/gen-mapping': 0.3.8
commander: 4.1.1
glob: 10.4.5
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.6
ts-interface-checker: 0.1.13
supports-preserve-symlinks-flag@1.0.0: {}
tailwindcss@3.4.16:
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
chokidar: 3.6.0
didyoumean: 1.2.2
dlv: 1.1.3
fast-glob: 3.3.2
glob-parent: 6.0.2
is-glob: 4.0.3
jiti: 1.21.6
lilconfig: 3.1.3
micromatch: 4.0.8
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.1.1
postcss: 8.4.49
postcss-import: 15.1.0(postcss@8.4.49)
postcss-js: 4.0.1(postcss@8.4.49)
postcss-load-config: 4.0.2(postcss@8.4.49)
postcss-nested: 6.2.0(postcss@8.4.49)
postcss-selector-parser: 6.1.2
resolve: 1.22.9
sucrase: 3.35.0
transitivePeerDependencies:
- ts-node
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1
thenify@3.3.1:
dependencies:
any-promise: 1.3.0
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
ts-interface-checker@0.1.13: {}
util-deprecate@1.0.2: {}
which@2.0.2:
dependencies:
isexe: 2.0.0
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@8.1.0:
dependencies:
ansi-styles: 6.2.1
string-width: 5.1.2
strip-ansi: 7.1.0
yaml@2.6.1: {}

View File

@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["**/*.razor", "**/*.cshtml", "**/*.html"],
theme: {
extend: {},
},
plugins: [],
}

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

View File

@ -13,78 +13,3 @@
font-display: block; font-display: block;
src: url(fonts/fa-solid-900.woff2) format("woff2"), url(fonts/fa-solid-900.ttf) format("truetype") src: url(fonts/fa-solid-900.woff2) format("woff2"), url(fonts/fa-solid-900.ttf) format("truetype")
} }
.essay-image {
width: 90%;
display: block;
margin: 1.5rem auto;
box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18),
0 4px 15px 0 rgba(0, 0, 0, 0.15);
border-radius: 4px;
background-color: transparent;
}
.table-wrapper {
overflow-x: auto;
}
body a {
text-decoration: none;
}
body main {
flex: 1;
min-height: 100vh;
overflow-x: visible;
}
body p {
margin: 0;
margin-block: 1em;
}
h2, h3 {
margin-block-start: 1.5em;
margin-block-end: 1em;
}
h4, h5 {
margin-block-start: 1em;
margin-block-end: 1em;
}
table {
margin: 0 auto;
border-collapse: collapse;
}
table td {
padding: 3px 20px;
border: 1px var(--bs-border-color) solid;
}
table thead {
background: var(--bs-secondary-bg);
}
table thead td {
font-weight: 700;
border: none;
}
table thead th {
padding: 3px 20px;
}
table thead tr {
border: 1px var(--bs-border-color) solid;
}
blockquote {
margin: 20px 0;
padding: 0 20px;
color: var(--bs-body-color);
background-color: var(--bs-primary-bg-subtle);
border-block-start: .1em solid var(--bs-primary-border-subtle);
border-block-end: .1em solid var(--bs-primary-border-subtle);
}

View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;