diff --git a/cs/Markdown/Converters/HtmlConverter.cs b/cs/Markdown/Converters/HtmlConverter.cs
new file mode 100644
index 000000000..379976f3c
--- /dev/null
+++ b/cs/Markdown/Converters/HtmlConverter.cs
@@ -0,0 +1,33 @@
+using System.Text;
+using Markdown.Tokenizers;
+
+namespace Markdown.Converters;
+
+public class HtmlConverter : IConverter
+{
+ private static readonly Dictionary HtmlTag = new()
+ {
+ { TokenType.Italic, "em" },
+ { TokenType.Strong, "strong" },
+ };
+
+ public string Convert(IEnumerable tokens)
+ {
+ var html = new StringBuilder();
+ var isClosed = Enum.GetValues().ToDictionary(type => type, type => true);
+
+ foreach (var token in tokens)
+ {
+ html.Append(token.Type switch
+ {
+ TokenType.Italic or TokenType.Strong =>
+ isClosed[token.Type] ? Tag.Open(HtmlTag[token.Type]) : Tag.Close(HtmlTag[token.Type]),
+ _ => token.Content
+ });
+
+ isClosed[token.Type] = !isClosed[token.Type];
+ }
+
+ return html.ToString();
+ }
+}
\ No newline at end of file
diff --git a/cs/Markdown/Converters/IConverter.cs b/cs/Markdown/Converters/IConverter.cs
new file mode 100644
index 000000000..f5607d7f8
--- /dev/null
+++ b/cs/Markdown/Converters/IConverter.cs
@@ -0,0 +1,8 @@
+using Markdown.Tokenizers;
+
+namespace Markdown.Converters;
+
+public interface IConverter
+{
+ public string Convert(IEnumerable tokens);
+}
\ No newline at end of file
diff --git a/cs/Markdown/Markdown.csproj b/cs/Markdown/Markdown.csproj
new file mode 100644
index 000000000..85b49591f
--- /dev/null
+++ b/cs/Markdown/Markdown.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net9.0
+ enable
+ enable
+
+
+
diff --git a/cs/Markdown/Md.cs b/cs/Markdown/Md.cs
new file mode 100644
index 000000000..0386c2fa4
--- /dev/null
+++ b/cs/Markdown/Md.cs
@@ -0,0 +1,51 @@
+using System.Text;
+using Markdown.Converters;
+using Markdown.Tokenizers;
+
+namespace Markdown;
+
+public class Md(ITokenizer tokenizer, IConverter converter)
+{
+ public string Render(string markdown)
+ {
+ if (string.IsNullOrEmpty(markdown))
+ return string.Empty;
+
+ var result = new StringBuilder();
+ var paragraphs = markdown.Split(Environment.NewLine);
+
+ foreach (var paragraph in paragraphs)
+ {
+ var htmlLine = ProcessParagraph(paragraph);
+ result.AppendLine(htmlLine);
+ }
+
+ return result
+ .ToString()
+ .TrimEnd(Environment.NewLine.ToCharArray());
+ }
+
+ private string ProcessParagraph(string line)
+ {
+ var trimmedLine = line.TrimEnd(Environment.NewLine.ToCharArray());
+
+ if (trimmedLine.StartsWith("# "))
+ {
+ var headerContent = trimmedLine[2..];
+ var htmlContent = ParseMarkdown(headerContent);
+ return Tag.Wrap("h1", htmlContent);
+ }
+ else
+ {
+ var htmlContent = ParseMarkdown(trimmedLine);
+ return htmlContent;
+ }
+ }
+
+ private string ParseMarkdown(string markdown)
+ {
+ var tokens = tokenizer.Tokenize(markdown);
+ var html = converter.Convert(tokens);
+ return html;
+ }
+}
\ No newline at end of file
diff --git a/cs/Markdown/Program.cs b/cs/Markdown/Program.cs
new file mode 100644
index 000000000..723b19aa0
--- /dev/null
+++ b/cs/Markdown/Program.cs
@@ -0,0 +1,16 @@
+using Markdown;
+using Markdown.Converters;
+using Markdown.Tokenizers;
+
+var tokenizer = new MdTokenizer();
+var converter = new HtmlConverter();
+var markdown = new Md(tokenizer, converter);
+
+const string firstExample = "This _is_ a __sample__ markdown _file_.";
+const string secondExample = "#This is another __sample__ markdown _file_";
+
+const string input = firstExample;
+
+var result = markdown.Render(input);
+
+Console.WriteLine(result);
\ No newline at end of file
diff --git a/cs/Markdown/Tag.cs b/cs/Markdown/Tag.cs
new file mode 100644
index 000000000..c1282e304
--- /dev/null
+++ b/cs/Markdown/Tag.cs
@@ -0,0 +1,10 @@
+namespace Markdown;
+
+public static class Tag
+{
+ public static string Open(string tagName) => $"<{tagName}>";
+
+ public static string Close(string tagName) => $"{tagName}>";
+
+ public static string Wrap(string tagName, string content) => $"{Open(tagName)}{content}{Close(tagName)}";
+}
\ No newline at end of file
diff --git a/cs/Markdown/Token.cs b/cs/Markdown/Token.cs
new file mode 100644
index 000000000..7a433c3c0
--- /dev/null
+++ b/cs/Markdown/Token.cs
@@ -0,0 +1,8 @@
+namespace Markdown;
+
+public record Token
+{
+ public TokenType Type { get; init; }
+ public required string Content { get; init; }
+ public Token? Pair { get; set; }
+}
\ No newline at end of file
diff --git a/cs/Markdown/TokenExtensions.cs b/cs/Markdown/TokenExtensions.cs
new file mode 100644
index 000000000..a29b5a6bb
--- /dev/null
+++ b/cs/Markdown/TokenExtensions.cs
@@ -0,0 +1,12 @@
+namespace Markdown;
+
+public static class TokenExtensions
+{
+ public static void RemovePair(this Token? token)
+ {
+ if (token?.Pair == null) return;
+
+ token.Pair.Pair = null;
+ token.Pair = null;
+ }
+}
\ No newline at end of file
diff --git a/cs/Markdown/TokenType.cs b/cs/Markdown/TokenType.cs
new file mode 100644
index 000000000..d4f01a473
--- /dev/null
+++ b/cs/Markdown/TokenType.cs
@@ -0,0 +1,11 @@
+namespace Markdown;
+
+public enum TokenType
+{
+ Punctuation,
+ Text,
+ Italic,
+ Strong,
+ Escape,
+ WhiteSpace
+}
\ No newline at end of file
diff --git a/cs/Markdown/Tokenizers/ITokenizer.cs b/cs/Markdown/Tokenizers/ITokenizer.cs
new file mode 100644
index 000000000..512299f26
--- /dev/null
+++ b/cs/Markdown/Tokenizers/ITokenizer.cs
@@ -0,0 +1,6 @@
+namespace Markdown.Tokenizers;
+
+public interface ITokenizer
+{
+ public List Tokenize(string markdown);
+}
\ No newline at end of file
diff --git a/cs/Markdown/Tokenizers/MdTokenizer.cs b/cs/Markdown/Tokenizers/MdTokenizer.cs
new file mode 100644
index 000000000..7c20b7bc6
--- /dev/null
+++ b/cs/Markdown/Tokenizers/MdTokenizer.cs
@@ -0,0 +1,123 @@
+namespace Markdown.Tokenizers;
+
+public class MdTokenizer : ITokenizer
+{
+ private readonly Dictionary tokensSymbols = new()
+ {
+ { TokenType.Escape, "\\" },
+ { TokenType.Italic, "_" },
+ { TokenType.Strong, "__" },
+ { TokenType.WhiteSpace, " " },
+ };
+
+ private readonly HashSet pairableTokens =
+ [
+ TokenType.Italic,
+ TokenType.Strong
+ ];
+
+ public List Tokenize(string markdown)
+ {
+ return GetTokens(markdown)
+ .CreateTokenPairs(TokenType.Strong)
+ .SplitFreeStrongTokens(tokensSymbols)
+ .CreateTokenPairs(TokenType.Italic)
+ .FilterStrongInsideItalic()
+ .ReplacePairless(pairableTokens, tokensSymbols);
+ }
+
+ private List GetTokens(string markdown)
+ {
+ var tokens = new List();
+
+ for (var index = 0; index < markdown.Length;)
+ {
+ tokens.Add(markdown[index] switch
+ {
+ '\\' => HandleEscape(ref index, markdown),
+ '_' => HandleUnderscore(ref index, markdown),
+ ' ' => HandleWhitespace(ref index),
+ var c when char.IsPunctuation(c) => HandlePunctuation(ref index, markdown[index]),
+ _ => HandleText(ref index, markdown[index])
+ });
+ }
+
+ return tokens;
+ }
+
+ private Token HandleEscape(ref int index, string markdown)
+ {
+ var currentChar = markdown[index].ToString();
+ var nextChar = markdown[index + 1].ToString();
+
+ if (index + 1 < markdown.Length && tokensSymbols.ContainsValue(nextChar))
+ {
+ index += 2;
+ return new Token
+ {
+ Type = TokenType.Escape,
+ Content = nextChar,
+ };
+ }
+
+ index++;
+ return new Token
+ {
+ Type = TokenType.Escape,
+ Content = currentChar,
+ };
+ }
+
+ private Token HandlePunctuation(ref int index, char markdown)
+ {
+ index++;
+ return new Token
+ {
+ Type = TokenType.Punctuation,
+ Content = markdown.ToString(),
+ };
+ }
+
+ private Token HandleText(ref int index, char markdown)
+ {
+ index++;
+ return new Token
+ {
+ Type = TokenType.Text,
+ Content = markdown.ToString(),
+ };
+ }
+
+ private Token HandleWhitespace(ref int index)
+ {
+ index++;
+ return new Token
+ {
+ Type = TokenType.WhiteSpace,
+ Content = tokensSymbols[TokenType.WhiteSpace],
+ };
+ }
+
+ private Token HandleUnderscore(ref int index, string markdown)
+ {
+ var tokenType = GetTokenType(markdown, index);
+ var tokenLenght = tokenType == TokenType.Strong ? 2 : 1;
+ index += tokenLenght;
+
+ return new Token
+ {
+ Type = tokenType,
+ Content = tokensSymbols[tokenType],
+ };
+ }
+
+ private TokenType GetTokenType(string text, int index)
+ {
+ if (index + 1 < text.Length && text[index + 1] == tokensSymbols[TokenType.Italic][0])
+ {
+ return TokenType.Strong;
+ }
+
+ return TokenType.Italic;
+ }
+}
\ No newline at end of file
diff --git a/cs/Markdown/Tokenizers/TokenListExtension.cs b/cs/Markdown/Tokenizers/TokenListExtension.cs
new file mode 100644
index 000000000..524f662ee
--- /dev/null
+++ b/cs/Markdown/Tokenizers/TokenListExtension.cs
@@ -0,0 +1,117 @@
+namespace Markdown.Tokenizers;
+
+public static class TokenListExtensions
+{
+ public static List ReplacePairless(this List tokens, HashSet pairableTokens, Dictionary tokensSymbols)
+ {
+ var result = new List();
+
+ foreach (var token in tokens)
+ {
+ if (token.Pair == null && pairableTokens.Contains(token.Type))
+ {
+ result.Add(new Token
+ {
+ Type = TokenType.Text,
+ Content = tokensSymbols[token.Type],
+ });
+ }
+ else result.Add(token);
+ }
+
+ return result;
+ }
+
+ public static List CreateTokenPairs(this List tokens, TokenType type)
+ {
+ var openStack = new Stack();
+
+ for (var index = 0; index < tokens.Count; index++)
+ {
+ var token = tokens[index];
+ if (token.Type != type) continue;
+
+ if (tokens.IsOpening(index))
+ {
+ openStack.Push(token);
+ }
+ else if (openStack.Count > 0 && tokens.IsClosing(index))
+ {
+ var opening = openStack.Pop();
+ token.Pair = opening;
+ opening.Pair = token;
+ }
+ }
+
+ return tokens;
+ }
+
+ public static List SplitFreeStrongTokens(this List tokens, Dictionary tokenSymbols)
+ {
+ var result = new List();
+
+ foreach (var token in tokens)
+ {
+ if (token is { Type: TokenType.Strong, Pair: null })
+ {
+ result.Add(new Token
+ {
+ Type = TokenType.Italic,
+ Content = tokenSymbols[TokenType.Italic],
+ });
+ result.Add(new Token
+ {
+ Type = TokenType.Italic,
+ Content = tokenSymbols[TokenType.Italic],
+ });
+ }
+ else
+ {
+ result.Add(token);
+ }
+ }
+
+ return result;
+ }
+
+ public static List FilterStrongInsideItalic(this List tokens)
+ {
+ var isItalicOpen = false;
+ Token? italicOpening = null;
+
+ for (var index = 0; index < tokens.Count; index++)
+ {
+ var token = tokens[index];
+ if (token.Pair == null) continue;
+
+ if (token.Type == TokenType.Italic)
+ {
+ isItalicOpen = !isItalicOpen;
+ italicOpening = isItalicOpen ? token : null;
+ }
+ else if (token.Type == TokenType.Strong && isItalicOpen && !tokens.IsNearItalic(index))
+ {
+ italicOpening?.RemovePair();
+ token.RemovePair();
+ isItalicOpen = false;
+ }
+ }
+
+ return tokens;
+ }
+
+ private static bool IsOpening(this List tokens, int index)
+ {
+ return index != tokens.Count - 1 && (index == 0 || (index - 1 >= 0 && tokens[index - 1].Type != TokenType.Text));
+ }
+
+ private static bool IsClosing(this List tokens, int index)
+ {
+ return index == tokens.Count - 1 || (index + 1 <= tokens.Count - 1 && tokens[index + 1].Type != TokenType.Text);
+ }
+
+ private static bool IsNearItalic(this List tokens, int index)
+ {
+ return index + 1 < tokens.Count && tokens[index + 1].Type == TokenType.Italic;
+ }
+}
\ No newline at end of file
diff --git a/cs/MarkdownTests/MarkdownTests.csproj b/cs/MarkdownTests/MarkdownTests.csproj
new file mode 100644
index 000000000..36e7d5ec2
--- /dev/null
+++ b/cs/MarkdownTests/MarkdownTests.csproj
@@ -0,0 +1,28 @@
+
+
+
+ net9.0
+ latest
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cs/MarkdownTests/MdTests.cs b/cs/MarkdownTests/MdTests.cs
new file mode 100644
index 000000000..874b01c93
--- /dev/null
+++ b/cs/MarkdownTests/MdTests.cs
@@ -0,0 +1,238 @@
+using System.Diagnostics;
+using System.Text;
+using FluentAssertions;
+using Markdown;
+using Markdown.Converters;
+using Markdown.Tokenizers;
+
+
+namespace MarkdownTests;
+
+[TestFixture]
+public class MdTests
+{
+ private Md renderer;
+
+ [SetUp]
+ public void Setup()
+ {
+ var tokenizer = new MdTokenizer();
+ var converter = new HtmlConverter();
+ renderer = new Md(tokenizer, converter);
+ }
+
+ [Test]
+ public void Render_EmptyString_ReturnsEmpty()
+ {
+ var result = renderer.Render("");
+ result.Should().Be(string.Empty);
+ }
+
+ [Test]
+ public void Render_NestedItalicNearStrong()
+ {
+ var result = renderer.Render("___some text___");
+ result.Should().Be("some text");
+ }
+
+ [Test]
+ public void Render_BeginWithPairlessStrong()
+ {
+ var result = renderer.Render("__Some_");
+ result.Should().Be("_Some");
+ }
+
+ [Test]
+ public void Render_EndWithPairlessStrong()
+ {
+ var result = renderer.Render("_Some__");
+ result.Should().Be("Some_");
+ }
+
+ [Test]
+ public void Render_Italic()
+ {
+ var result = renderer.Render("Текст, _окруженный с двух сторон_ одинарными символами подчерка");
+ result.Should().Be("Текст, окруженный с двух сторон одинарными символами подчерка");
+ }
+
+ [Test]
+ public void Render_Same_WhenUnderscoresInsideWords()
+ {
+ var result = renderer.Render("Some_Another_Text");
+ result.Should().Be("Some_Another_Text");
+ }
+
+ [Test]
+ public void Render_Strong()
+ {
+ var result = renderer.Render("__Выделенный двумя символами текст__");
+ result.Should().Be("Выделенный двумя символами текст");
+ }
+
+ [Test]
+ public void Render_Escaped()
+ {
+ var result = renderer.Render(@"\_Вот это\_, не должно выделиться");
+ result.Should().Be("_Вот это_, не должно выделиться");
+ }
+
+ [Test]
+ public void Render_FakeEscape()
+ {
+ var result = renderer.Render(@"123\456");
+ result.Should().Be(@"123\456");
+ }
+
+ [Test]
+ public void Render_EscapeEscape()
+ {
+ var result = renderer.Render(@"\\_some text_");
+ result.Should().Be(@"\some text");
+ }
+
+ [Test]
+ public void Render_ItalicInsideStrong()
+ {
+ var result = renderer.Render("Внутри __двойного выделения _одинарное_ тоже__ работает.");
+ result.Should().Be("Внутри двойного выделения одинарное тоже работает.");
+ }
+
+ [Test]
+ public void Render_DoubleNested()
+ {
+ var result = renderer.Render("Внутри __двойного _выделения_ _одинарное_ тоже__ работает.");
+ result.Should().Be("Внутри двойного выделения одинарное тоже работает.");
+ }
+
+ [Test]
+ public void Render_Same_StrongInsideItalic()
+ {
+ var result = renderer.Render("Но не наоборот — внутри _одинарного __двойное__ не_ работает.");
+ result.Should().Be("Но не наоборот — внутри _одинарного __двойное__ не_ работает.");
+ }
+
+ [Test]
+ public void Render_Same_WhenInsideDigits()
+ {
+ var result = renderer.Render("цифрами_12_3");
+ result.Should().Be("цифрами_12_3");
+ }
+
+ [Test]
+ public void Render_UnderscoresInsideWords()
+ {
+ var result = renderer.Render("Однако выделять часть слова они могут: и в _нач_але, и в сер_еди_не, и в кон_це._");
+ result.Should().Be("Однако выделять часть слова они могут: и в нач_але, и в сер_еди_не, и в кон_це.");
+ }
+
+ [Test]
+ public void Render_ItalicDifferentWords()
+ {
+ var result = renderer.Render(@"В то же время выделение в ра_зных сл_овах не работает.");
+ result.Should().Be("В то же время выделение в ра_зных сл_овах не работает.");
+ }
+
+ [Test]
+ public void Render_Same_NonPaired()
+ {
+ var result = renderer.Render(@"__Непарные_ символы в рамках одного абзаца не считаются выделением.");
+ result.Should().Be("_Непарные символы в рамках одного абзаца не считаются выделением.");
+ }
+
+ [Test]
+ public void Render_ItalicMustHaveNonWhitespaceAfterOpen()
+ {
+ var result = renderer.Render(@"За подчерками, начинающими выделение, должен следовать непробельный символ. Иначе эти_ подчерки_ не считаются выделением и остаются просто символами подчерка.");
+ result.Should().Be("За подчерками, начинающими выделение, должен следовать непробельный символ. Иначе эти_ подчерки_ не считаются выделением и остаются просто символами подчерка.");
+ }
+
+ [Test]
+ public void Render_ItalicMustHaveNonWhitespaceBeforeClose()
+ {
+ var result = renderer.Render(@"Иначе эти _подчерки _не считаются_ окончанием");
+ result.Should().Be("Иначе эти _подчерки не считаются окончанием");
+ }
+
+ [Test]
+ public void Render_Same_OverlappingPairs()
+ {
+ var result = renderer.Render(@"В случае __пересечения _двойных__ и одинарных_ подчерков ни один из них не считается выделением.");
+ result.Should().Be("В случае __пересечения _двойных__ и одинарных_ подчерков ни один из них не считается выделением.");
+ }
+
+ [Test]
+ public void Render_EmptyUnderscores()
+ {
+ var result = renderer.Render(@"Если внутри подчерков пустая строка ____, то они остаются символами подчерка.");
+ result.Should().Be("Если внутри подчерков пустая строка ____, то они остаются символами подчерка.");
+ }
+
+ [Test]
+ public void Render_Header()
+ {
+ var result = renderer.Render("# Header text");
+ result.Should().Be("Header text
");
+ }
+
+ [Test]
+ public void Render_HeaderWithTokens()
+ {
+ var result = renderer.Render(@"# Заголовок __с _разными_ символами__");
+ result.Should().Be("Заголовок с разными символами
");
+ }
+
+ [Test]
+ public void Render_NewLineHeader()
+ {
+ var result = renderer.Render("""
+ # Заголовок __с _разными_ символами__
+ # Заголовок __с _разными_ символами__
+ """);
+ result.Should().Be("""
+ Заголовок с разными символами
+ Заголовок с разными символами
+ """);
+ }
+
+ [Test]
+ public void Render_IsLinear()
+ {
+ const int tolerance = 2;
+ const int firstRunCount = 100_000;
+ const int secondRunCount = 1_000_000;
+ const double expectedCoefficient = secondRunCount / firstRunCount + tolerance;
+
+ var markdown = new StringBuilder();
+ for (var i = 0; i < firstRunCount; i++)
+ {
+ markdown.Append("_text_");
+ markdown.Append("__text__");
+ }
+
+ var firstRun = GetRunTime(() => renderer.Render(markdown.ToString()));;
+ markdown.Clear();
+
+ for (var i = 0; i < secondRunCount; i++)
+ {
+ markdown.Append("_text_");
+ markdown.Append("__text__");
+ }
+
+
+ var secondRun = GetRunTime(() => renderer.Render(markdown.ToString()));
+
+ var coefficient = secondRun / firstRun;
+
+ coefficient.Should().BeLessThan(expectedCoefficient);
+ }
+
+ private static double GetRunTime(Action run)
+ {
+ var sw = Stopwatch.StartNew();
+ run.Invoke();
+ sw.Stop();
+
+ return sw.ElapsedMilliseconds;
+ }
+}
\ No newline at end of file
diff --git a/cs/clean-code.sln b/cs/clean-code.sln
index 2206d54db..cc56d3b30 100644
--- a/cs/clean-code.sln
+++ b/cs/clean-code.sln
@@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlDigit", "ControlDigi
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markdown", "Markdown\Markdown.csproj", "{2AEFA03E-ABDD-44A0-98ED-109EE8BDAA6A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkdownTests", "MarkdownTests\MarkdownTests.csproj", "{25FE0800-F08D-437D-87B1-3DA0AF9B15B5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,5 +31,13 @@ Global
{C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3EF41D7-50EF-4CE1-B30A-D1D81C93D7FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2AEFA03E-ABDD-44A0-98ED-109EE8BDAA6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2AEFA03E-ABDD-44A0-98ED-109EE8BDAA6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2AEFA03E-ABDD-44A0-98ED-109EE8BDAA6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2AEFA03E-ABDD-44A0-98ED-109EE8BDAA6A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {25FE0800-F08D-437D-87B1-3DA0AF9B15B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {25FE0800-F08D-437D-87B1-3DA0AF9B15B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {25FE0800-F08D-437D-87B1-3DA0AF9B15B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {25FE0800-F08D-437D-87B1-3DA0AF9B15B5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/cs/clean-code.sln.DotSettings b/cs/clean-code.sln.DotSettings
index 135b83ecb..229f449d2 100644
--- a/cs/clean-code.sln.DotSettings
+++ b/cs/clean-code.sln.DotSettings
@@ -1,6 +1,9 @@
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></Policy>
+ True
True
True
Imported 10.10.2016