diff --git a/ErrorHandling/ErrorHandling.csproj b/ErrorHandling/ErrorHandling.csproj
deleted file mode 100644
index b593d0829..000000000
--- a/ErrorHandling/ErrorHandling.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- Exe
- net8.0
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ErrorHandling/QuerySyntax/ParseResultExtensions.cs b/ErrorHandling/QuerySyntax/ParseResultExtensions.cs
deleted file mode 100644
index 442dc3457..000000000
--- a/ErrorHandling/QuerySyntax/ParseResultExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace ErrorHandling.QuerySyntax;
-
-public static class ParseResultExtensions
-{
- public static Result ParseIntResult(this string s, string error = null)
- {
- int v;
- return int.TryParse(s, out v)
- ? v.AsResult()
- : Result.Fail(error ?? "Не число " + s);
- }
- public static Result ParseGuidResult(this string s, string error = null)
- {
- Guid v;
- return Guid.TryParse(s, out v)
- ? v.AsResult()
- : Result.Fail(error ?? "Не GUID " + s);
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/QuerySyntax/ResultQueryExpressionExtensions.cs b/ErrorHandling/QuerySyntax/ResultQueryExpressionExtensions.cs
deleted file mode 100644
index 736c83247..000000000
--- a/ErrorHandling/QuerySyntax/ResultQueryExpressionExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace ErrorHandling.QuerySyntax;
-
-public static class ResultQueryExpressionExtensions
-{
- public static Result SelectMany(
- this Result input,
- Func> continuation)
- {
- throw new NotImplementedException();
- }
-
- public static Result SelectMany(
- this Result input,
- Func> continuation,
- Func resultSelector)
- {
- throw new NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/QuerySyntax/ResultQueryExpression_Should.cs b/ErrorHandling/QuerySyntax/ResultQueryExpression_Should.cs
deleted file mode 100644
index 2f65b6d86..000000000
--- a/ErrorHandling/QuerySyntax/ResultQueryExpression_Should.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using FluentAssertions;
-using NUnit.Framework;
-
-namespace ErrorHandling.QuerySyntax;
-
-[TestFixture]
-public class ResultQueryExpression_Should
-{
- [Test]
- public void SupportLinqMethodChaining()
- {
- var res =
- "1358571172".ParseIntResult()
- .SelectMany(i => Convert.ToString(i, 16).AsResult())
- .SelectMany(hex => (hex + hex + hex + hex).ParseGuidResult());
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportLinqMethodChaining_WithResultSelector()
- {
- var res =
- "1358571172".ParseIntResult()
- .SelectMany(i => Convert.ToString(i, 16).AsResult(), (i, hex) => new { i, hex })
- .SelectMany(t => (t.hex + t.hex + t.hex + t.hex).ParseGuidResult());
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportQueryExpressions()
- {
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeOfType>();
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportQueryExpressions_WithComplexSelect()
- {
- // ��� ��������, ���� �������� ������ ������ Query Expressions ��� Result
- // �������� �������� �� ������������� i � select
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select i + " -> " + guid;
- res.Should().BeOfType>();
- res.Should().BeEquivalentTo(Result.Ok("1358571172 -> 50fa26a4-50fa-26a4-50fa-26a450fa26a4"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenErrorAtTheEnd()
- {
- var res =
- from i in "0".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult("error is here")
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenExceptionOnSomeStage()
- {
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Result.Of(() => Convert.ToString(i, 100500), "error is here")
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenErrorAtTheBeginning()
- {
- var res =
- from i in "UNPARSABLE".ParseIntResult("error is here")
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Result.cs b/ErrorHandling/Result.cs
deleted file mode 100644
index 2e8db379b..000000000
--- a/ErrorHandling/Result.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-
-namespace ErrorHandling;
-
-public class None
-{
- private None()
- {
- }
-}
-
-public struct Result
-{
- public Result(string error, T value = default(T))
- {
- Error = error;
- Value = value;
- }
-
- public string Error { get; }
- internal T Value { get; }
-
- public T GetValueOrThrow()
- {
- if (IsSuccess) return Value;
- throw new InvalidOperationException($"No value. Only Error {Error}");
- }
-
- public bool IsSuccess => Error == null;
-}
-
-public static class Result
-{
- public static Result AsResult(this T value)
- {
- return Ok(value);
- }
-
- public static Result Ok(T value)
- {
- return new Result(null, value);
- }
-
- public static Result Fail(string e)
- {
- return new Result(e);
- }
-
- public static Result Of(Func f, string error = null)
- {
- try
- {
- return Ok(f());
- }
- catch (Exception e)
- {
- return Fail(error ?? e.Message);
- }
- }
-
- public static Result Then(
- this Result input,
- Func continuation)
- {
- throw new NotImplementedException();
- }
-
- public static Result Then(
- this Result input,
- Func> continuation)
- {
- throw new NotImplementedException();
- }
-
- public static Result OnFail(
- this Result input,
- Action handleError)
- {
- throw new NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Result_should.cs b/ErrorHandling/Result_should.cs
deleted file mode 100644
index 45930f67d..000000000
--- a/ErrorHandling/Result_should.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-using System;
-using FakeItEasy;
-using FluentAssertions;
-using NUnit.Framework;
-
-namespace ErrorHandling;
-
-[TestFixture]
-public class Result_Should
-{
- [Test]
- public void Create_Ok()
- {
- var r = Result.Ok(42);
- r.IsSuccess.Should().BeTrue();
- r.GetValueOrThrow().Should().Be(42);
- }
-
- [Test]
- public void Create_Fail()
- {
- var r = Result.Fail("123");
-
- r.IsSuccess.Should().BeFalse();
- r.Error.Should().Be("123");
- }
-
- [Test]
- public void ReturnsFail_FromResultOf_OnException()
- {
- var res = Result.Of(() => { throw new Exception("123"); });
-
- res.Should().BeEquivalentTo(Result.Fail("123"));
- }
-
- [Test]
- public void ReturnsFailWithCustomMessage_FromResultOf_OnException()
- {
- var res = Result.Of(() => { throw new Exception("123"); }, "42");
-
- res.Should().BeEquivalentTo(Result.Fail("42"));
- }
-
- [Test]
- public void ReturnsOk_FromResultOf_WhenNoException()
- {
- var res = Result.Of(() => 42);
-
- res.Should().BeEquivalentTo(Result.Ok(42));
- }
-
- [Test]
- public void RunThen_WhenOk()
- {
- var res = Result.Ok(42)
- .Then(n => n + 10);
- res.Should().BeEquivalentTo(Result.Ok(52));
- }
-
- [Test]
- public void RunThen_WhenContinuationIsOk()
- {
- var res = Result.Ok(42)
- .Then(n => Result.Ok(n + 10));
- res.Should().BeEquivalentTo(Result.Ok(52));
- }
-
- [Test]
- public void SkipThen_WhenFail()
- {
- var fail = Result.Fail("������");
- var called = false;
- fail.Then(n =>
- {
- called = true;
- return n;
- });
- called.Should().BeFalse();
- }
-
- [Test]
- public void Then_ReturnsFail_OnException()
- {
- Func continuation = n => { throw new Exception("123"); };
- var res = Result.Ok(42)
- .Then(continuation);
- res.Should().BeEquivalentTo(Result.Fail("123"));
- }
-
- [Test]
- public void Then_ReturnsFail_OnFailedContinuation()
- {
- Func> continuation = n => Result.Fail("123");
- var res = Result.Ok(42)
- .Then(continuation);
- res.Should().BeEquivalentTo(Result.Fail("123"));
- }
-
- [Test]
- public void RunOnFail_WhenFail()
- {
- var fail = Result.Fail("������");
- var errorHandler = A.Fake>();
-
- var res = fail.OnFail(errorHandler);
-
- A.CallTo(() => errorHandler(null)).WithAnyArguments().MustHaveHappened();
- res.Should().BeEquivalentTo(fail);
- }
-
- [Test]
- public void SkipOnFail_WhenOk()
- {
- var ok = Result.Ok(42);
-
- var res = ok.OnFail(v => { Assert.Fail("Should not be called"); });
-
- res.Should().BeEquivalentTo(ok);
- }
-
- [Test]
- public void RunThen_WhenOk_Scenario()
- {
- var res =
- Result.Ok("1358571172")
- .Then(int.Parse)
- .Then(i => Convert.ToString(i, 16))
- .Then(hex => Guid.Parse(hex + hex + hex + hex));
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void RunThen_WhenOk_ComplexScenario()
- {
- var parsed = Result.Ok("1358571172").Then(int.Parse);
- var res = parsed
- .Then(i => Convert.ToString(i, 16))
- .Then(hex => parsed.GetValueOrThrow() + " -> " + Guid.Parse(hex + hex + hex + hex));
- res.Should().BeEquivalentTo(Result.Ok("1358571172 -> 50fa26a4-50fa-26a4-50fa-26a450fa26a4"));
- }
-
- // [Test]
- // public void ReplaceError_IfFail()
- // {
- // Result.Fail("error")
- // .ReplaceError(e => "replaced")
- // .Should().BeEquivalentTo(Result.Fail("replaced"));
- // }
- //
- // [Test]
- // public void ReplaceError_DoNothing_IfSuccess()
- // {
- // Result.Ok(42)
- // .ReplaceError(e => "replaced")
- // .Should().BeEquivalentTo(Result.Ok(42));
- // }
- //
- // [Test]
- // public void ReplaceError_DontReplace_IfCalledBeforeError()
- // {
- // Result.Ok(42)
- // .ReplaceError(e => "replaced")
- // .Then(n => Result.Fail("error"))
- // .Should().BeEquivalentTo(Result.Fail("error"));
- // }
- //
- // [Test]
- // public void RefineError_AddErrorMessageBeforePreviousErrorText()
- // {
- // var calculation = Result.Fail("No connection");
- // calculation
- // .RefineError("Posting results to db")
- // .Should().BeEquivalentTo(Result.Fail("Posting results to db. No connection"));
- // }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Solved/ParseResultExtensions.cs b/ErrorHandling/Solved/ParseResultExtensions.cs
deleted file mode 100644
index 0eb2dda6b..000000000
--- a/ErrorHandling/Solved/ParseResultExtensions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-
-namespace ResultOf
-{
- public static class ParseResultExtensions
- {
- public static Result ParseIntResult(this string s, string error = null)
- {
- int v;
- return int.TryParse(s, out v)
- ? v.AsResult()
- : Result.Fail(error ?? "Не число " + s);
- }
- public static Result ParseGuidResult(this string s, string error = null)
- {
- Guid v;
- return Guid.TryParse(s, out v)
- ? v.AsResult()
- : Result.Fail(error ?? "Не GUID " + s);
- }
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Solved/Result.cs b/ErrorHandling/Solved/Result.cs
deleted file mode 100644
index 3b5be71d8..000000000
--- a/ErrorHandling/Solved/Result.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using System;
-
-namespace ResultOf
-{
- public class None
- {
- private None()
- {
- }
- }
-
- public struct Result
- {
- public Result(string error, T value = default(T))
- {
- Error = error;
- Value = value;
- }
- public static implicit operator Result(T v)
- {
- return Result.Ok(v);
- }
-
- public string Error { get; }
- internal T Value { get; }
- public T GetValueOrThrow()
- {
- if (IsSuccess) return Value;
- throw new InvalidOperationException($"No value. Only Error {Error}");
- }
- public bool IsSuccess => Error == null;
- }
-
- public static class Result
- {
- public static Result AsResult(this T value)
- {
- return Ok(value);
- }
-
- public static Result Ok(T value)
- {
- return new Result(null, value);
- }
- public static Result Ok()
- {
- return Ok(null);
- }
-
- public static Result Fail(string e)
- {
- return new Result(e);
- }
-
- public static Result Of(Func f, string error = null)
- {
- try
- {
- return Ok(f());
- }
- catch (Exception e)
- {
- return Fail(error ?? e.Message);
- }
- }
-
- public static Result OfAction(Action f, string error = null)
- {
- try
- {
- f();
- return Ok();
- }
- catch (Exception e)
- {
- return Fail(error ?? e.Message);
- }
- }
-
- public static Result Then(
- this Result input,
- Func continuation)
- {
- return input.Then(inp => Of(() => continuation(inp)));
- }
-
- public static Result Then(
- this Result input,
- Action continuation)
- {
- return input.Then(inp => OfAction(() => continuation(inp)));
- }
-
- public static Result Then(
- this Result input,
- Func> continuation)
- {
- return input.IsSuccess
- ? continuation(input.Value)
- : Fail(input.Error);
- }
-
- public static Result OnFail(
- this Result input,
- Action handleError)
- {
- if (!input.IsSuccess) handleError(input.Error);
- return input;
- }
-
- public static Result ReplaceError(
- this Result input,
- Func replaceError)
- {
- if (input.IsSuccess) return input;
- return Fail(replaceError(input.Error));
- }
-
- public static Result RefineError(
- this Result input,
- string errorMessage)
- {
- return input.ReplaceError(err => errorMessage + ". " + err);
- }
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Solved/ResultQueryExpressionExtensions.cs b/ErrorHandling/Solved/ResultQueryExpressionExtensions.cs
deleted file mode 100644
index 88d3d7b09..000000000
--- a/ErrorHandling/Solved/ResultQueryExpressionExtensions.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-
-namespace ResultOf
-{
- public static class ResultQueryExpressionExtensions
- {
- public static Result SelectMany(
- this Result input,
- Func> continuation)
- {
- return input.Then(continuation);
- }
-
- public static Result SelectMany(
- this Result input,
- Func> continuation,
- Func resultSelector)
- {
- return input.Then(continuation)
- .Then(o => resultSelector(input.Value, o));
- }
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Solved/ResultQueryExpression_Should.cs b/ErrorHandling/Solved/ResultQueryExpression_Should.cs
deleted file mode 100644
index 7d1dcc4c4..000000000
--- a/ErrorHandling/Solved/ResultQueryExpression_Should.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using FluentAssertions;
-using NUnit.Framework;
-
-namespace ResultOf
-{
- [TestFixture]
- public class ResultQueryExpression_Should
- {
- [Test]
- public void SupportLinqMethodChaining()
- {
- var res =
- "1358571172".ParseIntResult()
- .SelectMany(i => Convert.ToString(i, 16).AsResult())
- .SelectMany(hex => (hex + hex + hex + hex).ParseGuidResult());
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportLinqMethodChaining_WithResultSelector()
- {
- var res =
- "1358571172".ParseIntResult()
- .SelectMany(i => Convert.ToString(i, 16).AsResult(), (i, hex) => new { i, hex })
- .SelectMany(t => (t.hex + t.hex + t.hex + t.hex).ParseGuidResult());
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportQueryExpressions()
- {
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeOfType>();
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void SupportQueryExpressions_WithComplexSelect()
- {
- // ��� ��������, ���� �������� ������ ������ Query Expressions ��� Result
- // �������� �������� �� ������������� i � select
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select i + " -> " + guid;
- res.Should().BeOfType>();
- res.Should().BeEquivalentTo(Result.Ok("1358571172 -> 50fa26a4-50fa-26a4-50fa-26a450fa26a4"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenErrorAtTheEnd()
- {
- var res =
- from i in "0".ParseIntResult()
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult("error is here")
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenExceptionOnSomeStage()
- {
- var res =
- from i in "1358571172".ParseIntResult()
- from hex in Result.Of(() => Convert.ToString(i, 100500), "error is here")
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
-
- [Test]
- public void ReturnFail_FromSelectMany_WhenErrorAtTheBeginning()
- {
- var res =
- from i in "UNPARSABLE".ParseIntResult("error is here")
- from hex in Convert.ToString(i, 16).AsResult()
- from guid in (hex + hex + hex + hex).ParseGuidResult()
- select guid;
- res.Should().BeEquivalentTo(Result.Fail("error is here"));
- }
- }
-}
\ No newline at end of file
diff --git a/ErrorHandling/Solved/Result_Should.cs b/ErrorHandling/Solved/Result_Should.cs
deleted file mode 100644
index db932e32f..000000000
--- a/ErrorHandling/Solved/Result_Should.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-using System;
-using FakeItEasy;
-using FluentAssertions;
-using NUnit.Framework;
-
-namespace ResultOf
-{
- [TestFixture]
- public class Result_Should
- {
- [Test]
- public void Create_Ok()
- {
- var r = Result.Ok(42);
- r.IsSuccess.Should().BeTrue();
- r.GetValueOrThrow().Should().Be(42);
- }
-
- [Test]
- public void Create_Fail()
- {
- var r = Result.Fail("123");
-
- r.IsSuccess.Should().BeFalse();
- r.Error.Should().Be("123");
- }
-
- [Test]
- public void ReturnsFail_FromResultOf_OnException()
- {
- var res = Result.Of(() => { throw new Exception("123"); });
-
- res.Should().BeEquivalentTo(Result.Fail("123"));
- }
-
- [Test]
- public void ReturnsFailWithCustomMessage_FromResultOf_OnException()
- {
- var res = Result.Of(() => { throw new Exception("123"); }, "42");
-
- res.Should().BeEquivalentTo(Result.Fail("42"));
- }
-
- [Test]
- public void ReturnsOk_FromResultOf_WhenNoException()
- {
- var res = Result.Of(() => 42);
-
- res.Should().BeEquivalentTo(Result.Ok(42));
- }
-
- [Test]
- public void RunThen_WhenOk()
- {
- var res = Result.Ok(42)
- .Then(n => n + 10);
- res.Should().BeEquivalentTo(Result.Ok(52));
- }
-
- [Test]
- public void SkipThen_WhenFail()
- {
- var fail = Result.Fail("������");
- var called = false;
- fail.Then(n =>
- {
- called = true;
- return n;
- });
- called.Should().BeFalse();
- }
-
- [Test]
- public void Then_ReturnsFail_OnException()
- {
- Func continuation = n =>
- {
- throw new Exception("123");
- };
- var res = Result.Ok(42)
- .Then(continuation);
- res.Should().BeEquivalentTo(Result.Fail("123"));
- }
-
- [Test]
- public void RunOnFail_WhenFail()
- {
- var fail = Result.Fail("������");
- var errorHandler = A.Fake>();
-
- var res = fail.OnFail(errorHandler);
-
- A.CallTo(() => errorHandler(null)).WithAnyArguments().MustHaveHappened();
- res.Should().BeEquivalentTo(fail);
- }
-
- [Test]
- public void SkipOnFail_WhenOk()
- {
- var ok = Result.Ok(42);
-
- var res = ok.OnFail(v => { Assert.Fail("Should not be called"); });
-
- res.Should().BeEquivalentTo(ok);
- }
-
- [Test]
- public void RunThen_WhenOk_Scenario()
- {
- var res =
- Result.Ok("1358571172")
- .Then(int.Parse)
- .Then(i => Convert.ToString(i, 16))
- .Then(hex => Guid.Parse(hex + hex + hex + hex));
- res.Should().BeEquivalentTo(Result.Ok(Guid.Parse("50FA26A450FA26A450FA26A450FA26A4")));
- }
-
- [Test]
- public void RunThen_WhenOk_ComplexScenario()
- {
- var parsed = Result.Ok("1358571172").Then(int.Parse);
- var res = parsed
- .Then(i => Convert.ToString(i, 16))
- .Then(hex => parsed.GetValueOrThrow() + " -> " + Guid.Parse(hex + hex + hex + hex));
- res.Should().BeEquivalentTo(Result.Ok("1358571172 -> 50fa26a4-50fa-26a4-50fa-26a450fa26a4"));
- }
-
- [Test]
- public void ReplaceError_IfFail()
- {
- Result.Fail("error")
- .ReplaceError(e => "replaced")
- .Should().BeEquivalentTo(Result.Fail("replaced"));
- }
-
- [Test]
- public void ReplaceError_DoNothing_IfSuccess()
- {
- Result.Ok(42)
- .ReplaceError(e => "replaced")
- .Should().BeEquivalentTo(Result.Ok(42));
- }
-
- [Test]
- public void ReplaceError_DontReplace_IfCalledBeforeError()
- {
- Result.Ok(42)
- .ReplaceError(e => "replaced")
- .Then(n => Result.Fail("error"))
- .Should().BeEquivalentTo(Result.Fail("error"));
- }
-
- [Test]
- public void RefineError_AddErrorMessageBeforePreviousErrorText()
- {
- var calculation = Result.Fail("No connection");
- calculation
- .RefineError("Posting results to db")
- .Should().BeEquivalentTo(Result.Fail("Posting results to db. No connection"));
- }
- }
-}
\ No newline at end of file
diff --git a/FileSenderRailway/Dependencies.cs b/FileSenderRailway/Dependencies.cs
deleted file mode 100644
index 43768227b..000000000
--- a/FileSenderRailway/Dependencies.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System;
-using System.Security.Cryptography.X509Certificates;
-
-namespace FileSenderRailway;
-
-public interface ICryptographer
-{
- byte[] Sign(byte[] content, X509Certificate certificate);
-}
-
-public interface IRecognizer
-{
- /// Not recognized
- Document Recognize(FileContent file);
-}
-
-public interface ISender
-{
- /// Can't send
- void Send(Document document);
-}
-
-public class Document
-{
- public Document(string name, byte[] content, DateTime created, string format)
- {
- Name = name;
- Created = created;
- Format = format;
- Content = content;
- }
-
- public string Name { get; set; }
- public DateTime Created { get; set; }
- public string Format { get; set; }
- public byte[] Content { get; set; }
-}
-
-public class FileContent
-{
- public FileContent(string name, byte[] content)
- {
- Name = name;
- Content = content;
- }
-
- public string Name { get; }
- public byte[] Content { get; }
-}
-
-public class FileSendResult
-{
- public FileSendResult(FileContent file, string error = null)
- {
- File = file;
- Error = error;
- }
-
- public FileContent File { get; }
- public string Error { get; }
- public bool IsSuccess => Error == null;
-}
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender.cs b/FileSenderRailway/FileSender.cs
deleted file mode 100644
index f7159a7ec..000000000
--- a/FileSenderRailway/FileSender.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Security.Cryptography.X509Certificates;
-
-namespace FileSenderRailway;
-
-public class FileSender
-{
- private readonly ICryptographer cryptographer;
- private readonly IRecognizer recognizer;
- private readonly Func now;
- private readonly ISender sender;
-
- public FileSender(
- ICryptographer cryptographer,
- ISender sender,
- IRecognizer recognizer,
- Func now)
- {
- this.cryptographer = cryptographer;
- this.sender = sender;
- this.recognizer = recognizer;
- this.now = now;
- }
-
- public IEnumerable SendFiles(FileContent[] files, X509Certificate certificate)
- {
- foreach (var file in files)
- {
- string errorMessage = null;
- try
- {
- Document doc = recognizer.Recognize(file);
- if (!IsValidFormatVersion(doc))
- throw new FormatException("Invalid format version");
- if (!IsValidTimestamp(doc))
- throw new FormatException("Too old document");
- doc.Content = cryptographer.Sign(doc.Content, certificate);
- sender.Send(doc);
- }
- catch (FormatException e)
- {
- errorMessage = "Can't prepare file to send. " + e.Message;
- }
- catch (InvalidOperationException e)
- {
- errorMessage = "Can't send. " + e.Message;
- }
- yield return new FileSendResult(file, errorMessage);
- }
- }
-
- private bool IsValidFormatVersion(Document doc)
- {
- return doc.Format == "4.0" || doc.Format == "3.1";
- }
-
- private bool IsValidTimestamp(Document doc)
- {
- var oneMonthBefore = now().AddMonths(-1);
- return doc.Created > oneMonthBefore;
- }
-}
\ No newline at end of file
diff --git a/FileSenderRailway/FileSenderRailway.csproj b/FileSenderRailway/FileSenderRailway.csproj
deleted file mode 100644
index 8c6447891..000000000
--- a/FileSenderRailway/FileSenderRailway.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
- Exe
- net8.0
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt b/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt
deleted file mode 100644
index 1a1340f6b..000000000
--- a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Invalid format version
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt b/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt
deleted file mode 100644
index c0d889604..000000000
--- a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Too old document
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt b/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt
deleted file mode 100644
index c0d889604..000000000
--- a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Too old document
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt b/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt
deleted file mode 100644
index 1a1340f6b..000000000
--- a/FileSenderRailway/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Invalid format version
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender_Should.Fail_WhenNotRecognized.approved.txt b/FileSenderRailway/FileSender_Should.Fail_WhenNotRecognized.approved.txt
deleted file mode 100644
index 3d51001d8..000000000
--- a/FileSenderRailway/FileSender_Should.Fail_WhenNotRecognized.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Can't recognize
\ No newline at end of file
diff --git a/FileSenderRailway/FileSender_Should.cs b/FileSenderRailway/FileSender_Should.cs
deleted file mode 100644
index 2a2031714..000000000
--- a/FileSenderRailway/FileSender_Should.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using System;
-using System.Linq;
-using System.Security.Cryptography.X509Certificates;
-using ApprovalTests;
-using ApprovalTests.Namers;
-using ApprovalTests.Reporters;
-using FakeItEasy;
-using FluentAssertions;
-using NUnit.Framework;
-
-namespace FileSenderRailway;
-
-[TestFixture]
-[UseReporter(typeof(DiffReporter))]
-public class FileSender_Should
-{
- private FileSender fileSender;
- private ICryptographer cryptographer;
- private ISender sender;
- private IRecognizer recognizer;
-
- private readonly FileContent file = new(Guid.NewGuid().ToString("N"), Guid.NewGuid().ToByteArray());
- private readonly DateTime now = new(2000, 01, 01);
- private readonly X509Certificate certificate = new();
-
- [SetUp]
- public void SetUp()
- {
- cryptographer = A.Fake();
- sender = A.Fake();
- recognizer = A.Fake();
- fileSender = new FileSender(cryptographer, sender, recognizer, () => now);
- }
-
- [Test]
- public void BeOk_WhenGoodFormat(
- [Values("4.0", "3.1")] string format,
- [Values(0, 30)] int daysBeforeNow)
- {
- var signed = SomeByteArray();
- PrepareDocument(file, signed, now.AddDays(-daysBeforeNow), format);
-
- fileSender.SendFiles(new[] { file }, certificate)
- .Should().BeEquivalentTo(new[] { new FileSendResult(file) });
- A.CallTo(() => sender.Send(A.That.Matches(d => d.Content == signed)))
- .MustHaveHappened();
- }
-
-
- [Test]
- public void Fail_WhenNotRecognized()
- {
- A.CallTo(() => recognizer.Recognize(file))
- .Throws(new FormatException("Can't recognize"));
-
- VerifyErrorOnPrepareFile(file, certificate);
- }
-
- [TestCase("1.0", 0)]
- [TestCase("4.0", 32)]
- [TestCase("3.1", 32)]
- [TestCase("wrong", 32)]
- [Test]
- public void Fail_WhenBadFormatOrTimestamp(string format, int daysBeforeNow)
- {
- PrepareDocument(file, null, now.AddDays(-daysBeforeNow), format);
- using (ApprovalResults.ForScenario(format, daysBeforeNow))
- VerifyErrorOnPrepareFile(file, certificate);
- }
-
- private void PrepareDocument(FileContent content, byte[] signedContent, DateTime created, string format)
- {
- var document = new Document(content.Name, content.Content, created, format);
- A.CallTo(() => recognizer.Recognize(content)).Returns(document);
- A.CallTo(() => cryptographer.Sign(content.Content, certificate)).Returns(signedContent);
- }
-
- private void VerifyErrorOnPrepareFile(FileContent fileContent, X509Certificate x509Certificate)
- {
- var res = fileSender
- .SendFiles(new[] { fileContent }, x509Certificate)
- .Single();
- res.IsSuccess.Should().BeFalse();
- Approvals.Verify(res.Error);
- }
-
- private static byte[] SomeByteArray()
- {
- return Guid.NewGuid().ToByteArray();
- }
-}
\ No newline at end of file
diff --git a/FileSenderRailway/README.md b/FileSenderRailway/README.md
deleted file mode 100644
index 8fcde6c69..000000000
--- a/FileSenderRailway/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-## Задание FileSenderRailway
-
-1. Сделать класс Document неизменяемым
-2. Выделить функцию PrepareFileToSend из SendFiles
-3. Добавить дополнительную информацию в тексты ошибок:
- * Версию формата, если он не поддерживается
- * Дату создания, если документ слишком старый
-4. Переделать логику на исключениях на Result.
-Можно и нужно менять интерфейсы зависимостей!
-5. Сделать метод PrepareFileToSend декларативным
diff --git a/FileSenderRailway/Solved/Dependencies.cs b/FileSenderRailway/Solved/Dependencies.cs
deleted file mode 100644
index 76d1f87ea..000000000
--- a/FileSenderRailway/Solved/Dependencies.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using System.Security.Cryptography.X509Certificates;
-using ResultOf;
-
-namespace FileSenderRailway.Solved
-{
- public class Document
- {
- public Document(string name, byte[] content, DateTime created, string format)
- {
- Name = name;
- Created = created;
- Format = format;
- Content = content;
- }
-
- public string Name { get; }
- public DateTime Created { get; }
- public string Format { get; }
- public byte[] Content { get; }
- public Document WithContent(byte[] newContent)
- => new Document(Name, newContent, Created, Format);
- }
-
- public class FileContent
- {
- public FileContent(string name, byte[] content)
- {
- Name = name;
- Content = content;
- }
-
- public string Name { get; }
- public byte[] Content { get; }
- }
-
- public class FileSendResult
- {
- public FileSendResult(FileContent file, string error)
- {
- File = file;
- Error = error;
- }
-
- public FileContent File { get; }
- public string Error { get; }
- }
-
- public interface ICryptographer
- {
- byte[] Sign(byte[] content, X509Certificate certificate);
- }
-
- public interface IRecognizer
- {
- Result Recognize(FileContent file);
- }
-
- public interface ISender
- {
- Result Send(Document content);
- }
-}
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender.cs b/FileSenderRailway/Solved/FileSender.cs
deleted file mode 100644
index c039fbdcb..000000000
--- a/FileSenderRailway/Solved/FileSender.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography.X509Certificates;
-using ResultOf;
-
-//using CSharpFunctionalExtensions;
-
-namespace FileSenderRailway.Solved
-{
- public class FileSender
- {
- private readonly ICryptographer cryptographer;
- private readonly IRecognizer recognizer;
- private readonly Func now;
- private readonly ISender sender;
-
- public FileSender(
- ICryptographer cryptographer,
- ISender sender,
- IRecognizer recognizer,
- Func now)
- {
- this.cryptographer = cryptographer;
- this.sender = sender;
- this.recognizer = recognizer;
- this.now = now;
- }
-
- public IEnumerable SendFiles(FileContent[] files, X509Certificate certificate)
- {
- return files.Select(file => new FileSendResult(file,
- PrepareFileToSend(file, certificate).Then(doc => sender.Send(doc)).Error));
- }
-
- public Result PrepareFileToSend(FileContent file, X509Certificate certificate)
- {
- return recognizer.Recognize(file)
- .Then(ValidateFormatIsSupported)
- .Then(ValidateIsNotTooOld)
- .Then(doc => doc.WithContent(cryptographer.Sign(doc.Content, certificate)))
- .RefineError("Can't prepare file to send");
- }
-
- private Result ValidateFormatIsSupported(Document doc)
- {
- return Validate(doc, d => d.Format == "4.0" || d.Format == "3.1", $"Invalid format version '{doc.Format}'");
- }
-
- private Result ValidateIsNotTooOld(Document doc)
- {
- var oneMonthBefore = now().AddMonths(-1);
- return Validate(doc, d => d.Created > oneMonthBefore, $"Too old document. CreationDate: {doc.Created} ");
- }
-
- private Result Validate(T obj, Func predicate, string errorMessage)
- {
- return predicate(obj)
- ? Result.Ok(obj)
- : Result.Fail(errorMessage);
- }
- }
-}
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt b/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt
deleted file mode 100644
index 3ea9f2ca2..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.1.0.0.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Invalid format version '1.0'
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt b/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt
deleted file mode 100644
index 4073d2488..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.3.1.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Too old document. CreationDate: 30.11.1999 0:00:00
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt b/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt
deleted file mode 100644
index 4073d2488..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.4.0.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Too old document. CreationDate: 30.11.1999 0:00:00
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt b/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt
deleted file mode 100644
index 366351f8c..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenBadFormatOrTimestamp.ForScenario.wrong.32.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Invalid format version 'wrong'
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenNotRecognized.approved.txt b/FileSenderRailway/Solved/FileSender_Should.Fail_WhenNotRecognized.approved.txt
deleted file mode 100644
index 3d51001d8..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.Fail_WhenNotRecognized.approved.txt
+++ /dev/null
@@ -1 +0,0 @@
-Can't prepare file to send. Can't recognize
\ No newline at end of file
diff --git a/FileSenderRailway/Solved/FileSender_Should.cs b/FileSenderRailway/Solved/FileSender_Should.cs
deleted file mode 100644
index 12e0a4a21..000000000
--- a/FileSenderRailway/Solved/FileSender_Should.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.IO;
-using System.Security.Cryptography.X509Certificates;
-using ApprovalTests;
-using ApprovalTests.Namers;
-using ApprovalTests.Reporters;
-using FakeItEasy;
-using FluentAssertions;
-using NUnit.Framework;
-using ResultOf;
-
-namespace FileSenderRailway.Solved
-{
- [TestFixture]
- [UseReporter(typeof(DiffReporter))]
- public class FileSender_Should
- {
- private FileSender fileSender;
- private ICryptographer cryptographer;
- private IRecognizer recognizer;
-
- [SetUp]
- public void SetUp()
- {
- Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
- cryptographer = A.Fake();
- recognizer = A.Fake();
- fileSender = new FileSender(cryptographer, A.Fake(), recognizer, () => now);
- }
-
- private readonly FileContent file = new FileContent(Guid.NewGuid().ToString("N"), Guid.NewGuid().ToByteArray());
- private readonly DateTime now = new DateTime(2000, 01, 01);
- private readonly X509Certificate certificate = new X509Certificate();
-
- [Test]
- public void BeOk_WhenGoodFormat(
- [Values("4.0", "3.1")]string format,
- [Values(0, 30)]int daysBeforeNow)
- {
- var signedContent = SomeByteArray();
- var document = PrepareDocument(file, signedContent, now.AddDays(-daysBeforeNow), format);
- var expectedDocument = document.WithContent(signedContent);
- var result = fileSender.PrepareFileToSend(file, certificate);
-
- result.IsSuccess.Should().BeTrue();
- result.Value.Should().BeEquivalentTo(expectedDocument);
- }
-
- [Test]
- public void Fail_WhenNotRecognized()
- {
- A.CallTo(() => recognizer.Recognize(file))
- .Returns(Result.Fail("Can't recognize"));
-
- VerifyErrorOnPrepareFile(file, certificate);
- }
-
- [TestCase("1.0", 0)]
- [TestCase("4.0", 32)]
- [TestCase("3.1", 32)]
- [TestCase("wrong", 32)]
- [Test]
- public void Fail_WhenBadFormatOrTimestamp(string format, int daysBeforeNow)
- {
- PrepareDocument(file, null, now.AddDays(-daysBeforeNow), format);
- using (ApprovalResults.ForScenario(format, daysBeforeNow))
- VerifyErrorOnPrepareFile(file, certificate);
- }
-
- private Document PrepareDocument(FileContent fileToPrepare, byte[] signed, DateTime created, string format)
- {
- var document = new Document(fileToPrepare.Name, fileToPrepare.Content, created, format);
- A.CallTo(() => recognizer.Recognize(fileToPrepare)).Returns(Result.Ok(document));
- A.CallTo(() => cryptographer.Sign(fileToPrepare.Content, certificate)).Returns(signed);
- return document;
- }
-
- private void VerifyErrorOnPrepareFile(FileContent fileContent, X509Certificate x509Certificate)
- {
- var res = fileSender.PrepareFileToSend(fileContent, x509Certificate);
- res.IsSuccess.Should().BeFalse();
- Approvals.Verify(res.Error);
- }
-
- private static byte[] SomeByteArray()
- {
- return Guid.NewGuid().ToByteArray();
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/ConsoleUi.cs b/Samples/ConwaysGameOfLife/ConsoleUi.cs
deleted file mode 100644
index 155904254..000000000
--- a/Samples/ConwaysGameOfLife/ConsoleUi.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-namespace ConwaysGameOfLife
-{
- public class ConsoleUi : IGameUi
- {
- public void UpdateAll(IReadonlyField field)
- {
- Console.SetCursorPosition(0, 0);
- for (int y = 0; y < field.Height; y++)
- {
- for (int x = 0; x < field.Width; x++)
- {
- var symbol = field.IsAlive(x, y) ? '#' : ' ';
- Console.Write(symbol);
- }
- Console.WriteLine();
- }
- }
-
- public void UpdateCell(int x, int y, bool alive)
- {
- Console.SetCursorPosition(x, y);
- Console.Write(alive ? '#' : ' ');
-
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/ConwaysGameOfLife.csproj b/Samples/ConwaysGameOfLife/ConwaysGameOfLife.csproj
deleted file mode 100644
index 7aec55587..000000000
--- a/Samples/ConwaysGameOfLife/ConwaysGameOfLife.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Exe
- net8.0
- false
-
-
- ConwaysGameOfLife.Program
-
-
-
-
-
-
-
-
diff --git a/Samples/ConwaysGameOfLife/Game.cs b/Samples/ConwaysGameOfLife/Game.cs
deleted file mode 100644
index e267ec079..000000000
--- a/Samples/ConwaysGameOfLife/Game.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace ConwaysGameOfLife
-{
- public class Game : IReadonlyField
- {
- public int Width { get; }
- public int Height { get; }
-
- private bool[,] isAlive;
-
- public Game(Size size)
- {
- Width = size.Width;
- Height = size.Height;
- isAlive = new bool[Width, Height];
- }
-
- private Game(bool[,] alive)
- {
- Width = alive.GetLength(0);
- Height = alive.GetLength(1);
- isAlive = alive;
- }
-
- public void Revive(params Point[] cells)
- {
- foreach (var pos in cells)
- isAlive[(pos.X + Width) % Width, (pos.Y + Height) % Height] = true;
- }
-
- public StepResult Step()
- {
- var willBeAlive = new bool[Width, Height];
- var changes = new List();
- for (int y = 0; y < Height; y++)
- for (int x = 0; x < Width; x++)
- {
- willBeAlive[x, y] = WillBeAlive(x, y);
- if (willBeAlive[x, y] != isAlive[x, y])
- {
- var change = new ChangedCell(x, y, willBeAlive[x, y]);
- changes.Add(change);
- }
- }
- isAlive = willBeAlive;
- return new StepResult(new Game(willBeAlive), changes);
- }
-
- private bool WillBeAlive(int x, int y)
- {
- var aliveCount = GetNeighbours(x, y).Count(IsAlive);
- return WillBeAlive(isAlive[x, y], aliveCount);
- }
-
- private bool WillBeAlive(bool alive, int aliveNeighbours)
- {
- return aliveNeighbours == 3 || aliveNeighbours == 2 && alive;
- }
-
- private IEnumerable GetNeighbours(int x, int y)
- {
- return
- from nx in new[] { x - 1, x, x + 1 }
- from ny in new[] { y - 1, y, y + 1 }
- where nx != x || ny != y
- select new Point(nx, ny);
- }
-
- public bool IsAlive(Point pos)
- {
- return IsAlive(pos.X, pos.Y);
- }
-
- public bool IsAlive(int x, int y)
- {
- return isAlive[(x + Width) % Width, (y + Height) % Height];
- }
-
- public override string ToString()
- {
-
- var rows = Enumerable.Range(0, Height)
- .Select(y =>
- string.Join("",
- Enumerable.Range(0, Width).Select(x => isAlive[x, y] ? "#" : " ")
- ));
- return string.Join("\n", rows);
- }
- }
-
- public class StepResult
- {
- public List ChangedCells { get; set; }
- public readonly Game NextState;
-
- public StepResult(Game nextState, List changes)
- {
- ChangedCells = changes;
- NextState = nextState;
- }
-
- }
-
- public class ChangedCell
- {
- public ChangedCell(int x, int y, bool isAlive)
- {
- X = x;
- Y = y;
- IsAlive = isAlive;
- }
-
- public int X { get; private set; }
- public int Y { get; private set; }
- public bool IsAlive { get; private set; }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/Game_Ui_Interaction_Tests.cs b/Samples/ConwaysGameOfLife/Game_Ui_Interaction_Tests.cs
deleted file mode 100644
index 44414bd17..000000000
--- a/Samples/ConwaysGameOfLife/Game_Ui_Interaction_Tests.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// using FakeItEasy;
-// using NUnit.Framework;
-//
-// namespace ConwaysGameOfLife
-// {
-// [TestFixture]
-// public class Game_Ui_Interaction_Tests
-// {
-// private IGameUi ui;
-// private Game game;
-//
-// [SetUp]
-// public void SetUp()
-// {
-// ui = A.Fake();
-// game = new Game(new Size(2, 2));
-// }
-//
-// [Test]
-// public void Revive_UpdatesAllUi()
-// {
-// game.Revive(new Point(1, 1));
-//
-// A.CallTo(() => ui.UpdateAll(game))
-// .MustHaveHappened(1, Times.Exactly);
-// }
-//
-// [Test]
-// public void Step_UpdatesOnlyChangedCellsInUi()
-// {
-// game.Revive(new Point(0, 0));
-// game.Step();
-//
-// A.CallTo(() => ui.UpdateCell(0, 0, false))
-// .MustHaveHappened(1, Times.Exactly);
-// A.CallTo(() => ui.UpdateCell(A.Ignored, A.Ignored, false))
-// .MustHaveHappened(1, Times.Exactly);
-// }
-// }
-// }
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/IGameUi.cs b/Samples/ConwaysGameOfLife/IGameUi.cs
deleted file mode 100644
index 957eed4a1..000000000
--- a/Samples/ConwaysGameOfLife/IGameUi.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace ConwaysGameOfLife
-{
- public interface IGameUi
- {
- void UpdateAll(IReadonlyField field);
- void UpdateCell(int x, int y, bool alive);
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/IReadonlyField.cs b/Samples/ConwaysGameOfLife/IReadonlyField.cs
deleted file mode 100644
index 0281e0622..000000000
--- a/Samples/ConwaysGameOfLife/IReadonlyField.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ConwaysGameOfLife
-{
- public interface IReadonlyField
- {
- int Width { get; }
- int Height { get; }
- bool IsAlive(int x, int y);
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/Patterns.cs b/Samples/ConwaysGameOfLife/Patterns.cs
deleted file mode 100644
index 8989e807f..000000000
--- a/Samples/ConwaysGameOfLife/Patterns.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Linq;
-
-namespace ConwaysGameOfLife
-{
- public class Patterns
- {
- public static Point[] GetHorizontalStick(Point topLeft)
- {
- return new[] { P(0, 0), P(1, 0), P(2, 0) }.Select(p => p.Add(topLeft)).ToArray();
- }
-
- public static Point[] GetGlider(Point topLeft)
- {
- return new[] {
- new Point(0, 0), new Point(0, 2),
- new Point(1, 1), new Point(1, 2),
- new Point(2, 1)
- }.Select(p => p.Add(topLeft)).ToArray();
-
- }
-
- public static Point[] GetR(Point topLeft)
- {
- return new[] {
- P(1, 0), P(2, 0),
- P(0, 1), P(1, 1),
- P(1, 2)
- }.Select(p => p.Add(topLeft)).ToArray();
- }
- private static Point P(int x, int y)
- {
- return new Point(x, y);
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/Point.cs b/Samples/ConwaysGameOfLife/Point.cs
deleted file mode 100644
index 2278955de..000000000
--- a/Samples/ConwaysGameOfLife/Point.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-namespace ConwaysGameOfLife
-{
- public class Point
- {
- public Point(int x, int y)
- {
- X = x;
- Y = y;
- }
-
- public readonly int X, Y;
-
- public Point Add(Point p)
- {
- return new Point(p.X + X, p.Y + Y);
- }
-
- protected bool Equals(Point other)
- {
- return X == other.X && Y == other.Y;
- }
-
- public override string ToString()
- {
- return string.Format("X: {0}, Y: {1}", X, Y);
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != this.GetType()) return false;
- return Equals((Point) obj);
- }
-
- public override int GetHashCode()
- {
- unchecked
- {
- return (X*397) ^ Y;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/Program.cs b/Samples/ConwaysGameOfLife/Program.cs
deleted file mode 100644
index 7398b28ce..000000000
--- a/Samples/ConwaysGameOfLife/Program.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using Ninject;
-using System;
-
-namespace ConwaysGameOfLife
-{
- public class Program
- {
- public Program(Game game, IGameUi ui)
- {
- this.game = game;
- this.ui = ui;
- }
-
- private Game game;
- private IGameUi ui;
-
- private static void Main()
- {
- var container = new StandardKernel();
- container.Bind().To();
- container.Bind().ToConstant(new Size(60, 20));
- container.Bind().ToSelf()
- .OnActivation(g => g.Revive(Patterns.GetGlider(new Point(25, 8))));
-
- var program = container.Get();
- program.PlayGame();
- }
-
- public void PlayGame()
- {
- ui.UpdateAll(game);
- while (true)
- {
- var key = Console.ReadKey(intercept: true);
- if (key.Key == ConsoleKey.Escape) break;
- game = DoGameStep(game, ui);
- }
- }
-
- public static Game DoGameStep(Game game, IGameUi ui)
- {
- var stepResult = game.Step();
- var newGame = stepResult.NextState;
- foreach (var changedCell in stepResult.ChangedCells)
- ui.UpdateCell(changedCell.X, changedCell.Y, changedCell.IsAlive);
- return newGame;
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/README.md b/Samples/ConwaysGameOfLife/README.md
deleted file mode 100644
index 5086516da..000000000
--- a/Samples/ConwaysGameOfLife/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## Задача Game of Life
-
-1. Уберите зависимость Game от IGameUi.
-
-2. Сделайте Game неизменяемым классом.
\ No newline at end of file
diff --git a/Samples/ConwaysGameOfLife/Size.cs b/Samples/ConwaysGameOfLife/Size.cs
deleted file mode 100644
index b58632be1..000000000
--- a/Samples/ConwaysGameOfLife/Size.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace ConwaysGameOfLife
-{
- public class Size
- {
- public int Width { get; }
- public int Height { get; }
-
- public Size(int width, int height)
- {
- Width = width;
- Height = height;
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/Summator/DataSource.cs b/Samples/Summator/DataSource.cs
deleted file mode 100644
index c51e262a4..000000000
--- a/Samples/Summator/DataSource.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.IO;
-
-namespace FP
-{
- ///Этот класс нельзя менять. Считайте, что он вам дан в виде бинарной зависимости.
- public class DataSource : IDisposable
- {
- private readonly StreamReader reader;
- public DataSource(string filename)
- {
- reader = new StreamReader(filename);
- }
-
- ///null if no more data
- public string[] NextRecord()
- {
- var line = reader.ReadLine();
- return line == null ? null : line.Split(' ');
- }
-
- public void Dispose()
- {
- reader.Close();
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/Summator/ISumFormatter.cs b/Samples/Summator/ISumFormatter.cs
deleted file mode 100644
index 4fbeca64f..000000000
--- a/Samples/Summator/ISumFormatter.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Linq;
-
-namespace FP
-{
- public interface ISumFormatter
- {
- string Format(int[] nums, int sum);
- }
-
- public class HexSumFormatter : ISumFormatter
- {
- public string Format(int[] nums, int sum)
- {
- return string.Format("Sum({0}) = {1}",
- string.Join(" ", nums.Select(n => Convert.ToString(n, 16))),
- Convert.ToString(sum, 16));
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/Summator/README.md b/Samples/Summator/README.md
deleted file mode 100644
index 200e59470..000000000
--- a/Samples/Summator/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Задача Functional Style
-
-Проект Summator написан в стиле SOLID.
-
-Перепишите его в функциональном стиле:
-
-1. Отделите максимум логики от побочных эффектов.
-2. Создайте нужные вам методы. Старайтесь, чтобы методы были самодостаточными и потенциально полезными вне контекста этой задачи.
-3. Тестируемость не должна пострадать.
-
-
-Проанализируйте гибкость финального решения. Стало ли оно гибче, чем исходное или наоборот?
\ No newline at end of file
diff --git a/Samples/Summator/Summator.cs b/Samples/Summator/Summator.cs
deleted file mode 100644
index bab9214f6..000000000
--- a/Samples/Summator/Summator.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace FP
-{
- public class Summator
- {
- private readonly ISumFormatter formatter;
- private readonly Func openDatasource;
- private readonly string outputFilename;
- /*
- Отрефакторите код.
- 1. Отделите максимум логики от побочных эффектов.
- 2. Создайте нужные вам методы.
- 3. Сделайте так, чтобы максимум кода оказалось внутри универсальных методов, потенциально полезных в других местах программы.
- */
-
- public Summator(Func openDatasource, ISumFormatter formatter, string outputFilename)
- {
- this.openDatasource = openDatasource;
- this.formatter = formatter;
- this.outputFilename = outputFilename;
- }
-
-
- public void ProcessOld()
- {
- using (var input = openDatasource())
- using (var writer = new StreamWriter(outputFilename))
- {
- var c = 0;
- while (true)
- {
- string[] record = input.NextRecord();
- if (record == null) break;
- c++;
- var nums = record.Select(part => Convert.ToInt32(part, 16)).ToArray();
- var sum = nums.Sum();
- var text = formatter.Format(nums, sum);
- writer.WriteLine(text);
- if (c % 100 == 0)
- Console.WriteLine("processed {0} items", c);
- }
- }
- }
-
- public void ProcessRefactored()
- {
- var res = SumRecords(openDatasource(), formatter)
- .AfterEvery(100, c => Console.WriteLine("processed {0} items", c));
- File.WriteAllLines(outputFilename, res);
- }
-
- public static IEnumerable SumRecords(
- DataSource dataSource,
- ISumFormatter formatter)
- {
- return dataSource.ReadIntRecords(16)
- .Select(args => formatter.Format(args, args.Sum()));
- }
- }
-
- public static class DataSourceExtensions
- {
- public static IEnumerable ReadRecords(this DataSource data)
- {
- return Enumeration.RepeatUntilNull(data.NextRecord);
- }
-
- public static IEnumerable ReadIntRecords(this DataSource data, int radix)
- {
- return data.ReadRecords()
- .Select(record => record.Select(f => Convert.ToInt32(f, radix))
- .ToArray());
- }
- }
-
- public static class Enumeration
- {
- public static IEnumerable RepeatUntilNull(Func get)
- {
- return Repeat(get).TakeWhile(i => i != null);
- }
-
- public static IEnumerable Repeat(Func get)
- {
- while (true) yield return get();
- // ReSharper disable once IteratorNeverReturns
- }
-
- public static IEnumerable AfterEvery(
- this IEnumerable items,
- int period,
- Action afterNth)
- {
- var n = 0;
- foreach (var item in items)
- {
- n++;
- yield return item;
- if (n % period == 0) afterNth(n);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/Summator/Summator.csproj b/Samples/Summator/Summator.csproj
deleted file mode 100644
index c024e602c..000000000
--- a/Samples/Summator/Summator.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- Exe
- net8.0
- false
- FP
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
-
diff --git a/Samples/Summator/SummatorTests.cs b/Samples/Summator/SummatorTests.cs
deleted file mode 100644
index 412b58b4e..000000000
--- a/Samples/Summator/SummatorTests.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using NUnit.Framework;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace FP
-{
- [TestFixture]
- public class SummatorTests
- {
- private Summator summator;
- private const string LargeInputFilename = "process-large-file.txt";
- private const string OutputFilename = "process-result.txt";
- private const string ExpectedOutputFilename = "expected-process-result.txt";
-
- [SetUp]
- public void SetUp()
- {
- Directory.SetCurrentDirectory(
- TestContext.CurrentContext.WorkDirectory);
- summator = new Summator(
- () => new DataSource(LargeInputFilename),
- new HexSumFormatter(),
- OutputFilename);
- }
-
-
- [Test]
- public void Process_GeneratesCorrectOutputFile()
- {
- var actualResultFile = new FileInfo(OutputFilename);
- if (actualResultFile.Exists) actualResultFile.Delete();
-
- summator.ProcessOld();
-
- CollectionAssert.AreEqual(
- File.ReadAllLines(ExpectedOutputFilename),
- File.ReadAllLines(actualResultFile.FullName));
- }
-
- [Test]
- public void Process_ShowProgressOnConsole()
- {
- var stdOut = Console.Out;
- try
- {
- var consoleOutput = new StringWriter();
- Console.SetOut(consoleOutput);
-
- summator.ProcessOld();
-
- var actualOutput = consoleOutput.ToString()
- .TrimEnd()
- .Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual("processed 100 items", actualOutput.First());
- Assert.AreEqual("processed 1000 items", actualOutput.Last());
- Assert.AreEqual(10, actualOutput.Length);
- }
- finally
- {
- Console.SetOut(stdOut);
- }
- }
-
- [Test]
- [Explicit("Генератор данных. Не нужен для выполнения задания")]
- public void GenerateInput()
- {
- var r = new Random();
- File.WriteAllLines(LargeInputFilename,
- Enumerable.Range(0, 1000).Select(i =>
- string.Join(
- " ",
- Enumerable.Range(0, 4).Select(j => Convert.ToString(r.Next(1000), 16))
- )));
- }
- }
-}
\ No newline at end of file
diff --git a/Samples/Summator/expected-process-result.txt b/Samples/Summator/expected-process-result.txt
deleted file mode 100644
index d4b89e1a9..000000000
--- a/Samples/Summator/expected-process-result.txt
+++ /dev/null
@@ -1,1000 +0,0 @@
-Sum(34f 21f 2d9 355) = b9c
-Sum(318 2a9 2a4 161) = 9c6
-Sum(2e3 82 1a6 231) = 73c
-Sum(162 2c7 36f 3c2) = b5a
-Sum(9d d4 20c 3af) = 72c
-Sum(9a 3ab 2df 163) = 887
-Sum(170 3e7 1 2f9) = 851
-Sum(3cc 185 30f 16a) = 9ca
-Sum(390 8b 127 1a2) = 6e4
-Sum(8 f9 36b 194) = 600
-Sum(68 2cb 1c5 1a1) = 699
-Sum(7b 35 69 321) = 43a
-Sum(e5 178 24b 26b) = 713
-Sum(8f 235 145 38c) = 795
-Sum(327 176 1e4 319) = 99a
-Sum(2a8 393 17c 15e) = 915
-Sum(15a 3b 288 d7) = 4f4
-Sum(1a0 1cc 3b9 38b) = ab0
-Sum(151 78 346 1b7) = 6c6
-Sum(1e6 13d e7 13a) = 544
-Sum(37d c8 214 253) = 8ac
-Sum(322 a4 da 15a) = 5fa
-Sum(32d 182 262 27a) = 98b
-Sum(2fc 52 2d4 bd) = 6df
-Sum(14e 67 47 3f) = 23b
-Sum(194 37a 180 300) = 98e
-Sum(1a7 2a7 11a 17) = 57f
-Sum(2d7 376 1a6 1ea) = 9dd
-Sum(8e a9 383 1df) = 699
-Sum(17f 311 223 b6) = 769
-Sum(348 12e 191 1d) = 624
-Sum(352 13e 8f ff) = 61e
-Sum(18c 289 68 17f) = 5fc
-Sum(f6 a8 38d 3) = 52e
-Sum(32f 2fb ac 7a) = 750
-Sum(371 c3 26b 39f) = a3e
-Sum(3c4 77 1ec 252) = 879
-Sum(b7 f4 325 225) = 6f5
-Sum(22b 378 df 66) = 6e8
-Sum(1e8 163 395 68) = 748
-Sum(218 1a 272 4d) = 4f1
-Sum(30d 27 f3 3cd) = 7f4
-Sum(103 37f 298 26b) = 985
-Sum(264 1a8 12c 284) = 7bc
-Sum(2ab 1da 41 2da) = 7a0
-Sum(33a 224 48 98) = 63e
-Sum(34b 22b 33b 166) = a17
-Sum(3b1 327 203 1cc) = aa7
-Sum(34e 43 24a 356) = 931
-Sum(239 21d 92 39d) = 885
-Sum(36c 206 14f 11f) = 7e0
-Sum(243 ba 3a8 82) = 727
-Sum(24c 242 1a3 e) = 63f
-Sum(121 ba 116 3dc) = 6cd
-Sum(3ba 1da ea e1) = 75f
-Sum(d3 375 1c 1c4) = 628
-Sum(17c cc 304 220) = 76c
-Sum(346 1bd 4b 8d) = 5db
-Sum(148 8b 356 133) = 65c
-Sum(d5 310 23d 290) = 8b2
-Sum(26a 2b8 301 16f) = 992
-Sum(184 1f4 aa 294) = 6b6
-Sum(315 256 384 5f) = 94e
-Sum(132 398 2c9 3df) = b72
-Sum(1ea 372 38b 176) = a5d
-Sum(19d 187 124 8e) = 4d6
-Sum(1f6 115 2ae 96) = 64f
-Sum(14b 3cb 307 aa) = 8c7
-Sum(384 241 25e 202) = a25
-Sum(73 295 40 36f) = 6b7
-Sum(22 70 2f3 ef) = 474
-Sum(221 3d4 343 197) = acf
-Sum(1a9 35f 331 14a) = 983
-Sum(36c c6 f2 e3) = 607
-Sum(193 272 360 6e) = 7d3
-Sum(32e 14 148 331) = 7bb
-Sum(337 2d9 c2 2d8) = 9aa
-Sum(139 c7 36b 33c) = 8a7
-Sum(332 1c 154 12d) = 5cf
-Sum(27c 35 255 209) = 70f
-Sum(1ba 116 2d4 1d4) = 778
-Sum(9a 1bc 125 2be) = 639
-Sum(14f 17b 6e 1e8) = 520
-Sum(31c 3b9 40 d) = 722
-Sum(30f 3a9 1a0 32f) = b87
-Sum(312 6a 5d e2) = 4bb
-Sum(3db 3dc 1ff 350) = d06
-Sum(359 3ad 24f 15e) = ab3
-Sum(1d 157 29c 217) = 627
-Sum(128 35c 297 17a) = 895
-Sum(1b3 1eb 189 3a6) = 8cd
-Sum(58 182 20 361) = 55b
-Sum(3c3 146 206 2ba) = 9c9
-Sum(27c 30d 2df 14f) = 9b7
-Sum(b9 1f1 1e0 a6) = 530
-Sum(3a5 1bd 34d 18a) = a39
-Sum(314 2f7 1ca 1c5) = 99a
-Sum(11c 211 2cd 39b) = 995
-Sum(112 25 17c 126) = 3d9
-Sum(2c9 9f 8a 258) = 64a
-Sum(3bc 285 375 212) = bc8
-Sum(1a6 37c 2ca f8) = 8e4
-Sum(25f 14d 15e 31e) = 828
-Sum(17b 1f1 1bc 3de) = 906
-Sum(286 3e7 91 148) = 846
-Sum(39f 242 244 1b1) = 9d6
-Sum(261 253 1a8 256) = 8b2
-Sum(191 1b8 26e 19) = 5d0
-Sum(167 36f d1 120) = 6c7
-Sum(22f 13a 3cb 37f) = ab3
-Sum(2d d2 34d 3b7) = 803
-Sum(b3 397 21f 308) = 971
-Sum(251 185 288 2ca) = 928
-Sum(d 329 2a1 179) = 750
-Sum(40 1c3 399 33b) = 8d7
-Sum(1d4 73 34f a6) = 63c
-Sum(2c7 144 1b6 1f3) = 7b4
-Sum(11f 9c 1ae 14b) = 4b4
-Sum(1b f9 11a 2cd) = 4fb
-Sum(2dc 275 fe 2b2) = 901
-Sum(33 287 5 b) = 2ca
-Sum(318 38b c 225) = 8d4
-Sum(ce 33f df 6c) = 558
-Sum(189 8f 1ab 3a2) = 765
-Sum(16b 2a7 f0 357) = 859
-Sum(1e0 2c 1e8 1b4) = 5a8
-Sum(3bf 13c 2ae 2fb) = aa4
-Sum(20f 3bb 285 1b3) = a02
-Sum(c4 e7 308 334) = 7e7
-Sum(6d 343 176 323) = 849
-Sum(137 379 124 1c7) = 79b
-Sum(3a5 141 3aa 373) = c03
-Sum(336 160 161 35) = 62c
-Sum(184 18f d1 6) = 3ea
-Sum(9f 239 34 1db) = 4e7
-Sum(dd f8 16 fb) = 2e6
-Sum(ba 314 38f a2) = 7ff
-Sum(16f 25f 334 20f) = 911
-Sum(130 1b5 21f 24f) = 753
-Sum(2ef 20 1f7 27d) = 783
-Sum(17a 322 3ad af) = 8f8
-Sum(259 24f 2e 31d) = 7f3
-Sum(15 301 295 21c) = 7c7
-Sum(30f 382 245 3e) = 914
-Sum(362 29 10d 91) = 529
-Sum(19a 308 204 d6) = 77c
-Sum(213 33a 2ec 3b7) = bf0
-Sum(358 26a ff 7e) = 73f
-Sum(41 19e 61 1a2) = 3e2
-Sum(133 34f 289 252) = 95d
-Sum(2e5 72 8c 255) = 638
-Sum(3b2 118 2e8 196) = 948
-Sum(357 1e0 2d5 2c5) = ad1
-Sum(2fb 166 e2 25a) = 79d
-Sum(11e 2d6 283 307) = 97e
-Sum(34a 5f 3ad 193) = 8e9
-Sum(202 216 1db 170) = 763
-Sum(320 a2 2f3 12) = 6c7
-Sum(188 2a2 193 128) = 6e5
-Sum(27b 396 10c fa) = 817
-Sum(52 156 5f 177) = 37e
-Sum(37d 221 16b 2c3) = 9cc
-Sum(bc 1ef 84 244) = 573
-Sum(cb 369 2f0 285) = 9a9
-Sum(ac 2e1 53 19b) = 57b
-Sum(325 177 25d 2b4) = 9ad
-Sum(2d4 2c2 13d 58) = 72b
-Sum(3ba 3a2 3c6 16f) = c91
-Sum(1ca 189 2b5 1f4) = 7fc
-Sum(3e7 235 1fd 3c8) = be1
-Sum(ab 2ff b4 131) = 58f
-Sum(1e ae 32e 207) = 601
-Sum(39a 2f5 7b 381) = a8b
-Sum(342 358 1bd 2c2) = b19
-Sum(2e1 192 28a ba) = 7b7
-Sum(e3 112 2f0 101) = 5e6
-Sum(210 2fd 7a 32a) = 8b1
-Sum(b3 fc 286 25f) = 694
-Sum(e4 72 f0 25) = 26b
-Sum(c2 12c 296 226) = 6aa
-Sum(37b 31e a6 c4) = 803
-Sum(327 45 214 25a) = 7da
-Sum(3b3 3db 2fa 254) = cdc
-Sum(392 142 2e5 380) = b39
-Sum(f 39b 308 108) = 7ba
-Sum(34 4 153 29e) = 429
-Sum(6f 203 29d 2cf) = 7de
-Sum(267 198 1ff 1b5) = 7b3
-Sum(2e4 64 127 1ad) = 61c
-Sum(6b 22b 1c1 1cb) = 622
-Sum(e8 208 35e c0) = 70e
-Sum(1e9 31 2b5 389) = 858
-Sum(175 157 16 10f) = 3f1
-Sum(20b 18d 1f2 377) = 901
-Sum(1cb 1f0 55 123) = 533
-Sum(18f 32c 3da 21b) = ab0
-Sum(1db 145 358 32d) = 9a5
-Sum(1b 137 315 1cb) = 632
-Sum(1d9 13d 20 213) = 549
-Sum(8d 92 b4 3d) = 210
-Sum(336 2fc 15a 10f) = 89b
-Sum(181 ef 391 156) = 757
-Sum(25a 197 3ca 263) = a1e
-Sum(1d6 9e 3b 1a3) = 452
-Sum(215 143 2cc a3) = 6c7
-Sum(c1 36f 36d 3e) = 7db
-Sum(22a 232 31e ce) = 848
-Sum(16d 3c6 2e9 138) = 954
-Sum(13b 17 1d4 27b) = 5a1
-Sum(1d2 2ca 99 eb) = 620
-Sum(19c 202 d3 26c) = 6dd
-Sum(155 b2 3dc 13a) = 71d
-Sum(101 265 3e5 332) = a7d
-Sum(1ae 11 364 3af) = 8d2
-Sum(376 11c 2cd 337) = a96
-Sum(1b9 2c2 3d1 27b) = ac7
-Sum(295 291 127 1be) = 80b
-Sum(2b1 1a7 3b8 332) = b42
-Sum(a9 1e1 2ef 2a6) = 81f
-Sum(29b 101 2d0 178) = 7e4
-Sum(23d 1e3 3b5 2f0) = ac5
-Sum(3c8 39f 372 12a) = c03
-Sum(9a 20d 2ed b6) = 64a
-Sum(3e5 14a 319 2c1) = b09
-Sum(219 23f 3be 2ab) = ac1
-Sum(372 21d 271 341) = b41
-Sum(294 b3 289 3b4) = 984
-Sum(109 bd 113 274) = 54d
-Sum(233 154 f9 3be) = 83e
-Sum(2f5 e0 29b 2de) = 94e
-Sum(307 3e5 123 a4) = 8b3
-Sum(2a2 302 335 346) = c1f
-Sum(2af 2e 8d 5c) = 3c6
-Sum(12b 25 1ee 20) = 35e
-Sum(359 73 5b 315) = 73c
-Sum(116 3a5 20 3c5) = 8a0
-Sum(f9 78 26b 291) = 66d
-Sum(51 343 3b3 138) = 87f
-Sum(38c e0 38b 374) = b6b
-Sum(f9 1cd 9e 37a) = 6de
-Sum(165 32a 105 db) = 66f
-Sum(2f b7 149 20e) = 43d
-Sum(34e d9 64 282) = 70d
-Sum(85 36e 1c7 34a) = 904
-Sum(3c4 146 392 22a) = ac6
-Sum(96 a3 2f4 353) = 780
-Sum(62 33d b8 4b) = 4a2
-Sum(81 261 30e 18c) = 77c
-Sum(3bc c9 1af 1d3) = 807
-Sum(29f 32c 395 42) = 9a2
-Sum(316 5d 32b 360) = 9fe
-Sum(2df 131 b2 1d) = 4df
-Sum(300 41 397 39b) = a73
-Sum(222 25b 2e3 c2) = 822
-Sum(35 19a 79 da) = 322
-Sum(3e7 fe 18c ec) = 75d
-Sum(1b3 2bf 2ad 3a3) = ac2
-Sum(1be 3db ab 98) = 6dc
-Sum(199 350 2fc 39) = 81e
-Sum(160 37c 74 319) = 869
-Sum(28a 9a 132 40) = 496
-Sum(2b1 35a 352 160) = abd
-Sum(1cd ed 19e 105) = 55d
-Sum(2b3 2ba 42 217) = 7c6
-Sum(2b8 23e 1ad 1f) = 6c2
-Sum(26b f6 247 30c) = 8b4
-Sum(37e 2ff 201 2ba) = b38
-Sum(347 2aa 349 a1) = 9db
-Sum(126 147 237 34d) = 7f1
-Sum(3b3 14b 223 240) = 961
-Sum(355 14c 1d6 d1) = 748
-Sum(23d 38d 1cc 2c6) = a5c
-Sum(30d e4 168 30a) = 863
-Sum(1ce 54 ae 193) = 463
-Sum(23a 20d aa 399) = 88a
-Sum(159 98 201 30b) = 6fd
-Sum(18b fc 3c7 16c) = 7ba
-Sum(83 dd 24c 16c) = 518
-Sum(1b 355 b2 11e) = 540
-Sum(308 175 cf 3d8) = 924
-Sum(133 323 394 262) = a4c
-Sum(141 3f 2ba d1) = 50b
-Sum(99 a3 112 1a6) = 3f4
-Sum(a1 271 e7 2bd) = 6b6
-Sum(333 2b2 32d 140) = a52
-Sum(3ae 5f 243 230) = 880
-Sum(280 3e3 2ee 261) = bb2
-Sum(389 377 273 c5) = a38
-Sum(13e ba 266 21d) = 67b
-Sum(ec 386 1c9 14c) = 787
-Sum(22a 2f5 d2 3c7) = 9b8
-Sum(3b2 a5 cb 192) = 6b4
-Sum(26e 1dd 1d3 55) = 673
-Sum(22f 376 29 d3) = 6a1
-Sum(e0 163 3ca 146) = 753
-Sum(138 59 12f 109) = 3c9
-Sum(218 4d 67 3cf) = 69b
-Sum(a 2b1 1d1 394) = 820
-Sum(e9 1e1 2fe b9) = 681
-Sum(374 263 265 1da) = a16
-Sum(318 15c 3db 1ac) = 9fb
-Sum(1a3 21d 27d 1af) = 7ec
-Sum(90 193 13d 370) = 6d0
-Sum(3a4 83 13 1d0) = 60a
-Sum(1c5 3b1 1af 365) = a8a
-Sum(3e e4 187 3a4) = 64d
-Sum(b 226 354 4e) = 5d3
-Sum(78 358 146 264) = 77a
-Sum(2e5 1ef 216 3c3) = aad
-Sum(66 36b 34d 3e2) = b00
-Sum(1b7 2a0 33f 25f) = 9f5
-Sum(173 248 3d8 65) = 7f8
-Sum(1ce 12d 2db 3ab) = 981
-Sum(b3 2e7 19c 234) = 76a
-Sum(3bd 36 1a0 365) = 8f8
-Sum(2b0 22f 136 11f) = 734
-Sum(4c 2c1 8a 1b4) = 54b
-Sum(255 37 16a 242) = 638
-Sum(63 1b4 1ae 186) = 54b
-Sum(18c 30f 231 1ab) = 877
-Sum(236 2ee 267 333) = abe
-Sum(7d 182 1b1 3e6) = 796
-Sum(53 3ca 6 2f) = 452
-Sum(1ca 3d0 131 370) = a3b
-Sum(169 21f 212 29a) = 834
-Sum(1bd 223 1f8 196) = 76e
-Sum(3aa 99 348 2e6) = a71
-Sum(139 16 a7 ad) = 2a3
-Sum(1ec 3dd 12e 3a9) = aa0
-Sum(3af 1eb a2 2b2) = 8ee
-Sum(110 8c 160 273) = 56f
-Sum(31 13b 78 7a) = 25e
-Sum(83 225 1c 355) = 619
-Sum(fd 37f 3d5 12) = 863
-Sum(f6 d1 371 3cb) = 903
-Sum(221 2b2 2ac 3d) = 7bc
-Sum(322 340 22b 1d4) = a61
-Sum(2a2 16f 3a8 366) = b1f
-Sum(17d 348 189 130) = 77e
-Sum(c3 36c 165 26f) = 803
-Sum(21 2ce 263 2fb) = 84d
-Sum(3e1 139 398 255) = b07
-Sum(7 11b 2b3 2de) = 6b3
-Sum(262 be 90 245) = 5f5
-Sum(1c8 123 338 d8) = 6fb
-Sum(2f8 28b 1bf 2fb) = a3d
-Sum(265 9e 1d7 19c) = 676
-Sum(1f5 2a4 337 171) = 941
-Sum(354 102 3aa 33b) = b3b
-Sum(4e 398 43 1e8) = 611
-Sum(390 3bd 1cd 186) = aa0
-Sum(2a4 ca 104 be) = 530
-Sum(2b7 32c 350 388) = cbb
-Sum(34 8c 35e 17d) = 59b
-Sum(10e 350 96 343) = 837
-Sum(34a 1fb 5f 14a) = 6ee
-Sum(1cc 141 371 15f) = 7dd
-Sum(fb 13d 1f7 217) = 646
-Sum(df 14f 12f 322) = 67f
-Sum(be 39 56 19a) = 2e7
-Sum(381 118 2cd 2b1) = a17
-Sum(33c 397 13d 2c7) = ad7
-Sum(18b 22d 22c e6) = 6ca
-Sum(301 e8 286 195) = 804
-Sum(35e 82 3a1 163) = 8e4
-Sum(141 38c 3ab 179) = 9f1
-Sum(134 139 2a8 2cc) = 7e1
-Sum(345 3c bf d5) = 515
-Sum(2f9 2e4 3a9 231) = bb7
-Sum(315 196 1f6 21d) = 8be
-Sum(3 a9 3bc 2b6) = 71e
-Sum(2f9 110 2fd 3df) = ae5
-Sum(2b0 381 3ab 3b) = a17
-Sum(7f 2db 59 3dd) = 790
-Sum(155 153 17c 203) = 627
-Sum(ee 258 36a 14e) = 7fe
-Sum(16d 157 1d4 1d) = 4b5
-Sum(126 55 267 1c8) = 5aa
-Sum(273 183 15f 97) = 5ec
-Sum(3b7 f4 268 23) = 736
-Sum(223 2b1 1b 3ab) = 89a
-Sum(78 83 55 1e) = 16e
-Sum(28b 3b4 db 1c2) = 8dc
-Sum(19 3db 12f 192) = 6b5
-Sum(126 26d 149 1a2) = 67e
-Sum(324 2e0 2b8 25b) = b17
-Sum(11a 1e3 1af 2e3) = 78f
-Sum(17c 3a9 25 61) = 5ab
-Sum(2d2 158 3c7 224) = a15
-Sum(23c 3a7 d6 e9) = 7a2
-Sum(101 1b6 179 15a) = 58a
-Sum(361 a4 1af 280) = 834
-Sum(54 3b4 358 149) = 8a9
-Sum(393 c6 e7 32b) = 86b
-Sum(3e1 1a8 290 27d) = a96
-Sum(2bb 159 28a 2ca) = 968
-Sum(38e 7a 2d8 2a8) = 988
-Sum(13 2f2 33d 167) = 7a9
-Sum(197 5f a0 16e) = 404
-Sum(166 15d 2e1 75) = 619
-Sum(34 317 28f 1af) = 789
-Sum(50 2c4 b6 20c) = 5d6
-Sum(71 9c 22b 94) = 3cc
-Sum(116 240 216 38f) = 8fb
-Sum(314 297 1b4 2e7) = a46
-Sum(1b4 2ee 26c 149) = 857
-Sum(76 1f1 399 333) = 933
-Sum(25 361 1c5 283) = 7ce
-Sum(2af 21b 249 38c) = a9f
-Sum(2b2 da 279 c9) = 6ce
-Sum(3ab cb 237 35f) = a0c
-Sum(c7 2a9 50 33f) = 6ff
-Sum(231 f8 242 2b6) = 821
-Sum(391 3e1 2a8 12d) = b47
-Sum(aa 145 138 247) = 56e
-Sum(312 16a 1e6 f8) = 75a
-Sum(2be 390 1cd 2e3) = afe
-Sum(3df 272 dd 239) = 967
-Sum(1e ea 323 e9) = 514
-Sum(b6 2f4 82 1b5) = 5e1
-Sum(1a0 5a 102 314) = 610
-Sum(11f 2f7 2d9 2b5) = 9a4
-Sum(35a 11b 2e1 16c) = 8c2
-Sum(389 31 19f 241) = 79a
-Sum(2cc 13f a0 11f) = 5ca
-Sum(dc 154 347 3a6) = 91d
-Sum(1b 8 297 2a6) = 560
-Sum(bd 1bf 77 19e) = 491
-Sum(c3 36b a6 2b7) = 78b
-Sum(67 2ba 3c0 3af) = a90
-Sum(b6 2ff 370 2c4) = 9e9
-Sum(378 359 297 3d5) = d3d
-Sum(332 e2 204 35f) = 977
-Sum(253 34a d8 4c) = 6c1
-Sum(fb 143 2f9 116) = 64d
-Sum(5f 32 1f7 19b) = 423
-Sum(a3 143 a8 1e) = 2ac
-Sum(373 2d0 1d9 12) = 82e
-Sum(166 d9 68 1c4) = 46b
-Sum(1cb 83 2e a9) = 325
-Sum(158 2aa 35b 3c2) = b1f
-Sum(3a3 ff 332 161) = 935
-Sum(292 5a 1bc 30b) = 7b3
-Sum(3a8 2aa 350 83) = a25
-Sum(107 1d5 220 235) = 731
-Sum(2b0 279 62 62) = 5ed
-Sum(2f1 1f1 1f8 17a) = 854
-Sum(2e1 2fc 268 77) = 8bc
-Sum(115 24f 3a5 19d) = 8a6
-Sum(be 21c 1df 38c) = 845
-Sum(1f8 32f 173 318) = 9b2
-Sum(113 2b5 52 2a4) = 6be
-Sum(171 3cd bc 3de) = 9d8
-Sum(24a 1e0 1e0 2c7) = 8d1
-Sum(248 2f9 d1 1b1) = 7c3
-Sum(2ee 1b7 267 37e) = a8a
-Sum(1da 144 1f6 158) = 66c
-Sum(2ec 1b2 3ac 2d2) = b1c
-Sum(3dd 27c 3d 369) = 9ff
-Sum(105 131 337 3b) = 5a8
-Sum(19f 33c 9 2fc) = 7e0
-Sum(23f 272 215 31d) = 9e3
-Sum(6e dd 33d 1ad) = 635
-Sum(14b 2e 9d 40) = 256
-Sum(c8 1dd 13e 3b6) = 799
-Sum(bf 2e1 39f 3a6) = ae5
-Sum(20 1d2 0 3b6) = 5a8
-Sum(1a3 25f 1c1 116) = 6d9
-Sum(3aa 96 12 39a) = 7ec
-Sum(1ae 352 13e 34f) = 98d
-Sum(317 2c1 ea 20e) = 8d0
-Sum(25d 1fe 187 3af) = 991
-Sum(1de 3e4 2a1 310) = b73
-Sum(3da 368 363 2a6) = d4b
-Sum(384 4a 2db 6d) = 716
-Sum(272 246 179 1f7) = 828
-Sum(303 226 1eb b4) = 7c8
-Sum(1b ea 27a 15d) = 4dc
-Sum(9e 1d6 9f 1e6) = 4f9
-Sum(1f7 191 148 20a) = 6da
-Sum(4a 38 1d7 1a7) = 400
-Sum(3a6 299 124 41) = 7a4
-Sum(11a 154 15 163) = 3e6
-Sum(77 d1 dd d0) = 2f5
-Sum(147 2db 2f2 37) = 74b
-Sum(13 d3 394 f4) = 56e
-Sum(16a 143 271 204) = 722
-Sum(2c9 17d af 1f3) = 6e8
-Sum(2ea d1 22 23a) = 617
-Sum(6f 3ba 238 6a) = 6cb
-Sum(102 1aa 381 2af) = 8dc
-Sum(d4 116 e6 3b5) = 685
-Sum(f9 3b6 9e 303) = 850
-Sum(286 111 1f6 35f) = 8ec
-Sum(8b e3 3d 262) = 40d
-Sum(27 308 160 385) = 814
-Sum(a4 20a 261 38d) = 89c
-Sum(ae 28b 61 174) = 50e
-Sum(a2 288 31d 251) = 898
-Sum(139 e4 1f 53) = 28f
-Sum(5d 2a4 10a 2fa) = 705
-Sum(de 193 354 1d9) = 79e
-Sum(2c2 ab 1ae 373) = 88e
-Sum(37d 3bd 42 1e1) = 95d
-Sum(49 3e4 20a 2b2) = 8e9
-Sum(29d 140 306 255) = 938
-Sum(354 311 261 3e6) = cac
-Sum(1db 38d 225 38f) = b1c
-Sum(c4 3d1 205 16b) = 805
-Sum(1fd 24d 2a6 2f9) = 9e9
-Sum(29d 88 cb 2) = 3f2
-Sum(dd d5 1df cd) = 45e
-Sum(245 13b 207 13d) = 6c4
-Sum(2c2 154 19d 305) = 8b8
-Sum(385 29d 38d 1b4) = b63
-Sum(31a 356 3e5 31c) = d71
-Sum(26e 207 2af 393) = ab7
-Sum(1b8 2bf 3cc 1e3) = a26
-Sum(13d 2f9 14 215) = 65f
-Sum(75 304 178 27f) = 770
-Sum(132 193 1a0 a0) = 505
-Sum(186 e8 cc 357) = 691
-Sum(234 2e7 1cd 348) = a30
-Sum(2a7 f1 3c7 32f) = a8e
-Sum(8a 196 17c 2bd) = 659
-Sum(20d 233 2fd 36e) = aab
-Sum(156 23 3e7 3b1) = 911
-Sum(140 370 290 81) = 7c1
-Sum(124 10e 82 186) = 43a
-Sum(1b6 345 196 186) = 817
-Sum(13a 33f 15f 2b8) = 890
-Sum(f1 84 323 4c) = 4e4
-Sum(319 cd 18a 2c6) = 836
-Sum(188 2a2 71 2e6) = 781
-Sum(27e 219 331 162) = 92a
-Sum(e8 103 217 2ab) = 6ad
-Sum(57 14c 223 199) = 55f
-Sum(6f 241 179 12d) = 556
-Sum(0 3dd 183 2b6) = 816
-Sum(d4 44 27d d2) = 467
-Sum(e8 39b 97 72) = 58c
-Sum(1e5 3b1 2e1 269) = ae0
-Sum(9d 183 2ef 384) = 893
-Sum(14 33 9d 36) = 11a
-Sum(128 29b 260 38d) = 9b0
-Sum(249 18a 3c4 d8) = 86f
-Sum(33c 5d 2c6 192) = 7f1
-Sum(11f 1a3 211 239) = 70c
-Sum(383 25f 7a 135) = 791
-Sum(6c 1a4 c6 8d) = 363
-Sum(253 3a1 fc 2d3) = 9c3
-Sum(339 1dc 118 3b4) = 9e1
-Sum(33f 14c 18d 221) = 839
-Sum(1cc 2d8 270 345) = a59
-Sum(3be 3a7 11e 187) = a0a
-Sum(eb 14e 14a 2e1) = 664
-Sum(359 b5 0 19d) = 5ab
-Sum(3a1 350 3b2 36b) = e0e
-Sum(1d4 1d3 139 290) = 770
-Sum(8e f1 186 160) = 465
-Sum(32d 2f9 23a 3ba) = c1a
-Sum(15 3d8 6d ab) = 505
-Sum(3d6 11d 15f ac) = 6fe
-Sum(86 327 38a 104) = 83b
-Sum(256 202 361 284) = a3d
-Sum(1db 363 13 3d7) = 928
-Sum(181 20a 4c 3e0) = 7b7
-Sum(19e 3c8 2b7 2cd) = aea
-Sum(221 3a6 242 1d9) = 9e2
-Sum(2fb 177 2cc 369) = aa7
-Sum(47 33d 1af 284) = 7b7
-Sum(1f0 306 2e4 295) = a6f
-Sum(230 35 39 274) = 512
-Sum(177 2e9 36c 3b1) = b7d
-Sum(2e6 24b 239 1f2) = 95c
-Sum(38c 74 2f4 d) = 701
-Sum(24e 27a 273 c7) = 802
-Sum(e4 1b0 1f0 de) = 562
-Sum(31d 3e0 23c 285) = bbe
-Sum(1b4 177 1e6 263) = 774
-Sum(30d 19e 1b0 169) = 7c4
-Sum(38f 42 155 31f) = 845
-Sum(39 278 2da b0) = 63b
-Sum(326 d9 3c5 3ba) = b7e
-Sum(48 1a1 36 35e) = 57d
-Sum(92 21d 1b1 7f) = 4df
-Sum(22c 342 33e 17f) = a2b
-Sum(ad e7 1fd 16f) = 500
-Sum(64 3bd 2cd 1ed) = 8db
-Sum(2ac 18b 66 20b) = 6a8
-Sum(124 33c 8e 253) = 741
-Sum(2bd 140 1a0 243) = 7e0
-Sum(1b 269 23c 12) = 4d2
-Sum(141 270 1d0 f0) = 671
-Sum(3d5 130 324 4c) = 875
-Sum(eb 3be 272 33a) = a55
-Sum(7b 16b 4c 351) = 583
-Sum(1f4 1d7 10e 2a5) = 77e
-Sum(13b 212 239 13e) = 6c4
-Sum(18e 345 1a9 ec) = 768
-Sum(1a2 fa 164 22b) = 62b
-Sum(292 1ea 2d 1dc) = 685
-Sum(1ec 1dc 200 17c) = 744
-Sum(24f 19 11f 14e) = 4d5
-Sum(ca 13b 1d8 152) = 52f
-Sum(f4 236 4f 22c) = 5a5
-Sum(15b 37f 2bf 316) = aaf
-Sum(36 92 349 8f) = 4a0
-Sum(36e 238 292 3d8) = c10
-Sum(25a 46 a8 279) = 5c1
-Sum(13d 258 164 17) = 510
-Sum(3be 379 55 122) = 8ae
-Sum(f2 eb 74 53) = 2a4
-Sum(16d 57 3df 353) = 8f6
-Sum(ab 31f cf 2fa) = 793
-Sum(313 ff 1a5 15a) = 711
-Sum(27b 171 1f5 16) = 5f7
-Sum(16f 12f 2dc 83) = 5fd
-Sum(93 346 14 284) = 671
-Sum(d2 38 255 1ca) = 529
-Sum(329 19d 223 332) = a1b
-Sum(1d 2f6 309 316) = 932
-Sum(240 326 32d 322) = bb5
-Sum(35f 195 34e 3e) = 880
-Sum(b2 9 183 24c) = 48a
-Sum(183 3f 39a 3ab) = 907
-Sum(1f7 3d9 3a8 20e) = b86
-Sum(43 15b 281 72) = 491
-Sum(ca 2ed 3b8 175) = 8e4
-Sum(2c3 25b 13d 36d) = 9c8
-Sum(24f 2c7 1bd 230) = 903
-Sum(1e9 3a1 10b 2e5) = 97a
-Sum(3e0 3bd 1d1 c8) = a36
-Sum(29c 8 46 2ea) = 5d4
-Sum(1ea 25f 13b 2b) = 5af
-Sum(335 fb 2d3 e4) = 7e7
-Sum(a4 2ba 257 72) = 627
-Sum(1c5 1d8 163 23e) = 73e
-Sum(2b4 1fe 3e5 2a4) = b3b
-Sum(269 16a 1c2 23d) = 7d2
-Sum(2ce c3 215 6d) = 613
-Sum(371 1b9 1bd c1) = 7a8
-Sum(2a7 ce 373 63) = 74b
-Sum(120 111 37 154) = 3bc
-Sum(3db d9 18b 316) = 955
-Sum(149 98 11f 208) = 508
-Sum(25a 37b 1fb 9e) = 86e
-Sum(b 189 80 80) = 294
-Sum(9d 2e5 145 272) = 739
-Sum(2cd 265 15a 2d3) = 95f
-Sum(fd 196 1b3 f7) = 53d
-Sum(24c ff 11e 1a3) = 60c
-Sum(1c7 291 2b1 190) = 899
-Sum(3c6 293 f3 235) = 981
-Sum(38b c 1fb 3de) = 970
-Sum(3a5 11f b6 11d) = 697
-Sum(4d 2f2 3ad 222) = 90e
-Sum(3b3 1ac 26e 176) = 943
-Sum(366 2a0 219 39b) = bba
-Sum(2cd 28 3a3 15a) = 7f2
-Sum(25c 57 2be 161) = 6d2
-Sum(2c0 2d8 a2 1f1) = 82b
-Sum(1f1 2f8 2cf 2c1) = a79
-Sum(69 164 315 3c5) = 8a7
-Sum(df 95 a9 341) = 55e
-Sum(139 2e3 1d8 1a) = 60e
-Sum(23 13a 212 125) = 494
-Sum(7a 140 350 362) = 86c
-Sum(50 a0 181 34d) = 5be
-Sum(249 33c 245 15d) = 927
-Sum(250 1bb 31 bb) = 4f7
-Sum(2c4 395 10c 202) = 967
-Sum(372 23c 2bb 237) = aa0
-Sum(367 61 21 361) = 74a
-Sum(267 2a3 13e 185) = 7cd
-Sum(c5 364 177 b1) = 651
-Sum(38f 355 270 3b1) = d05
-Sum(3ca 3b0 17c 18b) = a81
-Sum(238 334 f1 365) = 9c2
-Sum(2b2 11c 13d 75) = 580
-Sum(2d 10 19b 225) = 3fd
-Sum(26c 119 3e3 3d6) = b3e
-Sum(7f 208 e6 38d) = 6fa
-Sum(1fd bf 97 2d3) = 626
-Sum(44 367 113 357) = 815
-Sum(125 143 21f 3aa) = 831
-Sum(c0 130 3e6 33) = 609
-Sum(358 a3 af 14a) = 5f4
-Sum(165 c8 158 b5) = 43a
-Sum(1c9 33a 22c 276) = 9a5
-Sum(35a 281 331 1c1) = acd
-Sum(2c9 1d6 375 178) = 98c
-Sum(29c 205 321 332) = af4
-Sum(8 1ce 338 2d1) = 7df
-Sum(1d8 1d8 165 13c) = 651
-Sum(11a 3b0 7e 3c4) = 90c
-Sum(159 383 227 135) = 838
-Sum(34f 3c9 10a f2) = 914
-Sum(13b 285 3e5 28b) = a30
-Sum(1fa 5e e0 2d1) = 609
-Sum(1a2 26e 17e 153) = 6e1
-Sum(169 165 141 37f) = 78e
-Sum(177 26e 2c5 3d9) = a83
-Sum(1d4 ef 15b 392) = 7b0
-Sum(202 355 68 32e) = 8ed
-Sum(396 240 210 2bb) = aa1
-Sum(fb 22f 1f6 16b) = 68b
-Sum(1d0 ac d7 179) = 4cc
-Sum(f7 27b 381 293) = 986
-Sum(231 312 25a 3db) = b78
-Sum(241 290 3a5 e1) = 957
-Sum(103 118 305 4b) = 56b
-Sum(12a 53 89 28d) = 493
-Sum(3dd 19a 322 34a) = be3
-Sum(5e 2aa 58 322) = 682
-Sum(356 3be 1ae ca) = 98c
-Sum(196 14b 2e1 340) = 902
-Sum(155 2af 160 2d7) = 83b
-Sum(fa 74 ec 106) = 360
-Sum(282 12e 1b7 3ca) = 931
-Sum(312 1ab 40 17d) = 67a
-Sum(23 231 184 345) = 71d
-Sum(340 37 235 36f) = 91b
-Sum(2ba 320 85 26b) = 8ca
-Sum(e1 2da 332 39f) = a8c
-Sum(21f 3ac 2dd 262) = b0a
-Sum(2db 199 192 368) = 96e
-Sum(ad 21c c8 317) = 6a8
-Sum(f3 76 10 1ab) = 324
-Sum(37d 31 a7 34c) = 7a1
-Sum(3af 384 3e7 11e) = c38
-Sum(7a 1d9 1d 1c2) = 432
-Sum(3d7 269 24 38f) = 9f3
-Sum(1e4 1ff 1aa 34d) = 8da
-Sum(2b5 1c6 28a 272) = 977
-Sum(9f 203 297 124) = 65d
-Sum(357 306 27b 244) = b1c
-Sum(30f 2c1 2d5 b0) = 955
-Sum(233 3cd 3d8 283) = c5b
-Sum(3ad 1bf 1e8 102) = 856
-Sum(17b 3b8 378 22b) = ad6
-Sum(1f8 120 132 2db) = 725
-Sum(2b3 ab 2dd 1b7) = 7f2
-Sum(18e 21c 2ad 1ab) = 802
-Sum(ec 2c3 1af 15b) = 6b9
-Sum(345 1c0 29a 115) = 8b4
-Sum(37c 35b 15c 1fe) = a31
-Sum(20f 30f 387 f6) = 99b
-Sum(3c6 188 f6 ce) = 712
-Sum(273 6b 314 236) = 828
-Sum(1d3 388 379 264) = b38
-Sum(3cc 11e 30a 17) = 80b
-Sum(120 22c 196 ea) = 5cc
-Sum(f 8c 1a4 3a3) = 5e2
-Sum(11d 263 297 284) = 89b
-Sum(3ac 31c cc 38b) = b1f
-Sum(10b 1e7 1d8 6) = 4d0
-Sum(125 1de 320 80) = 6a3
-Sum(396 360 36f 3a4) = e09
-Sum(22f 35 131 25e) = 5f3
-Sum(51 145 de 3ca) = 63e
-Sum(179 29d e6 339) = 835
-Sum(3cb 13b 398 10) = 8ae
-Sum(1bc 90 272 29f) = 75d
-Sum(2bc 3d5 159 1e4) = 9ce
-Sum(32d 303 2d9 329) = c32
-Sum(2f4 115 13b 97) = 5db
-Sum(104 1e7 174 e8) = 547
-Sum(131 39 232 267) = 603
-Sum(23e e9 212 255) = 78e
-Sum(101 286 22 3d2) = 77b
-Sum(22d 310 2ac 306) = aef
-Sum(ed d0 e8 241) = 4e6
-Sum(2c4 335 318 136) = a47
-Sum(253 19d d5 63) = 528
-Sum(162 4e 234 1e3) = 5c7
-Sum(3af 2b0 2c6 182) = aa7
-Sum(245 b 61 1d2) = 483
-Sum(1c3 2ec e3 a7) = 639
-Sum(2e0 2ef fb 3cc) = a96
-Sum(251 21c 392 34) = 833
-Sum(ff 31a 20c 1e4) = 809
-Sum(108 fc 13 a0) = 2b7
-Sum(13 1af f2 b2) = 366
-Sum(51 227 22 365) = 5ff
-Sum(49 129 c1 e1) = 314
-Sum(6e 2fd 7d 3bf) = 7a7
-Sum(252 271 23d 34c) = a4c
-Sum(a1 f1 1fa 32e) = 6ba
-Sum(a4 200 e4 94) = 41c
-Sum(a4 e2 79 148) = 347
-Sum(3e0 3a8 1bf 14) = 95b
-Sum(1f9 30 55 b9) = 337
-Sum(2cc 17e 382 127) = 8f3
-Sum(15b 2b0 3ad 1e9) = 9a1
-Sum(29d 234 37a 27f) = aca
-Sum(2a7 af 3e7 30a) = a47
-Sum(39c 1ac e 239) = 78f
-Sum(143 376 2c0 34e) = ac7
-Sum(b0 360 e9 ae) = 5a7
-Sum(13e 69 1c5 221) = 58d
-Sum(21c 184 7f 30b) = 72a
-Sum(156 d3 1d2 1db) = 5d6
-Sum(23a 2e2 1df 258) = 953
-Sum(150 1e2 289 330) = 8eb
-Sum(3a9 29c 5f 4d) = 6f1
-Sum(21 203 35e 33e) = 8c0
-Sum(2a5 34 76 1e3) = 532
-Sum(1c7 2ff aa 233) = 7a3
-Sum(6e 158 63 122) = 34b
-Sum(2f db 1b3 2c9) = 586
-Sum(3c2 21b 3e7 248) = c0c
-Sum(196 68 1fe 2b5) = 6b1
-Sum(d6 1a1 ed 289) = 5ed
-Sum(a 178 1ff 18) = 399
-Sum(20e 128 65 122) = 4bd
-Sum(5c 3d7 13 323) = 769
-Sum(238 394 1e9 3e0) = b95
-Sum(17e 167 300 2ce) = 8b3
-Sum(e9 17d 73 1ee) = 4c7
-Sum(204 115 1a7 23d) = 6fd
-Sum(21e 1a8 10c 26) = 4f8
-Sum(212 208 228 2dd) = 91f
-Sum(341 4b 2fc 2ef) = 977
-Sum(75 91 26d 3d2) = 745
-Sum(207 c4 10 1ea) = 4c5
-Sum(266 205 137 357) = 8f9
-Sum(288 207 1a0 274) = 8a3
-Sum(105 11 1fb f8) = 409
-Sum(369 210 2ec 29b) = b00
-Sum(2ca 3d5 111 2f) = 7df
-Sum(16b 2f3 9f 133) = 630
-Sum(252 11 258 57) = 512
-Sum(2f8 88 3ce 140) = 88e
-Sum(105 3a5 3bf 18) = 881
-Sum(71 19d 185 a) = 39d
-Sum(67 39b 1d8 32f) = 909
-Sum(237 204 36e 24d) = 9f6
-Sum(18c 3b9 107 219) = 865
-Sum(39a 3c9 7e 35a) = b3b
-Sum(166 4 105 276) = 4e5
-Sum(396 149 364 7d) = 8c0
-Sum(2a bb 3da 3ab) = 86a
-Sum(238 2d4 229 12d) = 862
-Sum(24f 106 3af 1b7) = 8bb
-Sum(11b 157 2e3 4d) = 5a2
-Sum(8b b 2b2 326) = 66e
-Sum(368 1b5 18d 124) = 7ce
-Sum(326 65 299 6d) = 691
-Sum(98 2f6 5c 306) = 6f0
-Sum(37 15a 305 17c) = 612
-Sum(212 3aa 14 2a0) = 870
-Sum(190 3c2 3b1 294) = b97
-Sum(19 2af 23e f) = 515
-Sum(108 b7 1eb 38b) = 735
-Sum(27e 3e fc 25d) = 615
-Sum(315 2b5 84 1d3) = 821
-Sum(3b 1bc 95 340) = 5cc
-Sum(aa a8 180 3a8) = 67a
-Sum(239 167 223 c8) = 68b
-Sum(3de 12 196 38e) = 914
-Sum(1eb 2e0 10a 77) = 64c
-Sum(20e 289 34d 3c8) = bac
-Sum(10b b9 88 3e0) = 62c
-Sum(5e a8 24e 344) = 698
-Sum(325 229 265 3bb) = b6e
-Sum(32d 70 1ea 359) = 8e0
-Sum(12e 27d 1be 388) = 8f1
-Sum(27c 122 394 26b) = 99d
-Sum(290 156 71 34) = 48b
-Sum(1aa d 3ad 199) = 6fd
-Sum(256 b4 235 3d8) = 917
-Sum(1f 187 34a 190) = 680
-Sum(301 2c6 18b 1b5) = 907
-Sum(195 1c2 60 17a) = 531
-Sum(f6 199 330 378) = 937
-Sum(cb 3ad 14c 3d0) = 994
-Sum(10c 205 150 2f0) = 751
-Sum(36 219 199 317) = 6ff
-Sum(264 cb 164 278) = 70b
-Sum(223 1f9 339 38e) = ae3
-Sum(31b 2d 86 39d) = 76b
-Sum(37f 1de d6 cd) = 700
-Sum(f5 2df 326 11) = 70b
-Sum(c5 34 ce 291) = 458
-Sum(34f 24c 2cc 202) = a69
-Sum(37 5a 159 e8) = 2d2
-Sum(12c 25b 339 ca) = 78a
-Sum(5d 1cf 33e 2e4) = 84e
-Sum(247 389 5c 9d) = 6c9
-Sum(326 196 51 316) = 823
-Sum(12f 83 1fa 13f) = 4eb
-Sum(2db 188 252 22f) = 8e4
-Sum(3e4 2bb 311 3be) = d6e
-Sum(315 137 357 2c1) = a64
-Sum(2bb 386 271 123) = 9d5
-Sum(28d c 6f 30d) = 615
-Sum(388 41 1b1 123) = 69d
-Sum(3bf 30 352 1b9) = 8fa
-Sum(1fb 39e d3 39b) = a07
-Sum(247 1a 1f4 38b) = 7e0
-Sum(8 10a cd 18a) = 369
-Sum(2a6 368 3b7 110) = ad5
-Sum(31 183 1ca 388) = 706
-Sum(30d 315 88 122) = 7cc
-Sum(13 2d4 19e 299) = 71e
-Sum(3be 12e 257 3b4) = af7
-Sum(350 158 1c3 35f) = 9ca
-Sum(64 3a3 79 2a1) = 721
-Sum(191 2cd 11b 183) = 6fc
-Sum(326 2cd 67 20) = 67a
-Sum(71 a1 f1 23c) = 43f
-Sum(24e 3b2 293 2cd) = b60
-Sum(315 398 388 35b) = d90
-Sum(263 342 3b5 2c1) = c1b
-Sum(29a 101 221 14e) = 70a
-Sum(1a5 58 ab 76) = 31e
-Sum(109 310 1f6 40) = 64f
-Sum(1fa 2ed 1e4 12e) = 7f9
-Sum(26d 17e 227 31c) = 92e
-Sum(3d 1b 165 385) = 542
-Sum(2ac 2dd 49 b3) = 685
-Sum(1b 105 3d 236) = 393
-Sum(2ff 241 2d0 225) = a35
-Sum(ab 300 263 19) = 627
-Sum(3dd 7b 132 325) = 8af
-Sum(1bc 252 d3 28) = 509
-Sum(1b4 25a ee e5) = 5e1
-Sum(11b 98 284 27f) = 6b6
-Sum(383 284 289 2af) = b3f
-Sum(e 3e0 5a 3) = 44b
-Sum(2d3 3a7 128 3a1) = b43
-Sum(1c 3a6 82 354) = 798
-Sum(303 20e 327 3a9) = be1
-Sum(2d0 227 1c9 59) = 719
-Sum(20a 21 2e7 1a9) = 6bb
-Sum(17 340 11b 267) = 6d9
-Sum(3a4 51 28a 20f) = 88e
-Sum(77 39b b 3e5) = 802
-Sum(20 12e 52 1fc) = 39c
-Sum(12a 119 b 1f5) = 443
-Sum(1d7 181 1ca 2f4) = 816
-Sum(159 2c2 397 15c) = 90e
-Sum(bb 22f a4 3d4) = 762
-Sum(f8 299 3d4 37b) = ae0
-Sum(28b 2a8 3e5 3b3) = ccb
-Sum(11c 25b 2dd 34f) = 9a3
-Sum(202 329 389 1a1) = a55
-Sum(1d5 3b4 317 f0) = 990
-Sum(16 f1 3b9 27e) = 73e
-Sum(175 20e 10e e1) = 572
-Sum(a2 12d 154 22f) = 552
-Sum(2f7 1f 2ec 16e) = 770
-Sum(142 bf 358 269) = 7c2
-Sum(11c 40 d9 363) = 598
-Sum(28c 263 f2 217) = 7f8
-Sum(321 1f5 36f ee) = 973
-Sum(300 39b 3be 7) = a60
-Sum(2c8 156 205 7d) = 6a0
-Sum(19a 303 310 3d6) = b83
-Sum(107 ae 58 1e3) = 3f0
-Sum(3c 21a 5f 115) = 3ca
-Sum(5b ae 3bc 3bd) = 882
-Sum(18 55 3d9 2fa) = 740
-Sum(11c 2df 1a7 294) = 836
-Sum(1a6 65 316 343) = 864
-Sum(48 2e5 28e 3d4) = 98f
-Sum(2a1 2db ce 200) = 84a
-Sum(117 eb 25c 1de) = 63c
-Sum(20a 2f6 1da 106) = 7e0
-Sum(196 259 93 252) = 6d4
-Sum(3c7 0 3d6 272) = a0f
-Sum(164 2f2 348 2a3) = a41
-Sum(15b 7b 22f a2) = 4a7
-Sum(17f fc 19a 13e) = 553
-Sum(374 72 25c 167) = 7a9
-Sum(3c7 1bb 2a6 314) = b3c
-Sum(1e1 1fb ef 20d) = 6d8
-Sum(104 a0 fe 335) = 5d7
-Sum(3ba c4 363 48) = 829
-Sum(2f6 1c 26f 397) = 918
-Sum(37a 213 a4 9b) = 6cc
-Sum(2a3 1b9 5e 10d) = 5c7
-Sum(15b 9b 17a 123) = 493
-Sum(3e5 313 272 20b) = b75
-Sum(142 c2 90 350) = 5e4
-Sum(202 13b 19e bb) = 596
-Sum(365 2e2 d0 ba) = 7d1
-Sum(181 152 230 358) = 85b
-Sum(1ea 2ac 1d5 1b3) = 81e
-Sum(116 20a 71 27) = 3b8
-Sum(19d 3ca b1 69) = 681
-Sum(30e 3c3 338 a6) = aaf
-Sum(239 157 2ed 234) = 8b1
-Sum(373 307 194 23f) = a4d
-Sum(75 3d1 11e 3a9) = 90d
-Sum(e9 38b 374 9) = 7f1
-Sum(253 20a 320 138) = 8b5
-Sum(13d bf f5 320) = 611
-Sum(50 69 1b3 220) = 48c
diff --git a/Samples/Summator/process-large-file.txt b/Samples/Summator/process-large-file.txt
deleted file mode 100644
index 360c53010..000000000
--- a/Samples/Summator/process-large-file.txt
+++ /dev/null
@@ -1,1000 +0,0 @@
-34f 21f 2d9 355
-318 2a9 2a4 161
-2e3 82 1a6 231
-162 2c7 36f 3c2
-9d d4 20c 3af
-9a 3ab 2df 163
-170 3e7 1 2f9
-3cc 185 30f 16a
-390 8b 127 1a2
-8 f9 36b 194
-68 2cb 1c5 1a1
-7b 35 69 321
-e5 178 24b 26b
-8f 235 145 38c
-327 176 1e4 319
-2a8 393 17c 15e
-15a 3b 288 d7
-1a0 1cc 3b9 38b
-151 78 346 1b7
-1e6 13d e7 13a
-37d c8 214 253
-322 a4 da 15a
-32d 182 262 27a
-2fc 52 2d4 bd
-14e 67 47 3f
-194 37a 180 300
-1a7 2a7 11a 17
-2d7 376 1a6 1ea
-8e a9 383 1df
-17f 311 223 b6
-348 12e 191 1d
-352 13e 8f ff
-18c 289 68 17f
-f6 a8 38d 3
-32f 2fb ac 7a
-371 c3 26b 39f
-3c4 77 1ec 252
-b7 f4 325 225
-22b 378 df 66
-1e8 163 395 68
-218 1a 272 4d
-30d 27 f3 3cd
-103 37f 298 26b
-264 1a8 12c 284
-2ab 1da 41 2da
-33a 224 48 98
-34b 22b 33b 166
-3b1 327 203 1cc
-34e 43 24a 356
-239 21d 92 39d
-36c 206 14f 11f
-243 ba 3a8 82
-24c 242 1a3 e
-121 ba 116 3dc
-3ba 1da ea e1
-d3 375 1c 1c4
-17c cc 304 220
-346 1bd 4b 8d
-148 8b 356 133
-d5 310 23d 290
-26a 2b8 301 16f
-184 1f4 aa 294
-315 256 384 5f
-132 398 2c9 3df
-1ea 372 38b 176
-19d 187 124 8e
-1f6 115 2ae 96
-14b 3cb 307 aa
-384 241 25e 202
-73 295 40 36f
-22 70 2f3 ef
-221 3d4 343 197
-1a9 35f 331 14a
-36c c6 f2 e3
-193 272 360 6e
-32e 14 148 331
-337 2d9 c2 2d8
-139 c7 36b 33c
-332 1c 154 12d
-27c 35 255 209
-1ba 116 2d4 1d4
-9a 1bc 125 2be
-14f 17b 6e 1e8
-31c 3b9 40 d
-30f 3a9 1a0 32f
-312 6a 5d e2
-3db 3dc 1ff 350
-359 3ad 24f 15e
-1d 157 29c 217
-128 35c 297 17a
-1b3 1eb 189 3a6
-58 182 20 361
-3c3 146 206 2ba
-27c 30d 2df 14f
-b9 1f1 1e0 a6
-3a5 1bd 34d 18a
-314 2f7 1ca 1c5
-11c 211 2cd 39b
-112 25 17c 126
-2c9 9f 8a 258
-3bc 285 375 212
-1a6 37c 2ca f8
-25f 14d 15e 31e
-17b 1f1 1bc 3de
-286 3e7 91 148
-39f 242 244 1b1
-261 253 1a8 256
-191 1b8 26e 19
-167 36f d1 120
-22f 13a 3cb 37f
-2d d2 34d 3b7
-b3 397 21f 308
-251 185 288 2ca
-d 329 2a1 179
-40 1c3 399 33b
-1d4 73 34f a6
-2c7 144 1b6 1f3
-11f 9c 1ae 14b
-1b f9 11a 2cd
-2dc 275 fe 2b2
-33 287 5 b
-318 38b c 225
-ce 33f df 6c
-189 8f 1ab 3a2
-16b 2a7 f0 357
-1e0 2c 1e8 1b4
-3bf 13c 2ae 2fb
-20f 3bb 285 1b3
-c4 e7 308 334
-6d 343 176 323
-137 379 124 1c7
-3a5 141 3aa 373
-336 160 161 35
-184 18f d1 6
-9f 239 34 1db
-dd f8 16 fb
-ba 314 38f a2
-16f 25f 334 20f
-130 1b5 21f 24f
-2ef 20 1f7 27d
-17a 322 3ad af
-259 24f 2e 31d
-15 301 295 21c
-30f 382 245 3e
-362 29 10d 91
-19a 308 204 d6
-213 33a 2ec 3b7
-358 26a ff 7e
-41 19e 61 1a2
-133 34f 289 252
-2e5 72 8c 255
-3b2 118 2e8 196
-357 1e0 2d5 2c5
-2fb 166 e2 25a
-11e 2d6 283 307
-34a 5f 3ad 193
-202 216 1db 170
-320 a2 2f3 12
-188 2a2 193 128
-27b 396 10c fa
-52 156 5f 177
-37d 221 16b 2c3
-bc 1ef 84 244
-cb 369 2f0 285
-ac 2e1 53 19b
-325 177 25d 2b4
-2d4 2c2 13d 58
-3ba 3a2 3c6 16f
-1ca 189 2b5 1f4
-3e7 235 1fd 3c8
-ab 2ff b4 131
-1e ae 32e 207
-39a 2f5 7b 381
-342 358 1bd 2c2
-2e1 192 28a ba
-e3 112 2f0 101
-210 2fd 7a 32a
-b3 fc 286 25f
-e4 72 f0 25
-c2 12c 296 226
-37b 31e a6 c4
-327 45 214 25a
-3b3 3db 2fa 254
-392 142 2e5 380
-f 39b 308 108
-34 4 153 29e
-6f 203 29d 2cf
-267 198 1ff 1b5
-2e4 64 127 1ad
-6b 22b 1c1 1cb
-e8 208 35e c0
-1e9 31 2b5 389
-175 157 16 10f
-20b 18d 1f2 377
-1cb 1f0 55 123
-18f 32c 3da 21b
-1db 145 358 32d
-1b 137 315 1cb
-1d9 13d 20 213
-8d 92 b4 3d
-336 2fc 15a 10f
-181 ef 391 156
-25a 197 3ca 263
-1d6 9e 3b 1a3
-215 143 2cc a3
-c1 36f 36d 3e
-22a 232 31e ce
-16d 3c6 2e9 138
-13b 17 1d4 27b
-1d2 2ca 99 eb
-19c 202 d3 26c
-155 b2 3dc 13a
-101 265 3e5 332
-1ae 11 364 3af
-376 11c 2cd 337
-1b9 2c2 3d1 27b
-295 291 127 1be
-2b1 1a7 3b8 332
-a9 1e1 2ef 2a6
-29b 101 2d0 178
-23d 1e3 3b5 2f0
-3c8 39f 372 12a
-9a 20d 2ed b6
-3e5 14a 319 2c1
-219 23f 3be 2ab
-372 21d 271 341
-294 b3 289 3b4
-109 bd 113 274
-233 154 f9 3be
-2f5 e0 29b 2de
-307 3e5 123 a4
-2a2 302 335 346
-2af 2e 8d 5c
-12b 25 1ee 20
-359 73 5b 315
-116 3a5 20 3c5
-f9 78 26b 291
-51 343 3b3 138
-38c e0 38b 374
-f9 1cd 9e 37a
-165 32a 105 db
-2f b7 149 20e
-34e d9 64 282
-85 36e 1c7 34a
-3c4 146 392 22a
-96 a3 2f4 353
-62 33d b8 4b
-81 261 30e 18c
-3bc c9 1af 1d3
-29f 32c 395 42
-316 5d 32b 360
-2df 131 b2 1d
-300 41 397 39b
-222 25b 2e3 c2
-35 19a 79 da
-3e7 fe 18c ec
-1b3 2bf 2ad 3a3
-1be 3db ab 98
-199 350 2fc 39
-160 37c 74 319
-28a 9a 132 40
-2b1 35a 352 160
-1cd ed 19e 105
-2b3 2ba 42 217
-2b8 23e 1ad 1f
-26b f6 247 30c
-37e 2ff 201 2ba
-347 2aa 349 a1
-126 147 237 34d
-3b3 14b 223 240
-355 14c 1d6 d1
-23d 38d 1cc 2c6
-30d e4 168 30a
-1ce 54 ae 193
-23a 20d aa 399
-159 98 201 30b
-18b fc 3c7 16c
-83 dd 24c 16c
-1b 355 b2 11e
-308 175 cf 3d8
-133 323 394 262
-141 3f 2ba d1
-99 a3 112 1a6
-a1 271 e7 2bd
-333 2b2 32d 140
-3ae 5f 243 230
-280 3e3 2ee 261
-389 377 273 c5
-13e ba 266 21d
-ec 386 1c9 14c
-22a 2f5 d2 3c7
-3b2 a5 cb 192
-26e 1dd 1d3 55
-22f 376 29 d3
-e0 163 3ca 146
-138 59 12f 109
-218 4d 67 3cf
-a 2b1 1d1 394
-e9 1e1 2fe b9
-374 263 265 1da
-318 15c 3db 1ac
-1a3 21d 27d 1af
-90 193 13d 370
-3a4 83 13 1d0
-1c5 3b1 1af 365
-3e e4 187 3a4
-b 226 354 4e
-78 358 146 264
-2e5 1ef 216 3c3
-66 36b 34d 3e2
-1b7 2a0 33f 25f
-173 248 3d8 65
-1ce 12d 2db 3ab
-b3 2e7 19c 234
-3bd 36 1a0 365
-2b0 22f 136 11f
-4c 2c1 8a 1b4
-255 37 16a 242
-63 1b4 1ae 186
-18c 30f 231 1ab
-236 2ee 267 333
-7d 182 1b1 3e6
-53 3ca 6 2f
-1ca 3d0 131 370
-169 21f 212 29a
-1bd 223 1f8 196
-3aa 99 348 2e6
-139 16 a7 ad
-1ec 3dd 12e 3a9
-3af 1eb a2 2b2
-110 8c 160 273
-31 13b 78 7a
-83 225 1c 355
-fd 37f 3d5 12
-f6 d1 371 3cb
-221 2b2 2ac 3d
-322 340 22b 1d4
-2a2 16f 3a8 366
-17d 348 189 130
-c3 36c 165 26f
-21 2ce 263 2fb
-3e1 139 398 255
-7 11b 2b3 2de
-262 be 90 245
-1c8 123 338 d8
-2f8 28b 1bf 2fb
-265 9e 1d7 19c
-1f5 2a4 337 171
-354 102 3aa 33b
-4e 398 43 1e8
-390 3bd 1cd 186
-2a4 ca 104 be
-2b7 32c 350 388
-34 8c 35e 17d
-10e 350 96 343
-34a 1fb 5f 14a
-1cc 141 371 15f
-fb 13d 1f7 217
-df 14f 12f 322
-be 39 56 19a
-381 118 2cd 2b1
-33c 397 13d 2c7
-18b 22d 22c e6
-301 e8 286 195
-35e 82 3a1 163
-141 38c 3ab 179
-134 139 2a8 2cc
-345 3c bf d5
-2f9 2e4 3a9 231
-315 196 1f6 21d
-3 a9 3bc 2b6
-2f9 110 2fd 3df
-2b0 381 3ab 3b
-7f 2db 59 3dd
-155 153 17c 203
-ee 258 36a 14e
-16d 157 1d4 1d
-126 55 267 1c8
-273 183 15f 97
-3b7 f4 268 23
-223 2b1 1b 3ab
-78 83 55 1e
-28b 3b4 db 1c2
-19 3db 12f 192
-126 26d 149 1a2
-324 2e0 2b8 25b
-11a 1e3 1af 2e3
-17c 3a9 25 61
-2d2 158 3c7 224
-23c 3a7 d6 e9
-101 1b6 179 15a
-361 a4 1af 280
-54 3b4 358 149
-393 c6 e7 32b
-3e1 1a8 290 27d
-2bb 159 28a 2ca
-38e 7a 2d8 2a8
-13 2f2 33d 167
-197 5f a0 16e
-166 15d 2e1 75
-34 317 28f 1af
-50 2c4 b6 20c
-71 9c 22b 94
-116 240 216 38f
-314 297 1b4 2e7
-1b4 2ee 26c 149
-76 1f1 399 333
-25 361 1c5 283
-2af 21b 249 38c
-2b2 da 279 c9
-3ab cb 237 35f
-c7 2a9 50 33f
-231 f8 242 2b6
-391 3e1 2a8 12d
-aa 145 138 247
-312 16a 1e6 f8
-2be 390 1cd 2e3
-3df 272 dd 239
-1e ea 323 e9
-b6 2f4 82 1b5
-1a0 5a 102 314
-11f 2f7 2d9 2b5
-35a 11b 2e1 16c
-389 31 19f 241
-2cc 13f a0 11f
-dc 154 347 3a6
-1b 8 297 2a6
-bd 1bf 77 19e
-c3 36b a6 2b7
-67 2ba 3c0 3af
-b6 2ff 370 2c4
-378 359 297 3d5
-332 e2 204 35f
-253 34a d8 4c
-fb 143 2f9 116
-5f 32 1f7 19b
-a3 143 a8 1e
-373 2d0 1d9 12
-166 d9 68 1c4
-1cb 83 2e a9
-158 2aa 35b 3c2
-3a3 ff 332 161
-292 5a 1bc 30b
-3a8 2aa 350 83
-107 1d5 220 235
-2b0 279 62 62
-2f1 1f1 1f8 17a
-2e1 2fc 268 77
-115 24f 3a5 19d
-be 21c 1df 38c
-1f8 32f 173 318
-113 2b5 52 2a4
-171 3cd bc 3de
-24a 1e0 1e0 2c7
-248 2f9 d1 1b1
-2ee 1b7 267 37e
-1da 144 1f6 158
-2ec 1b2 3ac 2d2
-3dd 27c 3d 369
-105 131 337 3b
-19f 33c 9 2fc
-23f 272 215 31d
-6e dd 33d 1ad
-14b 2e 9d 40
-c8 1dd 13e 3b6
-bf 2e1 39f 3a6
-20 1d2 0 3b6
-1a3 25f 1c1 116
-3aa 96 12 39a
-1ae 352 13e 34f
-317 2c1 ea 20e
-25d 1fe 187 3af
-1de 3e4 2a1 310
-3da 368 363 2a6
-384 4a 2db 6d
-272 246 179 1f7
-303 226 1eb b4
-1b ea 27a 15d
-9e 1d6 9f 1e6
-1f7 191 148 20a
-4a 38 1d7 1a7
-3a6 299 124 41
-11a 154 15 163
-77 d1 dd d0
-147 2db 2f2 37
-13 d3 394 f4
-16a 143 271 204
-2c9 17d af 1f3
-2ea d1 22 23a
-6f 3ba 238 6a
-102 1aa 381 2af
-d4 116 e6 3b5
-f9 3b6 9e 303
-286 111 1f6 35f
-8b e3 3d 262
-27 308 160 385
-a4 20a 261 38d
-ae 28b 61 174
-a2 288 31d 251
-139 e4 1f 53
-5d 2a4 10a 2fa
-de 193 354 1d9
-2c2 ab 1ae 373
-37d 3bd 42 1e1
-49 3e4 20a 2b2
-29d 140 306 255
-354 311 261 3e6
-1db 38d 225 38f
-c4 3d1 205 16b
-1fd 24d 2a6 2f9
-29d 88 cb 2
-dd d5 1df cd
-245 13b 207 13d
-2c2 154 19d 305
-385 29d 38d 1b4
-31a 356 3e5 31c
-26e 207 2af 393
-1b8 2bf 3cc 1e3
-13d 2f9 14 215
-75 304 178 27f
-132 193 1a0 a0
-186 e8 cc 357
-234 2e7 1cd 348
-2a7 f1 3c7 32f
-8a 196 17c 2bd
-20d 233 2fd 36e
-156 23 3e7 3b1
-140 370 290 81
-124 10e 82 186
-1b6 345 196 186
-13a 33f 15f 2b8
-f1 84 323 4c
-319 cd 18a 2c6
-188 2a2 71 2e6
-27e 219 331 162
-e8 103 217 2ab
-57 14c 223 199
-6f 241 179 12d
-0 3dd 183 2b6
-d4 44 27d d2
-e8 39b 97 72
-1e5 3b1 2e1 269
-9d 183 2ef 384
-14 33 9d 36
-128 29b 260 38d
-249 18a 3c4 d8
-33c 5d 2c6 192
-11f 1a3 211 239
-383 25f 7a 135
-6c 1a4 c6 8d
-253 3a1 fc 2d3
-339 1dc 118 3b4
-33f 14c 18d 221
-1cc 2d8 270 345
-3be 3a7 11e 187
-eb 14e 14a 2e1
-359 b5 0 19d
-3a1 350 3b2 36b
-1d4 1d3 139 290
-8e f1 186 160
-32d 2f9 23a 3ba
-15 3d8 6d ab
-3d6 11d 15f ac
-86 327 38a 104
-256 202 361 284
-1db 363 13 3d7
-181 20a 4c 3e0
-19e 3c8 2b7 2cd
-221 3a6 242 1d9
-2fb 177 2cc 369
-47 33d 1af 284
-1f0 306 2e4 295
-230 35 39 274
-177 2e9 36c 3b1
-2e6 24b 239 1f2
-38c 74 2f4 d
-24e 27a 273 c7
-e4 1b0 1f0 de
-31d 3e0 23c 285
-1b4 177 1e6 263
-30d 19e 1b0 169
-38f 42 155 31f
-39 278 2da b0
-326 d9 3c5 3ba
-48 1a1 36 35e
-92 21d 1b1 7f
-22c 342 33e 17f
-ad e7 1fd 16f
-64 3bd 2cd 1ed
-2ac 18b 66 20b
-124 33c 8e 253
-2bd 140 1a0 243
-1b 269 23c 12
-141 270 1d0 f0
-3d5 130 324 4c
-eb 3be 272 33a
-7b 16b 4c 351
-1f4 1d7 10e 2a5
-13b 212 239 13e
-18e 345 1a9 ec
-1a2 fa 164 22b
-292 1ea 2d 1dc
-1ec 1dc 200 17c
-24f 19 11f 14e
-ca 13b 1d8 152
-f4 236 4f 22c
-15b 37f 2bf 316
-36 92 349 8f
-36e 238 292 3d8
-25a 46 a8 279
-13d 258 164 17
-3be 379 55 122
-f2 eb 74 53
-16d 57 3df 353
-ab 31f cf 2fa
-313 ff 1a5 15a
-27b 171 1f5 16
-16f 12f 2dc 83
-93 346 14 284
-d2 38 255 1ca
-329 19d 223 332
-1d 2f6 309 316
-240 326 32d 322
-35f 195 34e 3e
-b2 9 183 24c
-183 3f 39a 3ab
-1f7 3d9 3a8 20e
-43 15b 281 72
-ca 2ed 3b8 175
-2c3 25b 13d 36d
-24f 2c7 1bd 230
-1e9 3a1 10b 2e5
-3e0 3bd 1d1 c8
-29c 8 46 2ea
-1ea 25f 13b 2b
-335 fb 2d3 e4
-a4 2ba 257 72
-1c5 1d8 163 23e
-2b4 1fe 3e5 2a4
-269 16a 1c2 23d
-2ce c3 215 6d
-371 1b9 1bd c1
-2a7 ce 373 63
-120 111 37 154
-3db d9 18b 316
-149 98 11f 208
-25a 37b 1fb 9e
-b 189 80 80
-9d 2e5 145 272
-2cd 265 15a 2d3
-fd 196 1b3 f7
-24c ff 11e 1a3
-1c7 291 2b1 190
-3c6 293 f3 235
-38b c 1fb 3de
-3a5 11f b6 11d
-4d 2f2 3ad 222
-3b3 1ac 26e 176
-366 2a0 219 39b
-2cd 28 3a3 15a
-25c 57 2be 161
-2c0 2d8 a2 1f1
-1f1 2f8 2cf 2c1
-69 164 315 3c5
-df 95 a9 341
-139 2e3 1d8 1a
-23 13a 212 125
-7a 140 350 362
-50 a0 181 34d
-249 33c 245 15d
-250 1bb 31 bb
-2c4 395 10c 202
-372 23c 2bb 237
-367 61 21 361
-267 2a3 13e 185
-c5 364 177 b1
-38f 355 270 3b1
-3ca 3b0 17c 18b
-238 334 f1 365
-2b2 11c 13d 75
-2d 10 19b 225
-26c 119 3e3 3d6
-7f 208 e6 38d
-1fd bf 97 2d3
-44 367 113 357
-125 143 21f 3aa
-c0 130 3e6 33
-358 a3 af 14a
-165 c8 158 b5
-1c9 33a 22c 276
-35a 281 331 1c1
-2c9 1d6 375 178
-29c 205 321 332
-8 1ce 338 2d1
-1d8 1d8 165 13c
-11a 3b0 7e 3c4
-159 383 227 135
-34f 3c9 10a f2
-13b 285 3e5 28b
-1fa 5e e0 2d1
-1a2 26e 17e 153
-169 165 141 37f
-177 26e 2c5 3d9
-1d4 ef 15b 392
-202 355 68 32e
-396 240 210 2bb
-fb 22f 1f6 16b
-1d0 ac d7 179
-f7 27b 381 293
-231 312 25a 3db
-241 290 3a5 e1
-103 118 305 4b
-12a 53 89 28d
-3dd 19a 322 34a
-5e 2aa 58 322
-356 3be 1ae ca
-196 14b 2e1 340
-155 2af 160 2d7
-fa 74 ec 106
-282 12e 1b7 3ca
-312 1ab 40 17d
-23 231 184 345
-340 37 235 36f
-2ba 320 85 26b
-e1 2da 332 39f
-21f 3ac 2dd 262
-2db 199 192 368
-ad 21c c8 317
-f3 76 10 1ab
-37d 31 a7 34c
-3af 384 3e7 11e
-7a 1d9 1d 1c2
-3d7 269 24 38f
-1e4 1ff 1aa 34d
-2b5 1c6 28a 272
-9f 203 297 124
-357 306 27b 244
-30f 2c1 2d5 b0
-233 3cd 3d8 283
-3ad 1bf 1e8 102
-17b 3b8 378 22b
-1f8 120 132 2db
-2b3 ab 2dd 1b7
-18e 21c 2ad 1ab
-ec 2c3 1af 15b
-345 1c0 29a 115
-37c 35b 15c 1fe
-20f 30f 387 f6
-3c6 188 f6 ce
-273 6b 314 236
-1d3 388 379 264
-3cc 11e 30a 17
-120 22c 196 ea
-f 8c 1a4 3a3
-11d 263 297 284
-3ac 31c cc 38b
-10b 1e7 1d8 6
-125 1de 320 80
-396 360 36f 3a4
-22f 35 131 25e
-51 145 de 3ca
-179 29d e6 339
-3cb 13b 398 10
-1bc 90 272 29f
-2bc 3d5 159 1e4
-32d 303 2d9 329
-2f4 115 13b 97
-104 1e7 174 e8
-131 39 232 267
-23e e9 212 255
-101 286 22 3d2
-22d 310 2ac 306
-ed d0 e8 241
-2c4 335 318 136
-253 19d d5 63
-162 4e 234 1e3
-3af 2b0 2c6 182
-245 b 61 1d2
-1c3 2ec e3 a7
-2e0 2ef fb 3cc
-251 21c 392 34
-ff 31a 20c 1e4
-108 fc 13 a0
-13 1af f2 b2
-51 227 22 365
-49 129 c1 e1
-6e 2fd 7d 3bf
-252 271 23d 34c
-a1 f1 1fa 32e
-a4 200 e4 94
-a4 e2 79 148
-3e0 3a8 1bf 14
-1f9 30 55 b9
-2cc 17e 382 127
-15b 2b0 3ad 1e9
-29d 234 37a 27f
-2a7 af 3e7 30a
-39c 1ac e 239
-143 376 2c0 34e
-b0 360 e9 ae
-13e 69 1c5 221
-21c 184 7f 30b
-156 d3 1d2 1db
-23a 2e2 1df 258
-150 1e2 289 330
-3a9 29c 5f 4d
-21 203 35e 33e
-2a5 34 76 1e3
-1c7 2ff aa 233
-6e 158 63 122
-2f db 1b3 2c9
-3c2 21b 3e7 248
-196 68 1fe 2b5
-d6 1a1 ed 289
-a 178 1ff 18
-20e 128 65 122
-5c 3d7 13 323
-238 394 1e9 3e0
-17e 167 300 2ce
-e9 17d 73 1ee
-204 115 1a7 23d
-21e 1a8 10c 26
-212 208 228 2dd
-341 4b 2fc 2ef
-75 91 26d 3d2
-207 c4 10 1ea
-266 205 137 357
-288 207 1a0 274
-105 11 1fb f8
-369 210 2ec 29b
-2ca 3d5 111 2f
-16b 2f3 9f 133
-252 11 258 57
-2f8 88 3ce 140
-105 3a5 3bf 18
-71 19d 185 a
-67 39b 1d8 32f
-237 204 36e 24d
-18c 3b9 107 219
-39a 3c9 7e 35a
-166 4 105 276
-396 149 364 7d
-2a bb 3da 3ab
-238 2d4 229 12d
-24f 106 3af 1b7
-11b 157 2e3 4d
-8b b 2b2 326
-368 1b5 18d 124
-326 65 299 6d
-98 2f6 5c 306
-37 15a 305 17c
-212 3aa 14 2a0
-190 3c2 3b1 294
-19 2af 23e f
-108 b7 1eb 38b
-27e 3e fc 25d
-315 2b5 84 1d3
-3b 1bc 95 340
-aa a8 180 3a8
-239 167 223 c8
-3de 12 196 38e
-1eb 2e0 10a 77
-20e 289 34d 3c8
-10b b9 88 3e0
-5e a8 24e 344
-325 229 265 3bb
-32d 70 1ea 359
-12e 27d 1be 388
-27c 122 394 26b
-290 156 71 34
-1aa d 3ad 199
-256 b4 235 3d8
-1f 187 34a 190
-301 2c6 18b 1b5
-195 1c2 60 17a
-f6 199 330 378
-cb 3ad 14c 3d0
-10c 205 150 2f0
-36 219 199 317
-264 cb 164 278
-223 1f9 339 38e
-31b 2d 86 39d
-37f 1de d6 cd
-f5 2df 326 11
-c5 34 ce 291
-34f 24c 2cc 202
-37 5a 159 e8
-12c 25b 339 ca
-5d 1cf 33e 2e4
-247 389 5c 9d
-326 196 51 316
-12f 83 1fa 13f
-2db 188 252 22f
-3e4 2bb 311 3be
-315 137 357 2c1
-2bb 386 271 123
-28d c 6f 30d
-388 41 1b1 123
-3bf 30 352 1b9
-1fb 39e d3 39b
-247 1a 1f4 38b
-8 10a cd 18a
-2a6 368 3b7 110
-31 183 1ca 388
-30d 315 88 122
-13 2d4 19e 299
-3be 12e 257 3b4
-350 158 1c3 35f
-64 3a3 79 2a1
-191 2cd 11b 183
-326 2cd 67 20
-71 a1 f1 23c
-24e 3b2 293 2cd
-315 398 388 35b
-263 342 3b5 2c1
-29a 101 221 14e
-1a5 58 ab 76
-109 310 1f6 40
-1fa 2ed 1e4 12e
-26d 17e 227 31c
-3d 1b 165 385
-2ac 2dd 49 b3
-1b 105 3d 236
-2ff 241 2d0 225
-ab 300 263 19
-3dd 7b 132 325
-1bc 252 d3 28
-1b4 25a ee e5
-11b 98 284 27f
-383 284 289 2af
-e 3e0 5a 3
-2d3 3a7 128 3a1
-1c 3a6 82 354
-303 20e 327 3a9
-2d0 227 1c9 59
-20a 21 2e7 1a9
-17 340 11b 267
-3a4 51 28a 20f
-77 39b b 3e5
-20 12e 52 1fc
-12a 119 b 1f5
-1d7 181 1ca 2f4
-159 2c2 397 15c
-bb 22f a4 3d4
-f8 299 3d4 37b
-28b 2a8 3e5 3b3
-11c 25b 2dd 34f
-202 329 389 1a1
-1d5 3b4 317 f0
-16 f1 3b9 27e
-175 20e 10e e1
-a2 12d 154 22f
-2f7 1f 2ec 16e
-142 bf 358 269
-11c 40 d9 363
-28c 263 f2 217
-321 1f5 36f ee
-300 39b 3be 7
-2c8 156 205 7d
-19a 303 310 3d6
-107 ae 58 1e3
-3c 21a 5f 115
-5b ae 3bc 3bd
-18 55 3d9 2fa
-11c 2df 1a7 294
-1a6 65 316 343
-48 2e5 28e 3d4
-2a1 2db ce 200
-117 eb 25c 1de
-20a 2f6 1da 106
-196 259 93 252
-3c7 0 3d6 272
-164 2f2 348 2a3
-15b 7b 22f a2
-17f fc 19a 13e
-374 72 25c 167
-3c7 1bb 2a6 314
-1e1 1fb ef 20d
-104 a0 fe 335
-3ba c4 363 48
-2f6 1c 26f 397
-37a 213 a4 9b
-2a3 1b9 5e 10d
-15b 9b 17a 123
-3e5 313 272 20b
-142 c2 90 350
-202 13b 19e bb
-365 2e2 d0 ba
-181 152 230 358
-1ea 2ac 1d5 1b3
-116 20a 71 27
-19d 3ca b1 69
-30e 3c3 338 a6
-239 157 2ed 234
-373 307 194 23f
-75 3d1 11e 3a9
-e9 38b 374 9
-253 20a 320 138
-13d bf f5 320
-50 69 1b3 220
diff --git a/Samples/random_cloud_10.png b/Samples/random_cloud_10.png
new file mode 100644
index 000000000..d64e255f0
Binary files /dev/null and b/Samples/random_cloud_10.png differ
diff --git a/Samples/random_cloud_100.png b/Samples/random_cloud_100.png
new file mode 100644
index 000000000..ed9f9cc3e
Binary files /dev/null and b/Samples/random_cloud_100.png differ
diff --git a/Samples/random_cloud_50.png b/Samples/random_cloud_50.png
new file mode 100644
index 000000000..bc9dcc2a1
Binary files /dev/null and b/Samples/random_cloud_50.png differ
diff --git a/TagsCloudContainerCLI/CLI/CliHandler.cs b/TagsCloudContainerCLI/CLI/CliHandler.cs
new file mode 100644
index 000000000..a6d32c475
--- /dev/null
+++ b/TagsCloudContainerCLI/CLI/CliHandler.cs
@@ -0,0 +1,47 @@
+using System.Text.RegularExpressions;
+using TagsCloudContainerCore.Models;
+using TagsCloudContainerCore.TextProcessor;
+
+namespace TagsCloudContainerCLI.CLI;
+
+public partial class CliHandler
+{
+ public static Result ValidateOptions(CliOptions opts)
+ {
+ if (!Enum.TryParse(opts.SortOrder, true, out _))
+ {
+ return Result.Fail($"Invalid sort order: {opts.SortOrder}. Must be one of: {string.Join(", ", Enum.GetNames())}");
+ }
+
+ foreach (var part in opts.ExcludedPartsOfSpeech.Split(","))
+ {
+ if (!Enum.TryParse(part, true, out _))
+ {
+ return Result.Fail($"Invalid part of speech: {part}. Must be one of: {string.Join(", ", Enum.GetNames())}");
+ }
+ }
+
+ if (opts.RenderScale <= 0)
+ {
+ return Result.Fail($"Render scale must be positive, got: {opts.RenderScale}");
+ }
+
+ if (opts.MaxWords <= 0)
+ {
+ return Result.Fail($"Max words must be positive, got: {opts.MaxWords}");
+ }
+
+ if (opts.MinFontSize <= 0 || opts.MaxFontSize <= 0 || opts.MinFontSize > opts.MaxFontSize)
+ {
+ return Result.Fail($"Font sizes must be positive and min size must be less or equal to max size, got: {opts.MinFontSize}, {opts.MaxFontSize}");
+ }
+
+ if (opts.LayoutSpacing < 0)
+ {
+ return Result.Fail($"Layout spacing must be non-negative, got: {opts.LayoutSpacing}");
+ }
+
+ return Result.Ok();
+ }
+
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/CLI/CliOptions.cs b/TagsCloudContainerCLI/CLI/CliOptions.cs
new file mode 100644
index 000000000..a2bd25d5b
--- /dev/null
+++ b/TagsCloudContainerCLI/CLI/CliOptions.cs
@@ -0,0 +1,51 @@
+using CommandLine;
+
+namespace TagsCloudContainerCLI.CLI;
+
+public class CliOptions
+{
+ [Option('d', "demo", Required = false, HelpText = "Run the application in demo mode.")]
+ public bool Demo { get; set; }
+
+ [Option('f', "file", Required = false, HelpText = "Specify the file path.")]
+ public string File { get; set; }
+
+ [Option('o', "output", Required = false, HelpText = "Specify the output path.")]
+ public string? Output { get; set; }
+
+ [Option("font", Required = false, Default = "Arial", HelpText = "Specify the font family.")]
+ public string FontFamily { get; set; }
+
+ [Option("scale", Required = false, Default = 1, HelpText = "Specify the render scale.")]
+ public float RenderScale { get; set; }
+
+ [Option("max-words", Required = false, Default = 100, HelpText = "Maximum number of words to include.")]
+ public int MaxWords { get; set; }
+
+ [Option("min-font", Required = false, Default = 12f, HelpText = "Minimum font size.")]
+ public float MinFontSize { get; set; }
+
+ [Option("max-font", Required = false, Default = 48f, HelpText = "Maximum font size.")]
+ public float MaxFontSize { get; set; }
+
+ [Option("spacing", Required = false, Default = 0.1f, HelpText = "Space between words.")]
+ public float LayoutSpacing { get; set; }
+
+ [Option("radius", Required = false, Default = 0, HelpText = "Initial radius from center.")]
+ public double InitialRadius { get; set; }
+
+ [Option("excluded-words", Required = false, Default = "", HelpText = "Words to exclude.")]
+ public string ExcludedWords { get; set; }
+
+ [Option("excluded-parts", Required = false, Default = "PART,ADV,PR,CONJ,ANUM,APRO,SPRO,NUM", HelpText = "Parts of speech to exclude.")]
+ public string ExcludedPartsOfSpeech { get; set; }
+
+ [Option("sort", Required = false, Default = "Descending", HelpText = "Sort order (Ascending/Descending/Random).")]
+ public string SortOrder { get; set; }
+
+ [Option("background", Required = false, Default = "#000000", HelpText = "Background color in HEX.")]
+ public string BackgroundColor { get; set; }
+
+ [Option("foreground", Required = false, Default = "#FFFFFF", HelpText = "Foreground color in HEX.")]
+ public string ForegroundColor { get; set; }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/CLI/TagCloudConfig.cs b/TagsCloudContainerCLI/CLI/TagCloudConfig.cs
new file mode 100644
index 000000000..cd044afc8
--- /dev/null
+++ b/TagsCloudContainerCLI/CLI/TagCloudConfig.cs
@@ -0,0 +1,17 @@
+namespace TagsCloudContainerCLI.CLI;
+
+public record TagCloudConfig
+{
+ public string FontFamily { get; set; }
+ public float RenderScale { get; set; }
+ public int MaxWords { get; set; }
+ public float MinFontSize { get; set; }
+ public float MaxFontSize { get; set; }
+ public float LayoutSpacing { get; set; }
+ public double InitialRadius { get; set; }
+ public string[] ExcludedWords { get; set; }
+ public string[] ExcludedPartsOfSpeech { get; set; }
+ public string SortOrder { get; set; }
+ public string BackgroundColor { get; set; }
+ public string ForegroundColor { get; set; }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/Demo.cs b/TagsCloudContainerCLI/Demo.cs
new file mode 100644
index 000000000..07a74d0f2
--- /dev/null
+++ b/TagsCloudContainerCLI/Demo.cs
@@ -0,0 +1,89 @@
+using System.Text;
+using Microsoft.Extensions.Logging;
+using TagsCloudContainerCore.DataProvider;
+using TagsCloudContainerCore.Facade;
+using TagsCloudContainerCore.FontManager;
+using TagsCloudContainerCore.ImageEncoders;
+using TagsCloudContainerCore.Layouter;
+using TagsCloudContainerCore.Models.Graphics;
+using TagsCloudContainerCore.Renderer;
+using TagsCloudContainerCore.TextProcessor;
+
+namespace TagsCloudContainerCLI;
+
+public class Demo
+{
+ private ITagCloudFactory _cloudFactory;
+ private ILogger _logger;
+
+ public Demo(ITagCloudFactory cloudFactory, ILogger logger)
+ {
+ _cloudFactory = cloudFactory;
+ _logger = logger;
+ }
+
+ public Result Generate()
+ {
+ _logger.LogInformation("Generating random clouds");
+ Directory.CreateDirectory("results");
+
+ return GenerateRandomCloud(10)
+ .Then(_ => GenerateRandomCloud(50))
+ .Then(_ => GenerateRandomCloud(100));
+ }
+
+ private Result GenerateRandomCloud(int count)
+ {
+ _logger.LogInformation("Generating cloud with {Count} words", count);
+ return _cloudFactory.Create(builder => builder
+ .UseDataProvider()
+ .UseWordProcessor(
+ new MyStemTextProcessorConfig
+ {
+ ExcludedWords = ["тест"],
+ ExcludedPartsOfSpeech = []
+ })
+ .UseFontManager(
+ new FontManagerConfig
+ {
+ Font = new Font("Arial")
+ }
+ )
+ .UseLayouter(
+ new CircularCloudLayouterConfig
+ {
+ SpiralStep = 0.5,
+ InitialRadius = 100
+ })
+ .UseRenderer(new RendererConfig
+ {
+ BackgroundColor = new Color(200, 200, 255),
+ RenderingScale = 5,
+ TextColor = new Color(0, 0, 100)
+ }
+ )
+ .UseImageEncoder())
+ .Then(r => r.FromString(GenerateRandomString(count)))
+ .Then(imageBytes => File.WriteAllBytes($"results/random_cloud_{count}.png", imageBytes));
+ }
+
+ private static string GenerateRandomString(int count)
+ {
+ var randomString =
+ ("Lorem ipsum — классический текст-«рыба» (условный, зачастую бессмысленный текст-заполнитель, вставляемый в макет страницы, используемый для образца шрифта и текста, поля размещения на странице). "
+ + "Используется для демонстрации элементов графики в документах или презентациях, без отвлечения внимания на содержимое. "
+ + "Слова «Lorem ipsum» берут начало от латинского слова и начинаются с «dolorem ipsum», что означает «боль сама по себе». "
+ + "Текст не имеет смысла, но по своей структуре напоминает настоящий текст. "
+ + "Слова и предложения в «Lorem ipsum» обычно не повторяются, что делает его более правдоподобным. ")
+ .Split();
+ var random = new Random();
+ var sb = new StringBuilder();
+ for (var i = 0; i < count - 1; i++)
+ {
+ sb.Append(randomString[random.Next(randomString.Length)]);
+ sb.Append(' ');
+ }
+
+ return sb.ToString();
+ }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/FileMode.cs b/TagsCloudContainerCLI/FileMode.cs
new file mode 100644
index 000000000..e377a820a
--- /dev/null
+++ b/TagsCloudContainerCLI/FileMode.cs
@@ -0,0 +1,134 @@
+using Microsoft.Extensions.Logging;
+using TagsCloudContainerCLI.CLI;
+using TagsCloudContainerCore.DataProvider;
+using TagsCloudContainerCore.Facade;
+using TagsCloudContainerCore.FontManager;
+using TagsCloudContainerCore.ImageEncoders;
+using TagsCloudContainerCore.Layouter;
+using TagsCloudContainerCore.Models;
+using TagsCloudContainerCore.Models.Graphics;
+using TagsCloudContainerCore.Renderer;
+using TagsCloudContainerCore.TextProcessor;
+
+
+namespace TagsCloudContainerCLI;
+
+public class FileMode
+{
+ private readonly ILogger _logger;
+ private readonly ITagCloudFactory _cloudFactory;
+ private readonly TagCloudConfig _config;
+
+ public FileMode(ILogger logger, ITagCloudFactory cloudFactory, TagCloudConfig config)
+ {
+ _logger = logger;
+ _cloudFactory = cloudFactory;
+ _config = config;
+ }
+
+ public Result Generate(string filePath, string outputPath)
+ {
+ _logger.LogInformation("Generating tag cloud to {Path}", outputPath);
+
+ return _cloudFactory.Create(builder => builder
+ .GuessDataProvider(Path.GetExtension(filePath))
+ .UseWordProcessor(new MyStemTextProcessorConfig
+ {
+ MaxWordsCount = _config.MaxWords,
+ ExcludedWords = _config.ExcludedWords,
+ ExcludedPartsOfSpeech = _config.ExcludedPartsOfSpeech
+ .Select(pos =>
+ {
+ if (Enum.TryParse(pos, true, out var parsedPos))
+ {
+ return parsedPos;
+ }
+
+ _logger.LogWarning("Invalid PartOfSpeech value: {Value}", pos);
+ return (PartOfSpeech?)null;
+ })
+ .Where(pos => pos.HasValue)
+ .Select(pos => pos!.Value)
+ .ToArray(),
+ SortOrder = Enum.Parse(_config.SortOrder, true)
+ })
+ .UseFontManager(new FontManagerConfig
+ {
+ Font = new Font(_config.FontFamily)
+ })
+ .UseLayouter(new CircularCloudLayouterConfig
+ {
+ MaxFontSize = _config.MaxFontSize,
+ MinFontSize = _config.MinFontSize,
+ SpiralStep = _config.LayoutSpacing,
+ InitialRadius = _config.InitialRadius
+ })
+ .UseRenderer(new RendererConfig
+ {
+ TagFont = new Font(_config.FontFamily),
+ RenderingScale = _config.RenderScale,
+ BackgroundColor = new Color(_config.BackgroundColor),
+ TextColor = new Color(_config.ForegroundColor)
+ })
+ .GuessEncoder(Path.GetExtension(outputPath)))
+ .Then(r => r.FromFile(filePath)
+ .RefineError("Failed to generate tag cloud"))
+ .Then(imageBytes => SaveTo(outputPath, imageBytes));
+ }
+
+ private Result SaveTo(string outputPath, byte[] imageBytes)
+ {
+ var directory = Path.GetDirectoryName(outputPath);
+ if (!string.IsNullOrEmpty(directory))
+ {
+ try
+ {
+ Directory.CreateDirectory(directory);
+ }
+ catch (Exception ex)
+ {
+ return Result.Fail($"Failed to create directory: {ex.Message}");
+ }
+ }
+
+ var fullpath = Path.GetFullPath(outputPath);
+ _logger.LogInformation("Saving tag cloud to {Path}", fullpath);
+ try
+ {
+ File.WriteAllBytes(outputPath, imageBytes);
+ }
+ catch (Exception e)
+ {
+ return Result.Fail($"Failed to save image: {e.Message}");
+ }
+
+ return Result.Ok();
+ }
+}
+
+public static class BuilderExtensions
+{
+ public static TagCloudBuilder GuessDataProvider(this TagCloudBuilder b, string ext)
+ {
+ return ext switch
+ {
+ ".docx" => b.UseDataProvider(),
+ ".doc" => b.UseDataProvider(),
+ ".ppt" => b.UseDataProvider(),
+ ".pptx" => b.UseDataProvider(),
+ ".txt" => b.UseDataProvider(),
+ _ => b.UseDataProvider(),
+ };
+ }
+
+ public static TagCloudBuilder GuessEncoder(this TagCloudBuilder b, string ext)
+ {
+ return ext switch
+ {
+ ".png" => b.UseImageEncoder(),
+ ".jpeg" => b.UseImageEncoder(),
+ ".jpg" => b.UseImageEncoder(),
+ _ => b.UseImageEncoder(),
+ };
+ }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/Program.cs b/TagsCloudContainerCLI/Program.cs
new file mode 100644
index 000000000..39e6fef95
--- /dev/null
+++ b/TagsCloudContainerCLI/Program.cs
@@ -0,0 +1,122 @@
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using CommandLine;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using Serilog.Extensions.Autofac.DependencyInjection;
+using TagsCloudContainerCLI.CLI;
+using TagsCloudContainerCore.Facade;
+
+namespace TagsCloudContainerCLI;
+
+internal class Program
+{
+ private static ParserResult? _parseResult;
+
+ private static void Main(string[] args)
+ {
+ _parseResult = Parser.Default.ParseArguments(args);
+
+ if (_parseResult.Tag == ParserResultType.NotParsed)
+ {
+ Environment.Exit(1);
+ }
+
+ Result.Of(() => BuildHost(args))
+ .Then(host =>
+ {
+ using var scope = host.Services.CreateScope();
+ return ProcessArguments(scope.ServiceProvider);
+ })
+ .OnFail(error =>
+ {
+ Log.Fatal($"Application error: {error}");
+ Environment.Exit(1);
+ });
+ }
+
+ private static IHost BuildHost(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .UseServiceProviderFactory(new AutofacServiceProviderFactory())
+ .ConfigureServices(ConfigureServices)
+ .ConfigureContainer(ConfigureContainer)
+ .Build();
+
+ private static void ConfigureServices(HostBuilderContext _, IServiceCollection services)
+ {
+ services.AddOptions();
+ services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog());
+ }
+
+ private static void ConfigureContainer(ContainerBuilder builder)
+ {
+ ConfigureSerilog(builder);
+ ConfigureTagCloud(builder);
+ builder.RegisterInstance(CreateTagCloudConfig(_parseResult!.Value)).As();
+ }
+
+ private static void ConfigureSerilog(ContainerBuilder builder)
+ {
+ builder.RegisterSerilog(new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.Console()
+ .WriteTo.File("logs/log-.log", rollingInterval: RollingInterval.Day));
+ }
+
+ private static void ConfigureTagCloud(ContainerBuilder builder)
+ {
+ builder.RegisterType()
+ .As()
+ .InstancePerLifetimeScope();
+
+ builder.RegisterType().AsSelf();
+ builder.RegisterType().AsSelf().SingleInstance();
+ }
+
+ private static Result ProcessArguments(IServiceProvider services)
+ {
+ return _parseResult!
+ .MapResult(
+ opts => HandleValidOptions(opts, services),
+ errors => Result.Fail($"Invalid command line arguments: {errors}")
+ );
+ }
+
+ private static TagCloudConfig CreateTagCloudConfig(CliOptions options) =>
+ new()
+ {
+ FontFamily = options.FontFamily,
+ RenderScale = options.RenderScale,
+ MaxWords = options.MaxWords,
+ MinFontSize = options.MinFontSize,
+ MaxFontSize = options.MaxFontSize,
+ LayoutSpacing = options.LayoutSpacing,
+ InitialRadius = options.InitialRadius,
+ ExcludedWords = options.ExcludedWords.Split(","),
+ ExcludedPartsOfSpeech = options.ExcludedPartsOfSpeech.Split(","),
+ SortOrder = options.SortOrder,
+ ForegroundColor = options.ForegroundColor,
+ BackgroundColor = options.BackgroundColor,
+ };
+
+
+ private static Result HandleValidOptions(CliOptions opts, IServiceProvider services)
+ {
+ return CliHandler.ValidateOptions(opts)
+ .Then(_ =>
+ {
+ if (opts.Demo)
+ {
+ var demo = services.GetRequiredService();
+ return demo.Generate();
+ }
+
+ if (string.IsNullOrEmpty(opts.File))
+ return Result.Fail("No file specified");
+ var fileMode = services.GetRequiredService();
+ var outputPath = opts.Output ?? $"{opts.File}.png";
+ return fileMode.Generate(opts.File, outputPath);
+ });
+ }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCLI/TagsCloudContainerCLI.csproj b/TagsCloudContainerCLI/TagsCloudContainerCLI.csproj
new file mode 100644
index 000000000..84feca64c
--- /dev/null
+++ b/TagsCloudContainerCLI/TagsCloudContainerCLI.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TagsCloudContainerCore/DataProvider/FileDataProvider.cs b/TagsCloudContainerCore/DataProvider/FileDataProvider.cs
new file mode 100644
index 000000000..419cd4578
--- /dev/null
+++ b/TagsCloudContainerCore/DataProvider/FileDataProvider.cs
@@ -0,0 +1,22 @@
+using System.Text;
+using Microsoft.Extensions.Logging;
+
+namespace TagsCloudContainerCore.DataProvider;
+
+public class FileDataProvider : IDataProvider
+{
+ private readonly ILogger _logger;
+
+ public FileDataProvider(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public Result GetData(byte[] data)
+ {
+ _logger.LogInformation("Reading data with FileDataProvider");
+ var text = Encoding.UTF8.GetString(data);
+ _logger.LogInformation("Read {n} characters from file", data.Length);
+ return text;
+ }
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCore/DataProvider/IDataProvider.cs b/TagsCloudContainerCore/DataProvider/IDataProvider.cs
new file mode 100644
index 000000000..79fe08085
--- /dev/null
+++ b/TagsCloudContainerCore/DataProvider/IDataProvider.cs
@@ -0,0 +1,11 @@
+namespace TagsCloudContainerCore.DataProvider;
+
+public interface IDataProvider : IDataProvider
+{
+ TConfig Config { get; init; }
+}
+
+public interface IDataProvider
+{
+ Result GetData(byte[] data);
+}
\ No newline at end of file
diff --git a/TagsCloudContainerCore/DataProvider/OpenXmlDocumentsProvider.cs b/TagsCloudContainerCore/DataProvider/OpenXmlDocumentsProvider.cs
new file mode 100644
index 000000000..0457f78cc
--- /dev/null
+++ b/TagsCloudContainerCore/DataProvider/OpenXmlDocumentsProvider.cs
@@ -0,0 +1,36 @@
+using DocumentFormat.OpenXml.Packaging;
+using Microsoft.Extensions.Logging;
+
+namespace TagsCloudContainerCore.DataProvider;
+
+public class OpenXmlDocumentsProvider : IDataProvider
+{
+ private readonly ILogger