Compare commits

...

25 Commits

Author SHA1 Message Date
Phil Scott
223642b797 Add blog to docs (#484)
* Adding social card infrastructure
* Upgrades doc project to .NET 6
* Adds Playwright
* Changes the console to a web project for Playwright
* Adds social card template
* Added blog content
* Parallelized social image processing
* Updating CI to use .NET 6 for docs build
2021-07-15 19:53:01 +02:00
Nils Andresen
32d7ea15bd Change LogCommandSettings to CommandSettings in example
Instead of `LogCommandSettings` for the `Settings` of the `HelloCommand`
2021-07-15 09:39:25 +02:00
Patrik Svensson
fa5a1e88ec Clean up Widgets
* Move /Widgets/Live/* to /Live/*
* Move /Widgets/Prompt/* to /Prompts/*
* Move tests and expectations to match the new locations
2021-07-14 08:38:44 -04:00
Antonio Valentini
d532e1011f Add default value parameter to Confirm extension
Closes #482
2021-07-12 08:47:36 +02:00
Patrik Svensson
5f97f2300c Support cancellation of prompts
Closes #417
2021-07-11 23:10:17 -04:00
Patrik Svensson
884cb8ddd4 Install correct .NET Core SDK 2021-07-11 22:59:02 -04:00
Patrik Svensson
314e50b531 Move analyzer to own solution 2021-07-11 22:59:02 -04:00
Patrik Svensson
d9f06413d0 Remove examples from main solution 2021-07-11 22:59:02 -04:00
Patrik Svensson
6e2ca8449e Add solution for examples 2021-07-11 22:59:02 -04:00
Patrik Svensson
58eff30787 LineTreeGuide should not fall back to ASCII
If the user's environment didn't support unicode, we used
to fall back to using the AsciiTreeGuide if LineTreeGuide
was being used (which it is by default). This commit removes
that fallback since the characters used in LineTreeGuide is
covered by extended ASCII, which SHOULD be fine in almost all
scenarios.

Closes #324
2021-07-10 18:01:17 -04:00
Patrik Svensson
aa59f6cd55 Update .NET Core SDK to 5.0.301 2021-07-05 09:15:54 +02:00
Patrik Svensson
2011cb2eff Do not append suffix to text prompt
Do not append suffix to text prompt unless
there are choices or a default value specified.

Closes #413
2021-07-05 09:15:54 +02:00
Patrik Svensson
865552c3f2 Add support for selecting prompt items
Closes #447
2021-06-28 08:41:24 -04:00
Phil Scott
fa553fd72e Adds documentation for analyzers 2021-06-25 09:56:20 +02:00
Patrik Svensson
a186fd94ac Preserve whitespace trivia when applying code fix 2021-06-23 23:04:37 -04:00
Nils Andresen
6b5b31957c Added a TypeRegistrar to CommandAppTester
exposed as a public property.
For convenience, and to keep the similarity to the real CommandApp
it is also available in the ctor of CommandAppTester.
2021-06-24 01:42:29 +02:00
Nils Andresen
b92827ce3d (#460) added an overload to AnsiConsole.Ask
that takes an additional default value.
2021-06-23 23:47:12 +02:00
Patrik Svensson
c9b178ac96 Moved analyzer tests to its own project
Also moves tests to `./test` which makes it possible
for all test projects to share the same .editorconfig
files and similar.
2021-06-23 22:47:12 +02:00
Phil Scott
721d73e9eb Renames BaseAnalyzer to SpectreAnalyzer 2021-06-23 16:36:48 +02:00
Phil Scott
8b058d6342 Renaming analyzer test project to sandbox 2021-06-23 16:36:48 +02:00
Phil Scott
d1048260cc Making the project ready for deployment
Analyzer package needs all the dependencies to be private assets, and it's output pushed to teh analyzers/dotnet/cs folder. 

We don't want anything in the lib folder, so it also disables the auto build output and warnings that there are no files for the target framework in the lib folder
2021-06-23 16:36:48 +02:00
Phil Scott
bdcc01ea68 Adding analyzers for common mistakes with live renderables 2021-06-23 16:36:48 +02:00
Phil Scott
4f293d887d Adding analyzer project
Contains two analyzers with fixes

* Use AnsiConsole over System.Console
* Favor local instance over static implementation
2021-06-23 16:36:48 +02:00
GianHodgson
d015a4966f Hardblank 2021-06-21 01:23:18 +02:00
18-F-cali
5cbe9d40b0 Removed extra line from example code. 2021-06-19 02:38:01 +02:00
461 changed files with 3805 additions and 604 deletions

View File

@@ -21,7 +21,8 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 6.0.x
include-prerelease: true
- name: Setup Node.js
uses: actions/setup-node@v2
@@ -79,10 +80,10 @@ jobs:
with:
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
- name: Setup dotnet 5.0.301
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 5.0.301
- name: Integration Tests
shell: bash

View File

@@ -24,7 +24,8 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 6.0.x
include-prerelease: true
- name: Setup Node.js
uses: actions/setup-node@v2

View File

@@ -29,7 +29,8 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 6.0.x
include-prerelease: true
- name: Build
shell: bash
@@ -69,10 +70,10 @@ jobs:
with:
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
- name: Setup dotnet 5.0.301
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 5.0.301
- name: Build
shell: bash
@@ -100,10 +101,10 @@ jobs:
with:
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
- name: Setup dotnet 5.0.301
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
dotnet-version: 5.0.301
- name: Publish
shell: bash

View File

@@ -4,7 +4,14 @@ var configuration = Argument("configuration", "Release");
////////////////////////////////////////////////////////////////
// Tasks
Task("Clean")
.Does(context =>
{
context.CleanDirectory("./.artifacts");
});
Task("Build")
.IsDependentOn("Clean")
.Does(context =>
{
DotNetCoreBuild("./src/Spectre.Console.sln", new DotNetCoreBuildSettings {
@@ -15,11 +22,43 @@ Task("Build")
});
});
Task("Test")
Task("Build-Analyzer")
.IsDependentOn("Build")
.Does(context =>
{
DotNetCoreTest("./src/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetCoreTestSettings {
DotNetCoreBuild("./src/Spectre.Console.Analyzer.sln", new DotNetCoreBuildSettings {
Configuration = configuration,
NoIncremental = context.HasArgument("rebuild"),
MSBuildSettings = new DotNetCoreMSBuildSettings()
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
});
});
Task("Build-Examples")
.IsDependentOn("Build")
.Does(context =>
{
DotNetCoreBuild("./examples/Examples.sln", new DotNetCoreBuildSettings {
Configuration = configuration,
NoIncremental = context.HasArgument("rebuild"),
MSBuildSettings = new DotNetCoreMSBuildSettings()
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
});
});
Task("Test")
.IsDependentOn("Build")
.IsDependentOn("Build-Analyzer")
.IsDependentOn("Build-Examples")
.Does(context =>
{
DotNetCoreTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetCoreTestSettings {
Configuration = configuration,
NoRestore = true,
NoBuild = true,
});
DotNetCoreTest("./test/Spectre.Console.Analyzer.Tests/Spectre.Console.Analyzer.Tests.csproj", new DotNetCoreTestSettings {
Configuration = configuration,
NoRestore = true,
NoBuild = true,
@@ -30,8 +69,6 @@ Task("Package")
.IsDependentOn("Test")
.Does(context =>
{
context.CleanDirectory("./.artifacts");
context.DotNetCorePack($"./src/Spectre.Console.sln", new DotNetCorePackSettings {
Configuration = configuration,
NoRestore = true,
@@ -40,6 +77,15 @@ Task("Package")
MSBuildSettings = new DotNetCoreMSBuildSettings()
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
});
context.DotNetCorePack($"./src/Spectre.Console.Analyzer.sln", new DotNetCorePackSettings {
Configuration = configuration,
NoRestore = true,
NoBuild = true,
OutputDirectory = "./.artifacts",
MSBuildSettings = new DotNetCoreMSBuildSettings()
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
});
});
Task("Publish-GitHub")

1
docs/.gitignore vendored
View File

@@ -7,6 +7,7 @@
[Tt]ools/
![Tt]ools/packages.config
[Oo]utput/
[Cc]ache/
![Ii]nput/
nuget.exe
*.com

View File

@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
<NoWarn>MVC1000</NoWarn>
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
</PropertyGroup>
@@ -31,7 +32,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.27" />
<PackageReference Include="Microsoft.Playwright" Version="1.13.0-next-1" />
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.31" />
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.1" />
</ItemGroup>

View File

@@ -22,7 +22,7 @@ namespace Docs
.AddShortcode("Alert", typeof(AlertShortcode))
.AddShortcode("AsciiCast", typeof(AsciiCastShortcode))
.AddPipelines()
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install")
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install", "--audit", "false", "--fund", "false")
{
LogErrors = false
})

6
docs/global.json Normal file
View File

@@ -0,0 +1,6 @@
{
"sdk": {
"version": "2.2.200",
"rollForward": "latestMajor"
}
}

View File

@@ -14,11 +14,21 @@
<link rel="icon" type="image/png" sizes="16x16" href="@Context.GetLink("/assets/favicons/favicon-16x16.png")">
@{
string title = @Document.ContainsKey(Keys.Title) ? $"Spectre.Console - {Document.GetString(Keys.Title)}" : "Spectre.Console";
string description = @Document.ContainsKey(Constants.Description) ? Document.GetString(Constants.Description) : "Spectre.Console is a .NET Standard 2.0 library that makes it easier to create beautiful console applications";
string title = Document.ContainsKey(Keys.Title) ? $"Spectre.Console - {Document.GetString(Keys.Title)}" : "Spectre.Console";
string description = Document.ContainsKey(Constants.Description) ? Document.GetString(Constants.Description) : "Spectre.Console is a .NET Standard 2.0 library that makes it easier to create beautiful console applications";
var card = Outputs.FirstOrDefault(i => i.GetString("DocId") == Model.Id.ToString());
var urlBase = $"https://{Document.GetString(Keys.Host)}/";
}
<title>@title</title>
<meta name="description" content="@description" />
@if(card != null){
<meta name="twitter:card" content="summary_large_image" />
<meta name="og:title" content="@title" />
<meta name="og:description" content="@description" />
<meta name="og:image" content="@(urlBase + card.Destination)" />
}
</head>
<body class="antialiased text-gray-600 min-h-full flex flex-col bg-gray-50">
<header class="flex-none text-sm font-medium bg-gradient-to-b from-gray-200 to-gray-100 ring-1 ring-gray-900 ring-opacity-5 shadow py-2 md:py-4">
@@ -66,7 +76,7 @@
}
</div>
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OrderBy(i => i.GetInt("Order")).OnlyVisible())
{
if(string.IsNullOrWhiteSpace(document.GetTitle()))
{
@@ -100,7 +110,10 @@
}
</nav>
<article class="flex-1 min-w-0">
<h1 class="text-gray-800 text-4xl mb-4 font-extrabold">@(Document.GetString(Keys.Title) ?? Document.GetTitle())</h1>
<header class="text-gray-800 mb-4">
<h1 class="text-4xl font-extrabold">@(Document.GetString(Keys.Title) ?? Document.GetTitle())</h1>
@RenderSection("subheading", required: false)
</header>
<div class="prose max-w-none prose-sm lg:prose lg:max-w-none 2xl:prose-xl 2xl:max-w-none text-gray-700 font-light">
@RenderBody()
</div>

View File

@@ -1,42 +0,0 @@
<div>
@foreach (IDocument post in Document.GetChildren())
{
IDocument topicDocument = Outputs[nameof(Archives)][$"blog/topics/{post.GetString("topic")}/index.html"];
string excerpt = post.GetString(Statiq.Html.HtmlKeys.Excerpt);
<div>
<div class="p-3 mb-2 bg-light page-box">
<h5><a href="@Context.GetLink(post)">@post.GetString("Title")</a></h5>
<div class="small text-black-50">
@post.GetDateTime("Published").ToLongDateString() in
<a href="@(topicDocument.GetLink())"><span class="badge badge-light">@topicDocument.GetTitle()</span></a>
</div>
@if (!string.IsNullOrEmpty(excerpt))
{
@Html.Raw(excerpt)
<p class="small"><a href="@Context.GetLink(post)">Read more...</a></p>
}
</div>
</div>
}
@{
IDocument older = Document.GetDocument(Keys.Next);
IDocument newer = Document.GetDocument(Keys.Previous);
}
@if (older != null || newer != null)
{
<div class="d-flex flex-row justify-content-between">
<div>
@if (older != null)
{
<a class="btn btn-primary" href="@Context.GetLink(older)" role="button">Older</a>
}
</div>
<div>
@if (newer != null)
{
<a class="btn btn-primary" href="@Context.GetLink(newer)" role="button">Newer</a>
}
</div>
</div>
}
</div>

View File

@@ -0,0 +1,38 @@
---
Title: SpectreXxxx
Description: Rule title
Category: Usage
Severity: Hidden, Info, Warning, or Error
Excluded: true
---
## Cause
A concise-as-possible description of when this rule is violated. If there's a lot to explain, begin with "A violation of this rule occurs when..."
## Reason for rule
Explain why the user should care about the violation.
## How to fix violations
To fix a violation of this rule, [describe how to fix a violation].
## Examples
### Violates
Example(s) of code that violates the rule.
### Does not violate
Example(s) of code that does not violate the rule.
## How to suppress violations
**If the severity of your analyzer isn't _Warning_, delete this section.**
```csharp
#pragma warning disable Spectre1000 // <Rule name>
#pragma warning restore Spectre1000 // <Rule name>
```

View File

@@ -0,0 +1,56 @@
---
Title: Spectre1021
Description: Avoid prompting for input while a current renderable is running.
Category: Usage
Severity: Warning
---
## Cause
A violation of this rule occurs when a AnsiConsole prompt is called within the context of an executing renderable e.g. `Progress`, `Status` and `Live`. Concurrent LiveRenderable are not supported and will cause issues when running simultaneously.
## Reason for rule
When LiveRenderable such as `Progress`, `Status` or `Live` are running they expect to be running exclusively. They rely on ANSI sequences to draw and keep the console experience consistent. Prompts also rely on ANSI sequences for their drawing. Simultaneous running can result in corrupt output.
## How to fix violations
Redesign logic to allow one LiveRenderable to complete before using a prompt or prompt before starting the operation.
## Examples
### Violates
```csharp
AnsiConsole.Progress().Start(ctx =>
{
// code to update progress bar
var answer = AnsiConsole.Confirm("Continue?");
});
```
### Does not violate
```csharp
AnsiConsole.Progress().Start(ctx =>
{
// code to update progress bar
// persist state to restart progress after asking question
});
var answer = AnsiConsole.Confirm("Continue?");
AnsiConsole.Progress().Start(ctx =>
{
// apply persisted state
// code to update progress bar
```
## How to suppress violations
```csharp
#pragma warning disable Spectre1021 // <Rule name>
#pragma warning restore Spectre1021 // <Rule name>
```

View File

@@ -0,0 +1,3 @@
@{
Layout = @"_layout.cshtml";
}

View File

@@ -0,0 +1,10 @@
@inherits StatiqRazorPage<IDocument>
@{
Layout = @"/_layout.cshtml";
}
<p>@Document.GetString("Description")</p>
@RenderBody()

View File

@@ -0,0 +1,31 @@
Title: Roslyn Analyzers
Order: 20
---
<code>Spectre.Console.Analyzer</code> provides analyzers for common mistakes when using Spectre.Console. It can be installed via nuget
<pre><code>nuget install Spectre.Console.Analyzer</code></pre>
<h2>Supported Analyzers</h2>
<table>
<thead>
<tr>
<th>Analyzer</th>
<th>Description</th>
<th>Category</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<tr>
<td>@Html.DocumentLink(child)</td>
<td>@child.GetString("Description")</td>
<td>@child.GetString("Category") </td>
<td>@child.GetString("Severity") </td>
</tr>
}
</tbody>
</table>

View File

@@ -0,0 +1,27 @@
---
Title: Spectre1000
Description: Use AnsiConsole instead of System.Console
Category: Usage
Severity: Warning
---
## Cause
A violation of this rule occurs when `System.Console` is used for common methods exposed by Spectre.Console.
## Reason for rule
Methods implemented in Spectre.Console should be used over direct access to `System.Console` to allow for enhancements and
features to be enabled.
## How to fix violations
To fix a violation of this rule, change from `System.Console` to `Spectre.Console.AnsiConsole`.
## How to suppress violations
```csharp
#pragma warning disable Spectre1000 // Use AnsiConsole instead of System.Console
#pragma warning restore Spectre1000 // Use AnsiConsole instead of System.Console
```

View File

@@ -0,0 +1,63 @@
---
Title: Spectre1010
Description: Favor the use of the instance of AnsiConsole over the static helper
Category: Usage
Severity: Info
---
## Cause
A violation of this rule occurs when the static helper `AnsiConsole` is used when a field or method parameter of type
`IAnsiConsole` is available.
## Reason for rule
Use of `IAnsiConsole` improves testability of the code, and also allows upstream callers the ability to customize the console
capabilities and features. When a field variable or parameter is available it should be used to ensure the code takes advantage
of that configuration.
## How to fix violations
To fix a violation of this rule, change from `AnsiConsole` to the name of the local instance.
## Examples
### Violates
```csharp
class Example
{
private IAnsiConsole _ansiConsole;
public Example(IAnsiConsole ansiConsole)
{
_ansiConsole = ansiConsole;
}
public Run()
{
AnsiConsole.WriteLine("Running...");
}
}
```
### Does not violate
```csharp
class Example
{
private IAnsiConsole _ansiConsole;
public Example(IAnsiConsole ansiConsole)
{
_ansiConsole = ansiConsole;
}
public Run()
{
_ansiConsole.WriteLine("Running...");
}
}
```

View File

@@ -0,0 +1,46 @@
---
Title: Spectre1020
Description: Avoid calling other live renderables while a current renderable is running.
Category: Usage
Severity: Warning
---
## Cause
A violation of this rule occurs when a child LiveRenderable i.e. `Progress`, `Status` and `Live` are called within the context of an executing renderable. Concurrent LiveRenderable are not supported and will cause issues when running simultaneously.
## Reason for rule
When LiveRenderable such as `Progress`, `Status` or `Live` are running they expect to be running exclusively. They rely on ANSI sequences to draw and keep the console experience consistent. With simultaneous calls both renderables compete with the console causing concurrent writes corrupting the output.
## How to fix violations
Redesign logic to allow one LiveRenderable to complete before starting a second renderable.
## Examples
### Violates
```csharp
AnsiConsole.Progress().Start(ctx => {
AnsiConsole.Status().Start("Running status too...", statusCtx => {});
});
```
### Does not violate
```csharp
AnsiConsole.Progress().Start(ctx => {
// run progress and complete tasks
});
AnsiConsole.Status().Start("Running status afterwards...", statusCtx => {});
```
## How to suppress violations
```csharp
#pragma warning disable Spectre1020 // <Rule name>
#pragma warning restore Spectre1020 // <Rule name>
```

View File

@@ -1,5 +1,11 @@
Title: Borders
Order: 2
Description: "*Spectre.Console* makes it easy to create tables and panels with a variety of different styles of borders."
Highlights:
- Rounded
- Square
- Heavy
- And more...
---
There is different built-in borders you can use for tables and panels.

View File

@@ -1,5 +1,9 @@
Title: Colors
Order: 0
Description: "*Spectre.Console* allows easy rendering of the standard ANSI colors of your terminal, and also supports rendering up to 24-bit colors depending on the capabilities of your terminal."
Highlights:
- Predefined common colors
- Easy syntax for inline styling
---
The following is a list of the standard 8-bit colors supported in terminals.

View File

@@ -1,5 +1,9 @@
Title: Emojis
Order: 3
Description: "For terminals that support Emojis, *Spectre.Console* supports a simple syntax for rendering emojis."
Highlights:
- ":rocket: becomes 🚀"
- ":waning_gibbous_moon: becomes 🌖"
---
Please note that what emojis that can be used is completely up to

View File

@@ -1,5 +1,9 @@
Title: Spinners
Order: 4
Description: "*Spectre.Console* supports over 80 different types of spinners, and allows new ones to be defined. They are used automatically with the controls"
Highlights:
- Status display
- Progress display
---
For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embedded/result/

View File

@@ -1,5 +1,10 @@
Title: Styles
Order: 1
Description: "*Spectre.Console* makes it easy to write text with different styles beyond colors. Depending on your terminal, it can make it easy to use styles such as"
Highlights:
- Bold, Italic, Underline, strikethrough
- Dim, Invert
- Conceal, slowblink, rapidblink
---
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.

View File

@@ -0,0 +1,15 @@
ArchiveSources: => $"blog/posts/**/*"
ArchiveKey: Category
ArchiveKeyComparer: => StringComparer.OrdinalIgnoreCase.ToConvertingEqualityComparer()
ArchiveDestination: >
=> GetInt("Index") <= 1 ? $"blog/{NormalizedPath.OptimizeFileName(GetString("GroupKey"))}/index.html" : $"blog/{NormalizedPath.OptimizeFileName(GetString("GroupKey"))}/{GetInt("Index")}.html"
ArchivePageSize: => 5
ArchiveOrderKey: published
ArchiveOrderDescending: true
Title: Categories
ArchiveTitle: => GetString("GroupKey")
# we only show if we have a group key which means we are a category and not the index and also
# if we are the first page
Hidden: >
=> doc.GetString("GroupKey") != null && doc.GetInt("Index") <= 1 ? false : true
Order: 250

View File

@@ -0,0 +1,2 @@
Hidden: true
Order: 1000

View File

@@ -0,0 +1,10 @@
Title: Recent Blog Posts
ArchiveSources: => $"blog/posts/**/*"
ArchiveDestination: >
=> GetInt("Index") <= 1 ? $"blog/index.html" : $"blog/{GetInt("Index")}.html"
ArchivePageSize: => 5
ArchiveOrderKey: Published
ArchiveOrderDescending: true
Hidden: >
=> doc.GetInt("Index") == 1 ? false : true
Order: 25

View File

@@ -0,0 +1,27 @@
@inherits StatiqRazorPage<IDocument>
@model IDocument
@{
var older = Model.GetDocument(Keys.Next);
var newer = Model.GetDocument(Keys.Previous);
}
@if (older != null || newer != null)
{
<div class="flex flex-row justify-content-between">
<div>
@if (older != null)
{
<a class="py-0.5 px-1 mr-4 text-blue-900 bg-grey-50 border border-blue-200 hover:bg-grey-100 hover:text-blue-800 hover:border-blue-300 rounded transition-colors" href="@Context.GetLink(older)" role="button">Older</a>
}
</div>
<div>
@if (newer != null)
{
<a class="py-0.5 px-1 mr-4 text-blue-900 bg-grey-50 border border-blue-200 hover:bg-grey-100 hover:text-blue-800 hover:border-blue-300 rounded transition-colors" href="@Context.GetLink(newer)" role="button">Newer</a>
}
</div>
</div>
}

View File

@@ -0,0 +1,33 @@
@inherits StatiqRazorPage<IEnumerable<IDocument>>
@foreach (var post in Model)
{
<div>
<h3 class="mb-0"><a href="@Context.GetLink(post)">@post.GetString("Title")</a></h3>
@{
var author = post.GetString("Author");
var published = post.GetDateTime("Published");
var category = post.GetString("Category");
}
<div class="mt-2 font-light text-xs md:text-sm">
<span>Posted </span>
@if (published != default(DateTime)) {
<span>@published.ToLongDateString() </span>
}
@if (author != null) {
<span>by @author </span>
}
@if (category != null) {
var categoryUrl = @Context.GetLink($"blog/{NormalizedPath.OptimizeFileName(category)}/index.html");
<span>
to <a class="text-blue-800 underline" href="@categoryUrl">
@category
</a>
</span>
}
</div>
<article>
@Html.Raw(@post.GetString("Excerpt"))
</article>
</div>
}

View File

@@ -0,0 +1,14 @@
@inherits StatiqRazorPage<IDocument>
@if (Document.ContainsKey(Keys.GroupKey))
{
@Html.Partial("_posts.cshtml", Document.GetChildren())
@Html.Partial("_nextprevious.cshtml", Document)
}
else
{
@foreach (var tag in Document.GetChildren().OrderByDescending(x => x.GetChildren().Count()))
{
var postCount = tag.GetChildren().Count().ToString();
<a role="button" href="@Context.GetLink(tag)" class="badge badge-light"> @tag.GetTitle() (@postCount)</a>
}
}

View File

@@ -0,0 +1,3 @@
@inherits StatiqRazorPage<IDocument>
@Html.Partial("_posts.cshtml", Document.GetChildren())
@Html.Partial("_nextprevious.cshtml", Document)

View File

@@ -0,0 +1,9 @@
Title: Hello, World
Description: To help track new releases, updates and planning for Spectre.Console, we've added a new blog to the documentation.
Published: 20210711
Category: News
---
To help track new releases, updates and planning for Spectre.Console, we've added a new blog to the documentation.
Stay tuned for upcoming information related to the 0.41 release!

View File

@@ -0,0 +1,19 @@
Title: Short title, less than 50 characters
Description: Longer description, with optional *bold* and **italic** characters. Shouldn't be TOO long but can span multiple lines.
Published: 20210710
Category: Release Notes | News | or whatever
Excluded: true
---
Intro paragraph, maybe even just the description. No need for a title that's included automatically.
## Use second level headers
Main title will be set with h1
## Tasks
1. Set title and description
2. Set proper publish date
3. Set proper category
4. Remove excluded attribute.

View File

@@ -0,0 +1,3 @@
@{
Layout = @$"_layout.cshtml";
}

View File

@@ -0,0 +1,34 @@
@{
Layout = @"../../_layout.cshtml";
}
@inherits StatiqRazorPage<IDocument>
@{
var author = Model.GetString("Author");
var published = Model.GetDateTime("Published");
var category = Model.GetString("Category");
}
@section subheading{
<div class="mt-2 font-light text-xs md:text-sm">
<span>Posted </span>
@if (published != default(DateTime)) {
<span>@published.ToLongDateString() </span>
}
@if (author != null) {
<span>by @author </span>
}
@if (category != null) {
<span>
to <a class="text-blue-800 underline" href="@Context.GetLink($"blog/{NormalizedPath.OptimizeFileName(@category)}/index.html")">
@category
</a>
</span>
}
</div>
}
@RenderBody()

View File

@@ -1,5 +1,6 @@
Title: CommandApp
Order: 2
Description: "**CommandApp** is the entry point for a *Spectre.Console.Cli* command line application. It is used to configure the settings and commands used for execution of the application."
---
`CommandApp` is the entry point for a `Spectre.Console.Cli` command line application. It is used to configure the settings and commands used for execution of the application. Most `Spectre.Console.Cli` applications will need to specify a custom configuration using the `Configure` method.

View File

@@ -1,5 +1,6 @@
Title: Creating Commands
Order: 6
Description: "How to create commands for *Spectre.Console.Cli*"
---
Commands in `Spectre.Console.Cli` are defined by creating a class that inherits from either `Spectre.Console.Cli.Command<TSettings>` or `Spectre.Console.Cli.AsyncCommand<TSettings>`. `Command<TSettings>` must implement an `Execute` method that returns an int where as `AsyncCommand<TSettings>` must implement `ExecuteAsync` returning `Task<int>`.
@@ -7,7 +8,7 @@ Commands in `Spectre.Console.Cli` are defined by creating a class that inherits
```csharp
public class HelloCommand : Command<HelloCommand.Settings>
{
public class Settings : LogCommandSettings
public class Settings : CommandSettings
{
[CommandArgument(0, "[Name]")]
public string Name { get; set; }

View File

@@ -1,6 +1,8 @@
Title: Composing Commands
RedirectFrom: introduction
Order: 8
Description: "The underlying philosophy behind *Spectre.Console.Cli* is to rely on the .NET type system to
declare the commands, but tie everything together via composition."
---
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to

View File

@@ -1,5 +1,6 @@
Title: Getting Started
Order: 1
Description: "How to get started using *Spectre.Console.Cli* to write a modern console application that follows industry conventions for command line parsing."
---
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
@@ -49,8 +50,7 @@ internal sealed class FileSizeCommand : Command<FileSizeCommand.Settings>
var totalFileSize = files
.Sum(fileInfo => fileInfo.Length);
AnsiConsole.MarkupLine(
$"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes"); $"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes");
AnsiConsole.MarkupLine($"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes");
return 0;
}

View File

@@ -1,5 +1,6 @@
Title: Spectre.Console.Cli
Order: 10
Order: 80
Description: "The command line interface for the *Spectre.Console* project."
---
<p>Spectre.Console.Cli is a modern library for parsing command line arguments. While it's extremely opinionated in what it does, it tries to follow established industry conventions, and draws its inspiration from applications you use everyday.</p>

View File

@@ -1,5 +1,8 @@
Title: Introduction
Order: 1
Description: "*Spectre.Console.Cli* is a modern library for parsing command line arguments. While it's extremely
opinionated in what it does, it tries to follow established industry conventions, and draws
its inspiration from applications you use everyday."
---
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely

View File

@@ -1,5 +1,6 @@
Title: Migrate from Spectre.Cli
Order: 10
Description: "Migrating from *Specte.Cli* to *Spectre.Console.Cli*"
---
The functionality in `Spectre.Cli` has been moved into the `Spectre.Console`

View File

@@ -1,5 +1,6 @@
Title: Specifying Settings
Order: 5
Description: "How to define command line argument settings for your *Spectre.Console.Cli* Commands"
---
Settings for `Spectre.Console.Cli` commands are defined via classes that inherit from `CommandSettings`. Attributes are used to indicate how the parser interprets the command line arguments and create a runtime instance of the settings to be used.

View File

@@ -1,5 +1,9 @@
Title: Exceptions
Order: 3
Order: 40
Description: "Exceptions aren't always readable when viewed in the terminal. You can make exception a bit more readable by using the **WriteException** method."
Highlights:
- Color coded output.
- Shorten long identifiers and paths.
---
Exceptions aren't always readable when viewed in the terminal.

View File

@@ -1,4 +1,5 @@
Title: Welcome
Description: Spectre.Console is a .NET Standard 2.0 library that makes it easier to create beautiful console applications.
Order: 0
---

View File

@@ -1,5 +1,6 @@
Title: Live
Order: 4
Order: 50
Description: Live displays continue to redraw their contents until an action is complete.
---
Live displays continue to redraw their contents until an action is complete.

View File

@@ -1,5 +1,9 @@
Title: Live Display
Order: 0
Description: "*Spectre.Console* can update arbitrary widgets in-place."
Highlights:
- Update tables or graphs with new updates.
- Create a custom progress bar that extends the existing control.
---
Spectre.Console can update arbitrary widgets in-place.

View File

@@ -1,6 +1,11 @@
Title: Progress
Order: 5
RedirectFrom: progress
Description: "*Spectre.Console* can display information about long running tasks in the console using progress bars."
Highlights:
- Custom styling of progress bars.
- Multiple predefined columns such as Throughput, Estimated Time Remaining, and more.
- Fallback for non-interactive consoles such as CI runners.
---
Spectre.Console can display information about long running tasks in the console.

View File

@@ -1,6 +1,10 @@
Title: Status
Order: 10
RedirectFrom: status
Description: "*Spectre.Console* can display information about long running tasks in the console with the Status control."
Highlights:
- Custom spinner control for running tasks.
- Fallback for non-interactive consoles such as CI runners.
---
Spectre.Console can display information about long running tasks in the console.

View File

@@ -1,5 +1,10 @@
Title: Markup
Order: 2
Order: 30
Description: The Markup class allows you to output rich text to the console.
Highlights:
- Easily add *color*.
- Add hyperlinks to for supported terminals.
- Emoji 🚀 parsing.
---
The `Markup` class allows you to output rich text to the console.

View File

@@ -1,5 +1,6 @@
Title: Prompts
Order: 5
Order: 60
Description: "*Spectre.Console* has multiple controls to assist in user input."
---
<ul>

View File

@@ -1,5 +1,10 @@
Title: Multi Selection
Order: 3
Description: "The **MultiSelectionPrompt** can be used when you want the user to select one or many items from a provided list."
Highlights:
- Display multiple items for a user to scroll and choose from.
- Custom page sizes.
- Provide groups of selectable items.
---
The `MultiSelectionPrompt` can be used when you want the user to select

View File

@@ -1,5 +1,6 @@
Title: Selection
Order: 1
Description: "The **SelectionPrompt** can be used when you want the user to select a single item from a provided list."
---
The `SelectionPrompt` can be used when you want the user to select

View File

@@ -1,6 +1,12 @@
Title: Text prompt
Order: 0
RedirectFrom: prompt
Description: "*Spectre.Console* has multiple input functions for helping receive strongly typed input from a user."
Highlights:
- Confirmation.
- Strongly typed input.
- Input restricted to specific items.
- Secrets such as passwords or keys.
---
Sometimes you want to get some input from the user, and for this

View File

@@ -1,5 +1,6 @@
Title: Quick Start
Order: 1
Order: 20
Description: Getting started with *Spectre.Console*
---
The fastest way of getting started using Spectre.Console is

View File

@@ -1,5 +1,6 @@
Title: Sponsors
Order: 0
Order: 10
Description: The longevity of *Spectre.Console* is thanks to the support of our sponsors.
---
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)

View File

@@ -1,5 +1,10 @@
Title: Bar Chart
Order: 20
Description: "Use **BarChart** to render bar charts to the console."
Highlights:
- Custom colors
- Labels
- Use your own data with a converter.
---
Use `BarChart` to render bar charts to the console.

View File

@@ -1,6 +1,11 @@
Title: Calendar
Order: 40
RedirectFrom: calendar
Description: "The **Calendar** is used to render a calendar to the terminal."
Highlights:
- Include highlighted events.
- Culture aware.
- Custom headers.
---
The `Calendar` is used to render a calendar to the terminal.

View File

@@ -1,5 +1,6 @@
Title: Canvas Image
Order: 70
Description: "Use *ImageSharp* to parse images and render them as Ascii art to the console."
---
To add [ImageSharp](https://github.com/SixLabors/ImageSharp) superpowers to

View File

@@ -1,5 +1,6 @@
Title: Canvas
Order: 60
Description: "**Canvas** is a widget that allows you to render arbitrary pixels to the console."
---
`Canvas` is a widget that allows you to render arbitrary "pixels"

View File

@@ -1,6 +1,7 @@
Title: Figlet
Order: 50
RedirectFrom: figlet
Description: "*Spectre.Console* can render FIGlet text by using the **FigletText** class."
---
Spectre.Console can render [FIGlet](http://www.figlet.org/) text by using the `FigletText` class.

View File

@@ -1,5 +1,6 @@
Title: Widgets
Order: 9
Order: 70
Description: "*Spectre.Console* supports many built-in widgets to help render beautiful output."
---
<ul>

View File

@@ -1,6 +1,11 @@
Title: Rule
Order: 30
RedirectFrom: rule
Description: "The **Rule** class is used to render a horizontal rule (line) to the terminal."
Highlights:
- Custom colors for line and title.
- Specify left, center or right aligned title.
---
The `Rule` class is used to render a horizontal rule (line) to the terminal.

View File

@@ -1,6 +1,7 @@
Title: Table
Order: 0
RedirectFrom: tables
Description: "Tables are a perfect way of displaying tabular data in a terminal. *Spectre.Console* is super smart about rendering tables and will adjust all columns to fit whatever is inside them."
---
Tables are a perfect way of displaying tabular data in a terminal.

View File

@@ -1,5 +1,9 @@
Title: Tree
Order: 10
Description: "The **Tree** widget can be used to render hierarchical data."
Highlights:
- Custom colors and styles for guidelines.
- Include any *Spectre.Console* widgets as child nodes.
---
The `Tree` widget can be used to render hierarchical data.

238
docs/package-lock.json generated
View File

@@ -138,12 +138,29 @@
"lodash.uniq": "^4.5.0"
}
},
"@types/node": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
"integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==",
"dev": true,
"optional": true
},
"@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"@types/yauzl": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
"integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==",
"dev": true,
"optional": true,
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -167,6 +184,15 @@
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
"dev": true
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
"requires": {
"debug": "4"
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
@@ -262,6 +288,12 @@
"node-releases": "^1.1.71"
}
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -438,6 +470,15 @@
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"defined": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
@@ -494,6 +535,15 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -523,6 +573,18 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"requires": {
"@types/yauzl": "^2.9.1",
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
}
},
"fast-glob": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
@@ -546,6 +608,15 @@
"reusify": "^1.0.4"
}
},
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
"dev": true,
"requires": {
"pend": "~1.2.0"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -604,6 +675,15 @@
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
"dev": true
},
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -704,6 +784,16 @@
"integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==",
"dev": true
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dev": true,
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
@@ -825,6 +915,12 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"jpeg-js": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz",
"integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==",
"dev": true
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -941,6 +1037,12 @@
"picomatch": "^2.2.3"
}
},
"mime": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
"integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
"dev": true
},
"mini-svg-data-uri": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz",
@@ -968,6 +1070,12 @@
"integrity": "sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw==",
"dev": true
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"nanoid": {
"version": "3.1.22",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz",
@@ -1096,6 +1204,12 @@
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true
},
"picomatch": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
@@ -1108,6 +1222,34 @@
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
"playwright": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.12.3.tgz",
"integrity": "sha512-eyhHvZV7dMAUltqjQsgJ9CjZM8dznzN1+rcfCI6W6lfQ7IlPvTFGLuKOCcI4ETbjfbxqaS5FKIkb1WDDzq2Nww==",
"dev": true,
"requires": {
"commander": "^6.1.0",
"debug": "^4.1.1",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.0",
"jpeg-js": "^0.4.2",
"mime": "^2.4.6",
"pngjs": "^5.0.0",
"progress": "^2.0.3",
"proper-lockfile": "^4.1.1",
"proxy-from-env": "^1.1.0",
"rimraf": "^3.0.2",
"stack-utils": "^2.0.3",
"ws": "^7.4.6",
"yazl": "^2.5.1"
}
},
"pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"dev": true
},
"postcss": {
"version": "8.2.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.10.tgz",
@@ -1285,6 +1427,39 @@
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
"dev": true
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
"proper-lockfile": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
"integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.4",
"retry": "^0.12.0",
"signal-exit": "^3.0.2"
}
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"purgecss": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-3.1.3.tgz",
@@ -1367,12 +1542,27 @@
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
"dev": true
},
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -1397,6 +1587,12 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"dev": true
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -1418,6 +1614,23 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
"dev": true,
"requires": {
"escape-string-regexp": "^2.0.0"
},
"dependencies": {
"escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true
}
}
},
"string-width": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
@@ -1529,6 +1742,12 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"ws": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz",
"integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==",
"dev": true
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -1567,6 +1786,25 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
"integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
"dev": true
},
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"yazl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3"
}
}
}
}

View File

@@ -16,6 +16,7 @@
"@tailwindcss/typography": "^0.4.0",
"autoprefixer": "^10.2.5",
"cross-env": "^7.0.3",
"playwright": "^1.12.3",
"postcss": "^8.2.10",
"postcss-cli": "^8.3.1",
"tailwindcss": "^2.1.1"

View File

@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Playwright;
using Statiq.Common;
using Statiq.Core;
using Statiq.Web;
using Statiq.Web.Modules;
using Statiq.Web.Pipelines;
namespace Docs.Pipelines
{
public class SocialImages : Pipeline
{
public SocialImages()
{
Dependencies.AddRange(nameof(Inputs));
ProcessModules = new ModuleList
{
new GetPipelineDocuments(ContentType.Content),
// Filter to non-archive content
new FilterDocuments(Config.FromDocument(doc => !Archives.IsArchive(doc))),
// Process the content
new CacheDocuments
{
new AddTitle(),
new SetDestination(true),
new ExecuteIf(Config.FromSetting(WebKeys.OptimizeContentFileNames, true))
{
new OptimizeFileName()
},
new GenerateSocialImage(),
}
};
OutputModules = new ModuleList { new WriteFiles() };
}
}
class GenerateSocialImage : ParallelModule
{
private IPlaywright _playwright;
private IBrowser _browser;
private WebApplication _app;
protected override async Task BeforeExecutionAsync(IExecutionContext context)
{
var builder = WebApplication.CreateBuilder();
builder.Logging.ClearProviders();
builder.Services
.AddRazorPages()
.WithRazorPagesRoot("/src/SocialCards/");
_app = builder.Build();
_app.MapRazorPages();
_app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "src/SocialCards")),
RequestPath = "/static"
});
await _app.StartAsync().ConfigureAwait(false);
_playwright = await Playwright.CreateAsync().ConfigureAwait(false);
_browser = await _playwright.Chromium.LaunchAsync().ConfigureAwait(false);
}
protected override async Task FinallyAsync(IExecutionContext context)
{
await _browser.DisposeAsync().ConfigureAwait(false);
_playwright.Dispose();
await _app.DisposeAsync().ConfigureAwait(false);
await base.FinallyAsync(context);
}
protected override async Task<IEnumerable<IDocument>> ExecuteInputAsync(IDocument input, IExecutionContext context)
{
var url = _app.Urls.FirstOrDefault(u => u.StartsWith("http://"));
var page = await _browser.NewPageAsync(new BrowserNewPageOptions
{
ViewportSize = new ViewportSize { Width = 1200, Height = 618 },
}
);
var title = input.GetString("Title");
var description = input.GetString("Description");
var highlights = input.GetList<string>("Highlights") ?? Array.Empty<string>();
await page.GotoAsync($"{url}/?title={title}&desc={description}&highlights={string.Join("||", highlights)}");
var bytes = await page.ScreenshotAsync();
var destination = input.Destination.InsertSuffix("-social").ChangeExtension("png");
var doc = context.CreateDocument(
input.Source,
destination,
new MetadataItems { { "DocId", input.Id }},
context.GetContentProvider(bytes));
return new[] { doc };
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,120 @@
@page
@using Markdig
@model Docs.SocialCards.SocialCardModel
@{
Layout = null;
}
<html>
<head>
<link rel="stylesheet" href="static/styles.css" />
</head>
<body>
<div id="container">
<div id="console">
<div class="line"><span style="color:var(--brightBlack)">╭─</span><span style="color:var(--folder)">&#xe0b2;</span><span style="background-color:var(--folder);color:var(--black)"> ~/spectre.console</span><span style="color:var(--folder);background-color:var(--dotnet)">&#xe0b0;</span><span style="background-color:var(--blue)"> .NET 5.0 </span><span style="color:var(--dotnet);background-color:var(--git)">&#xe0b0;</span><span style="background-color:var(--git);color:var(--background)"> &#xe0a0; main </span><span style="color:var(--git)">&#xe0b4;</span></div>
<div class="line"><span style="color:var(--brightBlack)">╰─</span> dotnet run</div>
<div class="line"></div>
<div class="line">╭────────────────────────────────────────────────────────╮</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">│ │</div>
<div class="line">╰────────────────────────────────────────────────────────╯</div>
<div id="title"><span style="color:var(--brightPurple)">@Model.Title</span></div>
<div id="content">
@if (string.IsNullOrWhiteSpace(Model.Description) == false)
{
<p>@Html.Raw(Markdown.ToHtml(Model.Description))</p>
}
@if (string.IsNullOrWhiteSpace(Model.Highlights) == false)
{
<ul>
@foreach (var highlight in Model.Highlights.Split("||"))
{
<li>@Html.Raw(Markdown.ToHtml(highlight))</li>
}
</ul>
}
@if (string.IsNullOrWhiteSpace(Model.Footer) == false)
{
<div id="footer"><span style="color:var(--brightBlack)">@Html.Raw(@Markdown.ToHtml(@Model.Footer))</span></div>
}
</div>
</div>
<svg id="logo" version="1.0" xmlns="http://www.w3.org/2000/svg" width="1270.000000pt" height="1270.000000pt" viewBox="0 0 1270.000000 1270.000000" preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.16, written by Peter Selinger 2001-2019
</metadata>
<g transform="translate(0.000000,1270.000000) scale(0.100000,-0.100000)" stroke="none">
<path d="M799 10610 c-199 -48 -354 -191 -414 -383 l-25 -78 0 -3084 0 -3084
25 -79 c45 -141 155 -270 289 -335 124 -61 -80 -57 2819 -57 l2646 0 5 -43 c3
-23 8 -71 11 -105 13 -137 88 -334 179 -471 57 -85 187 -219 247 -254 25 -15
76 -34 112 -43 87 -22 163 -7 246 46 120 78 195 211 234 411 l23 124 14 -55
c63 -263 172 -511 326 -741 94 -142 229 -291 313 -348 272 -185 583 -197 750
-30 66 67 84 109 89 215 4 90 4 91 -51 230 -108 276 -137 477 -122 868 l7 196
77 0 c55 0 118 -11 229 -39 l154 -38 50 -84 c103 -172 221 -427 277 -599 38
-120 70 -274 86 -412 8 -75 21 -155 29 -178 37 -106 117 -199 220 -253 51 -26
202 -35 283 -17 83 18 193 97 268 192 157 199 256 485 286 825 11 122 6 524
-7 583 -5 24 -1 26 62 43 64 16 67 16 80 0 39 -50 109 -215 149 -351 25 -85
55 -174 67 -199 73 -156 261 -206 441 -117 65 32 110 70 159 135 128 169 178
414 157 764 -8 143 -38 350 -55 376 -2 4 7 25 22 46 77 112 168 344 200 504
l16 86 87 28 c188 60 391 170 498 269 132 122 183 230 183 383 0 71 -5 98 -24
138 -24 52 -82 112 -138 141 -52 28 -205 30 -378 5 -80 -11 -179 -23 -220 -27
l-75 -6 -29 56 c-33 65 -137 182 -211 236 -75 55 -156 94 -382 181 -110 43
-221 87 -245 100 -54 27 -92 69 -125 138 -25 52 -26 59 -20 180 4 69 16 200
26 291 52 430 53 809 5 1170 -54 405 -249 740 -569 979 -136 102 -297 190
-419 231 l-36 12 0 433 c0 433 0 434 -25 512 -52 167 -171 292 -341 360 l-69
28 -4215 2 c-2318 0 -4231 -3 -4251 -7z m8363 -1476 c417 -53 735 -193 962
-423 98 -98 155 -175 210 -282 84 -160 117 -292 141 -559 28 -313 17 -684 -30
-1025 -9 -60 -18 -164 -22 -230 -10 -208 22 -314 136 -452 76 -91 124 -118
391 -218 307 -116 377 -155 450 -249 23 -31 41 -58 39 -60 -2 -2 -47 8 -99 21
-131 35 -268 36 -360 3 -132 -47 -248 -116 -364 -218 -163 -143 -516 -488
-703 -687 -350 -372 -504 -514 -701 -644 -348 -231 -878 -408 -1322 -442 -409
-31 -796 45 -1059 208 -111 69 -249 210 -292 298 -32 65 -34 76 -33 165 1 104
23 178 85 287 75 131 137 194 430 441 181 152 251 295 250 511 -1 152 -16 223
-117 560 -35 117 -61 217 -58 222 3 5 20 9 38 9 55 0 217 31 261 50 53 23 103
73 132 131 43 88 56 187 59 437 2 266 -1 258 91 292 108 40 254 21 330 -45 35
-30 35 -32 53 -170 41 -311 106 -484 206 -546 48 -29 168 -48 381 -59 188 -10
432 -1 548 20 76 14 206 56 266 86 64 32 122 101 144 170 15 49 17 82 12 253
-5 198 -27 398 -52 482 -42 146 -125 221 -290 265 -57 15 -108 19 -268 19
l-197 0 0 45 c0 120 -37 255 -82 300 -76 77 -210 5 -291 -157 -31 -60 -67
-184 -67 -229 0 -27 -6 -34 -41 -50 -65 -29 -159 -98 -195 -144 -34 -43 -67
-119 -79 -181 l-6 -35 -57 28 c-114 57 -270 58 -379 2 -61 -31 -70 -21 -49 54
33 118 16 442 -29 536 -38 79 -114 84 -188 12 -68 -66 -136 -230 -137 -330 l0
-29 -61 7 c-34 3 -93 6 -131 6 l-69 0 6 48 c14 97 56 282 84 368 155 475 486
821 963 1008 108 42 308 94 430 110 62 9 124 17 138 20 76 11 479 5 592 -10z
m-7029 -78 c18 -8 261 -243 569 -552 582 -584 560 -559 543 -651 -6 -33 -69
-101 -523 -557 -553 -554 -564 -564 -644 -551 -89 15 -151 110 -128 198 10 37
65 95 463 495 l452 452 -472 473 c-414 414 -472 477 -478 510 -25 132 98 235
218 183z m7169 -1405 c164 -57 201 -136 234 -502 37 -414 9 -486 -212 -558
-155 -50 -298 -64 -579 -57 -249 6 -398 23 -439 50 -95 62 -177 346 -180 621
-1 135 0 142 28 203 50 109 148 179 304 218 149 37 329 53 567 50 191 -2 216
-4 277 -25z m-2002 -174 c95 -34 118 -52 152 -114 52 -94 63 -159 62 -368 -1
-358 -44 -479 -187 -520 -146 -42 -612 -65 -727 -36 -153 38 -196 98 -226 316
-16 120 -31 487 -21 527 9 35 89 121 140 151 99 58 228 76 522 73 200 -2 214
-3 285 -29z m-1604 -443 c45 -33 67 -70 71 -121 5 -59 -25 -117 -77 -147 -35
-21 -47 -21 -980 -24 -520 -2 -964 0 -988 3 -57 8 -116 60 -130 115 -19 75 12
146 78 182 34 17 75 18 1017 16 974 -3 982 -3 1009 -24z m5329 -2140 c66 -7
173 -14 237 -14 103 0 146 5 247 26 24 5 24 5 18 -64 -15 -159 -89 -371 -180
-515 l-43 -68 -57 113 c-72 145 -160 261 -318 422 l-126 128 51 -7 c28 -3 105
-13 171 -21z m-812 -652 c53 -41 140 -115 193 -165 96 -91 224 -231 224 -245
0 -5 -30 -18 -67 -30 -79 -25 -305 -84 -308 -80 -1 2 -12 53 -24 113 -28 135
-70 268 -127 402 -24 57 -44 106 -44 109 0 9 43 -20 153 -104z m-1173 -560
c-9 -4 -271 61 -315 78 -29 11 -28 12 79 55 59 24 111 46 114 49 3 3 33 -36
67 -87 34 -50 59 -93 55 -95z" />
</g>
</svg>
</div>
</body>
</html>

View File

@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace Docs.SocialCards{
public class SocialCardModel : PageModel
{
[BindProperty(Name = "title", SupportsGet = true)]
public string Title { get; set; }
[BindProperty(Name = "desc", SupportsGet = true)]
public string Description { get; set; }
[BindProperty(Name = "highlights", SupportsGet = true)]
public string Highlights { get; set; }
[BindProperty(Name = "footer", SupportsGet = true)]
public string Footer { get; set; }
private readonly ILogger<SocialCardModel> _logger;
public SocialCardModel(ILogger<SocialCardModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,148 @@
@font-face {
font-family: 'CascadiaCodePL';
src: url('CascadiaCodePL.woff2') format('woff2');
}
* {
padding:0;
margin:0;
}
:root {
--height: 618px;
--width:1200px;
--line-height: 39px;
--padding: 20px;
--rows: calc((--var(--height) - var(--padding) * 2) / var(--line-height));
--background: #1E2127;
--black: #000000;
--blue: #61AFEF;
--brightBlack: #5C6370;
--brightBlue: #61AFEF;
--brightCyan: #56B6C2;
--brightGreen: #98C379;
--brightPurple: #C678DD;
--brightRed: #E06C75;
--brightWhite: #FFFFFF;
--brightYellow: #D19A66;
--cyan: #56B6C2;
--foreground: #5C6370;
--green: #98C379;
--purple: #C678DD;
--red: #E06C75;
--white: #ABB2BF;
--yellow: #D19A66;
--folder: var(--yellow);
--dotnet: var(--blue);
--git: var(--green);
}
body{
font-family:'CascadiaCodePL',monospace;
font-weight:400;
font-size: calc(var(--line-height) - 5px);
}
#container {
background-color: var(--background);
color: #fff;
width: calc(var(--width) - var(--padding) * 2);
height: calc(var(--height) - var(--padding) * 2);
padding:var(--padding);
position: relative;
}
#console{
position: relative;
}
.line{
height:var(--line-height);
width:100%;
white-space: pre;
}
#title{
position: absolute;
left: 3ch;
top: calc(3 * var(--line-height));
margin: 0 -3px;
padding: 0 3px;
background:var(--background);
z-index:4;
}
#content{
position: absolute;
left: 3ch;
top: calc(5 * var(--line-height));;
height:calc(var(--height) - 7 * var(--line-height));
width: 53ch;
line-height:var(--line-height);
overflow-y: hidden;
}
#content p {
margin: 0;
}
#content p + ul {
margin-top:var(--line-height);
}
#content strong {
color: var(--yellow);
font-weight: 400;
}
#content em, #content i {
color: var(--blue);
font-style: normal;
}
#content ul {
list-style: "*";
margin-left: 1ch;
}
#content ul li {
padding-left:1ch;
}
#footer{
position: absolute;
top: calc(var(--height) - var(--padding) - var(--line-height) * 3);
left : 3ch;
background:var(--background);
width:51ch;
z-index:4;
}
#logo{
height:calc(var(--line-height) * 2.5);
width:calc(var(--line-height) * 2.5);
position:absolute;
right:2ch;
top:calc(var(--padding) / 2);
fill: var(--white);
opacity:.4;
}
#container::before {
/* fake scan lines */
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
z-index: 200;
background-size: 100% 4px, 5px 100%;
pointer-events: none;
}

View File

@@ -16,7 +16,7 @@ namespace Spectre.Console.Examples
// Create the tree
var tree = new Tree("Root")
.Style(Style.Parse("red"))
.Guide(TreeGuide.BoldLine);
.Guide(TreeGuide.Line);
// Add some nodes
var foo = tree.AddNode("[yellow]Foo[/]");

427
examples/Examples.sln Normal file
View File

@@ -0,0 +1,427 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{2571F1BD-6556-4F96-B27B-B6190E1BF13A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cli", "Cli", "{4682E9B7-B54C-419D-B92F-470DA4E5674C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Delegates", "Cli\Delegates\Delegates.csproj", "{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Demo", "Cli\Demo\Demo.csproj", "{7FC2594D-55D6-4688-AB7D-C9C903414448}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dynamic", "Cli\Dynamic\Dynamic.csproj", "{6EA8F935-A230-4171-8618-FDFABA553292}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Injection", "Cli\Injection\Injection.csproj", "{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logging", "Cli\Logging\Logging.csproj", "{37024E79-A857-4EB2-9B50-F724ED34E5EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{DD8EC1B0-F50C-44E4-8399-2D560F95E572}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borders", "Console\Borders\Borders.csproj", "{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Calendars", "Console\Calendars\Calendars.csproj", "{C64ADBA3-AED2-4938-8E26-8D6679C395CB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Canvas", "Console\Canvas\Canvas.csproj", "{B3393919-26F1-4200-88CD-B71EEAF0EA51}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Charts", "Console\Charts\Charts.csproj", "{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Colors", "Console\Colors\Colors.csproj", "{18562660-BF70-4EF3-A765-22713BDE2EB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Columns", "Console\Columns\Columns.csproj", "{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cursor", "Console\Cursor\Cursor.csproj", "{95BE948B-6102-4453-982D-C7B21E51B582}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emojis", "Console\Emojis\Emojis.csproj", "{6272C7ED-432E-4286-914C-898304A1880E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptions", "Console\Exceptions\Exceptions.csproj", "{20766F18-AEC7-4382-BDE2-0C846F2857AA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Figlet", "Console\Figlet\Figlet.csproj", "{1C374C51-6C82-4E71-9701-5F378BC0356C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grids", "Console\Grids\Grids.csproj", "{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "Console\Info\Info.csproj", "{FBCCBA12-9DBF-403C-9FA4-222CBB080955}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Links", "Console\Links\Links.csproj", "{B9414195-69A2-40E6-B071-751DCCE95AF0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Live", "Console\Live\Live.csproj", "{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Panels", "Console\Panels\Panels.csproj", "{12E7F2CE-E91B-446F-A269-F88FB546B6A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Progress", "Console\Progress\Progress.csproj", "{4554BDF3-0723-4076-B054-616D830942D4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prompt", "Console\Prompt\Prompt.csproj", "{85A37D38-54D9-4FA2-B311-CA48BD7AF916}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rules", "Console\Rules\Rules.csproj", "{305E2CE7-9D64-43D7-A26C-11036ACE2A89}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Showcase", "Console\Showcase\Showcase.csproj", "{5BEE8076-59A0-47BB-9CC6-222EC978AE16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Status", "Console\Status\Status.csproj", "{FCE2405B-A215-434B-A47C-32053E27A907}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tables", "Console\Tables\Tables.csproj", "{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trees", "Console\Trees\Trees.csproj", "{2BD88288-E05D-4978-B045-17937078E63C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|x64.ActiveCfg = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|x64.Build.0 = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|x86.ActiveCfg = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Debug|x86.Build.0 = Debug|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|Any CPU.Build.0 = Release|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|x64.ActiveCfg = Release|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|x64.Build.0 = Release|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|x86.ActiveCfg = Release|Any CPU
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF}.Release|x86.Build.0 = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|x64.ActiveCfg = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|x64.Build.0 = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|x86.ActiveCfg = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Debug|x86.Build.0 = Debug|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|Any CPU.Build.0 = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|x64.ActiveCfg = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|x64.Build.0 = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|x86.ActiveCfg = Release|Any CPU
{7FC2594D-55D6-4688-AB7D-C9C903414448}.Release|x86.Build.0 = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|x64.ActiveCfg = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|x64.Build.0 = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|x86.ActiveCfg = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Debug|x86.Build.0 = Debug|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|Any CPU.Build.0 = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|x64.ActiveCfg = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|x64.Build.0 = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|x86.ActiveCfg = Release|Any CPU
{6EA8F935-A230-4171-8618-FDFABA553292}.Release|x86.Build.0 = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|x64.ActiveCfg = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|x64.Build.0 = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|x86.ActiveCfg = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Debug|x86.Build.0 = Debug|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|Any CPU.Build.0 = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|x64.ActiveCfg = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|x64.Build.0 = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|x86.ActiveCfg = Release|Any CPU
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58}.Release|x86.Build.0 = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|x64.Build.0 = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Debug|x86.Build.0 = Debug|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|Any CPU.Build.0 = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|x64.ActiveCfg = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|x64.Build.0 = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|x86.ActiveCfg = Release|Any CPU
{37024E79-A857-4EB2-9B50-F724ED34E5EB}.Release|x86.Build.0 = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|x64.ActiveCfg = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|x64.Build.0 = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|x86.ActiveCfg = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Debug|x86.Build.0 = Debug|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|Any CPU.Build.0 = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|x64.ActiveCfg = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|x64.Build.0 = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|x86.ActiveCfg = Release|Any CPU
{DD8EC1B0-F50C-44E4-8399-2D560F95E572}.Release|x86.Build.0 = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|x64.ActiveCfg = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|x64.Build.0 = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|x86.ActiveCfg = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Debug|x86.Build.0 = Debug|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|Any CPU.Build.0 = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|x64.ActiveCfg = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|x64.Build.0 = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|x86.ActiveCfg = Release|Any CPU
{036D547D-1C9B-4E6F-B7E6-2E375E4CAF01}.Release|x86.Build.0 = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|x64.ActiveCfg = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|x64.Build.0 = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|x86.ActiveCfg = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Debug|x86.Build.0 = Debug|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|Any CPU.Build.0 = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|x64.ActiveCfg = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|x64.Build.0 = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|x86.ActiveCfg = Release|Any CPU
{C64ADBA3-AED2-4938-8E26-8D6679C395CB}.Release|x86.Build.0 = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|x64.ActiveCfg = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|x64.Build.0 = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|x86.ActiveCfg = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Debug|x86.Build.0 = Debug|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|Any CPU.Build.0 = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|x64.ActiveCfg = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|x64.Build.0 = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|x86.ActiveCfg = Release|Any CPU
{B3393919-26F1-4200-88CD-B71EEAF0EA51}.Release|x86.Build.0 = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|x64.Build.0 = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Debug|x86.Build.0 = Debug|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|Any CPU.Build.0 = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|x64.ActiveCfg = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|x64.Build.0 = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|x86.ActiveCfg = Release|Any CPU
{0CF6EE4B-4015-4DE0-9D48-1EADCDE296E6}.Release|x86.Build.0 = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|x64.ActiveCfg = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|x64.Build.0 = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|x86.ActiveCfg = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Debug|x86.Build.0 = Debug|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|Any CPU.Build.0 = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|x64.ActiveCfg = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|x64.Build.0 = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|x86.ActiveCfg = Release|Any CPU
{18562660-BF70-4EF3-A765-22713BDE2EB1}.Release|x86.Build.0 = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|x64.ActiveCfg = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|x64.Build.0 = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|x86.ActiveCfg = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Debug|x86.Build.0 = Debug|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|Any CPU.Build.0 = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|x64.ActiveCfg = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|x64.Build.0 = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|x86.ActiveCfg = Release|Any CPU
{264EBC5A-B897-4DA8-9C9E-9A445B1E368C}.Release|x86.Build.0 = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|x64.ActiveCfg = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|x64.Build.0 = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|x86.ActiveCfg = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Debug|x86.Build.0 = Debug|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|Any CPU.Build.0 = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|x64.ActiveCfg = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|x64.Build.0 = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|x86.ActiveCfg = Release|Any CPU
{95BE948B-6102-4453-982D-C7B21E51B582}.Release|x86.Build.0 = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|x64.ActiveCfg = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|x64.Build.0 = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|x86.ActiveCfg = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Debug|x86.Build.0 = Debug|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|Any CPU.Build.0 = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|x64.ActiveCfg = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|x64.Build.0 = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|x86.ActiveCfg = Release|Any CPU
{6272C7ED-432E-4286-914C-898304A1880E}.Release|x86.Build.0 = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|x64.ActiveCfg = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|x64.Build.0 = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|x86.ActiveCfg = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Debug|x86.Build.0 = Debug|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|Any CPU.Build.0 = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|x64.ActiveCfg = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|x64.Build.0 = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|x86.ActiveCfg = Release|Any CPU
{20766F18-AEC7-4382-BDE2-0C846F2857AA}.Release|x86.Build.0 = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|x64.ActiveCfg = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|x64.Build.0 = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Debug|x86.Build.0 = Debug|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|Any CPU.Build.0 = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|x64.ActiveCfg = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|x64.Build.0 = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|x86.ActiveCfg = Release|Any CPU
{1C374C51-6C82-4E71-9701-5F378BC0356C}.Release|x86.Build.0 = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|x64.ActiveCfg = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|x64.Build.0 = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|x86.ActiveCfg = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Debug|x86.Build.0 = Debug|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|Any CPU.Build.0 = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|x64.ActiveCfg = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|x64.Build.0 = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|x86.ActiveCfg = Release|Any CPU
{6F7AB11D-D2AE-4D1C-AFEE-7FBA922D6C26}.Release|x86.Build.0 = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|x64.ActiveCfg = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|x64.Build.0 = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|x86.ActiveCfg = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Debug|x86.Build.0 = Debug|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|Any CPU.Build.0 = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|x64.ActiveCfg = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|x64.Build.0 = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|x86.ActiveCfg = Release|Any CPU
{FBCCBA12-9DBF-403C-9FA4-222CBB080955}.Release|x86.Build.0 = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|x64.ActiveCfg = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|x64.Build.0 = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|x86.ActiveCfg = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Debug|x86.Build.0 = Debug|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|Any CPU.Build.0 = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|x64.ActiveCfg = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|x64.Build.0 = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|x86.ActiveCfg = Release|Any CPU
{B9414195-69A2-40E6-B071-751DCCE95AF0}.Release|x86.Build.0 = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|x64.ActiveCfg = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|x64.Build.0 = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|x86.ActiveCfg = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Debug|x86.Build.0 = Debug|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|Any CPU.Build.0 = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|x64.ActiveCfg = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|x64.Build.0 = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|x86.ActiveCfg = Release|Any CPU
{4AE3AC67-A927-42CC-B286-E0A0735DC7A2}.Release|x86.Build.0 = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|x64.ActiveCfg = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|x64.Build.0 = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|x86.ActiveCfg = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Debug|x86.Build.0 = Debug|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|Any CPU.Build.0 = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|x64.ActiveCfg = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|x64.Build.0 = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|x86.ActiveCfg = Release|Any CPU
{12E7F2CE-E91B-446F-A269-F88FB546B6A8}.Release|x86.Build.0 = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|x64.ActiveCfg = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|x64.Build.0 = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|x86.ActiveCfg = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Debug|x86.Build.0 = Debug|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|Any CPU.Build.0 = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|x64.ActiveCfg = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|x64.Build.0 = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|x86.ActiveCfg = Release|Any CPU
{4554BDF3-0723-4076-B054-616D830942D4}.Release|x86.Build.0 = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|x64.ActiveCfg = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|x64.Build.0 = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|x86.ActiveCfg = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Debug|x86.Build.0 = Debug|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|Any CPU.Build.0 = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|x64.ActiveCfg = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|x64.Build.0 = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|x86.ActiveCfg = Release|Any CPU
{85A37D38-54D9-4FA2-B311-CA48BD7AF916}.Release|x86.Build.0 = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|x64.ActiveCfg = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|x64.Build.0 = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|x86.ActiveCfg = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Debug|x86.Build.0 = Debug|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|Any CPU.Build.0 = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|x64.ActiveCfg = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|x64.Build.0 = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|x86.ActiveCfg = Release|Any CPU
{305E2CE7-9D64-43D7-A26C-11036ACE2A89}.Release|x86.Build.0 = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|x64.ActiveCfg = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|x64.Build.0 = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|x86.ActiveCfg = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Debug|x86.Build.0 = Debug|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|Any CPU.Build.0 = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|x64.ActiveCfg = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|x64.Build.0 = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|x86.ActiveCfg = Release|Any CPU
{5BEE8076-59A0-47BB-9CC6-222EC978AE16}.Release|x86.Build.0 = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|x64.ActiveCfg = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|x64.Build.0 = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|x86.ActiveCfg = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Debug|x86.Build.0 = Debug|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|Any CPU.Build.0 = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|x64.ActiveCfg = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|x64.Build.0 = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|x86.ActiveCfg = Release|Any CPU
{FCE2405B-A215-434B-A47C-32053E27A907}.Release|x86.Build.0 = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|x64.ActiveCfg = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|x64.Build.0 = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|x86.ActiveCfg = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Debug|x86.Build.0 = Debug|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|Any CPU.Build.0 = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|x64.ActiveCfg = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|x64.Build.0 = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|x86.ActiveCfg = Release|Any CPU
{3D16490A-9EBA-488C-9B3E-6A11FC1E0300}.Release|x86.Build.0 = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|x64.ActiveCfg = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|x64.Build.0 = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|x86.ActiveCfg = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Debug|x86.Build.0 = Debug|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|Any CPU.Build.0 = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|x64.ActiveCfg = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|x64.Build.0 = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|x86.ActiveCfg = Release|Any CPU
{2BD88288-E05D-4978-B045-17937078E63C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E2C9023A-D24F-4F5D-8411-5E2FEA642FEF} = {4682E9B7-B54C-419D-B92F-470DA4E5674C}
{7FC2594D-55D6-4688-AB7D-C9C903414448} = {4682E9B7-B54C-419D-B92F-470DA4E5674C}
{6EA8F935-A230-4171-8618-FDFABA553292} = {4682E9B7-B54C-419D-B92F-470DA4E5674C}
{DEB88B47-658E-4FCB-BD1D-05C99E7EFA58} = {4682E9B7-B54C-419D-B92F-470DA4E5674C}
{37024E79-A857-4EB2-9B50-F724ED34E5EB} = {4682E9B7-B54C-419D-B92F-470DA4E5674C}
{DD8EC1B0-F50C-44E4-8399-2D560F95E572} = {2571F1BD-6556-4F96-B27B-B6190E1BF13A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3EE724C5-CAB4-410D-AC63-8D4260EF83ED}
EndGlobalSection
EndGlobal

View File

@@ -1,7 +1,7 @@
{
"projects": [ "src" ],
"projects": [ "src", "tests" ],
"sdk": {
"version": "5.0.202",
"version": "5.0.301",
"rollForward": "latestPatch"
}
}

View File

@@ -92,4 +92,10 @@ dotnet_diagnostic.IDE0004.severity = warning
dotnet_diagnostic.CA1810.severity = none
# IDE0044: Add readonly modifier
dotnet_diagnostic.IDE0044.severity = warning
dotnet_diagnostic.IDE0044.severity = warning
# RCS1047: Non-asynchronous method name should not end with 'Async'.
dotnet_diagnostic.RCS1047.severity = none
# RCS1090: Call 'ConfigureAwait(false)'.
dotnet_diagnostic.RCS1090.severity = warning

View File

@@ -0,0 +1,16 @@
namespace Spectre.Console.Analyzer.Sandbox
{
/// <summary>
/// Sample sandbox for testing out analyzers.
/// </summary>
public static class Program
{
/// <summary>
/// The program's entry point.
/// </summary>
public static void Main()
{
AnsiConsole.WriteLine("Project is set up with a reference to Spectre.Console.Analyzer");
}
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\stylecop.json" Link="Properties/stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Spectre.Console.Analyzer\Spectre.Console.Analyzer.csproj" PrivateAssets="all" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
<ProjectReference Include="..\Spectre.Console\Spectre.Console.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,79 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Analyzer", "Spectre.Console.Analyzer\Spectre.Console.Analyzer.csproj", "{18178142-A80D-424F-882D-DB0F787210BD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Analyzer.Sandbox", "Spectre.Console.Analyzer.Sandbox\Spectre.Console.Analyzer.Sandbox.csproj", "{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Analyzer.Tests", "..\test\Spectre.Console.Analyzer.Tests\Spectre.Console.Analyzer.Tests.csproj", "{609D5D1B-D904-4A31-B237-A04B49910166}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console", "Spectre.Console\Spectre.Console.csproj", "{6BFF310F-9601-4E5D-BC80-118AC708D72A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|x64.ActiveCfg = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|x64.Build.0 = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|x86.ActiveCfg = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Debug|x86.Build.0 = Debug|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|Any CPU.Build.0 = Release|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|x64.ActiveCfg = Release|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|x64.Build.0 = Release|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|x86.ActiveCfg = Release|Any CPU
{18178142-A80D-424F-882D-DB0F787210BD}.Release|x86.Build.0 = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|x64.ActiveCfg = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|x64.Build.0 = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|x86.ActiveCfg = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Debug|x86.Build.0 = Debug|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|Any CPU.Build.0 = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|x64.ActiveCfg = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|x64.Build.0 = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|x86.ActiveCfg = Release|Any CPU
{44D2E280-8FCD-4FC1-9133-F61E344FD6A6}.Release|x86.Build.0 = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|Any CPU.Build.0 = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|x64.ActiveCfg = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|x64.Build.0 = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|x86.ActiveCfg = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Debug|x86.Build.0 = Debug|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|Any CPU.ActiveCfg = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|Any CPU.Build.0 = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|x64.ActiveCfg = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|x64.Build.0 = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|x86.ActiveCfg = Release|Any CPU
{609D5D1B-D904-4A31-B237-A04B49910166}.Release|x86.Build.0 = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|x64.ActiveCfg = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|x64.Build.0 = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|x86.ActiveCfg = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Debug|x86.Build.0 = Debug|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|Any CPU.Build.0 = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|x64.ActiveCfg = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|x64.Build.0 = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|x86.ActiveCfg = Release|Any CPU
{6BFF310F-9601-4E5D-BC80-118AC708D72A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3BABBA82-B60D-45CE-9C56-8B833474DD3C}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,89 @@
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Analyzer to suggest using available instances of AnsiConsole over the static methods.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class FavorInstanceAnsiConsoleOverStaticAnalyzer : SpectreAnalyzer
{
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic;
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(_diagnosticDescriptor);
/// <inheritdoc />
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
{
compilationStartContext.RegisterOperationAction(
context =>
{
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
// if this operation isn't an invocation against one of the System.Console methods
// defined in _methods then we can safely stop analyzing and return;
var invocationOperation = (IInvocationOperation)context.Operation;
if (!Equals(invocationOperation.TargetMethod.ContainingType, ansiConsoleType))
{
return;
}
if (!HasFieldAnsiConsole(invocationOperation.Syntax) &&
!HasParameterAnsiConsole(invocationOperation.Syntax))
{
return;
}
var methodSymbol = invocationOperation.TargetMethod;
var displayString = SymbolDisplay.ToDisplayString(
methodSymbol,
SymbolDisplayFormat.CSharpShortErrorMessageFormat
.WithParameterOptions(SymbolDisplayParameterOptions.None)
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
context.ReportDiagnostic(
Diagnostic.Create(
_diagnosticDescriptor,
invocationOperation.Syntax.GetLocation(),
displayString));
}, OperationKind.Invocation);
}
private static bool HasParameterAnsiConsole(SyntaxNode syntaxNode)
{
return syntaxNode
.Ancestors().OfType<MethodDeclarationSyntax>()
.First()
.ParameterList.Parameters
.Any(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole");
}
private static bool HasFieldAnsiConsole(SyntaxNode syntaxNode)
{
var isStatic = syntaxNode
.Ancestors()
.OfType<MethodDeclarationSyntax>()
.First()
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
return syntaxNode
.Ancestors().OfType<ClassDeclarationSyntax>()
.First()
.Members
.OfType<FieldDeclarationSyntax>()
.Any(i =>
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)));
}
}
}

View File

@@ -0,0 +1,78 @@
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Analyzer to detect calls to live renderables within a live renderable context.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[Shared]
public class NoConcurrentLiveRenderablesAnalyzer : SpectreAnalyzer
{
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
Descriptors.S1020_AvoidConcurrentCallsToMultipleLiveRenderables;
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(_diagnosticDescriptor);
/// <inheritdoc />
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
{
compilationStartContext.RegisterOperationAction(
context =>
{
var invocationOperation = (IInvocationOperation)context.Operation;
var methodSymbol = invocationOperation.TargetMethod;
const string StartMethod = "Start";
if (methodSymbol.Name != StartMethod)
{
return;
}
var liveTypes = Constants.LiveRenderables
.Select(i => context.Compilation.GetTypeByMetadataName(i))
.ToImmutableArray();
if (liveTypes.All(i => !Equals(i, methodSymbol.ContainingType)))
{
return;
}
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
var parentInvocations = invocationOperation
.Syntax.Ancestors()
.OfType<InvocationExpressionSyntax>()
.Select(i => model.GetOperation(i))
.OfType<IInvocationOperation>()
.ToList();
if (parentInvocations.All(parent =>
parent.TargetMethod.Name != StartMethod || !liveTypes.Contains(parent.TargetMethod.ContainingType)))
{
return;
}
var displayString = SymbolDisplay.ToDisplayString(
methodSymbol,
SymbolDisplayFormat.CSharpShortErrorMessageFormat
.WithParameterOptions(SymbolDisplayParameterOptions.None)
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
context.ReportDiagnostic(
Diagnostic.Create(
_diagnosticDescriptor,
invocationOperation.Syntax.GetLocation(),
displayString));
}, OperationKind.Invocation);
}
}
}

View File

@@ -0,0 +1,84 @@
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Analyzer to detect calls to live renderables within a live renderable context.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[Shared]
public class NoPromptsDuringLiveRenderablesAnalyzer : SpectreAnalyzer
{
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
Descriptors.S1021_AvoidPromptCallsDuringLiveRenderables;
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(_diagnosticDescriptor);
/// <inheritdoc />
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
{
compilationStartContext.RegisterOperationAction(
context =>
{
// if this operation isn't an invocation against one of the System.Console methods
// defined in _methods then we can safely stop analyzing and return;
var invocationOperation = (IInvocationOperation)context.Operation;
var methodSymbol = invocationOperation.TargetMethod;
var promptMethods = ImmutableArray.Create("Ask", "Confirm", "Prompt");
if (!promptMethods.Contains(methodSymbol.Name))
{
return;
}
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
var ansiConsoleExtensionsType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsoleExtensions");
if (!Equals(methodSymbol.ContainingType, ansiConsoleType) && !Equals(methodSymbol.ContainingType, ansiConsoleExtensionsType))
{
return;
}
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
var parentInvocations = invocationOperation
.Syntax.Ancestors()
.OfType<InvocationExpressionSyntax>()
.Select(i => model.GetOperation(i))
.OfType<IInvocationOperation>()
.ToList();
var liveTypes = Constants.LiveRenderables
.Select(i => context.Compilation.GetTypeByMetadataName(i))
.ToImmutableArray();
if (parentInvocations.All(parent =>
parent.TargetMethod.Name != "Start" ||
!liveTypes.Contains(parent.TargetMethod.ContainingType)))
{
return;
}
var displayString = SymbolDisplay.ToDisplayString(
methodSymbol,
SymbolDisplayFormat.CSharpShortErrorMessageFormat
.WithParameterOptions(SymbolDisplayParameterOptions.None)
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
context.ReportDiagnostic(
Diagnostic.Create(
_diagnosticDescriptor,
invocationOperation.Syntax.GetLocation(),
displayString));
}, OperationKind.Invocation);
}
}
}

View File

@@ -0,0 +1,25 @@
using Microsoft.CodeAnalysis.Diagnostics;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Base class for Spectre analyzers.
/// </summary>
public abstract class SpectreAnalyzer : DiagnosticAnalyzer
{
/// <inheritdoc />
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.EnableConcurrentExecution();
context.RegisterCompilationStartAction(AnalyzeCompilation);
}
/// <summary>
/// Analyze compilation.
/// </summary>
/// <param name="compilationStartContext">Compilation Start Analysis Context.</param>
protected abstract void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext);
}
}

View File

@@ -0,0 +1,63 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Analyzer to enforce the use of AnsiConsole over System.Console for known methods.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class UseSpectreInsteadOfSystemConsoleAnalyzer : SpectreAnalyzer
{
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
Descriptors.S1000_UseAnsiConsoleOverSystemConsole;
private static readonly string[] _methods = { "WriteLine", "Write" };
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(_diagnosticDescriptor);
/// <inheritdoc />
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
{
compilationStartContext.RegisterOperationAction(
context =>
{
// if this operation isn't an invocation against one of the System.Console methods
// defined in _methods then we can safely stop analyzing and return;
var invocationOperation = (IInvocationOperation)context.Operation;
var methodName = System.Array.Find(_methods, i => i.Equals(invocationOperation.TargetMethod.Name));
if (methodName == null)
{
return;
}
var systemConsoleType = context.Compilation.GetTypeByMetadataName("System.Console");
if (!Equals(invocationOperation.TargetMethod.ContainingType, systemConsoleType))
{
return;
}
var methodSymbol = invocationOperation.TargetMethod;
var displayString = SymbolDisplay.ToDisplayString(
methodSymbol,
SymbolDisplayFormat.CSharpShortErrorMessageFormat
.WithParameterOptions(SymbolDisplayParameterOptions.None)
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
context.ReportDiagnostic(
Diagnostic.Create(
_diagnosticDescriptor,
invocationOperation.Syntax.GetLocation(),
displayString));
}, OperationKind.Invocation);
}
}
}

View File

@@ -0,0 +1,15 @@
namespace Spectre.Console.Analyzer
{
internal static class Constants
{
internal const string StaticInstance = "AnsiConsole";
internal const string SpectreConsole = "Spectre.Console";
internal static readonly string[] LiveRenderables =
{
"Spectre.Console.LiveDisplay",
"Spectre.Console.Progress",
"Spectre.Console.Status",
};
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections.Concurrent;
using Microsoft.CodeAnalysis;
using static Microsoft.CodeAnalysis.DiagnosticSeverity;
using static Spectre.Console.Analyzer.Descriptors.Category;
namespace Spectre.Console.Analyzer
{
/// <summary>
/// Code analysis descriptors.
/// </summary>
public static class Descriptors
{
internal enum Category
{
Usage, // 1xxx
}
private static readonly ConcurrentDictionary<Category, string> _categoryMapping = new();
private static DiagnosticDescriptor Rule(string id, string title, Category category, DiagnosticSeverity defaultSeverity, string messageFormat, string? description = null)
{
var helpLink = $"https://spectreconsole.net/analyzer/rules/{id.ToLowerInvariant()}";
const bool IsEnabledByDefault = true;
return new DiagnosticDescriptor(
id,
title,
messageFormat,
_categoryMapping.GetOrAdd(category, c => c.ToString()),
defaultSeverity,
IsEnabledByDefault,
description,
helpLink);
}
/// <summary>
/// Gets definitions of diagnostics Spectre1000.
/// </summary>
public static DiagnosticDescriptor S1000_UseAnsiConsoleOverSystemConsole { get; } =
Rule(
"Spectre1000",
"Use AnsiConsole instead of System.Console",
Usage,
Warning,
"Use AnsiConsole instead of System.Console");
/// <summary>
/// Gets definitions of diagnostics Spectre1010.
/// </summary>
public static DiagnosticDescriptor S1010_FavorInstanceAnsiConsoleOverStatic { get; } =
Rule(
"Spectre1010",
"Favor the use of the instance of AnsiConsole over the static helper.",
Usage,
Info,
"Favor the use of the instance of AnsiConsole over the static helper.");
/// <summary>
/// Gets definitions of diagnostics Spectre1020.
/// </summary>
public static DiagnosticDescriptor S1020_AvoidConcurrentCallsToMultipleLiveRenderables { get; } =
Rule(
"Spectre1020",
"Avoid calling other live renderables while a current renderable is running.",
Usage,
Warning,
"Avoid calling other live renderables while a current renderable is running.");
/// <summary>
/// Gets definitions of diagnostics Spectre1020.
/// </summary>
public static DiagnosticDescriptor S1021_AvoidPromptCallsDuringLiveRenderables { get; } =
Rule(
"Spectre1021",
"Avoid prompting for input while a current renderable is running.",
Usage,
Warning,
"Avoid prompting for input while a current renderable is running.");
}
}

View File

@@ -0,0 +1,116 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Spectre.Console.Analyzer.CodeActions
{
/// <summary>
/// Code action to change calls to System.Console to AnsiConsole.
/// </summary>
public class SwitchToAnsiConsoleAction : CodeAction
{
private readonly Document _document;
private readonly InvocationExpressionSyntax _originalInvocation;
/// <summary>
/// Initializes a new instance of the <see cref="SwitchToAnsiConsoleAction"/> class.
/// </summary>
/// <param name="document">Document to change.</param>
/// <param name="originalInvocation">The method to change.</param>
/// <param name="title">Title of the fix.</param>
public SwitchToAnsiConsoleAction(Document document, InvocationExpressionSyntax originalInvocation, string title)
{
_document = document;
_originalInvocation = originalInvocation;
Title = title;
}
/// <inheritdoc />
public override string Title { get; }
/// <inheritdoc />
public override string EquivalenceKey => Title;
/// <inheritdoc />
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
var originalCaller = ((MemberAccessExpressionSyntax)_originalInvocation.Expression).Name.ToString();
var syntaxTree = await _document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var root = (CompilationUnitSyntax)await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
// If there is an ansiConsole passed into the method then we'll use it.
// otherwise we'll check for a field level instance.
// if neither of those exist we'll fall back to the static param.
var ansiConsoleParameterDeclaration = GetAnsiConsoleParameterDeclaration();
var ansiConsoleFieldIdentifier = GetAnsiConsoleFieldDeclaration();
var ansiConsoleIdentifier = ansiConsoleParameterDeclaration ??
ansiConsoleFieldIdentifier ??
Constants.StaticInstance;
// Replace the System.Console call with a call to the identifier above.
var newRoot = root.ReplaceNode(
_originalInvocation,
GetImportedSpectreCall(originalCaller, ansiConsoleIdentifier));
// If we are calling the static instance and Spectre isn't imported yet we should do so.
if (ansiConsoleIdentifier == Constants.StaticInstance && root.Usings.ToList().All(i => i.Name.ToString() != Constants.SpectreConsole))
{
newRoot = newRoot.AddUsings(Syntax.SpectreUsing);
}
return _document.WithSyntaxRoot(newRoot);
}
private string? GetAnsiConsoleParameterDeclaration()
{
return _originalInvocation
.Ancestors().OfType<MethodDeclarationSyntax>()
.First()
.ParameterList.Parameters
.FirstOrDefault(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole")
?.Identifier.Text;
}
private string? GetAnsiConsoleFieldDeclaration()
{
// let's look to see if our call is in a static method.
// if so we'll only want to look for static IAnsiConsoles
// and vice-versa if we aren't.
var isStatic = _originalInvocation
.Ancestors()
.OfType<MethodDeclarationSyntax>()
.First()
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
return _originalInvocation
.Ancestors().OfType<ClassDeclarationSyntax>()
.First()
.Members
.OfType<FieldDeclarationSyntax>()
.FirstOrDefault(i =>
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)))
?.Declaration.Variables.First().Identifier.Text;
}
private ExpressionSyntax GetImportedSpectreCall(string originalCaller, string ansiConsoleIdentifier)
{
return ExpressionStatement(
InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(ansiConsoleIdentifier),
IdentifierName(originalCaller)))
.WithArgumentList(_originalInvocation.ArgumentList)
.WithTrailingTrivia(_originalInvocation.GetTrailingTrivia())
.WithLeadingTrivia(_originalInvocation.GetLeadingTrivia()))
.Expression;
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Immutable;
using System.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Spectre.Console.Analyzer.CodeActions;
namespace Spectre.Console.Analyzer.FixProviders
{
/// <summary>
/// Fix provider to change System.Console calls to AnsiConsole calls.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp)]
[Shared]
public class StaticAnsiConsoleToInstanceFix : CodeFixProvider
{
/// <inheritdoc />
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic.Id);
/// <inheritdoc />
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
/// <inheritdoc />
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
context.RegisterCodeFix(
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static AnsiConsole calls to local instance."),
context.Diagnostics);
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Immutable;
using System.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Spectre.Console.Analyzer.CodeActions;
namespace Spectre.Console.Analyzer.FixProviders
{
/// <summary>
/// Fix provider to change System.Console calls to AnsiConsole calls.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp)]
[Shared]
public class SystemConsoleToAnsiConsoleFix : CodeFixProvider
{
/// <inheritdoc />
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
Descriptors.S1000_UseAnsiConsoleOverSystemConsole.Id);
/// <inheritdoc />
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
/// <inheritdoc />
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
context.RegisterCodeFix(
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static call to AnsiConsole to Spectre.Console.AnsiConsole"),
context.Diagnostics);
}
}
}

View File

@@ -0,0 +1,10 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Spectre.Console.Analyzer
{
internal static class Syntax
{
public static readonly UsingDirectiveSyntax SpectreUsing = UsingDirective(QualifiedName(IdentifierName("Spectre"), IdentifierName("Console")));
}
}

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Best practice analyzers for Spectre.Console.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<Nullable>enable</Nullable>
<NoPackageAnalysis>true</NoPackageAnalysis>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\stylecop.json" Link="Properties/stylecop.json" />
<None Include="../../resources/gfx/small-logo.png" Pack="true" PackagePath="\" Link="Properties/small-logo.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.8" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.6.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.6.1" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<None Remove="bin\Debug\netstandard2.0\\Spectre.Console.Analyzer.dll" />
</ItemGroup>
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Project>

View File

@@ -11,6 +11,20 @@ namespace Spectre.Console.Testing
private Action<CommandApp>? _appConfiguration;
private Action<IConfigurator>? _configuration;
/// <summary>
/// Initializes a new instance of the <see cref="CommandAppTester"/> class.
/// </summary>
/// <param name="registrar">The registrar.</param>
public CommandAppTester(ITypeRegistrar? registrar = null)
{
Registrar = registrar;
}
/// <summary>
/// Gets or sets the Registrar to use in the CommandApp.
/// </summary>
public ITypeRegistrar? Registrar { get; set; }
/// <summary>
/// Sets the default command.
/// </summary>
@@ -88,7 +102,7 @@ namespace Spectre.Console.Testing
CommandContext? context = null;
CommandSettings? settings = null;
var app = new CommandApp();
var app = new CommandApp(Registrar);
_appConfiguration?.Invoke(app);
if (_configuration != null)

View File

@@ -12,7 +12,7 @@ namespace Spectre.Console.Testing
public async Task<T> Run<T>(Func<Task<T>> func)
{
return await func();
return await func().ConfigureAwait(false);
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Spectre.Console.Testing
{
@@ -74,5 +76,11 @@ namespace Spectre.Console.Testing
return _input.Dequeue();
}
/// <inheritdoc/>
public Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)
{
return Task.FromResult(ReadKey(intercept));
}
}
}

View File

@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30225.117
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console", "Spectre.Console\Spectre.Console.csproj", "{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Tests", "Spectre.Console.Tests\Spectre.Console.Tests.csproj", "{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{20595AD4-8D75-4AF8-B6BC-9C38C160423F}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -17,28 +15,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{20595AD4-8
stylecop.json = stylecop.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F0575243-121F-4DEE-9F6B-246E26DC0844}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tables", "..\examples\Console\Tables\Tables.csproj", "{94ECCBA8-7EBF-4B53-8379-52EB2327417E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Panels", "..\examples\Console\Panels\Panels.csproj", "{BFF37228-B376-4ADD-9657-4E501F929713}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grids", "..\examples\Console\Grids\Grids.csproj", "{C7FF6FDB-FB59-4517-8669-521C96AB7323}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Colors", "..\examples\Console\Colors\Colors.csproj", "{1F51C55C-BA4C-4856-9001-0F7924FFB179}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Columns", "..\examples\Console\Columns\Columns.csproj", "{33357599-C79D-4299-888F-634E2C3EACEF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "..\examples\Console\Info\Info.csproj", "{225CE0D4-06AB-411A-8D29-707504FE53B3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borders", "..\examples\Console\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Links", "..\examples\Console\Links\Links.csproj", "{6AF8C93B-AA41-4F44-8B1B-B8D166576174}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emojis", "..\examples\Console\Emojis\Emojis.csproj", "{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptions", "..\examples\Console\Exceptions\Exceptions.csproj", "{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D}"
ProjectSection(SolutionItems) = preProject
..\.github\workflows\ci.yaml = ..\.github\workflows\ci.yaml
@@ -46,49 +22,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{C3E2CB
..\.github\workflows\publish.yaml = ..\.github\workflows\publish.yaml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Calendars", "..\examples\Console\Calendars\Calendars.csproj", "{57691C7D-683D-46E6-AA4F-57A8C5F65D25}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rules", "..\examples\Console\Rules\Rules.csproj", "{8622A261-02C6-40CA-9797-E3F01ED87D6B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cursor", "..\examples\Console\Cursor\Cursor.csproj", "{75C608C3-ABB4-4168-A229-7F8250B946D1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prompt", "..\examples\Console\Prompt\Prompt.csproj", "{6351C70F-F368-46DB-BAED-9B87CCD69353}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Figlet", "..\examples\Console\Figlet\Figlet.csproj", "{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Canvas", "..\examples\Console\Canvas\Canvas.csproj", "{5693761A-754A-40A8-9144-36510D6A4D69}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.ImageSharp", "Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj", "{0EFE694D-0770-4E71-BF4E-EC2B41362F79}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Progress", "..\examples\Console\Progress\Progress.csproj", "{2B712A52-40F1-4C1C-833E-7C869ACA91F3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Status", "..\examples\Console\Status\Status.csproj", "{3716AFDF-0904-4635-8422-86E6B9356840}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Charts", "..\examples\Console\Charts\Charts.csproj", "{0A1AFD26-86A0-4060-B277-D380172C7070}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cli", "Cli", "{42792D7F-0BB6-4EE1-A314-8889305A4C48}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Delegates", "..\examples\Cli\Delegates\Delegates.csproj", "{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dynamic", "..\examples\Cli\Dynamic\Dynamic.csproj", "{E9C02C5A-710C-4A57-A008-E3EAC89305CC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Injection", "..\examples\Cli\Injection\Injection.csproj", "{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Testing", "Spectre.Console.Testing\Spectre.Console.Testing.csproj", "{7D5F6704-8249-46DD-906C-9E66419F215F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{E0E45070-123C-4A4D-AA98-2A780308876C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trees", "..\examples\Console\Trees\Trees.csproj", "{CA7AF967-3FA5-4CB1-9564-740CF4527895}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logging", "..\examples\Cli\Logging\Logging.csproj", "{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Showcase", "..\examples\Console\Showcase\Showcase.csproj", "{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{A0C772BA-C5F4-451D-AA7A-4045F2FA0201}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "..\examples\Shared\Shared.csproj", "{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Live", "..\examples\Console\Live\Live.csproj", "{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Tests", "..\test\Spectre.Console.Tests\Spectre.Console.Tests.csproj", "{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -112,210 +52,6 @@ Global
{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x64.Build.0 = Release|Any CPU
{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x86.ActiveCfg = Release|Any CPU
{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x86.Build.0 = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x64.ActiveCfg = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x64.Build.0 = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x86.ActiveCfg = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x86.Build.0 = Debug|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|Any CPU.Build.0 = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x64.ActiveCfg = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x64.Build.0 = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x86.ActiveCfg = Release|Any CPU
{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x86.Build.0 = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|x64.ActiveCfg = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|x64.Build.0 = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|x86.ActiveCfg = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Debug|x86.Build.0 = Debug|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|Any CPU.Build.0 = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|x64.ActiveCfg = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|x64.Build.0 = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|x86.ActiveCfg = Release|Any CPU
{94ECCBA8-7EBF-4B53-8379-52EB2327417E}.Release|x86.Build.0 = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|x64.ActiveCfg = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|x64.Build.0 = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|x86.ActiveCfg = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Debug|x86.Build.0 = Debug|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|Any CPU.Build.0 = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|x64.ActiveCfg = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|x64.Build.0 = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|x86.ActiveCfg = Release|Any CPU
{BFF37228-B376-4ADD-9657-4E501F929713}.Release|x86.Build.0 = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|x64.ActiveCfg = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|x64.Build.0 = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|x86.ActiveCfg = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Debug|x86.Build.0 = Debug|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|Any CPU.Build.0 = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|x64.ActiveCfg = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|x64.Build.0 = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|x86.ActiveCfg = Release|Any CPU
{C7FF6FDB-FB59-4517-8669-521C96AB7323}.Release|x86.Build.0 = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|x64.ActiveCfg = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|x64.Build.0 = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|x86.ActiveCfg = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Debug|x86.Build.0 = Debug|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|Any CPU.Build.0 = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|x64.ActiveCfg = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|x64.Build.0 = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|x86.ActiveCfg = Release|Any CPU
{1F51C55C-BA4C-4856-9001-0F7924FFB179}.Release|x86.Build.0 = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|x64.ActiveCfg = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|x64.Build.0 = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|x86.ActiveCfg = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Debug|x86.Build.0 = Debug|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|Any CPU.Build.0 = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|x64.ActiveCfg = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|x64.Build.0 = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|x86.ActiveCfg = Release|Any CPU
{33357599-C79D-4299-888F-634E2C3EACEF}.Release|x86.Build.0 = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|x64.ActiveCfg = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|x64.Build.0 = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|x86.ActiveCfg = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Debug|x86.Build.0 = Debug|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|Any CPU.Build.0 = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x64.ActiveCfg = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x64.Build.0 = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x86.ActiveCfg = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x86.Build.0 = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|Any CPU.Build.0 = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x64.ActiveCfg = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x64.Build.0 = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x86.ActiveCfg = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x86.Build.0 = Debug|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|Any CPU.ActiveCfg = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|Any CPU.Build.0 = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.ActiveCfg = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.Build.0 = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.ActiveCfg = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.Build.0 = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.ActiveCfg = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.Build.0 = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.ActiveCfg = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.Build.0 = Debug|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.Build.0 = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.ActiveCfg = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.Build.0 = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.ActiveCfg = Release|Any CPU
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.Build.0 = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x64.ActiveCfg = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x64.Build.0 = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x86.ActiveCfg = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x86.Build.0 = Debug|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|Any CPU.Build.0 = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x64.ActiveCfg = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x64.Build.0 = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.ActiveCfg = Release|Any CPU
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.Build.0 = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x64.ActiveCfg = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x64.Build.0 = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x86.ActiveCfg = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x86.Build.0 = Debug|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|Any CPU.Build.0 = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x64.ActiveCfg = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x64.Build.0 = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x86.ActiveCfg = Release|Any CPU
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x86.Build.0 = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x64.ActiveCfg = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x64.Build.0 = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x86.ActiveCfg = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x86.Build.0 = Debug|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|Any CPU.Build.0 = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x64.ActiveCfg = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x64.Build.0 = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x86.ActiveCfg = Release|Any CPU
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x86.Build.0 = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x64.ActiveCfg = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x64.Build.0 = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x86.ActiveCfg = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x86.Build.0 = Debug|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|Any CPU.Build.0 = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x64.ActiveCfg = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x64.Build.0 = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x86.ActiveCfg = Release|Any CPU
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x86.Build.0 = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x64.ActiveCfg = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x64.Build.0 = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x86.Build.0 = Debug|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|Any CPU.Build.0 = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x64.ActiveCfg = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x64.Build.0 = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x86.ActiveCfg = Release|Any CPU
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x86.Build.0 = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x64.ActiveCfg = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x64.Build.0 = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x86.ActiveCfg = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x86.Build.0 = Debug|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|Any CPU.Build.0 = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x64.ActiveCfg = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x64.Build.0 = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.ActiveCfg = Release|Any CPU
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.Build.0 = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x64.ActiveCfg = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x64.Build.0 = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Debug|x86.Build.0 = Debug|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|Any CPU.Build.0 = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x64.ActiveCfg = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x64.Build.0 = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x86.ActiveCfg = Release|Any CPU
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1}.Release|x86.Build.0 = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|x64.ActiveCfg = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|x64.Build.0 = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|x86.ActiveCfg = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Debug|x86.Build.0 = Debug|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|Any CPU.Build.0 = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|x64.ActiveCfg = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|x64.Build.0 = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|x86.ActiveCfg = Release|Any CPU
{5693761A-754A-40A8-9144-36510D6A4D69}.Release|x86.Build.0 = Release|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -328,78 +64,6 @@ Global
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x64.Build.0 = Release|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x86.ActiveCfg = Release|Any CPU
{0EFE694D-0770-4E71-BF4E-EC2B41362F79}.Release|x86.Build.0 = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|x64.ActiveCfg = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|x64.Build.0 = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|x86.ActiveCfg = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Debug|x86.Build.0 = Debug|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|Any CPU.Build.0 = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|x64.ActiveCfg = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|x64.Build.0 = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|x86.ActiveCfg = Release|Any CPU
{2B712A52-40F1-4C1C-833E-7C869ACA91F3}.Release|x86.Build.0 = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|x64.ActiveCfg = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|x64.Build.0 = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|x86.ActiveCfg = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Debug|x86.Build.0 = Debug|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|Any CPU.Build.0 = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|x64.ActiveCfg = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|x64.Build.0 = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|x86.ActiveCfg = Release|Any CPU
{3716AFDF-0904-4635-8422-86E6B9356840}.Release|x86.Build.0 = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|x64.ActiveCfg = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|x64.Build.0 = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|x86.ActiveCfg = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Debug|x86.Build.0 = Debug|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|Any CPU.Build.0 = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|x64.ActiveCfg = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|x64.Build.0 = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|x86.ActiveCfg = Release|Any CPU
{0A1AFD26-86A0-4060-B277-D380172C7070}.Release|x86.Build.0 = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|x64.Build.0 = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Debug|x86.Build.0 = Debug|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|Any CPU.Build.0 = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|x64.ActiveCfg = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|x64.Build.0 = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|x86.ActiveCfg = Release|Any CPU
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB}.Release|x86.Build.0 = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|x64.ActiveCfg = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|x64.Build.0 = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|x86.ActiveCfg = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Debug|x86.Build.0 = Debug|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|Any CPU.Build.0 = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|x64.ActiveCfg = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|x64.Build.0 = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|x86.ActiveCfg = Release|Any CPU
{E9C02C5A-710C-4A57-A008-E3EAC89305CC}.Release|x86.Build.0 = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|x64.ActiveCfg = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|x64.Build.0 = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|x86.ActiveCfg = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Debug|x86.Build.0 = Debug|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|Any CPU.Build.0 = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|x64.ActiveCfg = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|x64.Build.0 = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|x86.ActiveCfg = Release|Any CPU
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12}.Release|x86.Build.0 = Release|Any CPU
{7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D5F6704-8249-46DD-906C-9E66419F215F}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -412,102 +76,25 @@ Global
{7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x64.Build.0 = Release|Any CPU
{7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x86.ActiveCfg = Release|Any CPU
{7D5F6704-8249-46DD-906C-9E66419F215F}.Release|x86.Build.0 = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|x64.ActiveCfg = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|x64.Build.0 = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|x86.ActiveCfg = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Debug|x86.Build.0 = Debug|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|Any CPU.Build.0 = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x64.ActiveCfg = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x64.Build.0 = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x86.ActiveCfg = Release|Any CPU
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x86.Build.0 = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x64.ActiveCfg = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x64.Build.0 = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x86.ActiveCfg = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x86.Build.0 = Debug|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|Any CPU.Build.0 = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x64.ActiveCfg = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x64.Build.0 = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x86.ActiveCfg = Release|Any CPU
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x86.Build.0 = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|x64.ActiveCfg = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|x64.Build.0 = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|x86.ActiveCfg = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Debug|x86.Build.0 = Debug|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|Any CPU.Build.0 = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|x64.ActiveCfg = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|x64.Build.0 = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|x86.ActiveCfg = Release|Any CPU
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF}.Release|x86.Build.0 = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|x64.ActiveCfg = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|x64.Build.0 = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|x86.ActiveCfg = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Debug|x86.Build.0 = Debug|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|Any CPU.Build.0 = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|x64.ActiveCfg = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|x64.Build.0 = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|x86.ActiveCfg = Release|Any CPU
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2}.Release|x86.Build.0 = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|x64.ActiveCfg = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|x64.Build.0 = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|x86.ActiveCfg = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Debug|x86.Build.0 = Debug|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|Any CPU.Build.0 = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|x64.ActiveCfg = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|x64.Build.0 = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|x86.ActiveCfg = Release|Any CPU
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1}.Release|x86.Build.0 = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|x64.ActiveCfg = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|x64.Build.0 = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|x86.ActiveCfg = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Debug|x86.Build.0 = Debug|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|Any CPU.Build.0 = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x64.ActiveCfg = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x64.Build.0 = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x86.ActiveCfg = Release|Any CPU
{60A4CADD-2B3D-48ED-89C0-1637A1F111AE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{94ECCBA8-7EBF-4B53-8379-52EB2327417E} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{BFF37228-B376-4ADD-9657-4E501F929713} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{C7FF6FDB-FB59-4517-8669-521C96AB7323} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{1F51C55C-BA4C-4856-9001-0F7924FFB179} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{33357599-C79D-4299-888F-634E2C3EACEF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{225CE0D4-06AB-411A-8D29-707504FE53B3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{6AF8C93B-AA41-4F44-8B1B-B8D166576174} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D} = {20595AD4-8D75-4AF8-B6BC-9C38C160423F}
{57691C7D-683D-46E6-AA4F-57A8C5F65D25} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{8622A261-02C6-40CA-9797-E3F01ED87D6B} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{75C608C3-ABB4-4168-A229-7F8250B946D1} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{6351C70F-F368-46DB-BAED-9B87CCD69353} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{45BF6302-6553-4E52-BF0F-B10D1AA9A6D1} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{5693761A-754A-40A8-9144-36510D6A4D69} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{0EFE694D-0770-4E71-BF4E-EC2B41362F79} = {E0E45070-123C-4A4D-AA98-2A780308876C}
{2B712A52-40F1-4C1C-833E-7C869ACA91F3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{3716AFDF-0904-4635-8422-86E6B9356840} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{0A1AFD26-86A0-4060-B277-D380172C7070} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{42792D7F-0BB6-4EE1-A314-8889305A4C48} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{2E8E045D-1D9F-43B5-BFBD-7073F60DCEBB} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
{E9C02C5A-710C-4A57-A008-E3EAC89305CC} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
{CA7AF967-3FA5-4CB1-9564-740CF4527895} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
{4C30C028-E97D-4B4C-AD17-C90F338A4DFF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{A0C772BA-C5F4-451D-AA7A-4045F2FA0201} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{8428A7DD-29FC-4417-9CA0-B90D34B26AB2} = {A0C772BA-C5F4-451D-AA7A-4045F2FA0201}
{E607AA2A-A4A6-48E4-8AAB-B0EB74EACAA1} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}

View File

@@ -34,6 +34,20 @@ namespace Spectre.Console
return new TextPrompt<T>(prompt).Show(Console);
}
/// <summary>
/// Displays a prompt to the user with a given default.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="prompt">The prompt markup text.</param>
/// <param name="defaultValue">The default value.</param>
/// <returns>The prompt input result.</returns>
public static T Ask<T>(string prompt, T defaultValue)
{
return new TextPrompt<T>(prompt)
.DefaultValue(defaultValue)
.Show(Console);
}
/// <summary>
/// Displays a prompt with two choices, yes or no.
/// </summary>

View File

@@ -81,7 +81,7 @@ namespace Spectre.Console.Cli
var context = new CommandContext(parsedResult.Remaining, leaf.Command.Name, leaf.Command.Data);
// Execute the command tree.
return await Execute(leaf, parsedResult.Tree, context, resolver, configuration);
return await Execute(leaf, parsedResult.Tree, context, resolver, configuration).ConfigureAwait(false);
}
}

View File

@@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Spectre.Console
{
@@ -10,7 +12,7 @@ namespace Spectre.Console
/// </summary>
public static partial class AnsiConsoleExtensions
{
internal static string ReadLine(this IAnsiConsole console, Style? style, bool secret, IEnumerable<string>? items = null)
internal static async Task<string> ReadLine(this IAnsiConsole console, Style? style, bool secret, IEnumerable<string>? items = null, CancellationToken cancellationToken = default)
{
if (console is null)
{
@@ -24,7 +26,7 @@ namespace Spectre.Console
while (true)
{
var rawKey = console.Input.ReadKey(true);
var rawKey = await console.Input.ReadKeyAsync(true, cancellationToken).ConfigureAwait(false);
if (rawKey == null)
{
continue;

View File

@@ -41,10 +41,15 @@ namespace Spectre.Console
/// </summary>
/// <param name="console">The console.</param>
/// <param name="prompt">The prompt markup text.</param>
/// <param name="defaultValue">Specifies the default answer.</param>
/// <returns><c>true</c> if the user selected "yes", otherwise <c>false</c>.</returns>
public static bool Confirm(this IAnsiConsole console, string prompt)
public static bool Confirm(this IAnsiConsole console, string prompt, bool defaultValue = true)
{
return new ConfirmationPrompt(prompt).Show(console);
return new ConfirmationPrompt(prompt)
{
DefaultValue = defaultValue,
}
.Show(console);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace Spectre.Console
{
internal static class StackExtensions
{
public static void PushRange<T>(this Stack<T> stack, IEnumerable<T> source)
{
if (stack is null)
{
throw new ArgumentNullException(nameof(stack));
}
if (source != null)
{
foreach (var item in source)
{
stack.Push(item);
}
}
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Spectre.Console
{
@@ -13,5 +15,13 @@ namespace Spectre.Console
/// <param name="intercept">Whether or not to intercept the key.</param>
/// <returns>The key that was read.</returns>
ConsoleKeyInfo? ReadKey(bool intercept);
/// <summary>
/// Reads a key from the console.
/// </summary>
/// <param name="intercept">Whether or not to intercept the key.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>The key that was read.</returns>
Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken);
}
}

Some files were not shown because too many files have changed in this diff Show More