diff --git a/Mailtrap.sln b/Mailtrap.sln
index 89218e89..519e9c79 100644
--- a/Mailtrap.sln
+++ b/Mailtrap.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
@@ -57,7 +57,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{CD08E7CB-C
CONTRIBUTING.md = CONTRIBUTING.md
LICENSE.md = LICENSE.md
README.md = README.md
- UPGRADE-3.0.md = UPGRADE-3.0.md
+ UPGRADE-3.0.md = UPGRADE-3.0.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.DependencyInjection", "examples\Mailtrap.Example.DependencyInjection\Mailtrap.Example.DependencyInjection.csproj", "{4457969D-4981-4F27-A304-A242DEC9FD92}"
@@ -116,136 +116,402 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.Webhooks",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.SubAccount", "examples\Mailtrap.Example.SubAccount\Mailtrap.Example.SubAccount.csproj", "{D5E6F7A8-1234-5678-9ABC-DEF012345603}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mailtrap.Example.WebhookSignature", "examples\Mailtrap.Example.WebhookSignature\Mailtrap.Example.WebhookSignature.csproj", "{E9478405-3D5D-439C-B0D5-753DC5F2F46D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|x64.Build.0 = Debug|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Debug|x86.Build.0 = Debug|Any CPU
{D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|x64.ActiveCfg = Release|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|x64.Build.0 = Release|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|x86.ActiveCfg = Release|Any CPU
+ {D18E67B4-9179-45A5-94DE-83A8AD7CAA64}.Release|x86.Build.0 = Release|Any CPU
{5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|x64.Build.0 = Debug|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Debug|x86.Build.0 = Debug|Any CPU
{5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|x64.ActiveCfg = Release|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|x64.Build.0 = Release|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|x86.ActiveCfg = Release|Any CPU
+ {5CFBF4CD-D0DE-4901-815C-06317C0AECE8}.Release|x86.Build.0 = Release|Any CPU
{D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|x64.Build.0 = Debug|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Debug|x86.Build.0 = Debug|Any CPU
{D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|x64.ActiveCfg = Release|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|x64.Build.0 = Release|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|x86.ActiveCfg = Release|Any CPU
+ {D3695456-3359-4D97-AE3B-23E2212C8E5F}.Release|x86.Build.0 = Release|Any CPU
{4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|x64.Build.0 = Debug|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Debug|x86.Build.0 = Debug|Any CPU
{4457969D-4981-4F27-A304-A242DEC9FD92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4457969D-4981-4F27-A304-A242DEC9FD92}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Release|x64.ActiveCfg = Release|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Release|x64.Build.0 = Release|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Release|x86.ActiveCfg = Release|Any CPU
+ {4457969D-4981-4F27-A304-A242DEC9FD92}.Release|x86.Build.0 = Release|Any CPU
{B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|x64.Build.0 = Debug|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Debug|x86.Build.0 = Debug|Any CPU
{B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|x64.ActiveCfg = Release|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|x64.Build.0 = Release|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|x86.ActiveCfg = Release|Any CPU
+ {B94183D6-5D5C-4EC4-8F58-7D0D803EA197}.Release|x86.Build.0 = Release|Any CPU
{02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|x64.Build.0 = Debug|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Debug|x86.Build.0 = Debug|Any CPU
{02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|Any CPU.Build.0 = Release|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|x64.ActiveCfg = Release|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|x64.Build.0 = Release|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|x86.ActiveCfg = Release|Any CPU
+ {02122FD2-9990-44CB-B9E1-1C5CDD388629}.Release|x86.Build.0 = Release|Any CPU
{5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|x64.Build.0 = Debug|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Debug|x86.Build.0 = Debug|Any CPU
{5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|x64.ActiveCfg = Release|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|x64.Build.0 = Release|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|x86.ActiveCfg = Release|Any CPU
+ {5CF5E1BC-D209-4EED-A34D-A96474D6189E}.Release|x86.Build.0 = Release|Any CPU
{EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|x64.Build.0 = Debug|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Debug|x86.Build.0 = Debug|Any CPU
{EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|x64.ActiveCfg = Release|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|x64.Build.0 = Release|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|x86.ActiveCfg = Release|Any CPU
+ {EAF0B25B-9DE8-422D-855E-4D0A59DEF316}.Release|x86.Build.0 = Release|Any CPU
{14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|x64.Build.0 = Debug|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Debug|x86.Build.0 = Debug|Any CPU
{14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|x64.ActiveCfg = Release|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|x64.Build.0 = Release|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|x86.ActiveCfg = Release|Any CPU
+ {14FDEACB-4933-423F-B6BA-7BF4E17E954A}.Release|x86.Build.0 = Release|Any CPU
{AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|x64.Build.0 = Debug|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Debug|x86.Build.0 = Debug|Any CPU
{AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|x64.ActiveCfg = Release|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|x64.Build.0 = Release|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|x86.ActiveCfg = Release|Any CPU
+ {AFAF16D5-6BEA-43AA-883D-A7B7B8B98D1B}.Release|x86.Build.0 = Release|Any CPU
{B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|x64.Build.0 = Debug|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Debug|x86.Build.0 = Debug|Any CPU
{B7957D47-EB36-405D-8899-50D208CEFA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7957D47-EB36-405D-8899-50D208CEFA64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Release|x64.ActiveCfg = Release|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Release|x64.Build.0 = Release|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Release|x86.ActiveCfg = Release|Any CPU
+ {B7957D47-EB36-405D-8899-50D208CEFA64}.Release|x86.Build.0 = Release|Any CPU
{45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|x64.Build.0 = Debug|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Debug|x86.Build.0 = Debug|Any CPU
{45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|x64.ActiveCfg = Release|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|x64.Build.0 = Release|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|x86.ActiveCfg = Release|Any CPU
+ {45CBA5F5-DE15-4F1A-9078-949D91773D99}.Release|x86.Build.0 = Release|Any CPU
{5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|x64.Build.0 = Debug|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Debug|x86.Build.0 = Debug|Any CPU
{5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|x64.ActiveCfg = Release|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|x64.Build.0 = Release|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B624EB6-155E-419B-A42E-7C63BFAA80D2}.Release|x86.Build.0 = Release|Any CPU
{8B147171-BECF-4693-8343-4F69E597386C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B147171-BECF-4693-8343-4F69E597386C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Debug|x64.Build.0 = Debug|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Debug|x86.Build.0 = Debug|Any CPU
{8B147171-BECF-4693-8343-4F69E597386C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B147171-BECF-4693-8343-4F69E597386C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Release|x64.ActiveCfg = Release|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Release|x64.Build.0 = Release|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Release|x86.ActiveCfg = Release|Any CPU
+ {8B147171-BECF-4693-8343-4F69E597386C}.Release|x86.Build.0 = Release|Any CPU
{AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Debug|x86.Build.0 = Debug|Any CPU
{AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|x64.Build.0 = Release|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA}.Release|x86.Build.0 = Release|Any CPU
{F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|x64.Build.0 = Debug|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Debug|x86.Build.0 = Debug|Any CPU
{F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|x64.ActiveCfg = Release|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|x64.Build.0 = Release|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|x86.ActiveCfg = Release|Any CPU
+ {F6357CAB-06C6-4603-99E7-1EDB79ACA8E8}.Release|x86.Build.0 = Release|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|x86.Build.0 = Debug|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|x64.Build.0 = Release|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|x86.Build.0 = Release|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|x64.Build.0 = Debug|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|x86.Build.0 = Debug|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|x64.ActiveCfg = Release|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|x64.Build.0 = Release|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|x86.ActiveCfg = Release|Any CPU
+ {3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|x86.Build.0 = Release|Any CPU
{E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|x64.Build.0 = Debug|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Debug|x86.Build.0 = Debug|Any CPU
{E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|x64.ActiveCfg = Release|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|x64.Build.0 = Release|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|x86.ActiveCfg = Release|Any CPU
+ {E7B8C1F2-9A3D-4C2E-8B7A-6D2F3A1E4B5C}.Release|x86.Build.0 = Release|Any CPU
{08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|x64.Build.0 = Debug|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Debug|x86.Build.0 = Debug|Any CPU
{08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|x64.ActiveCfg = Release|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|x64.Build.0 = Release|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|x86.ActiveCfg = Release|Any CPU
+ {08B23D8C-7AAC-4CE7-830C-4DFF9F296BFB}.Release|x86.Build.0 = Release|Any CPU
{5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|x64.Build.0 = Debug|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Debug|x86.Build.0 = Debug|Any CPU
{5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|x64.ActiveCfg = Release|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|x64.Build.0 = Release|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|x86.ActiveCfg = Release|Any CPU
+ {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD}.Release|x86.Build.0 = Release|Any CPU
{AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|x64.Build.0 = Debug|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Debug|x86.Build.0 = Debug|Any CPU
{AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|x64.ActiveCfg = Release|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|x64.Build.0 = Release|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|x86.ActiveCfg = Release|Any CPU
+ {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A}.Release|x86.Build.0 = Release|Any CPU
{A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|x64.Build.0 = Debug|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Debug|x86.Build.0 = Debug|Any CPU
{A52169E1-8653-4B7D-9F14-84837E237E43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A52169E1-8653-4B7D-9F14-84837E237E43}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x64.ActiveCfg = Release|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x64.Build.0 = Release|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x86.ActiveCfg = Release|Any CPU
+ {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x86.Build.0 = Release|Any CPU
{9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|x64.Build.0 = Debug|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|x86.Build.0 = Debug|Any CPU
{9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|x64.ActiveCfg = Release|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|x64.Build.0 = Release|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|x86.ActiveCfg = Release|Any CPU
+ {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Release|x86.Build.0 = Release|Any CPU
{8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|x64.Build.0 = Debug|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Debug|x86.Build.0 = Debug|Any CPU
{8791C343-7B1E-4206-A954-A0CFD573E460}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8791C343-7B1E-4206-A954-A0CFD573E460}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Release|x64.ActiveCfg = Release|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Release|x64.Build.0 = Release|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Release|x86.ActiveCfg = Release|Any CPU
+ {8791C343-7B1E-4206-A954-A0CFD573E460}.Release|x86.Build.0 = Release|Any CPU
{11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|x64.Build.0 = Debug|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Debug|x86.Build.0 = Debug|Any CPU
{11894B20-F780-4FC9-8140-3601EBF54C10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11894B20-F780-4FC9-8140-3601EBF54C10}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Release|x64.ActiveCfg = Release|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Release|x64.Build.0 = Release|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Release|x86.ActiveCfg = Release|Any CPU
+ {11894B20-F780-4FC9-8140-3601EBF54C10}.Release|x86.Build.0 = Release|Any CPU
{B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|x64.Build.0 = Debug|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Debug|x86.Build.0 = Debug|Any CPU
{B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|x64.ActiveCfg = Release|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|x64.Build.0 = Release|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|x86.ActiveCfg = Release|Any CPU
+ {B3E7A1C2-4D5F-6E8A-9B0C-1D2E3F4A5B6C}.Release|x86.Build.0 = Release|Any CPU
{C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|x64.Build.0 = Debug|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Debug|x86.Build.0 = Debug|Any CPU
{C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|x64.ActiveCfg = Release|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|x64.Build.0 = Release|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|x86.ActiveCfg = Release|Any CPU
+ {C4F8B2D3-5E6A-7F9B-0C1D-2E3F4A5B6C7D}.Release|x86.Build.0 = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Debug|x86.Build.0 = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|x64.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345601}.Release|x86.Build.0 = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Debug|x86.Build.0 = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|x64.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345602}.Release|x86.Build.0 = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Debug|x86.Build.0 = Debug|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|x64.Build.0 = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5E6F7A8-1234-5678-9ABC-DEF012345603}.Release|x86.Build.0 = Release|Any CPU
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|Any CPU.ActiveCfg = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|Any CPU.Build.0 = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|x64.ActiveCfg = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|x64.Build.0 = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|x86.ActiveCfg = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Debug|x86.Build.0 = Debug|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|Any CPU.ActiveCfg = Release|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|Any CPU.Build.0 = Release|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|x64.ActiveCfg = Release|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|x64.Build.0 = Release|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|x86.ActiveCfg = Release|anycpu
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D}.Release|x86.Build.0 = Release|anycpu
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -282,6 +548,7 @@ Global
{D5E6F7A8-1234-5678-9ABC-DEF012345601} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
{D5E6F7A8-1234-5678-9ABC-DEF012345602} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
{D5E6F7A8-1234-5678-9ABC-DEF012345603} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
+ {E9478405-3D5D-439C-B0D5-753DC5F2F46D} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0FF614CC-FEBC-4C66-B3FC-FCB73EE511D7}
diff --git a/README.md b/README.md
index 67700dcb..34ddf6c9 100644
--- a/README.md
+++ b/README.md
@@ -277,6 +277,7 @@ private static SendEmailRequest TemplateBasedRequest()
- Email logs (list with filters and pagination; get message details with events) – [`examples/Mailtrap.Example.EmailLogs`](examples/Mailtrap.Example.EmailLogs/)
- Email sending statistics – [`examples/Mailtrap.Example.Stats`](examples/Mailtrap.Example.Stats/)
- Webhooks management – [`examples/Mailtrap.Example.Webhooks`](examples/Mailtrap.Example.Webhooks/)
+- Verifying webhook signatures – [`examples/Mailtrap.Example.WebhookSignature`](examples/Mailtrap.Example.WebhookSignature/)
### Email Sandbox (Testing)
@@ -314,6 +315,28 @@ private static SendEmailRequest TemplateBasedRequest()
Each example includes detailed comments and demonstrates best practices for error handling, configuration, and resource management.
+### Verifying webhook signatures
+
+Mailtrap signs every outbound webhook with HMAC-SHA256 and sends the lowercase hex digest in the `Mailtrap-Signature` header. Verify the signature against the raw request body using the `signing_secret` returned when you created the webhook:
+
+```csharp
+using Mailtrap.Webhooks;
+
+// `payload` must be the unparsed request body — do NOT re-serialize the
+// parsed JSON, as that may reorder keys and invalidate the signature.
+var valid = WebhookSignature.Verify(
+ payload,
+ request.Headers["Mailtrap-Signature"].ToString(),
+ Environment.GetEnvironmentVariable("MAILTRAP_WEBHOOK_SIGNING_SECRET")!);
+
+if (!valid)
+{
+ return Results.Unauthorized();
+}
+```
+
+The helper performs a constant-time comparison and returns `false` (rather than throwing) for empty, missing, or malformed signatures.
+
---
## Documentation
diff --git a/examples/Mailtrap.Example.WebhookSignature/Mailtrap.Example.WebhookSignature.csproj b/examples/Mailtrap.Example.WebhookSignature/Mailtrap.Example.WebhookSignature.csproj
new file mode 100644
index 00000000..6b512ec9
--- /dev/null
+++ b/examples/Mailtrap.Example.WebhookSignature/Mailtrap.Example.WebhookSignature.csproj
@@ -0,0 +1 @@
+
diff --git a/examples/Mailtrap.Example.WebhookSignature/Program.cs b/examples/Mailtrap.Example.WebhookSignature/Program.cs
new file mode 100644
index 00000000..90caa8fc
--- /dev/null
+++ b/examples/Mailtrap.Example.WebhookSignature/Program.cs
@@ -0,0 +1,17 @@
+using System.Security.Cryptography;
+using System.Text;
+using Mailtrap.Webhooks;
+
+var payload = "{\"event\":\"delivery\",\"message_id\":\"abc-123\"}";
+var signingSecret = "8d9a3c0e7f5b2d4a6c1e9f8b3a7d5c2e";
+
+string signature;
+using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signingSecret)))
+{
+ signature = Convert.ToHexStringLower(hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)));
+}
+
+if (!WebhookSignature.Verify(payload, signature, signingSecret))
+{
+ throw new InvalidOperationException("Signature verification failed!");
+}
diff --git a/examples/Mailtrap.Example.WebhookSignature/Properties/launchSettings.json b/examples/Mailtrap.Example.WebhookSignature/Properties/launchSettings.json
new file mode 100644
index 00000000..b8daf491
--- /dev/null
+++ b/examples/Mailtrap.Example.WebhookSignature/Properties/launchSettings.json
@@ -0,0 +1,10 @@
+{
+ "profiles": {
+ "Project": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/examples/Mailtrap.Example.WebhookSignature/appsettings.json b/examples/Mailtrap.Example.WebhookSignature/appsettings.json
new file mode 100644
index 00000000..a4e2270e
--- /dev/null
+++ b/examples/Mailtrap.Example.WebhookSignature/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "System": "Warning",
+ "Microsoft": "Warning"
+ }
+ }
+}
diff --git a/src/Mailtrap.Abstractions/Webhooks/WebhookSignature.cs b/src/Mailtrap.Abstractions/Webhooks/WebhookSignature.cs
new file mode 100644
index 00000000..e2e4869d
--- /dev/null
+++ b/src/Mailtrap.Abstractions/Webhooks/WebhookSignature.cs
@@ -0,0 +1,175 @@
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Mailtrap.Webhooks;
+
+
+///
+/// Helpers for verifying inbound Mailtrap webhook signatures.
+///
+///
+///
+///
+/// Mailtrap signs every outbound webhook by computing
+/// HMAC-SHA256(signing_secret, raw_request_body) and sending the lowercase hex digest
+/// in the Mailtrap-Signature HTTP header. To authenticate a webhook on the receiver
+/// side, compute the same digest using the signing_secret returned when the webhook
+/// was created and compare it to the value of the header in constant time.
+///
+///
+/// The comparison is performed in constant time to avoid timing side-channels.
+///
+///
+/// never throws on inputs that could plausibly
+/// arrive over the wire ( / empty strings, wrong-length signatures,
+/// non-hex characters, missing secret) — it simply returns . This
+/// makes it safe to call directly from a request handler without wrapping in try/catch.
+///
+///
+/// See the
+///
+/// Mailtrap documentation — Verifying the signature.
+///
+///
+public static class WebhookSignature
+{
+ ///
+ /// Hex-encoded HMAC-SHA256 signature length (SHA-256 produces 32 bytes / 64 hex chars).
+ ///
+ public const int SignatureHexLength = 64;
+
+ ///
+ /// Verifies the HMAC-SHA256 signature of a Mailtrap webhook payload.
+ ///
+ ///
+ ///
+ /// The raw request body, exactly as received. Do not parse and
+ /// re-serialize the JSON — re-encoding may reorder keys or alter whitespace and
+ /// invalidate the signature. In ASP.NET Core, call
+ /// HttpRequest.EnableBuffering() and read the body via
+ /// new StreamReader(Request.Body).ReadToEndAsync(), or bind directly to a
+ /// byte[] / on the webhook endpoint so the
+ /// body is preserved verbatim.
+ ///
+ ///
+ /// The value of the Mailtrap-Signature HTTP header (lowercase hex string).
+ ///
+ ///
+ /// The webhook's signing_secret, returned by the Webhooks API on webhook creation.
+ ///
+ ///
+ ///
+ /// if is valid for the given
+ /// and ;
+ /// otherwise (including any / empty input, wrong-length or
+ /// non-hex signatures).
+ ///
+ public static bool Verify(string payload, string signature, string signingSecret)
+ {
+ if (string.IsNullOrEmpty(signature))
+ {
+ return false;
+ }
+ if (string.IsNullOrEmpty(signingSecret))
+ {
+ return false;
+ }
+ if (string.IsNullOrEmpty(payload))
+ {
+ return false;
+ }
+ if (signature.Length != SignatureHexLength)
+ {
+ return false;
+ }
+
+ if (!TryParseHex(signature, out var providedBytes))
+ {
+ return false;
+ }
+
+ byte[] expectedBytes;
+ using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signingSecret)))
+ {
+ expectedBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
+ }
+
+ // Defensive: the hex-length check above already pins providedBytes to 32 bytes
+ // (= expectedBytes.Length), but reassert before the constant-time compare so a
+ // future change to SignatureHexLength can't accidentally introduce a timing leak.
+ if (expectedBytes.Length != providedBytes.Length)
+ {
+ return false;
+ }
+
+ return FixedTimeEquals(expectedBytes, providedBytes);
+ }
+
+ ///
+ /// Parses a lowercase/uppercase hex string into bytes without throwing on invalid input.
+ ///
+ private static bool TryParseHex(string hex, out byte[] bytes)
+ {
+ if ((hex.Length & 1) != 0)
+ {
+ bytes = [];
+ return false;
+ }
+
+ var result = new byte[hex.Length / 2];
+ for (var i = 0; i < result.Length; i++)
+ {
+ if (!TryParseHexDigit(hex[(i * 2) + 0], out var high) ||
+ !TryParseHexDigit(hex[(i * 2) + 1], out var low))
+ {
+ bytes = [];
+ return false;
+ }
+
+ result[i] = (byte)((high << 4) | low);
+ }
+
+ bytes = result;
+ return true;
+ }
+
+ private static bool TryParseHexDigit(char c, out int value)
+ {
+ if (c is >= '0' and <= '9')
+ {
+ value = c - '0';
+ return true;
+ }
+ if (c is >= 'a' and <= 'f')
+ {
+ value = c - 'a' + 10;
+ return true;
+ }
+ if (c is >= 'A' and <= 'F')
+ {
+ value = c - 'A' + 10;
+ return true;
+ }
+
+ value = 0;
+ return false;
+ }
+
+ ///
+ /// Constant-time byte-array equality. Equivalent to
+ /// CryptographicOperations.FixedTimeEquals, which is unavailable on
+ /// netstandard2.0.
+ ///
+ private static bool FixedTimeEquals(byte[] left, byte[] right)
+ {
+ // Lengths are checked up-front by the caller; equal-length guarantees a constant
+ // number of loop iterations and avoids leaking length information via timing.
+ var diff = 0;
+ for (var i = 0; i < left.Length; i++)
+ {
+ diff |= left[i] ^ right[i];
+ }
+
+ return diff == 0;
+ }
+}
diff --git a/tests/Mailtrap.UnitTests/GlobalUsings.cs b/tests/Mailtrap.UnitTests/GlobalUsings.cs
index 10a9248e..1fd40eac 100644
--- a/tests/Mailtrap.UnitTests/GlobalUsings.cs
+++ b/tests/Mailtrap.UnitTests/GlobalUsings.cs
@@ -68,6 +68,7 @@
global using Mailtrap.TestingMessages;
global using Mailtrap.TestingMessages.Requests;
global using Mailtrap.UnitTests.TestConstants;
+global using Mailtrap.Webhooks;
global using Mailtrap.UnitTests.TestExtensions;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
diff --git a/tests/Mailtrap.UnitTests/Webhooks/WebhookSignatureTests.cs b/tests/Mailtrap.UnitTests/Webhooks/WebhookSignatureTests.cs
new file mode 100644
index 00000000..4a892846
--- /dev/null
+++ b/tests/Mailtrap.UnitTests/Webhooks/WebhookSignatureTests.cs
@@ -0,0 +1,198 @@
+using System.Security.Cryptography;
+
+namespace Mailtrap.UnitTests.Webhooks;
+
+
+[TestFixture]
+internal sealed class WebhookSignatureTests
+{
+ // ---------------------------------------------------------------------
+ // Cross-SDK shared fixture — DO NOT CHANGE.
+ //
+ // The same (payload, signing_secret, expected_signature) triple is
+ // embedded verbatim in the test suites of every official Mailtrap SDK
+ // (Ruby, Python, PHP, Node.js, Java, .NET) to guarantee byte-for-byte
+ // compatibility of the verification algorithm across languages. Keep
+ // these three strings in sync with the other SDKs.
+ // ---------------------------------------------------------------------
+ private const string FixturePayload =
+ "{\"event\":\"delivery\",\"sending_stream\":\"transactional\",\"category\":\"welcome\","
+ + "\"message_id\":\"a8b1d8f6-1f8d-4a3c-9b2e-1a2b3c4d5e6f\","
+ + "\"email\":\"recipient@example.com\","
+ + "\"event_id\":\"f1e2d3c4-b5a6-7890-1234-567890abcdef\","
+ + "\"timestamp\":1716070000}";
+
+ private const string FixtureSigningSecret = "8d9a3c0e7f5b2d4a6c1e9f8b3a7d5c2e";
+
+ private const string FixtureExpectedSignature =
+ "6d262e2611cd09be1f948382b5c611d63b0e585c4c9c5e40139d6ac3876d5433";
+
+
+ // ---------------------------------------------------------------------
+ // 1. Valid signature → true
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithValidSignature_ReturnsTrue()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, FixtureExpectedSignature, FixtureSigningSecret)
+ .Should().BeTrue();
+ }
+
+ // ---------------------------------------------------------------------
+ // 2. Wrong secret → false
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithWrongSecret_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, FixtureExpectedSignature, "wrong_secret_value")
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 3. Payload tampered (one byte changed) → false
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithTamperedPayload_ReturnsFalse()
+ {
+ // Flip "delivery" to "delivere" — same length, different bytes.
+ var tampered = FixturePayload.Replace("\"delivery\"", "\"delivere\"", StringComparison.Ordinal);
+
+ WebhookSignature
+ .Verify(tampered, FixtureExpectedSignature, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 4. Signature with wrong length → false (no throw)
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithSignatureOfWrongLength_ReturnsFalse()
+ {
+ var tooShort = FixtureExpectedSignature[..63];
+ var tooLong = FixtureExpectedSignature + "a";
+
+ WebhookSignature
+ .Verify(FixturePayload, tooShort, FixtureSigningSecret)
+ .Should().BeFalse();
+
+ WebhookSignature
+ .Verify(FixturePayload, tooLong, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 5. Signature with non-hex characters → false (no throw)
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithNonHexCharactersInSignature_ReturnsFalse()
+ {
+ // Same length (64), but contains 'z' which is not a hex digit.
+ var nonHex = string.Concat("z", FixtureExpectedSignature.AsSpan(1));
+ nonHex.Should().HaveLength(WebhookSignature.SignatureHexLength);
+
+ WebhookSignature
+ .Verify(FixturePayload, nonHex, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 6. Empty signature string → false
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithEmptySignature_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, string.Empty, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 7. Empty signingSecret → false
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithEmptySigningSecret_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, FixtureExpectedSignature, string.Empty)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 8. Empty payload with non-empty signature → false
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithEmptyPayload_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(string.Empty, FixtureExpectedSignature, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ // ---------------------------------------------------------------------
+ // 9. Known-good fixture round-trip — independently recompute the HMAC
+ // in the test (not via the helper) and assert it matches both the
+ // embedded expected signature AND the helper's verdict.
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_FixtureRoundTrip_MatchesIndependentlyComputedHmac()
+ {
+ // Recompute the HMAC-SHA256 independently of the helper, using BCL
+ // primitives directly. If this drifts from FixtureExpectedSignature,
+ // either the fixture is wrong or the algorithm/encoding has changed.
+ byte[] digest;
+ using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(FixtureSigningSecret)))
+ {
+ digest = hmac.ComputeHash(Encoding.UTF8.GetBytes(FixturePayload));
+ }
+
+ var computedHex = ToLowerHex(digest);
+
+ computedHex.Should().Be(
+ FixtureExpectedSignature,
+ "independently computed HMAC must equal embedded fixture signature");
+
+ WebhookSignature
+ .Verify(FixturePayload, FixtureExpectedSignature, FixtureSigningSecret)
+ .Should().BeTrue("helper must agree the fixture is valid");
+ }
+
+ // ---------------------------------------------------------------------
+ // Bonus: null inputs → false (no NullReferenceException)
+ // ---------------------------------------------------------------------
+ [Test]
+ public void Verify_WithNullPayload_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(null!, FixtureExpectedSignature, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ [Test]
+ public void Verify_WithNullSignature_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, null!, FixtureSigningSecret)
+ .Should().BeFalse();
+ }
+
+ [Test]
+ public void Verify_WithNullSigningSecret_ReturnsFalse()
+ {
+ WebhookSignature
+ .Verify(FixturePayload, FixtureExpectedSignature, null!)
+ .Should().BeFalse();
+ }
+
+
+ private static string ToLowerHex(byte[] bytes)
+ {
+ var sb = new StringBuilder(bytes.Length * 2);
+ foreach (var b in bytes)
+ {
+ sb.Append(b.ToString("x2", System.Globalization.CultureInfo.InvariantCulture));
+ }
+ return sb.ToString();
+ }
+}