From 73170daeead075e7e5cf6a575b166ad39df25854 Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Thu, 26 Sep 2024 12:09:53 +0300 Subject: [PATCH] Add schema to configs that enables autocompletion --- .../Nethermind.Runner/configs/op-mainnet.cfg | 1 + tools/SchemaGenerator/Program.cs | 77 +++++++ tools/SchemaGenerator/SchemaGenerator.csproj | 20 ++ tools/SchemaGenerator/SchemaGenerator.sln | 217 ++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 tools/SchemaGenerator/Program.cs create mode 100644 tools/SchemaGenerator/SchemaGenerator.csproj create mode 100644 tools/SchemaGenerator/SchemaGenerator.sln diff --git a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg index ba5b7fce5d9..0bd07015b0a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg @@ -1,4 +1,5 @@ { + "$schema": "https://gist.githubusercontent.com/flcl42/25b0396678b02cfc0c5dc1d68ea085a7/raw/2fda5155f38e9816bead94682eac92d3b7e74b8c/nethermind-config-schema.json", "Init": { "ChainSpecPath": "chainspec/op-mainnet.json", "GenesisHash": "0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b", diff --git a/tools/SchemaGenerator/Program.cs b/tools/SchemaGenerator/Program.cs new file mode 100644 index 00000000000..f176340bf22 --- /dev/null +++ b/tools/SchemaGenerator/Program.cs @@ -0,0 +1,77 @@ + +using NJsonSchema; +using System.Reflection; +using System.Reflection.Emit; +using Nethermind.Config; +using Nethermind.Core.Collections; + +Type iConfigType = typeof(IConfig); + +Type[] types = [ + ..Directory.GetFiles(".", "Nethermind.*.dll").SelectMany(f => GetConfigTypes(Assembly.LoadFrom(f))), + ]; + +var assemblyName = new AssemblyName("Nethermind.Config"); +var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); +ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); + +TypeBuilder typeBuilder = moduleBuilder.DefineType("NethermindConfig", TypeAttributes.Public); + +foreach (Type configInterface in types) +{ + CreateProperty(typeBuilder, configInterface); +} + +Type configType = typeBuilder.CreateType(); + +JsonSchema schema = JsonSchema.FromType(configType); + +foreach (var def in schema.Definitions) +{ + if(def.Value.Enumeration is { Count: > 0 }) + { + def.Value.Type = JsonObjectType.String; + def.Value.Enumeration.Clear(); + def.Value.Enumeration.AddRange(def.Value.EnumerationNames); + } +} + +Console.WriteLine(schema.ToJson()); + +void CreateProperty(TypeBuilder typeBuilder, Type classType) +{ + Type interfaceType = classType.GetInterfaces().First(i => iConfigType.IsAssignableFrom(i) && i != iConfigType); + string propertyName = interfaceType.Name.Substring(1, interfaceType.Name.Length - 7); + FieldBuilder fieldBuilder = typeBuilder.DefineField($"_{propertyName}", interfaceType, FieldAttributes.Private); + PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, interfaceType, null); + MethodBuilder getMethodBuilder = typeBuilder.DefineMethod($"get_{propertyName}", + MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, + interfaceType, + Type.EmptyTypes); + + ILGenerator getIL = getMethodBuilder.GetILGenerator(); + getIL.Emit(OpCodes.Ldarg_0); + getIL.Emit(OpCodes.Ldfld, fieldBuilder); + getIL.Emit(OpCodes.Ret); + + // Define the 'set' accessor method + MethodBuilder setMethodBuilder = typeBuilder.DefineMethod($"set_{propertyName}", + MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, + null, + [interfaceType]); + + ILGenerator setIL = setMethodBuilder.GetILGenerator(); + setIL.Emit(OpCodes.Ldarg_0); + setIL.Emit(OpCodes.Ldarg_1); + setIL.Emit(OpCodes.Stfld, fieldBuilder); + setIL.Emit(OpCodes.Ret); + + // Map the get and set methods to the property + propertyBuilder.SetGetMethod(getMethodBuilder); + propertyBuilder.SetSetMethod(setMethodBuilder); +} + +IEnumerable GetConfigTypes(Assembly assembly) +{ + return assembly.GetTypes().Where(t => iConfigType.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract); +} diff --git a/tools/SchemaGenerator/SchemaGenerator.csproj b/tools/SchemaGenerator/SchemaGenerator.csproj new file mode 100644 index 00000000000..b39da78f36f --- /dev/null +++ b/tools/SchemaGenerator/SchemaGenerator.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + diff --git a/tools/SchemaGenerator/SchemaGenerator.sln b/tools/SchemaGenerator/SchemaGenerator.sln new file mode 100644 index 00000000000..37635584f94 --- /dev/null +++ b/tools/SchemaGenerator/SchemaGenerator.sln @@ -0,0 +1,217 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35303.130 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SchemaGenerator", "SchemaGenerator.csproj", "{3670AA89-2A73-4C09-A13F-F207035D89EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Api", "..\..\src\Nethermind\Nethermind.Api\Nethermind.Api.csproj", "{B0399199-3C55-4AF3-9A59-5BC1D1616A19}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Blockchain", "..\..\src\Nethermind\Nethermind.Blockchain\Nethermind.Blockchain.csproj", "{F23FB617-5FA1-4C89-A38A-C2DFA7DB5440}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Facade", "..\..\src\Nethermind\Nethermind.Facade\Nethermind.Facade.csproj", "{AA9C67C6-7B46-4A48-818F-2856CE5EF01D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Grpc", "..\..\src\Nethermind\Nethermind.Grpc\Nethermind.Grpc.csproj", "{854CA332-FC2D-4D49-B4D9-BD2AD2A45C89}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.JsonRpc", "..\..\src\Nethermind\Nethermind.JsonRpc\Nethermind.JsonRpc.csproj", "{CFD4097F-01A5-46FF-94D6-05A05EB1C534}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Monitoring", "..\..\src\Nethermind\Nethermind.Monitoring\Nethermind.Monitoring.csproj", "{9A58A4EE-4EEF-4244-B62B-0A784E846397}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Network", "..\..\src\Nethermind\Nethermind.Network\Nethermind.Network.csproj", "{C0E61E05-970E-4DE0-A61F-02F2A98305BB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Sockets", "..\..\src\Nethermind\Nethermind.Sockets\Nethermind.Sockets.csproj", "{FA9E459A-5A17-4C24-BABD-0AD9272AB98E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Abi", "..\..\src\Nethermind\Nethermind.Abi\Nethermind.Abi.csproj", "{1A56D354-D7A1-4CE7-A385-3D48459DF949}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Core", "..\..\src\Nethermind\Nethermind.Core\Nethermind.Core.csproj", "{50BC4631-B36C-4A80-A950-747AA0126751}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Db", "..\..\src\Nethermind\Nethermind.Db\Nethermind.Db.csproj", "{634922FD-45FB-4236-9319-57546C5E9D5D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Evm", "..\..\src\Nethermind\Nethermind.Evm\Nethermind.Evm.csproj", "{1CE18A05-8048-4227-80A7-663EAF120A09}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Network.Stats", "..\..\src\Nethermind\Nethermind.Network.Stats\Nethermind.Network.Stats.csproj", "{96656EF2-848C-4D80-87A1-DB70DC5C280D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Specs", "..\..\src\Nethermind\Nethermind.Specs\Nethermind.Specs.csproj", "{42EA22A8-271B-40B8-A14C-C0B3320F8A53}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.State", "..\..\src\Nethermind\Nethermind.State\Nethermind.State.csproj", "{BE93E6ED-345B-4F84-82FE-B2306DCA12F0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.TxPool", "..\..\src\Nethermind\Nethermind.TxPool\Nethermind.TxPool.csproj", "{2BD3F956-C335-4C64-A517-282012F54A7E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Consensus", "..\..\src\Nethermind\Nethermind.Consensus\Nethermind.Consensus.csproj", "{DC68F63C-407F-444D-A436-EFE423F3B2A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Crypto", "..\..\src\Nethermind\Nethermind.Crypto\Nethermind.Crypto.csproj", "{6C517105-7845-4A46-AFBD-22431C64461C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Synchronization", "..\..\src\Nethermind\Nethermind.Synchronization\Nethermind.Synchronization.csproj", "{8C618588-0380-408C-89A3-EBD1D98CC521}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Config", "..\..\src\Nethermind\Nethermind.Config\Nethermind.Config.csproj", "{1DE1E47A-7A2E-4E32-8BB1-11281C501D73}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Serialization.Json", "..\..\src\Nethermind\Nethermind.Serialization.Json\Nethermind.Serialization.Json.csproj", "{8D4E493F-2063-49B5-AAC2-458F10FAC073}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Serialization.Rlp", "..\..\src\Nethermind\Nethermind.Serialization.Rlp\Nethermind.Serialization.Rlp.csproj", "{CB2A6251-A878-4F5D-A049-9B3B9891B123}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Trie", "..\..\src\Nethermind\Nethermind.Trie\Nethermind.Trie.csproj", "{F0B78631-1159-4797-8277-1ADB7070DCDC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Optimism", "..\..\src\Nethermind\Nethermind.Optimism\Nethermind.Optimism.csproj", "{3B3380FE-674F-4059-B134-516B848A0749}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Init", "..\..\src\Nethermind\Nethermind.Init\Nethermind.Init.csproj", "{54BBF9B5-6106-4BDB-9ED1-2A1DBA9F6918}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Merge.Plugin", "..\..\src\Nethermind\Nethermind.Merge.Plugin\Nethermind.Merge.Plugin.csproj", "{7D28812C-C6F2-473D-904E-BE2D8CC5F5BE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Db.Rocks", "..\..\src\Nethermind\Nethermind.Db.Rocks\Nethermind.Db.Rocks.csproj", "{981A3E24-AEF7-4F6E-B87F-6249AC10BCD4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Db.Rpc", "..\..\src\Nethermind\Nethermind.Db.Rpc\Nethermind.Db.Rpc.csproj", "{7B16F7F4-CCB9-4DB7-A53A-0FD6ED698AAF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Network.Discovery", "..\..\src\Nethermind\Nethermind.Network.Discovery\Nethermind.Network.Discovery.csproj", "{28638961-FEF8-4334-95BD-E55F2F92D0AF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Network.Dns", "..\..\src\Nethermind\Nethermind.Network.Dns\Nethermind.Network.Dns.csproj", "{EFB9367F-EFB8-4940-97A8-62F3967FC17D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Network.Enr", "..\..\src\Nethermind\Nethermind.Network.Enr\Nethermind.Network.Enr.csproj", "{C1F412BA-FC1F-4701-B947-BA42DA855423}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Init.Snapshot", "..\..\src\Nethermind\Nethermind.Init.Snapshot\Nethermind.Init.Snapshot.csproj", "{90AA7A9D-FC7F-419E-A671-A07FDD02DA10}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3670AA89-2A73-4C09-A13F-F207035D89EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3670AA89-2A73-4C09-A13F-F207035D89EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3670AA89-2A73-4C09-A13F-F207035D89EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3670AA89-2A73-4C09-A13F-F207035D89EA}.Release|Any CPU.Build.0 = Release|Any CPU + {B0399199-3C55-4AF3-9A59-5BC1D1616A19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0399199-3C55-4AF3-9A59-5BC1D1616A19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0399199-3C55-4AF3-9A59-5BC1D1616A19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0399199-3C55-4AF3-9A59-5BC1D1616A19}.Release|Any CPU.Build.0 = Release|Any CPU + {F23FB617-5FA1-4C89-A38A-C2DFA7DB5440}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F23FB617-5FA1-4C89-A38A-C2DFA7DB5440}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F23FB617-5FA1-4C89-A38A-C2DFA7DB5440}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F23FB617-5FA1-4C89-A38A-C2DFA7DB5440}.Release|Any CPU.Build.0 = Release|Any CPU + {AA9C67C6-7B46-4A48-818F-2856CE5EF01D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA9C67C6-7B46-4A48-818F-2856CE5EF01D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA9C67C6-7B46-4A48-818F-2856CE5EF01D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA9C67C6-7B46-4A48-818F-2856CE5EF01D}.Release|Any CPU.Build.0 = Release|Any CPU + {854CA332-FC2D-4D49-B4D9-BD2AD2A45C89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {854CA332-FC2D-4D49-B4D9-BD2AD2A45C89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {854CA332-FC2D-4D49-B4D9-BD2AD2A45C89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {854CA332-FC2D-4D49-B4D9-BD2AD2A45C89}.Release|Any CPU.Build.0 = Release|Any CPU + {CFD4097F-01A5-46FF-94D6-05A05EB1C534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFD4097F-01A5-46FF-94D6-05A05EB1C534}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFD4097F-01A5-46FF-94D6-05A05EB1C534}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFD4097F-01A5-46FF-94D6-05A05EB1C534}.Release|Any CPU.Build.0 = Release|Any CPU + {9A58A4EE-4EEF-4244-B62B-0A784E846397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A58A4EE-4EEF-4244-B62B-0A784E846397}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A58A4EE-4EEF-4244-B62B-0A784E846397}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A58A4EE-4EEF-4244-B62B-0A784E846397}.Release|Any CPU.Build.0 = Release|Any CPU + {C0E61E05-970E-4DE0-A61F-02F2A98305BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0E61E05-970E-4DE0-A61F-02F2A98305BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0E61E05-970E-4DE0-A61F-02F2A98305BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0E61E05-970E-4DE0-A61F-02F2A98305BB}.Release|Any CPU.Build.0 = Release|Any CPU + {FA9E459A-5A17-4C24-BABD-0AD9272AB98E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA9E459A-5A17-4C24-BABD-0AD9272AB98E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA9E459A-5A17-4C24-BABD-0AD9272AB98E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA9E459A-5A17-4C24-BABD-0AD9272AB98E}.Release|Any CPU.Build.0 = Release|Any CPU + {1A56D354-D7A1-4CE7-A385-3D48459DF949}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A56D354-D7A1-4CE7-A385-3D48459DF949}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A56D354-D7A1-4CE7-A385-3D48459DF949}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A56D354-D7A1-4CE7-A385-3D48459DF949}.Release|Any CPU.Build.0 = Release|Any CPU + {50BC4631-B36C-4A80-A950-747AA0126751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50BC4631-B36C-4A80-A950-747AA0126751}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50BC4631-B36C-4A80-A950-747AA0126751}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50BC4631-B36C-4A80-A950-747AA0126751}.Release|Any CPU.Build.0 = Release|Any CPU + {634922FD-45FB-4236-9319-57546C5E9D5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {634922FD-45FB-4236-9319-57546C5E9D5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {634922FD-45FB-4236-9319-57546C5E9D5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {634922FD-45FB-4236-9319-57546C5E9D5D}.Release|Any CPU.Build.0 = Release|Any CPU + {1CE18A05-8048-4227-80A7-663EAF120A09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CE18A05-8048-4227-80A7-663EAF120A09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CE18A05-8048-4227-80A7-663EAF120A09}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CE18A05-8048-4227-80A7-663EAF120A09}.Release|Any CPU.Build.0 = Release|Any CPU + {96656EF2-848C-4D80-87A1-DB70DC5C280D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96656EF2-848C-4D80-87A1-DB70DC5C280D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96656EF2-848C-4D80-87A1-DB70DC5C280D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96656EF2-848C-4D80-87A1-DB70DC5C280D}.Release|Any CPU.Build.0 = Release|Any CPU + {42EA22A8-271B-40B8-A14C-C0B3320F8A53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42EA22A8-271B-40B8-A14C-C0B3320F8A53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42EA22A8-271B-40B8-A14C-C0B3320F8A53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42EA22A8-271B-40B8-A14C-C0B3320F8A53}.Release|Any CPU.Build.0 = Release|Any CPU + {BE93E6ED-345B-4F84-82FE-B2306DCA12F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE93E6ED-345B-4F84-82FE-B2306DCA12F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE93E6ED-345B-4F84-82FE-B2306DCA12F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE93E6ED-345B-4F84-82FE-B2306DCA12F0}.Release|Any CPU.Build.0 = Release|Any CPU + {2BD3F956-C335-4C64-A517-282012F54A7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BD3F956-C335-4C64-A517-282012F54A7E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BD3F956-C335-4C64-A517-282012F54A7E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BD3F956-C335-4C64-A517-282012F54A7E}.Release|Any CPU.Build.0 = Release|Any CPU + {DC68F63C-407F-444D-A436-EFE423F3B2A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC68F63C-407F-444D-A436-EFE423F3B2A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC68F63C-407F-444D-A436-EFE423F3B2A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC68F63C-407F-444D-A436-EFE423F3B2A8}.Release|Any CPU.Build.0 = Release|Any CPU + {6C517105-7845-4A46-AFBD-22431C64461C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C517105-7845-4A46-AFBD-22431C64461C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C517105-7845-4A46-AFBD-22431C64461C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C517105-7845-4A46-AFBD-22431C64461C}.Release|Any CPU.Build.0 = Release|Any CPU + {8C618588-0380-408C-89A3-EBD1D98CC521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C618588-0380-408C-89A3-EBD1D98CC521}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C618588-0380-408C-89A3-EBD1D98CC521}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C618588-0380-408C-89A3-EBD1D98CC521}.Release|Any CPU.Build.0 = Release|Any CPU + {1DE1E47A-7A2E-4E32-8BB1-11281C501D73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DE1E47A-7A2E-4E32-8BB1-11281C501D73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DE1E47A-7A2E-4E32-8BB1-11281C501D73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DE1E47A-7A2E-4E32-8BB1-11281C501D73}.Release|Any CPU.Build.0 = Release|Any CPU + {8D4E493F-2063-49B5-AAC2-458F10FAC073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D4E493F-2063-49B5-AAC2-458F10FAC073}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D4E493F-2063-49B5-AAC2-458F10FAC073}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D4E493F-2063-49B5-AAC2-458F10FAC073}.Release|Any CPU.Build.0 = Release|Any CPU + {CB2A6251-A878-4F5D-A049-9B3B9891B123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB2A6251-A878-4F5D-A049-9B3B9891B123}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB2A6251-A878-4F5D-A049-9B3B9891B123}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB2A6251-A878-4F5D-A049-9B3B9891B123}.Release|Any CPU.Build.0 = Release|Any CPU + {F0B78631-1159-4797-8277-1ADB7070DCDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0B78631-1159-4797-8277-1ADB7070DCDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0B78631-1159-4797-8277-1ADB7070DCDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0B78631-1159-4797-8277-1ADB7070DCDC}.Release|Any CPU.Build.0 = Release|Any CPU + {3B3380FE-674F-4059-B134-516B848A0749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B3380FE-674F-4059-B134-516B848A0749}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B3380FE-674F-4059-B134-516B848A0749}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B3380FE-674F-4059-B134-516B848A0749}.Release|Any CPU.Build.0 = Release|Any CPU + {54BBF9B5-6106-4BDB-9ED1-2A1DBA9F6918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54BBF9B5-6106-4BDB-9ED1-2A1DBA9F6918}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54BBF9B5-6106-4BDB-9ED1-2A1DBA9F6918}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54BBF9B5-6106-4BDB-9ED1-2A1DBA9F6918}.Release|Any CPU.Build.0 = Release|Any CPU + {7D28812C-C6F2-473D-904E-BE2D8CC5F5BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D28812C-C6F2-473D-904E-BE2D8CC5F5BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D28812C-C6F2-473D-904E-BE2D8CC5F5BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D28812C-C6F2-473D-904E-BE2D8CC5F5BE}.Release|Any CPU.Build.0 = Release|Any CPU + {981A3E24-AEF7-4F6E-B87F-6249AC10BCD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {981A3E24-AEF7-4F6E-B87F-6249AC10BCD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {981A3E24-AEF7-4F6E-B87F-6249AC10BCD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {981A3E24-AEF7-4F6E-B87F-6249AC10BCD4}.Release|Any CPU.Build.0 = Release|Any CPU + {7B16F7F4-CCB9-4DB7-A53A-0FD6ED698AAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B16F7F4-CCB9-4DB7-A53A-0FD6ED698AAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B16F7F4-CCB9-4DB7-A53A-0FD6ED698AAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B16F7F4-CCB9-4DB7-A53A-0FD6ED698AAF}.Release|Any CPU.Build.0 = Release|Any CPU + {28638961-FEF8-4334-95BD-E55F2F92D0AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28638961-FEF8-4334-95BD-E55F2F92D0AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28638961-FEF8-4334-95BD-E55F2F92D0AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28638961-FEF8-4334-95BD-E55F2F92D0AF}.Release|Any CPU.Build.0 = Release|Any CPU + {EFB9367F-EFB8-4940-97A8-62F3967FC17D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EFB9367F-EFB8-4940-97A8-62F3967FC17D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EFB9367F-EFB8-4940-97A8-62F3967FC17D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EFB9367F-EFB8-4940-97A8-62F3967FC17D}.Release|Any CPU.Build.0 = Release|Any CPU + {C1F412BA-FC1F-4701-B947-BA42DA855423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1F412BA-FC1F-4701-B947-BA42DA855423}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1F412BA-FC1F-4701-B947-BA42DA855423}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1F412BA-FC1F-4701-B947-BA42DA855423}.Release|Any CPU.Build.0 = Release|Any CPU + {90AA7A9D-FC7F-419E-A671-A07FDD02DA10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90AA7A9D-FC7F-419E-A671-A07FDD02DA10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90AA7A9D-FC7F-419E-A671-A07FDD02DA10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90AA7A9D-FC7F-419E-A671-A07FDD02DA10}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {80A498BE-33FF-4A03-AEF1-979170084AB3} + EndGlobalSection +EndGlobal