15 Commits

Author SHA1 Message Date
tparnell
17d69ac124 stop 2019-02-06 22:32:22 -05:00
tparnell
be5c4cc806 fix rss 2019-02-06 22:32:14 -05:00
tparnell
ca0344c902 hopefully this fixes rss readers 2019-02-06 20:55:23 -05:00
tparnell
5a844f34f9 add img back in meta 2019-02-06 20:42:25 -05:00
tparnell
57a129cf8d tools for frontend devs 2019-02-06 19:12:18 -05:00
tparnell
a31b9d4fa9 stop 2019-02-06 19:01:46 -05:00
Tommy Parnell
7013e61c2f alt text for pictures 2019-02-06 07:56:24 -05:00
Tommy Parnell
6ce47adb8a webp avatar 2019-02-06 07:53:29 -05:00
tparnell
b9b9e81213 support webp 2019-02-05 23:32:21 -05:00
tparnell
53b8b448da webp 2019-02-05 23:32:21 -05:00
tparnell
aa6ed52d93 picture elem 2019-02-05 23:32:21 -05:00
Tommy Parnell
16c10c9ca1 app insights 2019-02-03 22:37:57 -05:00
Tommy Parnell
c3cb61619b fix some spacing 2019-02-03 21:40:49 -05:00
Tommy Parnell
7ff61450f9 Merge branch 'master' of github.com:TerribleDev/blog.terribledev.io.dotnet 2019-02-03 21:22:06 -05:00
Tommy Parnell
f3faede79e cache home page and posts in cf for 15 minutes 2019-02-03 21:21:57 -05:00
103 changed files with 287 additions and 15 deletions

13
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"ban.spellright"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
]
}

19
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"files.eol": "\n",
"spellchecker.language": "en_US",
"spellchecker.ignoreWordsList": [
"dotnet",
"csproj's",
"VS2017",
"vs2017",
"refactor"
],
"spellchecker.documentTypes": [
"markdown",
"latex",
"plaintext"
],
"spellchecker.ignoreRegExp": [],
"spellchecker.ignoreFileExtensions": [],
"spellchecker.checkInterval": 5000
}

5
.vscode/spellright.dict vendored Normal file
View File

@@ -0,0 +1,5 @@
intellisense
docker
env
mydocklinting
eslint

10
Readme.md Normal file
View File

@@ -0,0 +1,10 @@
## Compress webp
find . -iname '*.png' -exec cwebp -lossless '{}' -o '{}'.webp \;
find . -iname '*.jpg' -exec cwebp '{}' -o '{}'.webp \;
find . -iname '*.gif' -exec gif2webp -mixed '{}' -o '{}'.webp \;
## resize image
find . -iname '*' -exec convert '{}' -resize 750 '{}' \;

View File

@@ -0,0 +1,7 @@
{
"ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider",
"Version": "8.14.11009.1",
"GettingStartedDocument": {
"Uri": "https://go.microsoft.com/fwlink/?LinkID=798432"
}
}

View File

