diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..622db8e
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,69 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-format": {
+ "version": "5.1.250801",
+ "commands": [
+ "dotnet-format"
+ ],
+ "rollForward": false
+ },
+ "dotnet-stryker": {
+ "version": "4.0.6",
+ "commands": [
+ "dotnet-stryker"
+ ],
+ "rollForward": false
+ },
+ "winsharpfuzz.commandline": {
+ "version": "1.0.0",
+ "commands": [
+ "winsharpfuzz"
+ ],
+ "rollForward": false
+ },
+ "winsharpfuzz.instrument": {
+ "version": "1.0.0",
+ "commands": [
+ "winsharpfuzz-instrument"
+ ],
+ "rollForward": false
+ },
+ "sharpfuzz.commandline": {
+ "version": "2.1.1",
+ "commands": [
+ "sharpfuzz"
+ ],
+ "rollForward": false
+ },
+ "dotnet-reportgenerator-globaltool": {
+ "version": "5.3.7",
+ "commands": [
+ "reportgenerator"
+ ],
+ "rollForward": false
+ },
+ "microsoft.sbom.dotnettool": {
+ "version": "2.2.6",
+ "commands": [
+ "sbom-tool"
+ ],
+ "rollForward": false
+ },
+ "husky": {
+ "version": "0.7.0",
+ "commands": [
+ "husky"
+ ],
+ "rollForward": false
+ },
+ "dotnet-validate": {
+ "version": "0.0.1-preview.304",
+ "commands": [
+ "dotnet-validate"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a4ac02a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,307 @@
+# Remove the line below if you want to inherit .editorconfig settings from higher directories
+root = true
+
+# C# files
+[*.cs]
+
+# Spell checker
+[*]
+spelling_languages = en-US
+spelling_checkable_types = strings,identifiers,comments
+spelling_error_severity = information
+spelling_exclusion_path = ./spellcheckerexclusion.dic
+spelling_use_default_exclusion_dictionary = true
+
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = false
+file_header_template = unset
+
+# Warning and severity.
+dotnet_diagnostic.CA1416.severity = error
+
+# Code analyzers.
+dotnet_diagnostic.CA1307.severity = error
+dotnet_diagnostic.CA1309.severity = error
+dotnet_diagnostic.CA1311.severity = error
+dotnet_diagnostic.CA1815.severity = error
+dotnet_diagnostic.CA1825.severity = error
+
+# nullability checks.
+dotnet_diagnostic.IDE0029.severity = error
+dotnet_diagnostic.IDE0031.severity = error
+dotnet_diagnostic.IDE0041.severity = error
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false
+dotnet_style_qualification_for_field = false
+dotnet_style_qualification_for_method = false
+dotnet_style_qualification_for_property = false
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true
+dotnet_style_predefined_type_for_member_access = true
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true
+dotnet_style_collection_initializer = true
+dotnet_style_explicit_tuple_names = true
+dotnet_style_namespace_match_folder = true
+dotnet_style_null_propagation = true
+dotnet_style_object_initializer = true
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true
+dotnet_style_prefer_compound_assignment = true
+dotnet_style_prefer_conditional_expression_over_assignment = true
+dotnet_style_prefer_conditional_expression_over_return = true
+dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+dotnet_style_prefer_simplified_boolean_expressions = true
+dotnet_style_prefer_simplified_interpolation = true
+
+# Field preferences
+dotnet_style_readonly_field = true
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all
+
+# Suppression preferences
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+# New line preferences
+dotnet_style_allow_multiple_blank_lines_experimental = true
+dotnet_style_allow_statement_immediately_after_block_experimental = true
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_for_built_in_types = false:suggestion
+csharp_style_var_when_type_is_apparent = false:none
+csharp_style_var_elsewhere = false:suggestion
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true
+csharp_style_prefer_switch_expression = true
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true
+
+# Modifier preferences
+csharp_prefer_static_local_function = true
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion
+
+# Code-block preferences
+csharp_prefer_braces = true:silent
+csharp_prefer_simple_using_statement = false:suggestion
+csharp_style_namespace_declarations = block_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true
+csharp_style_deconstructed_variable_declaration = true
+csharp_style_implicit_object_creation_when_type_is_apparent = true
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_prefer_index_operator = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_prefer_range_operator = true
+csharp_style_prefer_tuple_swap = true
+csharp_style_prefer_utf8_string_literals = true
+csharp_style_throw_expression = true
+csharp_style_unused_value_assignment_preference = discard_variable
+csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:silent
+
+# New line preferences
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
+csharp_style_allow_embedded_statements_on_same_line_experimental = true
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = false
+csharp_indent_labels = flush_left
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_before_attribute_colon = false
+csharp_space_after_attribute_colon = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_before_type_parameter_constraint_colon = false
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = false
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = false
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+csharp_style_prefer_primary_constructors = true:suggestion
+
+# C++ Files
+[*.{cpp,h,in}]
+curly_bracket_next_line = true
+indent_brace_style = Allman
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
+indent_size = 2
+
+[*.{csproj,vbproj,proj,nativeproj,locproj}]
+charset = utf-8
+
+# Xml build files
+[*.builds]
+indent_size = 2
+
+# Xml files
+[*.{xml,stylecop,resx,ruleset}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,config,nuspec}]
+indent_size = 2
+
+# YAML config files
+[*.{yml,yaml}]
+indent_size = 2
+
+# Shell scripts
+[*.sh]
+end_of_line = lf
+[*.{cmd,bat}]
+end_of_line = crlf
+
+[*.{cs,vb}]
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+indent_size = 4
+end_of_line = crlf
+dotnet_style_prefer_collection_expression = true:suggestion
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a57a77c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,54 @@
+# Auto detect text files
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.vb diff=csharp
+*.fs diff=csharp
+*.fsi diff=csharp
+*.fsx diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
+
+# LFS
+*.png binary
+*.jpg binary
+*.tga binary
+*.psd binary
+*.gif binary
+*.docx binary
+*.pptx binary
+*.bin binary
+*.exe binary
+test/Verifiable.FuzzTests/libfuzzer-dotnet-ubuntu binary
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.jffs2 filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.a filter=lfs diff=lfs merge=lfs -text
+*.pdf filter=lfs diff=lfs merge=lfs -text
+*.exe filter=lfs diff=lfs merge=lfs -text
+*.apk filter=lfs diff=lfs merge=lfs -text
+*.avi filter=lfs diff=lfs merge=lfs -text
+*.chm filter=lfs diff=lfs merge=lfs -text
+*.mp4 filter=lfs diff=lfs merge=lfs -text
+*.wma filter=lfs diff=lfs merge=lfs -text
+*.ldf filter=lfs diff=lfs merge=lfs -text
+*.mdf filter=lfs diff=lfs merge=lfs -text
+*.mp4 filter=lfs diff=lfs merge=lfs -text
+*.mp3 filter=lfs diff=lfs merge=lfs -text
+*.wav filter=lfs diff=lfs merge=lfs -text
+*.myo filter=lfs diff=lfs merge=lfs -text
+*.vsmdi filter=lfs diff=lfs merge=lfs -text
+*.vsmdi filter=lfs diff=lfs merge=lfs -text
+
+
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..7ca1035
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,11 @@
+# https://help.github.com/articles/about-codeowners/
+
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence, they will
+# be requested for review when someone opens a PR.
+* @veikkoeeva
+
+# Order is important; the last matching pattern takes the most
+# precedence. When someone opens a PR that only modifies
+# .yml files, only the following people and NOT the global
+# owner(s) will be requested for a review.
\ No newline at end of file
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..d7ade82
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,84 @@
+
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at
+[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..d386b79
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,192 @@
+# Contributing Guidelines
+
+*Issues, pull requests, bug reports, stars and all other forms of contribution are welcomed and much appreciated!*
+
+### Contents
+
+- [Code of Conduct](#book-code-of-conduct)
+- [Asking Questions](#bulb-asking-questions)
+- [Opening an Issue](#inbox_tray-opening-an-issue)
+- [Feature Requests](#love_letter-feature-requests)
+- [Triaging Issues](#mag-triaging-issues)
+- [Submitting Pull Requests](#repeat-submitting-pull-requests)
+- [Writing Commit Messages](#memo-writing-commit-messages)
+- [Code Review](#white_check_mark-code-review)
+- [Coding Style](#nail_care-coding-style)
+- [Certificate of Origin](#medal_sports-certificate-of-origin)
+- [Credits](#pray-credits)
+
+> **This guide sets expectations for everyone involved with this project. This way we can improve it together while also creating a welcoming space for everyone to participate. Following these guidelines will help ensure a positive experience for contributors and maintainers. If you come up with improvement, like a more positive tone or point of view, please do open an issue and do tell.**
+
+## :book: Code of Conduct
+
+Please review our [Code of Conduct](CODE_OF_CONDUCT.md). It is in effect at all times. We expect it to be honored by everyone who contributes to this project.
+
+## :bulb: Asking Questions
+
+See our [Support Guide](SUPPORT.md).
+
+## :inbox_tray: Opening an Issue
+
+Before [creating an issue](https://help.github.com/en/github/managing-your-work-on-github/creating-an-issue), check if you are using the latest version of the project. If you are not up-to-date, see if updating fixes your issue first. Also note this software is still in alpha phase.
+
+### :lock: Reporting Security Issues
+
+Review our [Security Policy](SECURITY.md).
+
+### :beetle: Bug Reports and Other Issues
+
+A great way to contribute to the project is to send a detailed issue when you encounter a problem. We always appreciate a well-written, thorough bug report. :v:
+
+If you are a developer, **provide a ticket that you would like to receive**.
+
+- **Review the documentation and [Support Guide](SUPPORT.md)** before opening a new issue.
+
+- **Do not open a duplicate issue!** Please, search existing issues to see if your issue has previously been reported. If your issue exists, comment with any additional information you have. You may simply note "I have this problem too", which helps prioritize the most common problems and requests.
+
+- **Prefer using [reactions](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)**, not comments (e.g. no "+1" comments).
+
+- **Fully complete the provided issue template.** The bug report template requests all the information we need to quickly and efficiently address your issue. Be clear, concise, and descriptive. Provide as much information as you can, including steps to reproduce, stack traces, compiler errors, library versions, OS versions, and screenshots (if applicable).
+
+- **Use [GitHub-flavored Markdown](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).** Especially put code blocks and console outputs in backticks (```).
+
+## :love_letter: Feature Requests
+
+Feature requests are apprciated and welcome! While we will consider all requests, we cannot guarantee your request will be accepted. We want to avoid [feature creep](https://en.wikipedia.org/wiki/Feature_creep). Your idea may be great, but also out-of-scope for the project. If accepted, we cannot make any commitments regarding the timeline for implementation and release. However, you are welcome to submit a pull request to help!
+
+- **Do not open a duplicate feature request.** Search for existing feature requests first. If you find your feature (or one very similar) previously requested, comment on that issue.
+
+- **Fully complete the provided issue template.** The feature request template asks for all necessary information for us to begin a productive conversation.
+
+- Be precise about the proposed outcome of the feature and how it relates to existing features. Include implementation details if possible.
+
+## :mag: Triaging Issues
+
+You can triage issues which may include reproducing bug reports or asking for additional information, such as version numbers or reproduction instructions. Any help you can provide to quickly resolve an issue is much appreciated!
+
+## :repeat: Submitting Pull Requests
+
+We **love** pull requests! Before [forking the repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) and [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) for non-trivial changes, it is usually best to first open an issue to discuss the changes, or discuss your intended approach for solving the problem in the comments for an existing issue.
+
+For most contributions, after your first pull request is accepted and merged, you will be [invited to the project](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) and given **push access**. :tada:
+
+*Note: All contributions will be licensed under the project's license.*
+
+- **Smaller is better.** Submit **one** pull request per bug fix or feature. A pull request should contain isolated changes pertaining to a single bug fix or feature implementation. **Do not** refactor or reformat code that is unrelated to your change. It is better to **submit many small pull requests** rather than a single large one. Enormous pull requests will take enormous amounts of time to review, or may be rejected altogether.
+
+- **Coordinate bigger changes.** For large and non-trivial changes, open an issue to discuss a strategy with the maintainers. Otherwise, you risk doing a lot of work for nothing!
+
+- **Prioritize understanding over cleverness.** Source code usually gets written once and read often. The purpose and logic should be obvious to a reasonably skilled developer, otherwise you should add a comment that explains it. It is all right and encouraged to add comments to code based on review and other discussions.
+
+- **Follow existing coding style and conventions.** Keep your code consistent with the style, formatting, and conventions in the rest of the code base. When possible, these will be enforced with a linter. Consistency makes it easier to review and modify in the future.
+
+- **Include test coverage.** Add unit tests or UI tests when possible. Follow existing patterns for implementing tests.
+
+- **Update the example project** if one exists to exercise any new functionality you have added.
+
+- **Add documentation.** Document your changes with code doc comments or in existing guides.
+
+- **Update the CHANGELOG** for all enhancements and bug fixes. Include the corresponding issue number if one exists, and your GitHub username. (example: "- Fixed crash in profile view. #123 @jessesquires")
+
+- **Use the repo's default branch.** Branch from and [submit your pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) to the repo's default branch (`main`).
+
+- **[Resolve any merge conflicts](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github)** that occur.
+
+- **Address CI failures**. If your pull request fails to build or pass tests, please push another commit to fix it. It is OK if it takes a while to do so or requires some team work.
+
+- When writing comments, use properly constructed sentences, including punctuation.
+
+
+## :memo: Writing Commit Messages
+
+Please [write a great commit message](https://chris.beams.io/posts/git-commit/).
+
+1. Separate subject from body with a blank line
+2. Limit the subject line to 50 characters
+3. Capitalize the subject line
+4. Do not end the subject line with a period
+5. Use the imperative mood in the subject line (example: "Fix networking issue")
+6. Wrap the body at about 72 characters
+7. Use the body to explain **why**, *not what and how* (the code shows that!)
+8. If applicable, prefix the title with the relevant component name. (examples: "[Docs] Fix typo", "[Profile] Fix missing avatar")
+
+```
+[TAG] Short summary of changes in 50 chars or less
+
+Add a more detailed explanation here, if necessary. Possibly give
+some background about the issue being fixed, etc. The body of the
+commit message can be several paragraphs. Further paragraphs come
+after blank lines and please do proper word-wrap.
+
+Wrap it to about 72 characters or so. In some contexts,
+the first line is treated as the subject of the commit and the
+rest of the text as the body. The blank line separating the summary
+from the body is critical (unless you omit the body entirely);
+various tools like `log`, `shortlog` and `rebase` can get confused
+if you run the two together.
+
+Explain the problem that this commit is solving. Focus on why you
+are making this change as opposed to how or what. The code explains
+how or what. Reviewers and your future self can read the patch,
+but might not understand why a particular solution was implemented.
+Are there side effects or other unintuitive consequences of this
+change? Here's the place to explain them.
+
+ - Bullet points are okay, too
+
+ - A hyphen or asterisk should be used for the bullet, preceded
+ by a single space, with blank lines in between
+
+Note the fixed or relevant GitHub issues at the end:
+
+Resolves: #123
+See also: #456, #789
+```
+
+## :white_check_mark: Code Review
+
+- **Review the code, not the author.** Look for and suggest improvements without disparaging or insulting the author. Provide actionable feedback and explain your reasoning.
+
+- **You are not your code.** When your code is critiqued, questioned, or constructively criticized, remember that you are not your code. Do not take code review personally.
+
+- **Make at least for a reasonably good effort.** No one writes bugs on purpose. Good effort should be enough nobody's at their best all the time).
+
+- Kindly note any violations to the guidelines specified in this document.
+
+## :nail_care: Coding Style
+
+Please, follow the existing style, formatting, and naming conventions of the file you are modifying and of the overall project. If you are new to .NET, [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) and linters helps here. This can also be fixed in review and even after merge. This way reviewing is easier and can focus more on improving its functionality and performance.
+
+For example, if all private properties are prefixed with an underscore `_`, then new ones you add should be prefixed in the same way. Or, if methods are named using camelcase, like `thisIsMyNewMethod`, then do not diverge from that by writing `this_is_my_new_method`. You get the idea. If in doubt, please ask or search the codebase for something similar.
+
+When possible, style and format will be enforced with a linter.
+
+## :medal_sports: Certificate of Origin
+
+*Developer's Certificate of Origin 1.1*
+
+By making a contribution to this project, I certify that:
+
+> 1. The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
+> 2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
+> 3. The contribution was provided directly to me by some other person who certified (1), (2) or (3) and I have not modified it.
+> 4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
+
+## [No Brown M&M's](https://en.wikipedia.org/wiki/Van_Halen#Contract_riders)
+
+If you are reading this, bravo dear user and (hopefully) contributor for making it this far! You are awesome. :100:
+
+## :pray: Credits
+
+This considers [GitHub Minimum Viable Governance](https://github.com/github/MVG) and is adapted from [@jessesquires](https://github.com/jessesquires), who in turn writes:
+
+> **Please feel free to adopt this guide in your own projects. Fork it wholesale or remix it for your needs.**
+>
+> *Many of the ideas and prose for the statements in this document were based on or inspired by work from the following communities:*
+>
+> - [Alamofire](https://github.com/Alamofire/Alamofire/blob/master/CONTRIBUTING.md)
+> - [CocoaPods](https://github.com/CocoaPods/CocoaPods/blob/master/CONTRIBUTING.md)
+> - [Docker](https://github.com/moby/moby/blob/master/CONTRIBUTING.md)
+> - [Linux](https://elinux.org/Developer_Certificate_Of_Origin)
+>
+> *We commend them for their efforts to facilitate collaboration in their projects.*
\ No newline at end of file
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 0000000..51f48b9
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,15 @@
+# Security Policy
+
+If you discover a security issue, please open an issue about it.
+
+## Reporting a Vulnerability
+
+This project is still in pre-alpha.
+
+## Supported Versions
+
+There are currently no supported versions.
+
+## Useful security standards
+
+[NIST: Recommended Minimum Standard for Vendor or Developer Verification of Code](https://www.nist.gov/itl/executive-order-improving-nations-cybersecurity/recommended-minimum-standard-vendor-or-developer).
\ No newline at end of file
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
new file mode 100644
index 0000000..c76bd5b
--- /dev/null
+++ b/.github/SUPPORT.md
@@ -0,0 +1,31 @@
+# Support and Help
+
+This project is still in alpha phase.
+
+## How to get help
+
+We do not use GitHub as a support forum general questions or questions specific to your particular project. Asking on [Stack Overflow](https://stackoverflow.com) or other forums, such as [TPM.DEV](https://developers.tpm.dev/), are better for these questions. By doing so, you are more likely to quickly solve your problem, and you will allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.
+
+Please seek support in the following ways:
+
+1. :book: **Read the documentation and other guides** for the project to see if you can figure it out on your own. These should be located in a root `docs/` directory. If there is an example project, explore that to learn how it works to see if you can answer your question.
+
+1. :bulb: **Search for answers and ask questions on [Stack Overflow](https://stackoverflow.com).** This is the most appropriate place for debugging issues specific to your use of the project, or figuring out how to use the project in a specific way.
+
+1. :memo: As a **last resort**, you may open an issue on GitHub to ask for help. However, please clearly explain what you are trying to do, and list what you have already attempted to solve the problem. Provide code samples, but **do not** attach your entire project for someone else to debug. Review our [contributing guidelines](CONTRIBUTING.md).
+
+## What NOT to do
+
+Please **do not** do any the following:
+
+1. :x: Do not reach out to authors or contributors on Twitter (or other social media) by tweeting or sending a direct message.
+
+1. :x: Do not email the authors or contributors.
+
+1. :x: Do not open duplicate issues or litter an existing issue with +1's.
+
+These are not appropriate avenues for seeking help or support with an open-source project. Please follow the guidelines in the previous section. Public questions get public answers, which benefits everyone in the community. ✌️
+
+## Customer Support
+
+There is no any sort of customer support for this project on behalf of Lumoin currently. Consulting is possible. One place to contact for hardware specific consultation could be [TPM.DEV](https://developers.tpm.dev/).
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..be0b86f
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,30 @@
+# See more at
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: nuget
+ directory: '/'
+ schedule:
+ interval: daily
+ time: '05:00'
+ timezone: Etc/GMT
+ labels:
+ - dependencies
+ commit-message:
+ prefix: ci
+ prefix-development: chore
+ include: scope
+
+ - package-ecosystem: github-actions
+ directory: '/'
+ schedule:
+ interval: daily
+ time: '05:00'
+ timezone: Etc/GMT
+ labels:
+ - dependencies
+ commit-message:
+ prefix: ci
+ prefix-development: chore
+ include: scope
\ No newline at end of file
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..07a9d62
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,55 @@
+name: "CoreLoop CodeQL analysis"
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ - develop
+ # pull_request:
+ # branches:
+ # - main
+ # paths-ignore:
+ # - "**.md"
+ schedule:
+ # A daily build to check all is still functioning.
+ - cron: "0 0 * * *"
+
+jobs:
+ analyze:
+ name: CodeQL Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: 'csharp'
+ build-mode: none
+ queries: security-and-quality
+
+ - uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
+ with:
+ global-json-file: global.json
+
+ - name: Autobuild
+ if: ${{ github.actor != 'dependabot[bot]' }}
+ uses: github/codeql-action/autobuild@v3
+
+ - name: CodeQL Analysis
+ if: ${{ github.actor != 'dependabot[bot]' }}
+ uses: github/codeql-action/analyze@v3
+ timeout-minutes: 100
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..0573468
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,346 @@
+name: CoreLoop .NET build
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ pull_request:
+ paths-ignore:
+ - "**.md"
+ release:
+ types:
+ - published
+
+ schedule:
+ # A daily build to check all is still functioning.
+ - cron: "0 0 * * *"
+
+env:
+ # This environment variable is checked in tests.
+ # For TPM either a Windows simulator or a platform TPM is used.
+ # Tests check that platform TPM tests must be run on Windows or Linux,
+ # MacOS tests are skipped.
+ USE_PLATFORM_TPM: true
+
+ DOTNET_ENVIRONMENT: CI
+ BUILD_CONFIGURATION: Release
+ DOTNET_CLI_TELEMETRY_OPTOUT: true
+ DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
+ DOTNET_NOLOGO: true
+ NUGET_XMLDOC_MODE: skip
+ NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
+ NUGET_FEED: https://api.nuget.org/v3/index.json
+ GITHUB_USER: ${{ github.repository_owner }}
+ GITHUB_FEED: https://nuget.pkg.github.com/lumoin/
+
+ # These are the Nuget packages that will be packed and uploaded.
+ CORELOOP_UNTP: CoreLoop.Untp
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
+
+ steps:
+
+ - name: Harden Runner
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
+ with:
+ disable-sudo: true
+ egress-policy: block
+ allowed-endpoints: >
+ dotnetbuilds.azureedge.net:443
+ aka.ms:443
+ api.github.com:443
+ api.nuget.org:443
+ pkgs.dev.azure.com:443
+ dashboard.stryker-mutator.io:443
+ dotnetcli.azureedge.net:443
+ github.com:443
+ nuget.pkg.github.com:443
+ api.clearlydefined.io:443
+ cacerts.digicert.com:80
+ ts-crl.ws.symantec.com:80
+ crl3.digicert.com:80
+ crl4.digicert.com:80
+ s.symcb.com:80
+ ocsp.digicert.com:80
+
+ # Windows builds may have insufficient resource limits, so they're increased.
+ - name: Configure Windows Pagefile
+ if: ${{ matrix.os == 'windows-latest' }}
+ uses: al-cheb/configure-pagefile-action@a3b6ebd6b634da88790d9c58d4b37a7f4a7b8708
+ with:
+ minimum-size: 8GB
+ maximum-size: 32GB
+ disk-root: "D:"
+
+ - name: Checkout code
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
+ with:
+ fetch-depth: 0
+ fetch-tags: true
+
+ - name: Cache Nuget packages '${{ matrix.os }}'
+ uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
+ with:
+ path: ${{ env.NUGET_PACKAGES }}
+ key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
+ restore-keys: |
+ ${{runner.os}}-nuget-
+
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee
+ with:
+ global-json-file: global.json
+
+ - name: Install dependencies
+ run: dotnet restore --locked-mode
+
+ - name: Restore local .NET tools
+ run: dotnet tool restore
+
+ - name: Add Problem Matcher for dotnet-format
+ uses: xt0rted/dotnet-format-problem-matcher@b90c4f18e3daa4f8fd266e41eba4f351b2e00b75
+
+ # - name: Run dotnet format
+ # run: dotnet format --check
+
+ # The version numbers are determined and set here so it can be set appropriately to code and NuGet packages.
+ # See explanation at https://dusted.codes/github-actions-for-dotnet-core-nuget-packages.
+ - name: Set NuGet packages and suffix version
+ run: |
+ # Bash script to determine the version and version suffix for CI/CD
+ # Use git to find the latest tag; if none are found, default to "0.0.1".
+ latestTag=$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.1)
+
+ # Case 1: A release is being created.
+ # Extract the version from the tag and add a suffix with the short SHA.
+ if [[ $GITHUB_EVENT_NAME == 'release' ]]; then
+ # Extract the version number from the release tag and remove any 'v' prefix.
+ arrTag=(${GITHUB_REF//\// })
+ VERSION="${arrTag[2]}"
+ VERSION="${VERSION//v}"
+ # Set PACKAGE_VERSION and VERSION, and add a VERSION_SUFFIX for clarity in identifying the release and commit.
+ echo "PACKAGE_VERSION=${VERSION}+${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
+ echo "TAG_VERSION=${VERSION}" >> "$GITHUB_ENV"
+
+ # Case 2: The 'develop' branch.
+ # Use the latestTag as the base version and add a suffix with "develop", the run_id, and the short SHA.
+ elif [[ $GITHUB_REF == 'refs/heads/develop' ]]; then
+ # Set PACKAGE_VERSION and PACKAGE, and add a VERSION_SUFFIX for clarity in identifying the development build, run, and commit.
+ echo "PACKAGE_VERSION=${latestTag//v}-develop.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ echo "VERSION=${latestTag//v}-develop.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ echo "TAG_VERSION=${latestTag//v}" >> "$GITHUB_ENV"
+
+ # Case 3: Any other build (e.g., feature branches).
+ # Use the latestTag as the base version and add a suffix with "build", the run_id, and the short SHA.
+ else
+ # Set PACKAGE_VERSION and VERSION, and add a VERSION_SUFFIX for clarity in identifying the build, run, and commit.
+ echo "PACKAGE_VERSION=${latestTag//v}-build.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ echo "VERSION=${latestTag//v}-build.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ echo "TAG_VERSION=${latestTag//v}" >> "$GITHUB_ENV"
+ fi
+ shell: bash
+
+ - name: Build
+ # At the moment CoreLoop.Tests cannot be built with -isolate alone due to Coverlet.
+ run: dotnet build --binaryLogger --tl --graphBuild -isolate:MessageUponIsolationViolation --configuration ${{ env.BUILD_CONFIGURATION }} --no-restore --property:ContinuousIntegrationBuild=true --property:Version=${{ env.VERSION }} --property:InformationalVersion=${{ env.PACKAGE_VERSION }} --property:AssemblyVersion=${{ env.TAG_VERSION }} --property:FileVersion=${{ env.TAG_VERSION }}
+ timeout-minutes: 5
+
+ # - name: Set PR markdown title name
+ # run: |
+ # echo "title=Test Run (${{ github.run_number }})" >> $GITHUB_ENV
+ # echo "file_name=TestReport.${{ github.run_number }}.md" >> $GITHUB_ENV
+ # shell: bash
+
+ - name: Test
+ # See the difference on drivers and paths at https://github.com/microsoft/vstest/issues/2378 and further
+ # here on generating the reports.
+ # run: dotnet test --verbosity normal --no-restore --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --property:CollectCoverage=true --property:CoverletOutputFormat=cobertura --property:DeterministicSourcePaths=true --property:IncludeTestAssembly=true --property:CoverletOutput='${{ github.workspace }}/reports/coverage/'
+ run: dotnet test --collect:"XPlat Code Coverage" --verbosity normal --no-restore --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --logger JUnit -property:DeterministicSourcePaths=true -property:IncludeTestAssembly=true --results-directory '${{ github.workspace }}/reports/coverage/'
+ timeout-minutes: 5
+
+ # Mutation tests skipped for now due to CI limits and temporarily reduced test coverage...
+ # This either requires cd to test directory or --solution-path CoreLoop.sln (which may not work).
+ # - name: Stryker.NET mutation Tests for CoreLoop.Untp.csproj
+ # if: ${{ matrix.os == 'ubuntu-latest' }}
+ # run: dotnet stryker --config-file stryker-config.json --reporter progress --reporter html --reporter dashboard --dashboard-api-key ${{ secrets.STRYKER_API_KEY }} --project CoreLoop.UNTransparencyProtocol.csproj
+ # timeout-minutes: 15
+
+ #- name: Upload Stryker output artefacts
+ # if: ${{ matrix.os == 'ubuntu-latest' }}
+ # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
+ # with:
+ # name: 'Stryker output artefacts'
+ # path: ${{ github.workspace }}/StrykerOutput/
+
+ # - name: Publish
+ # run: dotnet publish -c Release --verbosity normal -o ./publish/
+
+ # - name: Archive publish results
+ # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
+ # with:
+ # name: CoreLoop.Benchmarks
+ # path: ./publish/*
+
+ # - name: Run Benchmarks
+ # run: dotnet "./publish/CoreLoop.Benchmarks.dll" -f "CoreLoop.Benchmarks.*"
+
+ # - name: Upload benchmark results
+ # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
+ # with:
+ # name: Benchmark_Results
+ # path: ./BenchmarkDotNet.Artifacts/results/*
+
+ # This step is run always (e.g. also for non-PRs) so the results can be inspected on the command line too.
+ # - name: ReportGenerator
+ # if: ${{ matrix.os == 'ubuntu-latest' }}
+
+ # If not using MSBuild driver but the VSTest one, the files need to be explicitly found due to randomized path segmenets.
+ # See more at https://github.com/microsoft/vstest/issues/2378.
+ # run: dotnet reportgenerator -assemblyfilters:'-xunit*' -reports:'${{ github.workspace }}/reports/coverage/coverage.cobertura.xml' -targetdir:'${{ github.workspace }}/reports/coverage/' -reporttypes:'HtmlInline;Cobertura;MarkdownSummary'
+ # run: dotnet reportgenerator -assemblyfilters:'-xunit*' -reports:`find ${{ github.workspace }}/reports/coverage/ -name coverage.cobertura.xml` -targetdir:'${{ github.workspace }}/reports/coverage/' -reporttypes:'HtmlInline;Cobertura;MarkdownSummary'
+
+ # - name: Publish coverage report
+ # if: ${{ matrix.os == 'ubuntu-latest' }}
+ # uses: 5monkeys/cobertura-action@master
+ # with:
+ # path: '${{ github.workspace }}/reports/coverage/Cobertura.xml'
+ # repo_token: ${{ secrets.GITHUB_TOKEN }}
+ # minimum_coverage: 75
+
+ - name: Publish coverage summary
+ if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }}
+ uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
+ with:
+ header: Report
+ path: '${{ github.workspace }}/reports/coverage/Summary.md'
+ recreate: true
+
+ - name: Create test summary
+ if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }}
+ uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86
+ with:
+ paths: '${{ github.workspace }}/reports/coverage/TestResults.xml'
+ # output: '${{ github.workspace }}/${{ env.file_name }}'
+
+ # - name: Comment PR with the generated test Markdown
+ # if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }}
+ # uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
+ # with:
+ # path: ${{ env.file_name }}
+
+ # - name: Upload PR build information artefact
+ # if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }}
+ # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
+ # with:
+ # name: 'Test Run'
+ # path: ${{ github.workspace }}/${{ env.file_name }}
+
+ # - name: Comment PR with the generated test Markdown
+ # if: ${{ matrix.os == 'ubuntu-latest' }}
+ # uses: machine-learning-apps/pr-comment@78e77cd435e0f9706512ea294d846058ae46f7ff
+ # env:
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # with:
+ # path: ${{ env.file_name }}
+
+ # - name: The sbom-tool does not generate the output directory and fails if it not present.
+ - name: Create SBOM output directory
+ run: mkdir -p "${{ github.workspace }}/${{ matrix.os }}/sbom/"
+
+ # There may a difference in libraries between platforms, so the tool is being run on all platforms.
+ - name: Run BOM analysis
+ run: dotnet tool run sbom-tool generate -DeleteManifestDirIfPresent true -BuildDropPath "${{ github.workspace }}/${{ matrix.os }}/sbom/" -FetchLicenseInformation true -EnablePackageMetadataParsing true -BuildComponentPath . -PackageName "CoreLoop" -PackageSupplier "Lumoin" -NamespaceUriBase "https://lumoin.com/coreloop" -PackageVersion ${{ env.PACKAGE_VERSION }} -Verbosity Verbose
+
+ - name: Pack NuGet files
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ run: |
+ dotnet pack --verbosity normal --configuration ${{ env.BUILD_CONFIGURATION }} --no-build --output nupkgs --property:PackageVersion=$PACKAGE_VERSION src/$CORELOOP_UNTP/$CORELOOP_UNTP.*proj
+
+ # Note that on Windows this would be simply "dotnet dotnet-validate package local ./snupkgs/*.nupkg", the handling of an array of paths works directly.
+ - name: Validate generated NuGet files
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ run: |
+ for file in ./nupkgs/*.nupkg; do
+ dotnet dotnet-validate package local "$file"
+ done
+
+ - name: Upload CoreLoop NuGet packages
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
+ with:
+ name: nupkg
+ path: ./nupkgs/*.*
+
+ # The release idea is inspired by https://dusted.codes/github-actions-for-dotnet-core-nuget-packages.
+ prerelease:
+ permissions:
+ # For setup-dotnet to create package.
+ packages: write
+ needs: build
+ if: ${{ github.ref == 'refs/heads/develop' && github.repository_owner == 'lumoin' }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Harden Runner
+ uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
+ with:
+ disable-sudo: true
+ egress-policy: block
+ allowed-endpoints: >
+ aka.ms:443
+ api.github.com:443
+ api.nuget.org:443
+ dashboard.stryker-mutator.io:443
+ dotnetcli.azureedge.net:443
+ github.com:443
+ nuget.pkg.github.com:443
+ api.clearlydefined.io:443
+
+ - name: Download NuGet artifacts
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
+ with:
+ name: nupkg
+
+ - name: Push to GitHub developer feed
+ run: dotnet nuget push "**/*.nupkg" --source $GITHUB_FEED --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
+
+ deploy:
+ permissions:
+ # For setup-dotnet to create package.
+ packages: write
+ needs: build
+ if: ${{ github.event_name == 'release' && github.repository_owner == 'lumoin' }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Harden Runner
+ uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
+ with:
+ disable-sudo: true
+ egress-policy: audit
+ allowed-endpoints: >
+ aka.ms:443
+ api.github.com:443
+ api.nuget.org:443
+ dashboard.stryker-mutator.io:443
+ dotnetcli.azureedge.net:443
+ github.com:443
+ nuget.pkg.github.com:443
+
+ - name: Download NuGet artifacts
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
+ with:
+ name: nupkg
+
+ - name: Push to GitHub developer feed
+ run: dotnet nuget push "**/*.nupkg" --source $GITHUB_FEED --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
+
+ - name: Push to NuGet feed
+ run: dotnet nuget push "**/*.nupkg" --source $NUGET_FEED --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6ac59f5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,370 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Script result directories
+sbom/
+generated-reports/
+generated-nugets/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# Stryker test results
+StrykerOutput/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
\ No newline at end of file
diff --git a/BannedSymbols.txt b/BannedSymbols.txt
new file mode 100644
index 0000000..b34f220
--- /dev/null
+++ b/BannedSymbols.txt
@@ -0,0 +1,2 @@
+P:System.DateTime.Now;Use System.DateTime.UtcNow instead.
+M:System.IO.File.GetCreationTime(System.String);Use GetCreationTimeUtc instead.
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..e8adc60
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,20 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+
+
+## [Unreleased]
+
+## [0.0.0.0] - 2024-09-01
+
diff --git a/CoreLoop.sln b/CoreLoop.sln
new file mode 100644
index 0000000..d0db63c
--- /dev/null
+++ b/CoreLoop.sln
@@ -0,0 +1,81 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.12.35209.166
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreLoop.Untp", "src\CoreLoop.Untp\CoreLoop.Untp.csproj", "{797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{19BA6154-3246-4F4B-94DA-F11D1E9E7FD6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22E2F94D-0070-4D47-8E5A-DF82B3579678}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreLoop.Tests", "test\CoreLoop.Tests\CoreLoop.Tests.csproj", "{16F6E4DA-18F2-46CE-8806-1F85598D3936}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECFBA01C-5FE9-46E8-8CCF-AC458C56F7DB}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ .gitattributes = .gitattributes
+ .gitignore = .gitignore
+ BannedSymbols.txt = BannedSymbols.txt
+ CHANGELOG.md = CHANGELOG.md
+ create-nugets.ps1 = create-nugets.ps1
+ Directory.Build.props = Directory.Build.props
+ Directory.Packages.props = Directory.Packages.props
+ generate-sbom.ps1 = generate-sbom.ps1
+ global.json = global.json
+ LICENSE = LICENSE
+ NuGet.config = NuGet.config
+ README.md = README.md
+ spellcheckerexclusion.dic = spellcheckerexclusion.dic
+ stryker-config.json = stryker-config.json
+ stryker-tests-dev.ps1 = stryker-tests-dev.ps1
+ tests-with-reportgenerator.ps1 = tests-with-reportgenerator.ps1
+ update-dotnet-tools.ps1 = update-dotnet-tools.ps1
+ verify-packages.ps1 = verify-packages.ps1
+ verify-packages.sh = verify-packages.sh
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{054F4985-1C55-407D-AC57-96A79366CA41}"
+ ProjectSection(SolutionItems) = preProject
+ .github\CODEOWNERS = .github\CODEOWNERS
+ .github\CODE_OF_CONDUCT.md = .github\CODE_OF_CONDUCT.md
+ .github\CONTRIBUTING.md = .github\CONTRIBUTING.md
+ .github\dependabot.yml = .github\dependabot.yml
+ .github\SECURITY.md = .github\SECURITY.md
+ .github\SUPPORT.md = .github\SUPPORT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{A245F1E1-7ECF-4664-BFC2-4EB1094F0E09}"
+ ProjectSection(SolutionItems) = preProject
+ .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
+ .github\workflows\main.yml = .github\workflows\main.yml
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3} = {19BA6154-3246-4F4B-94DA-F11D1E9E7FD6}
+ {16F6E4DA-18F2-46CE-8806-1F85598D3936} = {22E2F94D-0070-4D47-8E5A-DF82B3579678}
+ {054F4985-1C55-407D-AC57-96A79366CA41} = {ECFBA01C-5FE9-46E8-8CCF-AC458C56F7DB}
+ {A245F1E1-7ECF-4664-BFC2-4EB1094F0E09} = {054F4985-1C55-407D-AC57-96A79366CA41}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7B04A0D7-B0EF-438C-89BC-66A7A96BD1C2}
+ EndGlobalSection
+EndGlobal
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..9b2f5ec
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,105 @@
+