diff --git a/.editorconfig b/.editorconfig
index c04a279..2cd5f5b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,7 +9,9 @@ charset = utf-8
indent_style = space
indent_size = 4
tab_width = 4
-end_of_line = crlf
+# LF on every platform, matching the `* text=auto eol=lf` default in .gitattributes.
+# Overrides below must stay in step with the eol pins in that file.
+end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
@@ -17,7 +19,7 @@ trim_trailing_whitespace = true
[*.{cs,csx,cake,fs,fsx,vb,vbx}]
indent_style = tab
-file_header_template = Copyright (c) ktsu.dev\nAll rights reserved.\nLicensed under the MIT license.
+file_header_template = Copyright (c) 2023-2026 ktsu-dev contributors
# Default severity for all .NET Code Style rules
dotnet_analyzer_diagnostic.severity = error
@@ -503,4 +505,9 @@ indent_style = tab
# Shell scripts
[*.sh]
end_of_line = lf
-indent_size = 2
\ No newline at end of file
+indent_size = 2
+
+# Windows batch scripts and Visual Studio solution files keep CRLF on every platform.
+# These match the eol=crlf pins in .gitattributes.
+[*.{cmd,bat,sln}]
+end_of_line = crlf
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index d67e40c..a0bea35 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,20 +4,25 @@
# Git Line Endings #
###############################
-# Set default behaviour to automatically normalize line endings.
-* text=auto
+# Normalize all text files to LF in the repository, and check them out as LF on every
+# platform. The explicit eol overrides each machine's core.autocrlf, so the working tree
+# is byte-identical on Windows, Linux and macOS. This must stay in step with the
+# end_of_line settings in .editorconfig.
+* text=auto eol=lf
-# csharp files to match .editorconfig
-*.cs text eol=crlf
+# Force bash scripts to always use LF line endings so that if a repo is accessed
+# in Unix via a file share from Windows, the scripts will work. Redundant with the
+# default above, kept explicit because these files break outright with CRLF.
+*.sh text eol=lf
# Force batch scripts to always use CRLF line endings so that if a repo is accessed
# in Windows via a file share from Linux, the scripts will work.
-*.{cmd,[cC][mM][dD]} text eol=crlf
-*.{bat,[bB][aA][tT]} text eol=crlf
+*.cmd text eol=crlf
+*.bat text eol=crlf
-# Force bash scripts to always use LF line endings so that if a repo is accessed
-# in Unix via a file share from Windows, the scripts will work.
-*.sh text eol=lf
+# Visual Studio rewrites solution files with CRLF regardless of the checkout, so pin
+# them to avoid a spurious whole-file diff every time the solution is opened.
+*.sln text eol=crlf
###############################
# Git Large File System (LFS) #
diff --git a/.runsettings b/.runsettings
index 3c3169d..9bd9f05 100644
--- a/.runsettings
+++ b/.runsettings
@@ -1,25 +1,6 @@
-
- .\coverage
+ TestResults
-
-
- .\coverage
-
-
-
-
-
-
-
- opencover
- coverage.opencover.xml
- [*Test*]*,[*Tests*]*
- **/obj/**/*
-
-
-
-
diff --git a/Directory.Packages.props b/Directory.Packages.props
index cabde0b..1e18e23 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -3,13 +3,11 @@
true
-
-
diff --git a/TUI.App/AssemblyInfo.cs b/TUI.App/AssemblyInfo.cs
index 1e9a906..d771f7e 100644
--- a/TUI.App/AssemblyInfo.cs
+++ b/TUI.App/AssemblyInfo.cs
@@ -1,5 +1,3 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ktsu.TUI.Test")]
diff --git a/TUI.App/InteractiveDemo.cs b/TUI.App/InteractiveDemo.cs
index 286fbd6..5551fd8 100644
--- a/TUI.App/InteractiveDemo.cs
+++ b/TUI.App/InteractiveDemo.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.App;
diff --git a/TUI.App/Program.cs b/TUI.App/Program.cs
index 0833978..78aca7f 100644
--- a/TUI.App/Program.cs
+++ b/TUI.App/Program.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
using ktsu.TUI.App;
diff --git a/TUI.App/SampleApp.cs b/TUI.App/SampleApp.cs
index 07ffefa..ee0db37 100644
--- a/TUI.App/SampleApp.cs
+++ b/TUI.App/SampleApp.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.App;
diff --git a/TUI.App/ShowcaseDemo.cs b/TUI.App/ShowcaseDemo.cs
index a082db4..588b9d5 100644
--- a/TUI.App/ShowcaseDemo.cs
+++ b/TUI.App/ShowcaseDemo.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.App;
diff --git a/TUI.CLI/SampleCLI.cs b/TUI.CLI/SampleCLI.cs
index 1e37e45..d5c03c4 100644
--- a/TUI.CLI/SampleCLI.cs
+++ b/TUI.CLI/SampleCLI.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
using ktsu.TUI.Core.Contracts;
using ktsu.TUI.Core.Elements.Layouts;
diff --git a/TUI.Core/Contracts/IConsoleProvider.cs b/TUI.Core/Contracts/IConsoleProvider.cs
index da33f09..39ca5a4 100644
--- a/TUI.Core/Contracts/IConsoleProvider.cs
+++ b/TUI.Core/Contracts/IConsoleProvider.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Contracts;
diff --git a/TUI.Core/Contracts/IUIApplication.cs b/TUI.Core/Contracts/IUIApplication.cs
index 770c721..bd20cdc 100644
--- a/TUI.Core/Contracts/IUIApplication.cs
+++ b/TUI.Core/Contracts/IUIApplication.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Contracts;
diff --git a/TUI.Core/Contracts/IUIContainer.cs b/TUI.Core/Contracts/IUIContainer.cs
index c87e3df..5619e31 100644
--- a/TUI.Core/Contracts/IUIContainer.cs
+++ b/TUI.Core/Contracts/IUIContainer.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Contracts;
diff --git a/TUI.Core/Contracts/IUIElement.cs b/TUI.Core/Contracts/IUIElement.cs
index 0228e07..4a9b9da 100644
--- a/TUI.Core/Contracts/IUIElement.cs
+++ b/TUI.Core/Contracts/IUIElement.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Contracts;
diff --git a/TUI.Core/Elements/Layouts/Orientation.cs b/TUI.Core/Elements/Layouts/Orientation.cs
index 2efe733..34ada75 100644
--- a/TUI.Core/Elements/Layouts/Orientation.cs
+++ b/TUI.Core/Elements/Layouts/Orientation.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Layouts;
diff --git a/TUI.Core/Elements/Layouts/StackPanel.cs b/TUI.Core/Elements/Layouts/StackPanel.cs
index 956d243..12a5b14 100644
--- a/TUI.Core/Elements/Layouts/StackPanel.cs
+++ b/TUI.Core/Elements/Layouts/StackPanel.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Layouts;
diff --git a/TUI.Core/Elements/Primitives/BorderElement.cs b/TUI.Core/Elements/Primitives/BorderElement.cs
index 4ce6157..e91a21d 100644
--- a/TUI.Core/Elements/Primitives/BorderElement.cs
+++ b/TUI.Core/Elements/Primitives/BorderElement.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Primitives;
diff --git a/TUI.Core/Elements/Primitives/BorderStyle.cs b/TUI.Core/Elements/Primitives/BorderStyle.cs
index 0d3785b..ef4eae7 100644
--- a/TUI.Core/Elements/Primitives/BorderStyle.cs
+++ b/TUI.Core/Elements/Primitives/BorderStyle.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Primitives;
diff --git a/TUI.Core/Elements/Primitives/HorizontalAlignment.cs b/TUI.Core/Elements/Primitives/HorizontalAlignment.cs
index 2ac82b0..c0d44b1 100644
--- a/TUI.Core/Elements/Primitives/HorizontalAlignment.cs
+++ b/TUI.Core/Elements/Primitives/HorizontalAlignment.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Primitives;
diff --git a/TUI.Core/Elements/Primitives/TextElement.cs b/TUI.Core/Elements/Primitives/TextElement.cs
index ff2b273..0e519b1 100644
--- a/TUI.Core/Elements/Primitives/TextElement.cs
+++ b/TUI.Core/Elements/Primitives/TextElement.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Primitives;
diff --git a/TUI.Core/Elements/Primitives/VerticalAlignment.cs b/TUI.Core/Elements/Primitives/VerticalAlignment.cs
index e281c38..f91282e 100644
--- a/TUI.Core/Elements/Primitives/VerticalAlignment.cs
+++ b/TUI.Core/Elements/Primitives/VerticalAlignment.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements.Primitives;
diff --git a/TUI.Core/Elements/UIContainerBase.cs b/TUI.Core/Elements/UIContainerBase.cs
index 991072e..916e681 100644
--- a/TUI.Core/Elements/UIContainerBase.cs
+++ b/TUI.Core/Elements/UIContainerBase.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements;
diff --git a/TUI.Core/Elements/UIElementBase.cs b/TUI.Core/Elements/UIElementBase.cs
index ba5b9c2..fc4c5e4 100644
--- a/TUI.Core/Elements/UIElementBase.cs
+++ b/TUI.Core/Elements/UIElementBase.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Elements;
diff --git a/TUI.Core/Extensions/ServiceCollectionExtensions.cs b/TUI.Core/Extensions/ServiceCollectionExtensions.cs
index 052e141..8683300 100644
--- a/TUI.Core/Extensions/ServiceCollectionExtensions.cs
+++ b/TUI.Core/Extensions/ServiceCollectionExtensions.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Extensions;
diff --git a/TUI.Core/Models/Dimensions.cs b/TUI.Core/Models/Dimensions.cs
index 361eec5..2aee73c 100644
--- a/TUI.Core/Models/Dimensions.cs
+++ b/TUI.Core/Models/Dimensions.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/InputModifiers.cs b/TUI.Core/Models/InputModifiers.cs
index 88c6d24..1af320d 100644
--- a/TUI.Core/Models/InputModifiers.cs
+++ b/TUI.Core/Models/InputModifiers.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/InputResult.cs b/TUI.Core/Models/InputResult.cs
index 002f501..28dac20 100644
--- a/TUI.Core/Models/InputResult.cs
+++ b/TUI.Core/Models/InputResult.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/InputType.cs b/TUI.Core/Models/InputType.cs
index e639beb..0786d48 100644
--- a/TUI.Core/Models/InputType.cs
+++ b/TUI.Core/Models/InputType.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/Padding.cs b/TUI.Core/Models/Padding.cs
index b43c1e5..12f8a16 100644
--- a/TUI.Core/Models/Padding.cs
+++ b/TUI.Core/Models/Padding.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/Position.cs b/TUI.Core/Models/Position.cs
index 472580f..5ba825d 100644
--- a/TUI.Core/Models/Position.cs
+++ b/TUI.Core/Models/Position.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Models/TextStyle.cs b/TUI.Core/Models/TextStyle.cs
index 4ce5580..83ab7dd 100644
--- a/TUI.Core/Models/TextStyle.cs
+++ b/TUI.Core/Models/TextStyle.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Models;
diff --git a/TUI.Core/Services/SpectreConsoleProvider.cs b/TUI.Core/Services/SpectreConsoleProvider.cs
index 294a8c3..1370e9c 100644
--- a/TUI.Core/Services/SpectreConsoleProvider.cs
+++ b/TUI.Core/Services/SpectreConsoleProvider.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Services;
diff --git a/TUI.Core/Services/UIApplication.cs b/TUI.Core/Services/UIApplication.cs
index 85a0765..54d2502 100644
--- a/TUI.Core/Services/UIApplication.cs
+++ b/TUI.Core/Services/UIApplication.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Services;
diff --git a/TUI.Core/Services/UIApplicationBuilder.cs b/TUI.Core/Services/UIApplicationBuilder.cs
index 1e7ce5c..87af8ab 100644
--- a/TUI.Core/Services/UIApplicationBuilder.cs
+++ b/TUI.Core/Services/UIApplicationBuilder.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Core.Services;
diff --git a/TUI.Test/AssemblyInfo.cs b/TUI.Test/AssemblyInfo.cs
index 3dad956..8c2c96f 100644
--- a/TUI.Test/AssemblyInfo.cs
+++ b/TUI.Test/AssemblyInfo.cs
@@ -1,5 +1,3 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
[assembly: Microsoft.VisualStudio.TestTools.UnitTesting.Parallelize(Scope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope.MethodLevel)]
diff --git a/TUI.Test/BorderElementTests.cs b/TUI.Test/BorderElementTests.cs
index 7c3f7ee..58c1065 100644
--- a/TUI.Test/BorderElementTests.cs
+++ b/TUI.Test/BorderElementTests.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Test;
@@ -176,7 +174,7 @@ public void BorderElementSetChildUpdatesChildProperty()
// Assert
Assert.AreEqual(childElement, borderElement.Child);
- Assert.AreEqual(borderElement, childElement.Parent);
+ Assert.AreSame(borderElement, childElement.Parent);
}
///
@@ -254,7 +252,7 @@ public void BorderElementConstructorWithChildSetsPropertiesCorrectly()
// Assert
Assert.AreEqual(childElement, borderElement.Child);
- Assert.AreEqual(borderElement, childElement.Parent);
+ Assert.AreSame(borderElement, childElement.Parent);
}
///
diff --git a/TUI.Test/ModelsTests.cs b/TUI.Test/ModelsTests.cs
index be565c5..f85a6b7 100644
--- a/TUI.Test/ModelsTests.cs
+++ b/TUI.Test/ModelsTests.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Test;
diff --git a/TUI.Test/SampleTests.cs b/TUI.Test/SampleTests.cs
index 70a2b0b..96693f4 100644
--- a/TUI.Test/SampleTests.cs
+++ b/TUI.Test/SampleTests.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Test;
diff --git a/TUI.Test/StackPanelTests.cs b/TUI.Test/StackPanelTests.cs
index bfb850a..f0e1642 100644
--- a/TUI.Test/StackPanelTests.cs
+++ b/TUI.Test/StackPanelTests.cs
@@ -1,6 +1,4 @@
-// Copyright (c) ktsu.dev
-// All rights reserved.
-// Licensed under the MIT license.
+// Copyright (c) 2023-2026 ktsu-dev contributors
namespace ktsu.TUI.Test;
@@ -122,7 +120,7 @@ public void StackPanelAddChildAddsChildToCollection()
// Assert
Assert.HasCount(1, stackPanel.Children);
Assert.AreEqual(child, stackPanel.Children.First());
- Assert.AreEqual(stackPanel, child.Parent);
+ Assert.AreSame(stackPanel, child.Parent);
}
///
diff --git a/global.json b/global.json
index 15c86b6..39f7683 100644
--- a/global.json
+++ b/global.json
@@ -5,15 +5,15 @@
},
"msbuild-sdks": {
"MSTest.Sdk": "4.3.3",
- "ktsu.Sdk": "2.18.0",
- "ktsu.Sdk.ConsoleApp": "2.18.0",
- "ktsu.Sdk.Tool": "2.18.0",
- "ktsu.Sdk.App": "2.18.0",
- "ktsu.Sdk.Windows": "2.18.0",
- "ktsu.Sdk.Linux": "2.18.0",
- "ktsu.Sdk.macOS": "2.18.0",
- "ktsu.Sdk.iOS": "2.18.0",
- "ktsu.Sdk.Android": "2.18.0"
+ "ktsu.Sdk": "2.21.1",
+ "ktsu.Sdk.ConsoleApp": "2.21.1",
+ "ktsu.Sdk.Tool": "2.21.1",
+ "ktsu.Sdk.App": "2.21.1",
+ "ktsu.Sdk.Windows": "2.21.1",
+ "ktsu.Sdk.Linux": "2.21.1",
+ "ktsu.Sdk.macOS": "2.21.1",
+ "ktsu.Sdk.iOS": "2.21.1",
+ "ktsu.Sdk.Android": "2.21.1"
},
"test": {
"runner": "Microsoft.Testing.Platform"