@@ -48,6 +48,7 @@ namespace TerribleDev.Blog.Web.Controllers
[Route("/index.html")]
[Route("/page/{pageNumber?}" )]
[OutputCache(Duration = 31536000, VaryByParam = "pageNumber")]
[ResponseCache(Duration = 900)]
public IActionResult Index(int pageNumber = 1)
{
if(!postsByPage.TryGetValue(pageNumber, out var result))
@@ -77,7 +78,7 @@ namespace TerribleDev.Blog.Web.Controllers
[Route("{postUrl}")]
[OutputCache(Duration = 31536000, VaryByParam = "postUrl")]
[ResponseCache(Duration = 180)]
[ResponseCache(Duration = 900)]
public IActionResult Post(string postUrl)
{
if(!posts.TryGetValue(postUrl, out var currentPost))

View File

@@ -11,13 +11,15 @@ namespace TerribleDev.Blog.Web
{
public static SyndicationItem ToSyndicationItem(this IPost x)
{
return new SyndicationItem()
Uri.TryCreate($"https://blog.terribledev.io/{x.Url}", UriKind.Absolute, out var url);
var syn = new SyndicationItem()
{
Title = x.Title,
Description = x.Content.ToString(),
Id = $"https://blog.terribledev.io/{x.Url}",
Id = url.ToString(),
Published = x.PublishDate
};
syn.AddLink(new SyndicationLink(url));
}
}
}

View File

@@ -8,6 +8,7 @@ using YamlDotNet.Serialization;
using Microsoft.AspNetCore.Html;
using Markdig;
using TerribleDev.Blog.Web.MarkExtension.TerribleDev.Blog.Web.ExternalLinkParser;
using TerribleDev.Blog.Web.MarkExtension;
namespace TerribleDev.Blog.Web
{
@@ -42,8 +43,11 @@ namespace TerribleDev.Blog.Web
var splitFile = postText.Split("---");
var ymlRaw = splitFile[0];
var markdownText = string.Join("", splitFile.Skip(1));
var postSettings = ParseYaml(ymlRaw);
var resolvedUrl = !string.IsNullOrWhiteSpace(postSettings.permalink) ? postSettings.permalink : fileName.Split('.')[0].Replace(' ', '-').WithoutSpecialCharacters();
List<string> postImages = new List<string>();
var pipeline = new MarkdownPipelineBuilder()
.Use<PictureInline>(new PictureInline(resolvedUrl))
.Use<TargetLinkExtension>()
.Use<ImageRecorder>(new ImageRecorder(ref postImages))
.UseMediaLinks()
@@ -51,8 +55,7 @@ namespace TerribleDev.Blog.Web
.Build();
var postContent = Markdown.ToHtml(markdownText, pipeline);
var postContentPlain = String.Join("", Markdown.ToPlainText(markdownText, pipeline).Split("<!-- more -->"));
var postSettings = ParseYaml(ymlRaw);
var resolvedUrl = !string.IsNullOrWhiteSpace(postSettings.permalink) ? postSettings.permalink : fileName.Split('.')[0].Replace(' ', '-').WithoutSpecialCharacters();
var summary = postContent.Split("<!-- more -->")[0];
var postSummaryPlain = postContentPlain.Split("<!-- more -->")[0];
return new Post()

View File

@@ -62,7 +62,6 @@ namespace TerribleDev.Blog.Web.MarkExtension
private void RenderTargetAttribute(Uri uri, HtmlRenderer renderer, LinkInline linkInline)
{
linkInline.SetAttributes(new HtmlAttributes() { Properties = new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("target", "_blank"), new KeyValuePair<string, string>("rel", "noopener"), } });
}

View File

@@ -0,0 +1,34 @@
using System;
using Markdig;
using Markdig.Renderers;
using Markdig.Renderers.Html.Inlines;
namespace TerribleDev.Blog.Web.MarkExtension
{
public class LinkConverter : IMarkdownExtension
{
private readonly Func<string, string> convertLink;
public LinkConverter(Func<string, string> convertLink)
{
this.convertLink = convertLink;
}
public void Setup(MarkdownPipelineBuilder pipeline)
{
}
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
{
var htmlRenderer = renderer as HtmlRenderer;
if(htmlRenderer == null) return;
var inlineRenderer = htmlRenderer.ObjectRenderers.FindExact<LinkInlineRenderer>();
if(inlineRenderer == null) return;
inlineRenderer.TryWriters.Add((ren, inline) => {
return false;
inline.GetDynamicUrl =
});
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using Markdig;
using Markdig.Renderers;
using Markdig.Renderers.Html.Inlines;
namespace TerribleDev.Blog.Web.MarkExtension
{
public class PictureInline : IMarkdownExtension
{
private readonly string postUrl;
public PictureInline(string postUrl)
{
this.postUrl = postUrl;
}
public void Setup(MarkdownPipelineBuilder pipeline)
{
}
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
{
var htmlRenderer = renderer as HtmlRenderer;
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<PictureInlineRenderer>())
{
htmlRenderer.ObjectRenderers.ReplaceOrAdd<LinkInlineRenderer>(new PictureInlineRenderer(postUrl));
}
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using Markdig.Renderers;
using Markdig.Renderers.Html;
using Markdig.Renderers.Html.Inlines;
using Markdig.Syntax.Inlines;
using System.Linq;
using System.Collections.Generic;
namespace TerribleDev.Blog.Web.MarkExtension
{
// <summary>
/// A HTML renderer for a <see cref="LinkInline"/>.
/// </summary>
/// <seealso cref="Markdig.Renderers.Html.HtmlObjectRenderer{Markdig.Syntax.Inlines.LinkInline}" />
public class PictureInlineRenderer : LinkInlineRenderer
{
private readonly string baseUrl;
public PictureInlineRenderer(string baseUrl)
{
this.baseUrl = baseUrl;
}
private void WriteImageTag(HtmlRenderer renderer, LinkInline link, string suffix, string type = null)
{
renderer.Write(string.IsNullOrWhiteSpace(type) ? $"<img src=\"" : $"<source type=\"{type}\" srcset=\"");
var escapeUrl = link.GetDynamicUrl != null ? link.GetDynamicUrl() ?? link.Url : link.Url;
//todo: this should be a seperate plugin
// urls that are like "3.png" should resolve to /<postUrl>/3.png mostly for rss readers
if(!System.Uri.TryCreate(escapeUrl, UriKind.RelativeOrAbsolute, out var parsedResult))
{
throw new Exception($"Error making link for {escapeUrl} @ {baseUrl}");
}
if(!escapeUrl.StartsWith("/"))
{
escapeUrl = $"{baseUrl}/{escapeUrl}";
}
renderer.WriteEscapeUrl($"{escapeUrl}{suffix}");
renderer.Write("\"");
renderer.WriteAttributes(link);
if (renderer.EnableHtmlForInline)
{
renderer.Write(" alt=\"");
}
var wasEnableHtmlForInline = renderer.EnableHtmlForInline;
renderer.EnableHtmlForInline = false;
renderer.WriteChildren(link);
renderer.EnableHtmlForInline = wasEnableHtmlForInline;
if (renderer.EnableHtmlForInline)
{
renderer.Write("\"");
}
if (renderer.EnableHtmlForInline)
{
renderer.Write(" />");
}
}
protected override void Write(HtmlRenderer renderer, LinkInline link)
{
if (!link.IsImage)
{
base.Write(renderer, link);
return;
}
renderer.Write("<picture>");
WriteImageTag(renderer, link, ".webp", "image/webp");
WriteImageTag(renderer, link, string.Empty);
renderer.Write("</picture>");
}
}
}

View File

@@ -0,0 +1,49 @@
title: Must have vscode plugins for front-end devs
date: 2019-02-06
tags:
- visual studio
- javascript
- css
- front-end
---
I've had a lot of people ask me about my choice of editors, and plugins. A while back I switched to vscode for all my programming work, for both front and back end. In the past I've blogged about [the best plugins for visual studio](/VS-2017-best-extensions-on-launch/) as a backend dev, but I thought I'd give you a more front-end angle
<!-- more -->
## Document this
My first one, and in my opinion the most underrated is [document this](https://marketplace.visualstudio.com/items?itemName=joelday.docthis). So if you have ever had to write [jsdoc](http://usejsdoc.org/) comments you can know how tedious it gets, and if you haven't, trust me you should. VSCode and most other editors can read [jsdoc](http://usejsdoc.org/) comments above functions, and class declarations to improve the intellisense and type completion statements. Simply have your cursor over a function, invoke document this, and quickly you will be given jsdoc comments for your code.
![Animated gif showing off document this](document-this.gif)
## Import Cost
Another extension I find vital to my every day is [import cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost). This is a package, that leaves you little notes on the side of any import you have as to how big it will be. This package will even highlight the size text in red for large imports which you can configure. What I love about this package, is it tells me if the package I'm about to use is going to be very expensive size wise. That way I find out long before I commit the code, and my pages get slow.
![a static image showing off import cost](import-cost.png)
## ESlint and Prettier
Hopefully both of these will not be new to you. ESLint is a linting tool that looks for potential errors in your code. Prettier is an opinionated style enforcer for your code. The [eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) extensions for vscode can automatically show you problems in your code as you type, and can even fix your code on save. What I love about both of these tools, is together they make a great force for improving your code base. Prettier eliminates many debates over code style between team members, and eslint prevents you from shipping many bugs to production. These extensions can call out problems as you type, which decreases the feedback loops, and increases your productivity.
## Filesize
As a web developer I spend a lot of my time looking at file size. Right now file sizes are ever inflating, and are causing pain for bandwidth constrained devices. I often download bundles, and inspect their compiled source, or just have to look at how big a file is on the filesystem. A big tool I have in my belt is [filesize](https://marketplace.visualstudio.com/items?itemName=mkxml.vscode-filesize). This is a crazy simple extension, but one that brings me joy everyday. The premise is simple, print the file size of the current file in the status bar at the bottom. Click on it, and you get a nice output of what its like gzipped, and the mime type. Dirt simple, but saved me a ton of time everyday!
![a picture of the filesize plugin in action](filesize2.jpg)
## Runner ups
Here is a list of additional extensions I certainly couldn't live without
* [path intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) - autocomplete file paths in various files (including html)
* [npm intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.npm-intellisense) - autocomplete npm pages in imports
* [html 5 boilerplate](https://marketplace.visualstudio.com/items?itemName=sidthesloth.html5-boilerplate) - dirt simple html boilerplate snippets
* [icon fonts](https://marketplace.visualstudio.com/items?itemName=idleberg.icon-fonts) - Autocomplete for various icon fonts such as font awesome
* [git lens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) - Show git history inline, along with other information from git

View File

@@ -19,6 +19,7 @@ namespace TerribleDev.Blog.Web
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseApplicationInsights()
.UseStartup<Startup>()
.ConfigureKestrel(a =>
{

View File

@@ -5,6 +5,8 @@
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<UserSecretsId>9a1f51b6-f4d9-4df7-a0af-e345176e9927</UserSecretsId>
<ApplicationInsightsResourceId>/subscriptions/088a81c7-d703-41c9-a1d0-476bce11df60/resourcegroups/WebResourceGroup/providers/microsoft.insights/components/tparnellblognew</ApplicationInsightsResourceId>
<ApplicationInsightsAnnotationResourceId>/subscriptions/088a81c7-d703-41c9-a1d0-476bce11df60/resourcegroups/WebResourceGroup/providers/microsoft.insights/components/tparnellblognew</ApplicationInsightsAnnotationResourceId>
</PropertyGroup>
<ItemGroup>
@@ -21,6 +23,7 @@
<ItemGroup>
<PackageReference Include="BuildBundlerMinifier" Version="2.8.391" />
<PackageReference Include="Markdig" Version="0.15.7" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.0.2105168" />
@@ -36,4 +39,9 @@
<Content Include="Posts\*.md" CopyToOutputDirectory="Always" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,5 @@
@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
@{
Layout = null;
}
@@ -7,9 +8,9 @@
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-48128396-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-48128396-1');
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-48128396-1');
</script>
@Html.Raw(JavaScriptSnippet.FullScript)

View File

@@ -2,7 +2,10 @@
var hideNav = ViewData["HideNav"] != null ? "" : "withBody";
}
<nav class="navBar hide @hideNav" id="navBar">
<img src="" alt="An image of TerribleDev" data-src="/content/tommyAvatar4.jpg" class="lazy round" />
<picture>
<source srcset="" type="image/webp" alt="An image of TerribleDev" data-src="/content/tommyAvatar4.jpg.webp" class="lazy round" />
<img src="" alt="An image of TerribleDev" data-src="/content/tommyAvatar4.jpg" class="lazy round" />
</picture>
<span>Tommy "Terrible Dev" Parnell</span>
<ul class="sidebarBtns">
<li><a href="/" class="link-unstyled">Home</a></li>

View File

@@ -13,5 +13,8 @@
"Blog": {
"title": "The Ramblings of TerribleDev",
"link": "https://blog.terribledev.io"
},
"ApplicationInsights": {
"InstrumentationKey": "974b47d2-1f08-42df-b498-bbfda7425f0b"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -29,6 +29,10 @@ h5 {
font-size: 2rem;
}
article {
margin-top: .5em;
}
body {
text-rendering: optimizeLegibility;
letter-spacing: -.01em;
@@ -47,7 +51,7 @@ body {
padding-bottom: 1.2em;
}
.headerBump {
padding-top: 4rem;
padding-top: 3.5rem;
}
.main-content-wrap img {

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

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