First version of a Windows TrayIcon working against a http server.

git-svn-id: https://duplicati.googlecode.com/svn/branches/v2.0@1026 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
kenneth@hexad.dk
2011-11-21 22:28:20 +00:00
parent 48259fb87b
commit 933a61b954
54 changed files with 2841 additions and 407 deletions
+221 -210
View File
@@ -57,11 +57,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server", "Duplicati\Server\Duplicati.Server.csproj", "{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.GUI.TrayIcon", "Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{17566860-3D98-4604-AA5B-47661F75609F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
EndProject
Global
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
@@ -69,22 +73,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.ActiveCfg = Debug|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.Build.0 = Debug|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.ActiveCfg = Release|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.Build.0 = Release|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.ActiveCfg = Debug|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.Build.0 = Debug|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.ActiveCfg = Release|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.Build.0 = Release|x86
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|x86.ActiveCfg = Debug|x86
@@ -93,140 +81,6 @@ Global
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|Any CPU.Build.0 = Release|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|x86.ActiveCfg = Release|x86
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|x86.Build.0 = Release|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.ActiveCfg = Debug|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.Build.0 = Debug|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.ActiveCfg = Release|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.Build.0 = Release|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|x86.ActiveCfg = Debug|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|x86.Build.0 = Debug|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.Build.0 = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.ActiveCfg = Release|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.Build.0 = Release|x86
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.ActiveCfg = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.Build.0 = Debug|x86
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.Build.0 = Release|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|x86.ActiveCfg = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.ActiveCfg = Debug|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.Build.0 = Debug|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.Build.0 = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.ActiveCfg = Release|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.Build.0 = Release|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.ActiveCfg = Debug|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.Build.0 = Debug|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.ActiveCfg = Release|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.Build.0 = Release|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.ActiveCfg = Debug|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.Build.0 = Debug|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.Build.0 = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.ActiveCfg = Release|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.Build.0 = Release|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.ActiveCfg = Debug|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.Build.0 = Debug|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.Build.0 = Release|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.ActiveCfg = Release|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.Build.0 = Release|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|x86.ActiveCfg = Debug|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|x86.Build.0 = Debug|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.Build.0 = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.ActiveCfg = Release|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.Build.0 = Release|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.ActiveCfg = Debug|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.Build.0 = Debug|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.ActiveCfg = Release|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.Build.0 = Release|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.ActiveCfg = Debug|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.Build.0 = Debug|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.Build.0 = Release|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.ActiveCfg = Release|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.Build.0 = Release|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|x86.ActiveCfg = Debug|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|x86.Build.0 = Debug|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.ActiveCfg = Release|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.Build.0 = Release|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|x86.ActiveCfg = Debug|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|x86.Build.0 = Debug|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.Build.0 = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.ActiveCfg = Release|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.Build.0 = Release|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|x86.ActiveCfg = Debug|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|x86.Build.0 = Debug|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.ActiveCfg = Release|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.Build.0 = Release|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.ActiveCfg = Debug|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|x86
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|x86.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|x86.Build.0 = Debug|x86
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|x86.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.ActiveCfg = Debug|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.Build.0 = Debug|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.ActiveCfg = Release|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.Build.0 = Release|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.ActiveCfg = Debug|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.Build.0 = Debug|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.ActiveCfg = Release|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.Build.0 = Release|x86
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.ActiveCfg = Debug|x86
@@ -235,38 +89,14 @@ Global
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|x86
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.ActiveCfg = Debug|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.Build.0 = Debug|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.Build.0 = Release|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.ActiveCfg = Release|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.Build.0 = Release|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|x86.ActiveCfg = Debug|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|x86.Build.0 = Debug|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.Build.0 = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.ActiveCfg = Release|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.Build.0 = Release|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.ActiveCfg = Debug|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.Build.0 = Debug|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.Build.0 = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.ActiveCfg = Release|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.Build.0 = Release|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.ActiveCfg = Debug|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.Build.0 = Debug|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.ActiveCfg = Release|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.Build.0 = Release|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.ActiveCfg = Debug|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.Build.0 = Debug|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.ActiveCfg = Release|x86
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.Build.0 = Release|x86
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|x86.ActiveCfg = Debug|x86
@@ -275,14 +105,180 @@ Global
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.ActiveCfg = Release|x86
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.Build.0 = Release|x86
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|x86.ActiveCfg = Debug|x86
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|x86.Build.0 = Debug|x86
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.Build.0 = Release|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|x86.ActiveCfg = Release|x86
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|x86.Build.0 = Release|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.ActiveCfg = Debug|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.Build.0 = Debug|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.ActiveCfg = Release|x86
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.Build.0 = Release|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.ActiveCfg = Debug|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.Build.0 = Debug|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.ActiveCfg = Release|x86
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.Build.0 = Release|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.ActiveCfg = Debug|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.Build.0 = Debug|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.ActiveCfg = Release|x86
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.Build.0 = Release|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.ActiveCfg = Debug|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.Build.0 = Debug|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.Build.0 = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.ActiveCfg = Release|x86
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.Build.0 = Release|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.ActiveCfg = Debug|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.Build.0 = Debug|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.ActiveCfg = Release|x86
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.Build.0 = Release|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|x86.ActiveCfg = Debug|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|x86.Build.0 = Debug|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.ActiveCfg = Release|x86
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.Build.0 = Release|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|x86.ActiveCfg = Debug|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|x86.Build.0 = Debug|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.Build.0 = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.ActiveCfg = Release|x86
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.Build.0 = Release|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.ActiveCfg = Debug|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.Build.0 = Debug|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.Build.0 = Release|Any CPU
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.ActiveCfg = Release|x86
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.Build.0 = Release|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|x86.ActiveCfg = Debug|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|x86.Build.0 = Debug|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.ActiveCfg = Release|x86
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.Build.0 = Release|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|x86.ActiveCfg = Debug|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|x86.Build.0 = Debug|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.Build.0 = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.ActiveCfg = Release|x86
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.Build.0 = Release|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.ActiveCfg = Debug|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.Build.0 = Debug|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.Build.0 = Release|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.ActiveCfg = Release|x86
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.Build.0 = Release|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.ActiveCfg = Debug|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.Build.0 = Debug|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.Build.0 = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.ActiveCfg = Release|x86
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.Build.0 = Release|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|x86.ActiveCfg = Debug|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|x86.Build.0 = Debug|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.Build.0 = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.ActiveCfg = Release|x86
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.Build.0 = Release|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.ActiveCfg = Debug|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|x86
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.ActiveCfg = Debug|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.Build.0 = Debug|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.ActiveCfg = Release|x86
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.Build.0 = Release|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.ActiveCfg = Debug|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.Build.0 = Debug|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.ActiveCfg = Release|x86
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.Build.0 = Release|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.ActiveCfg = Debug|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.Build.0 = Debug|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.ActiveCfg = Release|x86
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.Build.0 = Release|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.ActiveCfg = Debug|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.Build.0 = Debug|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.Build.0 = Release|Any CPU
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.ActiveCfg = Release|x86
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.Build.0 = Release|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.ActiveCfg = Debug|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.Build.0 = Debug|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.Build.0 = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.ActiveCfg = Release|x86
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.Build.0 = Release|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|x86.ActiveCfg = Debug|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|x86.Build.0 = Debug|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.Build.0 = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.ActiveCfg = Release|x86
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.Build.0 = Release|x86
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|x86.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|x86.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|x86.ActiveCfg = Release|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.ActiveCfg = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.Build.0 = Debug|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.Build.0 = Release|Any CPU
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|x86.ActiveCfg = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|x86.ActiveCfg = Debug|x86
@@ -291,6 +287,14 @@ Global
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.Build.0 = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|x86.ActiveCfg = Release|x86
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|x86.Build.0 = Release|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|x86.ActiveCfg = Debug|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|x86.Build.0 = Debug|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.Build.0 = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.ActiveCfg = Release|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.Build.0 = Release|x86
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|x86.ActiveCfg = Debug|x86
@@ -307,27 +311,34 @@ Global
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|Any CPU.Build.0 = Release|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|x86.ActiveCfg = Release|x86
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|x86.Build.0 = Release|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|x86.ActiveCfg = Debug|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|x86.Build.0 = Debug|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.Build.0 = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.ActiveCfg = Release|x86
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Duplicati\GUI\Duplicati.csproj
Policies = $0
$0.StandardHeader = $1
$1.Text = @ Copyright (C) 2011, Kenneth Skovhede\r\n http://www.hexad.dk, opensource@hexad.dk\n \n This library is free software; you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as\n published by the Free Software Foundation; either version 2.1 of the\n License, or (at your option) any later version.\n\n This library is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public\n License along with this library; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$1.IncludeInNewFiles = True
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Duplicati\Server\Duplicati.Server.csproj
Policies = $0
$0.StandardHeader = $1
$1.Text = @ Copyright (C) 2011, Kenneth Skovhede\r\n http://www.hexad.dk, opensource@hexad.dk\n \n This library is free software; you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as\n published by the Free Software Foundation; either version 2.1 of the\n License, or (at your option) any later version.\n\n This library is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public\n License along with this library; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$1.IncludeInNewFiles = True
$0.DotNetNamingPolicy = $2
$2.DirectoryNamespaceAssociation = None
$2.ResourceNamePolicy = FileFormatDefault
$0.TextStylePolicy = $3
$3.FileWidth = 120
$3.EolMarker = Windows
$3.inheritsSet = VisualStudio
$3.inheritsScope = text/plain
$3.scope = text/x-csharp
$0.CSharpFormattingPolicy = $4
$4.BeforeMethodCallParentheses = False
$4.BeforeConstructorDeclarationParentheses = False
$4.BeforeIndexerDeclarationBracket = False
$4.BeforeDelegateDeclarationParentheses = False
$4.NewParentheses = False
$4.SpacesBeforeBrackets = False
$4.inheritsSet = Mono
$4.inheritsScope = text/x-csharp
$4.scope = text/x-csharp
EndGlobalSection
EndGlobal
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -11,6 +11,21 @@
<RootNamespace>Duplicati.GUI.TrayIcon</RootNamespace>
<AssemblyName>Duplicati.GUI.TrayIcon</AssemblyName>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
@@ -35,12 +50,14 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<OutputPath>bin\Debug</OutputPath>
<DebugType>none</DebugType>
<DebugType>full</DebugType>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>true</CodeAnalysisFailOnMissingRules>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<DefineConstants>DEBUG</DefineConstants>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release</OutputPath>
@@ -51,6 +68,15 @@
<CodeAnalysisFailOnMissingRules>true</CodeAnalysisFailOnMissingRules>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>Duplicati.GUI.TrayIcon.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -63,17 +89,28 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs">
<Compile Include="HostedInstanceKeeper.cs" />
<Compile Include="SerializationHelper.cs" />
<Compile Include="Strings\WindowsMainForm.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>WindowsMainForm.resx</DependentUpon>
</Compile>
<Compile Include="WindowsMainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
<Compile Include="WindowsMainForm.Designer.cs">
<DependentUpon>WindowsMainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="HttpServerConnection.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
<EmbeddedResource Include="Strings\WindowsMainForm.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>WindowsMainForm.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="WindowsMainForm.resx">
<DependentUpon>WindowsMainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
@@ -83,7 +120,10 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="app.config" />
<None Include="Duplicati.snk" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -95,11 +135,94 @@
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Server\Duplicati.Server.csproj">
<Project>{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}</Project>
<Name>Duplicati.Server</Name>
</ProjectReference>
<ProjectReference Include="..\..\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj">
<Project>{33FD1D24-C28F-4C71-933F-98F1586EA76C}</Project>
<Name>Duplicati.Server.Serialization</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<None Include="Resources\CloseMenuIcon.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\SettingsMenuIcon.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\StatusMenuIcon.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\WizardMenuIcon.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Clock05.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Clock15.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Clock30.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Clock60.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Delay.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Throttle.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Stop.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayNormal.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayNormalError.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayNormalPause.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayNormalWarning.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayWorking.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\TrayWorkingPause.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Pause.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Play.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<EnableUnmanagedDebugging>true</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>
Binary file not shown.
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.GUI.TrayIcon
{
/// <summary>
/// We keep the hosted instance here to allow the TrayIcon executable to load without requiring the Server.exe
/// </summary>
internal class HostedInstanceKeeper : IDisposable
{
private System.Threading.Thread m_runner;
public HostedInstanceKeeper(string[] args)
{
m_runner = new System.Threading.Thread(ThreadRunner);
m_runner.Start(args);
//TODO: Should wait for a event or similar
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
}
private void ThreadRunner(object a)
{
Duplicati.Server.Program.Main((string[])a);
}
public void Dispose()
{
m_runner.Abort();
m_runner.Join(TimeSpan.FromSeconds(10));
}
}
}
@@ -6,29 +6,153 @@ using Duplicati.Server.Serialization;
namespace Duplicati.GUI.TrayIcon
{
public class HttpServerConnection
public class HttpServerConnection : IDisposable
{
private Uri m_uri;
private System.Net.NetworkCredential m_credentials;
private ServiceState m_serviceState;
private static readonly System.Text.Encoding ENCODING = System.Text.Encoding.GetEncoding("utf-8");
public delegate void StatusUpdate(ISerializableStatus status);
public event StatusUpdate StatusUpdated;
private ISerializableStatus m_status;
private TimeSpan m_updateIntervalIdle = TimeSpan.FromSeconds(15);
private TimeSpan m_updateIntervalActive = TimeSpan.FromSeconds(5);
private TimeSpan m_currentInterval;
private volatile bool m_shutdown = false;
private volatile System.Threading.Thread m_thread;
private System.Threading.AutoResetEvent m_waitLock;
private Serializer m_serializer;
private readonly Dictionary<string, string> m_updateRequest;
public ISerializableStatus Status { get { return m_status; } }
private object m_lock = new object();
private Queue<Dictionary<string, string>> m_workQueue = new Queue<Dictionary<string,string>>();
public HttpServerConnection(Uri server, System.Net.NetworkCredential credentials)
{
m_uri = server;
m_serializer = new Serializer();
m_updateRequest = new Dictionary<string, string>();
m_updateRequest.Add("action", "get-current-state");
UpdateStatus();
m_waitLock = new System.Threading.AutoResetEvent(false);
m_thread = new System.Threading.Thread(ThreadRunner);
m_thread.Start();
}
private void UpdateStatus()
{
ISerializableStatus old_status = m_status;
m_status = PerformRequest<ISerializableStatus>(m_updateRequest);
m_currentInterval = m_status.ProgramState == Server.Serialization.LiveControlState.Paused ? m_updateIntervalIdle :
m_status.ActiveScheduleId < 0 ? m_updateIntervalIdle : m_updateIntervalActive;
bool somethingChanged = false;
if (old_status != null)
{
somethingChanged |=
old_status.ActiveBackupState != m_status.ActiveBackupState
||
old_status.ActiveScheduleId != m_status.ActiveScheduleId
||
old_status.ProgramState != m_status.ProgramState
||
old_status.SchedulerQueueIds.Count != m_status.SchedulerQueueIds.Count;
if (!somethingChanged && old_status.RunningBackupStatus != null && m_status.RunningBackupStatus != null && m_status.ActiveScheduleId >= 0)
{
somethingChanged |=
old_status.RunningBackupStatus.Message != m_status.RunningBackupStatus.Message
||
old_status.RunningBackupStatus.Mode != m_status.RunningBackupStatus.Mode
||
old_status.RunningBackupStatus.Operation != m_status.RunningBackupStatus.Operation
||
old_status.RunningBackupStatus.Progress != m_status.RunningBackupStatus.Progress
||
old_status.RunningBackupStatus.SubMessage != m_status.RunningBackupStatus.SubMessage
||
old_status.RunningBackupStatus.SubProgress != m_status.RunningBackupStatus.SubProgress;
}
if (!somethingChanged)
{
for (int i = 0; i < m_status.SchedulerQueueIds.Count; i++)
somethingChanged |= old_status.SchedulerQueueIds[i] != m_status.SchedulerQueueIds[i];
}
if (somethingChanged && StatusUpdated != null)
StatusUpdated(m_status);
}
}
private void ThreadRunner()
{
while (!m_shutdown)
{
try
{
Dictionary<string, string> req;
bool any = false;
do
{
req = null;
lock (m_lock)
if (m_workQueue.Count > 0)
req = m_workQueue.Dequeue();
if (m_shutdown)
return;
if (req != null)
{
any = true;
PerformRequest<string>(req);
}
} while (req != null);
if (!(any || m_shutdown))
m_waitLock.WaitOne(m_currentInterval, true);
if (m_shutdown)
return;
UpdateStatus();
}
catch (Exception ex)
{
Console.WriteLine("Request error: " + ex.Message);
}
}
}
public void Close()
{
m_shutdown = true;
m_waitLock.Set();
if (!m_thread.Join(TimeSpan.FromSeconds(10)))
m_thread.Abort();
m_thread.Join(TimeSpan.FromSeconds(10));
}
private static string EncodeQueryString(Dictionary<string, string> dict)
{
return string.Join("&", Array.ConvertAll(dict.Keys.ToArray(), key => string.Format("{0}={1}", Uri.EscapeUriString(key), Uri.EscapeUriString(dict[key]))));
}
private string PerformRequest(Dictionary<string, string> queryparams)
private T PerformRequest<T>(Dictionary<string, string> queryparams)
{
queryparams["format"] = "json";
string query = EncodeQueryString(queryparams);
byte[] data = ENCODING.GetBytes(query);
@@ -43,16 +167,81 @@ namespace Duplicati.GUI.TrayIcon
using(System.Net.HttpWebResponse r = (System.Net.HttpWebResponse)req.GetResponse())
using (System.IO.Stream s = r.GetResponseStream())
using(System.IO.MemoryStream ms = new System.IO.MemoryStream())
if (typeof(T) == typeof(string))
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
s.CopyTo(ms);
return (T)(object)ENCODING.GetString(ms.ToArray());
}
}
else
{
using (var sr = new System.IO.StreamReader(s, ENCODING, true))
return m_serializer.Deserialize<T>(sr);
}
}
private void ExecuteAndNotify(Dictionary<string, string> req)
{
lock (m_lock)
{
s.CopyTo(ms);
return ENCODING.GetString(ms.ToArray());
m_workQueue.Enqueue(req);
m_waitLock.Set();
}
}
public ServiceState State
public void Pause(string duration = null)
{
get { return m_serviceState; }
Dictionary<string, string> req = new Dictionary<string, string>();
req.Add("action", "send-command");
req.Add("command", "pause");
if (!string.IsNullOrWhiteSpace(duration))
req.Add("duration", duration);
ExecuteAndNotify(req);
}
public void Resume()
{
Dictionary<string, string> req = new Dictionary<string, string>();
req.Add("action", "send-command");
req.Add("command", "resume");
ExecuteAndNotify(req);
}
public void StopBackup()
{
Dictionary<string, string> req = new Dictionary<string, string>();
req.Add("action", "send-command");
req.Add("command", "stop");
ExecuteAndNotify(req);
}
public void AbortBackup()
{
Dictionary<string, string> req = new Dictionary<string, string>();
req.Add("action", "send-command");
req.Add("command", "abort");
ExecuteAndNotify(req);
}
public void RunBackup(long id, bool forcefull = false)
{
Dictionary<string, string> req = new Dictionary<string, string>();
req.Add("action", "send-command");
req.Add("command", "run-backup");
req.Add("id", id.ToString());
if (forcefull)
req.Add("full", "true");
ExecuteAndNotify(req);
}
public void Dispose()
{
Close();
}
}
}
@@ -7,15 +7,24 @@ namespace Duplicati.GUI.TrayIcon
{
static class Program
{
public static HttpServerConnection Connection;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
//TODO: Fix options for non-hosted
using (new HostedInstanceKeeper(args))
{
using (Connection = new HttpServerConnection(new Uri("http://localhost:8080/control.cgi"), null))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WindowsMainForm());
}
}
}
}
}
@@ -1,17 +1,17 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.225
// Runtime Version:4.0.30319.239
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Duplicati.GUI.TrayIcon.Properties
{
namespace Duplicati.GUI.TrayIcon.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -22,50 +22,175 @@ namespace Duplicati.GUI.TrayIcon.Properties
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Duplicati.GUI.TrayIcon.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}
internal static System.Drawing.Bitmap Clock05 {
get {
object obj = ResourceManager.GetObject("Clock05", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Clock15 {
get {
object obj = ResourceManager.GetObject("Clock15", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Clock30 {
get {
object obj = ResourceManager.GetObject("Clock30", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Clock60 {
get {
object obj = ResourceManager.GetObject("Clock60", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap CloseMenuIcon {
get {
object obj = ResourceManager.GetObject("CloseMenuIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Delay {
get {
object obj = ResourceManager.GetObject("Delay", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Pause {
get {
object obj = ResourceManager.GetObject("Pause", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Play {
get {
object obj = ResourceManager.GetObject("Play", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap SettingsMenuIcon {
get {
object obj = ResourceManager.GetObject("SettingsMenuIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap StatusMenuIcon {
get {
object obj = ResourceManager.GetObject("StatusMenuIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Stop {
get {
object obj = ResourceManager.GetObject("Stop", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Throttle {
get {
object obj = ResourceManager.GetObject("Throttle", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Icon TrayNormal {
get {
object obj = ResourceManager.GetObject("TrayNormal", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Icon TrayNormalError {
get {
object obj = ResourceManager.GetObject("TrayNormalError", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Icon TrayNormalPause {
get {
object obj = ResourceManager.GetObject("TrayNormalPause", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Icon TrayNormalWarning {
get {
object obj = ResourceManager.GetObject("TrayNormalWarning", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Icon TrayWorking {
get {
object obj = ResourceManager.GetObject("TrayWorking", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Icon TrayWorkingPause {
get {
object obj = ResourceManager.GetObject("TrayWorkingPause", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
internal static System.Drawing.Bitmap WizardMenuIcon {
get {
object obj = ResourceManager.GetObject("WizardMenuIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
@@ -68,9 +69,10 @@
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
@@ -85,9 +87,10 @@
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
@@ -109,9 +112,67 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Clock05" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Clock05.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Clock15" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Clock15.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Clock30" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Clock30.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Clock60" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Clock60.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="CloseMenuIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\CloseMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Delay" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Delay.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Pause" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Pause.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Play" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="SettingsMenuIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\SettingsMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="StatusMenuIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\StatusMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Stop" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Throttle" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Throttle.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayNormal" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayNormal.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayNormalError" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayNormalError.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayNormalPause" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayNormalPause.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayNormalWarning" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayNormalWarning.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayWorking" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayWorking.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TrayWorkingPause" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TrayWorkingPause.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="WizardMenuIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\WizardMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.GUI.TrayIcon
{
public enum RunnerState
{
Started,
Suspended,
Running,
Stopped,
}
public enum LiveControlState
{
Running,
Paused
}
}
@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.239
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Duplicati.GUI.TrayIcon.Strings {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class WindowsMainForm {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal WindowsMainForm() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Duplicati.GUI.TrayIcon.Strings.WindowsMainForm", typeof(WindowsMainForm).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Pause.
/// </summary>
internal static string PauseMenuText {
get {
return ResourceManager.GetString("PauseMenuText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Resume.
/// </summary>
internal static string ResumeMenuText {
get {
return ResourceManager.GetString("ResumeMenuText", resourceCulture);
}
}
}
}
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PauseMenuText" xml:space="preserve">
<value>Pause</value>
</data>
<data name="ResumeMenuText" xml:space="preserve">
<value>Resume</value>
</data>
</root>
@@ -0,0 +1,251 @@
namespace Duplicati.GUI.TrayIcon
{
partial class WindowsMainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowsMainForm));
this.label1 = new System.Windows.Forms.Label();
this.TrayMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.statusToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.wizardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.controlToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pauseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pausePeriodToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DelayDuration05Menu = new System.Windows.Forms.ToolStripMenuItem();
this.DelayDuration15Menu = new System.Windows.Forms.ToolStripMenuItem();
this.DelayDuration30Menu = new System.Windows.Forms.ToolStripMenuItem();
this.DelayDuration60Menu = new System.Windows.Forms.ToolStripMenuItem();
this.stopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.throttleOptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.TrayIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.TrayMenu.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label1.Location = new System.Drawing.Point(8, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(123, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Duplicati dummy window";
//
// TrayMenu
//
this.TrayMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statusToolStripMenuItem,
this.wizardToolStripMenuItem,
this.toolStripSeparator1,
this.optionsToolStripMenuItem,
this.toolStripSeparator2,
this.controlToolStripMenuItem,
this.toolStripSeparator3,
this.quitToolStripMenuItem});
this.TrayMenu.Name = "TrayMenu";
this.TrayMenu.Size = new System.Drawing.Size(153, 154);
//
// statusToolStripMenuItem
//
this.statusToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
this.statusToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.StatusMenuIcon;
this.statusToolStripMenuItem.Name = "statusToolStripMenuItem";
this.statusToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.statusToolStripMenuItem.Text = "Status";
this.statusToolStripMenuItem.Click += new System.EventHandler(this.statusToolStripMenuItem_Click);
//
// wizardToolStripMenuItem
//
this.wizardToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.WizardMenuIcon;
this.wizardToolStripMenuItem.Name = "wizardToolStripMenuItem";
this.wizardToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.wizardToolStripMenuItem.Text = "Wizard...";
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6);
//
// optionsToolStripMenuItem
//
this.optionsToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.SettingsMenuIcon;
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.optionsToolStripMenuItem.Text = "Options...";
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6);
//
// controlToolStripMenuItem
//
this.controlToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.pauseToolStripMenuItem,
this.pausePeriodToolStripMenuItem,
this.stopToolStripMenuItem,
this.throttleOptionsToolStripMenuItem});
this.controlToolStripMenuItem.Name = "controlToolStripMenuItem";
this.controlToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.controlToolStripMenuItem.Text = "Control";
//
// pauseToolStripMenuItem
//
this.pauseToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Pause;
this.pauseToolStripMenuItem.Name = "pauseToolStripMenuItem";
this.pauseToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
this.pauseToolStripMenuItem.Text = "Pause";
this.pauseToolStripMenuItem.Click += new System.EventHandler(this.pauseToolStripMenuItem_Click);
//
// pausePeriodToolStripMenuItem
//
this.pausePeriodToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.DelayDuration05Menu,
this.DelayDuration15Menu,
this.DelayDuration30Menu,
this.DelayDuration60Menu});
this.pausePeriodToolStripMenuItem.Name = "pausePeriodToolStripMenuItem";
this.pausePeriodToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
this.pausePeriodToolStripMenuItem.Text = "Pause period";
//
// DelayDuration05Menu
//
this.DelayDuration05Menu.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Clock05;
this.DelayDuration05Menu.Name = "DelayDuration05Menu";
this.DelayDuration05Menu.Size = new System.Drawing.Size(152, 22);
this.DelayDuration05Menu.Tag = "5m";
this.DelayDuration05Menu.Text = "5 minutes";
this.DelayDuration05Menu.Click += new System.EventHandler(this.DelayDuration05Menu_Click);
//
// DelayDuration15Menu
//
this.DelayDuration15Menu.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Clock15;
this.DelayDuration15Menu.Name = "DelayDuration15Menu";
this.DelayDuration15Menu.Size = new System.Drawing.Size(152, 22);
this.DelayDuration15Menu.Tag = "15m";
this.DelayDuration15Menu.Text = "15 minutes";
this.DelayDuration15Menu.Click += new System.EventHandler(this.DelayDuration15Menu_Click);
//
// DelayDuration30Menu
//
this.DelayDuration30Menu.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Clock30;
this.DelayDuration30Menu.Name = "DelayDuration30Menu";
this.DelayDuration30Menu.Size = new System.Drawing.Size(152, 22);
this.DelayDuration30Menu.Tag = "30m";
this.DelayDuration30Menu.Text = "30 minutes";
this.DelayDuration30Menu.Click += new System.EventHandler(this.DelayDuration30Menu_Click);
//
// DelayDuration60Menu
//
this.DelayDuration60Menu.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Clock60;
this.DelayDuration60Menu.Name = "DelayDuration60Menu";
this.DelayDuration60Menu.Size = new System.Drawing.Size(152, 22);
this.DelayDuration60Menu.Tag = "1h";
this.DelayDuration60Menu.Text = "1 hour";
this.DelayDuration60Menu.Click += new System.EventHandler(this.DelayDuration60Menu_Click);
//
// stopToolStripMenuItem
//
this.stopToolStripMenuItem.Enabled = false;
this.stopToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Stop;
this.stopToolStripMenuItem.Name = "stopToolStripMenuItem";
this.stopToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
this.stopToolStripMenuItem.Text = "Stop";
this.stopToolStripMenuItem.Click += new System.EventHandler(this.stopToolStripMenuItem_Click);
//
// throttleOptionsToolStripMenuItem
//
this.throttleOptionsToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.Throttle;
this.throttleOptionsToolStripMenuItem.Name = "throttleOptionsToolStripMenuItem";
this.throttleOptionsToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
this.throttleOptionsToolStripMenuItem.Text = "Throttle options...";
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(149, 6);
//
// quitToolStripMenuItem
//
this.quitToolStripMenuItem.Image = global::Duplicati.GUI.TrayIcon.Properties.Resources.CloseMenuIcon;
this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
this.quitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.quitToolStripMenuItem.Text = "Quit";
//
// TrayIcon
//
this.TrayIcon.ContextMenuStrip = this.TrayMenu;
this.TrayIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("TrayIcon.Icon")));
//
// WindowsMainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(142, 29);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "WindowsMainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "Duplicati Control Window";
this.Load += new System.EventHandler(this.MainForm_Load);
this.TrayMenu.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ContextMenuStrip TrayMenu;
private System.Windows.Forms.ToolStripMenuItem statusToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem wizardToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem controlToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem pauseToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem pausePeriodToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem DelayDuration05Menu;
private System.Windows.Forms.ToolStripMenuItem DelayDuration15Menu;
private System.Windows.Forms.ToolStripMenuItem DelayDuration30Menu;
private System.Windows.Forms.ToolStripMenuItem DelayDuration60Menu;
private System.Windows.Forms.ToolStripMenuItem stopToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem throttleOptionsToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
private System.Windows.Forms.NotifyIcon TrayIcon;
}
}
@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Duplicati.GUI.TrayIcon
{
public partial class WindowsMainForm : Form
{
private bool m_stateIsPaused = false;
private bool m_hasError = false;
private bool m_hasWarning = false;
public WindowsMainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
BeginInvoke((Action)(() => { this.Visible = false; }));
TrayIcon.Visible = true;
Program.Connection.StatusUpdated += new HttpServerConnection.StatusUpdate(Connection_StatusUpdated);
Connection_StatusUpdated(Program.Connection.Status);
}
void Connection_StatusUpdated(Server.Serialization.ISerializableStatus status)
{
if (this.InvokeRequired)
this.Invoke(new HttpServerConnection.StatusUpdate(Connection_StatusUpdated), status);
else
{
if (status.ActiveScheduleId < 0)
{
if (status.ProgramState == Server.Serialization.LiveControlState.Running)
{
if (m_hasError)
TrayIcon.Icon = Properties.Resources.TrayNormalError;
else if (m_hasWarning)
TrayIcon.Icon = Properties.Resources.TrayNormalWarning;
else
TrayIcon.Icon = Properties.Resources.TrayNormal;
}
else
TrayIcon.Icon = Properties.Resources.TrayNormalPause;
}
else
{
TrayIcon.Icon =
status.ProgramState == Server.Serialization.LiveControlState.Running ?
Properties.Resources.TrayWorking : Properties.Resources.TrayWorkingPause;
}
if (status.ProgramState == Server.Serialization.LiveControlState.Running)
{
pauseToolStripMenuItem.Image = Properties.Resources.Pause;
pauseToolStripMenuItem.Text = Strings.WindowsMainForm.PauseMenuText;
m_stateIsPaused = false;
}
else
{
pauseToolStripMenuItem.Image = Properties.Resources.Play;
pauseToolStripMenuItem.Text = Strings.WindowsMainForm.ResumeMenuText;
m_stateIsPaused = true;
}
}
}
private void statusToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
{
if (m_stateIsPaused)
Program.Connection.Resume();
else
Program.Connection.Pause();
}
private void stopToolStripMenuItem_Click(object sender, EventArgs e)
{
Program.Connection.StopBackup();
}
private void DelayDuration05Menu_Click(object sender, EventArgs e)
{
Program.Connection.Pause("5m");
}
private void DelayDuration15Menu_Click(object sender, EventArgs e)
{
Program.Connection.Pause("15m");
}
private void DelayDuration30Menu_Click(object sender, EventArgs e)
{
Program.Connection.Pause("30m");
}
private void DelayDuration60Menu_Click(object sender, EventArgs e)
{
Program.Connection.Pause("1h");
}
}
}
@@ -0,0 +1,630 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>221, 17</value>
</metadata>
<metadata name="TrayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>327, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="TrayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAwAMDAQAAEABABoBgAAxgAAACAgEAABAAQA6AIAAC4HAAAYGBAAAQAEAOgBAAAWCgAAEBAQAAEA
BAAoAQAA/gsAADAwAAABAAgAqA4AACYNAAAgIAAAAQAIAKgIAADOGwAAGBgAAAEACADIBgAAdiQAABAQ
AAABAAgAaAUAAD4rAAAwMAAAAQAgAKglAACmMAAAICAAAAEAIACoEAAATlYAABgYAAABACAAiAkAAPZm
AAAQEAAAAQAgAGgEAAB+cAAAKAAAADAAAABgAAAAAQAEAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4d3d3d3d3
d3d3d3d3d3d3d3cAAAAAAIeIiPj4+Pj4+Pj4+Pj4+Pj4+Ph4AAAACHh3JyNiNiNiNiNiNiNiNiNiNniH
cAAACIcnInI2I2I2I2I2I2I2I2I2MiN/cAAAh4JyemJjanJ6cnpyenJ6cnpyY2poiAAAiHIqNjOmMjYj
ajY2JycjajYnpycnhwAAiCcnImJyemOoeHh4eHh4eHh4dyMniAAAh3KnJ6cqNjY4////////////h6an
hwAAiCciejJyY6Jn/4+PiPiI+I+P9ycj9wAAiCJ6JyajYnJ4+P+P+Pj4j4iPh6cmiAAAiHo2NqNjp6Ko
/4+Pj4+PiPiP9yJ69wAAiCYno2NiYnJ3//j4iIiIiIj492OniAAAiCOmJjpjo2p4+PiIiIiIiIiPh6Yy
9wAAiHJzeHd4d3d3//j/j/j4+Ij49yemiAAAiCpqiP/4///4//+P+Pj4j4+Ph6Yz+AAAiHI3j4j4+IiI
+PiIiPiIiIiP9yNqiAAA96emf/j4+Pj3//j4+Ij4+IiPh6aniAAAiHI6j4+PiPiI+P+P/4//j/iP92On
iAAA9yp2iPj4j4iI/4iIj4j4+Pj496cm+AAAiHp6j4+IiIiI//j4j4j//4iPh6ajiAAA+CcjiPiIiIiI
+P//+Pj4+Pj/9yen+AAAiCp6j////4+I/4iIj4j4+PiPh6ei9wAAiHpjiIiIiIiI//iIj4iIiIj/96Y2
+AAA+Cenj/+IiPiIj4//////+Pj492p6iAAAiKeniPj/j4iI//+Pj4+Pj4+Ph6en+AAAiHp6j/+IiPj4
+P///////4iIiHp6iAAA+Cd3j4+I+PiI/4+Pj4+Pj4iIhqh3+AAAiKeoj/j/j4+I////////+I+Id3p6
iAAAiHeniP+I+PiI/4+Pj4+Pj4iIp6in9wAAiKeKj/j4iPj4////////+IiGiod6+AAAiDqHj/+P+P+I
+Pj4+Pj4/4eoqKiniAAAiGioj4/4/4/4iIiIiIiIeH53d3qK9wAAiKeKj/j/j/j///iPiH6neoqKioh6
9wAAiHqIj/+P+P+Pj4iIiIeKiKiHeKin9wAAh6h3j4/4/4//+Pj4iKiod4qKioiKiAAA93d3j///j/j4
/4j4joeHd4eHiKin9wAAiKh4j4+P////j/iId3eoeoqKh4eKiAAAiDioj///j4+P+PiOuKiIeIiIqKh6
9wAA92eIiIiIiIiIiIh4qIiod6ioiId3iAAAiHqKh4eHiHiHjod4iKiIeIiHd3eohwAAD3eoioeKh4qH
h3h3eIioioeHh6eHgAAACIh3p6p6emp6qqqqqqenp6qqp3h4cAAAAIiHh4eHh4h4eIiIh4eHeHh4h4eI
AAAAAACIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA/AAAAAA/AADwAAAAAA8AAOAAAAAABwAA4AAAAAAH
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADgAAAAAAcAAOAA
AAAABwAA8AAAAAAPAAD8AAAAAD8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAId3d3d3d3d3d3d3eAAAAAeIiHiI
eIh4iHiIeIhwAACHciJyInIiciJyInInhwAIgicnononpypypyejYniACHcqcnI2d3d3d3d3d3oocAhy
ciKnInj///////hyeHAIenJ6cnp4+Pj4iIj/aihwCHJ6cmOmP/+Pj/j4j3NogAh6NiOmMn+IiIiIiI9q
OHAIgmeIiIh///+PiI+PcmiACHOn+PiPiPiI+IiIj2OocAiCd/j4+I//j4j/+P96eIAIemf4+IiPj4j4
+PiPY6hwCIKo+IiIiPj4+P+I/2pogAh3p//4+I/4+PiP+PhzqHAIinf4iIiPj4j4iIj/aniACHp3/4/4
j//////4+HeocAiHqPiIj4j4+Pj4+Ih6eIAIenj//4+P/////4j3eniACIeo+Ij4j4+Pj4+IioeocAh6
iI/4/4//////iH6oqIAIh6j/j4+IiIiHeOeod4hwCHqI//////iIjqioiop4cAh4ePj4+Pj4+HiKh3h4
qIAIeoj/////+Ih6iHioqIhwCHio+I+I+IiOiKh4h4eocAiKiIiIiOiId3iHeoeHqIAAh3qKinqKioqK
ioiop4gAAAiHd3eHd3d3d3d3d4hwAAAAiIiIiIiIiIiIiIiIAAAAAAAAAAAAAAAAAAAAAAAA//////AA
AA/gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAcAAAAPgAAAH8AAAD///
//8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA
AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAACI
iIiIiIiIiIh4AAh3IiIiIiIiIid4gAhycnNnNnNnNjIngAgiNiY2iIiIiPgigAh6Y6On////j4hjgAgj
anYn/4iI+IimgAhqdzd3+Pj4iPgjgAg2j4+I/4+IiIhqgAgjj4+I+Pj/+PgngAh6j4iI+I+I+PimgAin
j4+I//j/iPgjgAh6j4iI+I+I+Pim8Ainj4+I////+Ih6gAh3j4+I/4+PiIengAinj4j4////+IqK8Ah3
j//4iIiIiGh3gAioj4+P+PiKioqKgAh4j///+IjoeHiogAioj/j4+IioqKiKgAh4iIiIiHiIiIeHgAiK
enp6eoqnp6iogACIiIiIiIiIiIiIAAAAAAAAAAAAAAAAAP///wDAAAMAgAABAIAAAQCAAAEAgAABAIAA
AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA
AQDAAAMA////ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAA
AAAId3d3d3d3gAcioqenp6JwB6cnj4+P93AHInKI+IiGcAd4iI+Pj/KACn+Pj4+I9jAHeIiPj/j3oAev
+P+Pj4eAB4j4j//4ioAHf4+P+PiGgAeI//iId6igCo/4+Iioh4AIiIiIh4d4oAh6h3qKioeAAAAAAAAA
AAD//wAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
AAD//wAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAvkS8AL5YvAC+a
LwAvnS8ANYk1ADWMNQA/hj8AN484ADiPOAAwkTAAMJUwADaRNgA2lTYAMJgwADCeMAA3kzgAOJQ4ADiZ
OAA5nTkAMKMwADigNwAwqzAAOqE6ADumOwA8ojwAPaY8ADyrPAAxsDEAPbQ9AECLQABdi10AQK9BAEK0
QgBDu0QATb5NAFukXABZvlkAYY1hAGGQYgBrkGkAdJJyAHWUcwB2lnQAd5h0AHicdgB8n3oAYaphAH6i
fAB7sXkARMREAEjASABUwlQAW8ZbAF/KXwBjxWMAY8xjAGrMagBr0WsAbNpsAHPUcwB22HYAe9V7AHzZ
fACAk30AgaJ/AIDXfwCLi4sAi4uMAI2NjgCFkYEAg5eDAIaShQCIlIQAiZWIAI+PkACRkZIAlJaQAJSU
lQCWmZMAl5qUAJiblQCZnJYAl5eYAJiYmQCbnpgAnJ6YAJqanACdnZ0AhKSFAI+jjwCGsIQAi7OJAJC1
jwCYoZkAnaCaAJq6mACjp58An5+gAKGhogCjpKAApaaiAKOjpACkpKYAqqamAKOooAClqaEApqikAKio
pACnp6gAp66oAKioqQCrrKgAqqqsAKysrgCyrq0AqrSoALOwrwCurrAAsLCyALWxsQC2tbIAs7O0ALa2
tgC8tbIAtby1ALq5tQC5uLkAvbq6AL2+ugC+vLwAwreyAMK4swDBubYAxbq2AMG8uQDGvbkAwb+/AMW/
vADIv7wAgt2CAIrdigCSwpEAmcSXAJ7AnQCF4IUAi+KLAJPkkwClwaIAqcOnAK/HrQCzzrEAvsy8AMPA
vgDIwb4AwM2+AMHBwADFwsEAxcXCAMPDxADGxcYAy8PAAMrEwQDMxcIAyMbFAM3HxADCzcAAzcjGAMnJ
yADNysgAy8zJAM3OywDNzc4A2s3HAN3MxgDSzcoA2M7JAN7OyADP0M0A1dDOAN7QygDa0s0A3tHNAM/P
0ADR0dEA1tLQANPT1ADV1dUA29XSAN7Y1QDX19gA2dnZANvb3ADc3N0A4dHKAODTzQDk08wA4tTPAOXV
zgDr1s4A7NfOAOzYzwDh1tIA5tfQAOjX0ADm2NIA4drWAOXa1QDo2dMA7drSAO3c0wDp2tQA7tvUAOnc
1gDu3dUA4tzZAOXd2gDh390A5d/cAOne2QDt39gA8N/XAOXg3QDr4d0A8OHaAPDi3ADx5N4A4+LhAOrk
4ADs5eEA6ubkAOzn5ADu6OUA6urpAOvs6wDv7+0A8ubgAPLo4gDx6eYA9OrmAPTs5wDw6+gA8u3qAPXu
6gDz7uwA9O/tAPbw7QD48u8A8vLxAPn08QD5+PcA+fn4AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUU1NERERERERERERERERERERERERERERERERE
RERERERERFMAAAAAAAAAAAAAZ2dUiauruLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLjAuHJEVAAA
AAAAAAByZ2duHwcFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUHJ324S1QAAAAAAACeZ0cFCgoK
AQoBAQEKAQEKAQEKAQEKAQEKAQEKAQoBAQoBAQoKCgVauFMAAAAAAH9tVAUKCgoKCgoKCgoKCgoKCgoK
CgoKCgoKCgoKCgoKCgoKCgoKCgoJfXpTAAAAALhnHwELAQEKAQoBAQEKAQEKCgkSCQkJEgkJCRIJCQkS
CQkJEgkKCgoBJ8BTAAAAALhUHgEKAQEKAQoBAQEKAQESSmFfX19fX19fVVVVVVVVUVVRUVEoAQoBHsBV
AAAAAKtUCRICAhIBAhIBAhIBAhISYfv7+/v7+/v7+/v7+/r6+vr7++kpChICCr5TAAAAALdUEQECAgIC
AgICAgICAgESYfvw8Ozs7Ozd3d3d3cnd3cnd3ekpAgICCbhUAAAAALhUCQ8PAQICAgICAgICAgIVavvw
7Ozs3d3d3d3HycnHx8fH7OkpAgICCcBUAAAAALhnEQIPAgIPAgIPAgIPAg8Vavvw8PDs7Ozs3d3d3cfJ
x8fH3ekpAhUCEr5nAAAAALhnChICDwIUAhQCDw8PAg8Vavvw8N3OzsXFtraxsbGurq7H7OksAg8CEr5n
AAAAALhnEg8PDxQUFQ8PDw8PDw8Xavv38KShoaGIiIiGhoaGg4PH7OkpDw8PEr9nAAAAALhnEg8PFUBH
R0dHR0dGRkZHaPv28PDn593n3dvb3c7dxczd7OksDw8PE79nAAAAALhyEhQUF2fp6enp6enp6enncvv2
9vDw6e3w8N3n293O3d3M7OksFBQPE8BuAAAAALhyEhQVF2Hw59vb293O3c7Fc/v28KSkpaHavaSkiIiI
hobd8OksFBQUE8ByAAAAAMByFw8WF2rp3dvdxc7HxcWxc/v29trazs7wvbbn3efd2ojb8OksFBUPF8By
AAAAALhyFxYWGmr43d7a293FzsfFc/v29vD38/P3vbbw8PDw7Yjd8OksFhYWF8ByAAAAAMByFxYVGmrr
593Oxb22xa6uc/v28LOvr6fnvb329vDw8Ijp8OktFBQWF8B2AAAAAL92FxYWGmrr6dqIf4Z8fHx8c/v2
9raztq/tvb3w9vfw8KHt8OktFhYWF8B6AAAAAL92GhwWHXDr593Avb22tranc/v39vb28Pbwvb3w9vf3
8J7w9+ktFhYWGsF2AAAAAMB2GhwWHWfr5+fd593j3d7devv38L29vb3pva/n3ePn3Z7w9ukuHBYcGsF6
AAAAAMB2GhwcHXDp6d2eiYl/3q+Ic/v28K+ppKTd2qukqaSkpKTw+ekuHBwcGsF6AAAAAMB2HSIdIXL2
596vr6+n3amkevv29vDw8/D28PDw8PDw8PDw8OkuIiIiHcB6AAAAAL92HSMjJXr26fDn6fDp6a+zfvv3
9vf39/P58Pn58/fw59ra4+MuIyMjIMB2AAAAAL9yITQ0NXz48Oe2s7Oz3bi9ifv59/f39/n5+ff5+fnw
r56IqKtBNDQ0IcB2AAAAAL5yHTQlN3746eevr6+p6ba4ofv59/f39/f39/f38/nnc6ief2gxNDQ0IcB2
AAAAALh2ITU1OH/48Onw6fDp8L29nvv59/f59/f59/f5+fPngOnZiVs1NTU1IcByAAAAAMByHTg1OYH4
8Ona2trO6b24qfv5+fn5+fn5+fn3+fnnf9mJXDg2NTg1IsByAAAAALhyHTg4OZ748Omvr6un3cCvnvv7
+fv5+/n7+fn5+fnwiaBdOTg4ODg4IsBuAAAAALhnIjk6PIn48PDp6fDp6fDnpPj4+Pj4+Pj4+Pj4+Pjp
e2A5OTo6Ojo6IsBnAAAAALhnIjo6PKT49unw8PDw8Onwr6urpKSknqSedpSUlJSUjzw6Ojo6Ojo6IsBn
AAAAALhnIjw8PqT66fbw8Pjw+PD48PDw6b2vqbezXTw8PD08PDw8PDw8PDw8M71jAAAAALhhIj09Qqv4
9vD48Pjw8Pjw+PD424CeiYl6jj09PT09PT09PT09PT09M75jAAAAALdUIj1CQqv49vbw+PD4+PD48Pjw
457p2aiQPUI9jD2MPYw9jD2MPYw9I7hjAAAAALdUM4yMkqv4+Pjw+Pj48Pjw+PD446jZt5RCjIyMQoxC
QoyMjEKMjIyMI75UAAAAALhUMoyMkrP4+Pj4+Pj3+Pj4+Pj456i3lY2MkYySjJKMkpKMkoySjIyMMrhU
AAAAAMBUIZKSk7L4+Pn4+Pj4+Pj3+Pn46YmWjZKSkpKSkpKSkpKSkpKSkpKRI7hjAAAAAMBULzuSk5um
pqampqSmpJukm6Sbm5eTjZKSk5KSkpKSkpKSkpKSkpI7L6RUAAAAAH9/SjKSk5OTk5OTk5OTk5OTkpOS
k5OTk5OTk5OTk5OTkpOSk5KTk5IylGNjAAAAAADjUykyPJOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OT
k5OTk5OTOzJZbW0AAAAAAAB6uFNKJCIyMzMzMzIyMzIyMzI0MjIjMjMzMjMyMzIzMjMyNDIzL15fbm0A
AAAAAAAAesB6U0tMTExNTFFMTUxRTExMTExMTExMTExMTExMTUxNSkxTU2OfcgAAAAAAAAAAAAB6uMCr
pKCgpJ+goKCkn6CboKCfoKCgoKCgoKCgoKCgoKC3t30AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA/AAAAAA/AADwAAAAAA8AAOAAAAAABwAA4AAAAAAH
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADgAAAAAAcAAOAA
AAAABwAA8AAAAAAPAAD8AAAAAD8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
AAAAAAAAAAAAAAABAAAAAQAAAAAAADCPMAAwkTAAMJYwADCaMAAwnTAAMaIxADGlMQAxqjEAMa0xADKw
MgA1sjUARItEAEWMRQBGlkUATJJLAFWaVABWnlUAXZNcAF6VXABemF0AYJteAGCeXgBGu0YAS79LAEy9
TABVu1YAYaJfAHmXdwBzm3EAc5p0AHSadAB9kH4Ae5R8AH2XfgB6mHgAfJp6AH6cewB+nXwAYqVgAG+q
bQB0r3IAfaJ+AFHCUQBVx1UAVshWAFrHWgBfw18AWstaAFzMXABnx2YAYcthAGHPYQBoz2gAb8tuAGXS
ZQBo02gAa9ZrAG/TbwBu124AbNpsAHbXdgBy2nIAeNJ4AH3bfQB94H0AhoaGAI2NjQCBlIIAhJKEAIeU
hwCAmoEAgp2DAISYhQCQkJEAk5OUAJWVlgCXl5gAmZmaAJubnACenp8AgaWCAIWghgCDp4QAhqaEAIao
hQCIqoYAiayHAIejiACJpooAiamJAIuqjACMq40Ai6yMAIysjQCZopoAmqiaAJe3lQCetp4AnrybAKOn
nwCgsp4An7egAKGhogClpaYApa2iAKavpACmpqgAqamqAKqqrACtra4AprKmAKiwpQCjvKQApL6kAKm4
pwCsuakAqr6rALixrgCvr7AAr7uwALGxsQC1t7MAs7O0ALW1tQC7trQAsr+yALy4twC5ubkAvrq5ALu7
vAC+vb0Awru3AMa6tQDDvLkAxL+9AMi9uQCOzo0AhN6EAJPDkgCSx5EAlMiSAJXRlACd1J0Ant6eAKDf
nwCK4YoAkeSRAJrgmgCiwKAApsKlAKPIowCmyqYAp8OoAKnGqQCpyqoArsqtALLNsQC6w7oAt9G1ALrU
uQDGwL4AysG9AM3BvAC/v8AAwcHBAMXCwgDDw8QAxcXGAMjCwADNxMEAz8fEAMjIxgDHx8gAycnJAM3K
yQDNzMsAzMzMANDFwQDRyMUA1MvHANHNywDUzcoA0s7NANXPzADW0M4A2NHOANXU1ADY09AA2tTRANzW
0wDa1dQA3djVANrZ2QDf29gA3d3dAODSzQDl1M0A7NfOAOzYzwDi1tEA5tfQAOfZ0wDg2dYA5NrVAOrZ
0gDs2dEA6dvVAO7b1ADu3dYA4drYAOLd2gDl3tsA6t7YAO/f2ADl4N0A6uDbAO7h2wDp4t0A7uPdAO/k
3wDw4doA8ePcAPHk3gDj4uEA5OPiAOTk4wDl5eQA6OLgAOrk4ADt5eEA6OfmAOzn5ADu6OQA6urpAO3q
6QDt7OoA7u7sAPDm4QDx6eUA9OnkAPXs5wDw6+gA8u3qAPXu6QDy7uwA8vDuAPbw7QD48u8A8/HwAPXz
8QD09PIA+PPwAPj08gAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHlK
QkJCQkJCQkJCQkJCQkJCQkJCQkJDbQAAAAAAAABQbW9iYmJiYmJiYmJiYmJiYmJiYmJiZnilSgAAAAAA
bWANAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ2eUAAAAK5tDQECAgICAgICAgICAgICAgICAgICAgICAg2l
eQAApEYBAQICAgICAgIOJSUlJSUlJSUlJRwlHA8CAn5NAACkHAIEAgQCBAIEAhDg/f39+Pj29vb29vbs
EgIEcUoAAKQcAgQEBAQCBAQEEODw7u7W1tbGxsbGxvYSBAKWUAAApEcEBAQEBAQEBAQQ4Pju7u7W1tbO
xsbG6RIEBHFQAAClRwQEBAQEBgQEBhHg+MSysrKIiIiIiMbsFAQGllAAAKVYBgYdb29qb2pqZOD48PDm
3Nzczs7OzuwUBgSZZwAArVgGBlTs5tzc1Nyr4PjCvLjmuLS0qqrW7BUGBplnAAClWwYGVezWzMzJybLg
+Obm1Pa08ObctNzsFQYGm2sAAK5bCAZV7NzMyMm6iOD31MK+6br29PC07vYWCAiZbQAArlsICFfs1KmH
hIR24P3cwszpxPb097rw7BsICJttAACuWwgIV+zm5tzc1rTg9+bUwva45vDmuPD2GwgIm20AAK5bCwtV
7NyppKm6fef4wsLE5r6+usS6+OwnCwubbQAArlsXGGHs6dTm5r6l5vj49vb3+Pb29tTm4CgYGJttAACu
WxgrY/jmvK68wq7s+Pf39/f39/fCh32eKSsYm20AAK1bKy6W7Ozg5uDCuOz99/399/39977CwmYvLiub
bQAApVssM5b46cLCwsK47P399/399/33wrxzMjMzLJtnAAClVy43mf3swtTg8Lzg/f39/f39/f3CczY1
NTUum2cAAKVVNDqb/fb29vb25sK8vK6upYuNjYs/Ojo6OjeYZwAApVE3PZ347Pbw9vb29vaqpap5PT09
PT0/PT0/N5hQAACkKjlAn/329vbw9vbw9q7srYlAQEBAQEBAQEA7mEoAAKQqO4qg/fb2+Pj29vj2uK6O
ioqKioqKioqKij2YTQAApUY5kqDg4Obg4ODg4OCuj5KSkpKSkpKSkpKSPJZQAACuahqSlJGRkZGRkZGR
kZSTk5OTk5OTk5OTk5IreXkAAACtRho9QUFBQUFBQUFBQUFBQUFBQUFBQUE7K2BnAAAAAAClZxwdHh4e
HR4dHh0eHR0dHR0dHR0dHUZndwAAAAAAAACupYB5gHmAeYB5gHmAeYB5gHmAeYB7gK0AAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////8AAAD+AAAAfAAAADgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABwAAAA+AAAAfwAAAP/////ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
AAAAAAAAAAEAAAABAAAAAAAAL5EvAC+WLwAvmi8AMowyADWLNQAwkTAAMZQxADSSNAAwmjAAMZ4xADSZ
NAA1nzUAMKEwADClMAA1ojUANqY2ADCpMAAwrTAANqk2ADetNgA7rzsAObM5ADyxPABWklYAW5ZaAFuY
WQBcmFoAX5pfAEi4SABNvE0AZ5tlAG6ibABmtmcAabppAG2/bQBRwFEAVsBWAFbFVgBYxlgAXsZeAF3J
XQBizGIAZcxlAGvRawBs0WwAbdVtAHDRbwB11nUAedZ5AH/bfwB+3H4AhKGBAIK0gACRvY8Al6iVAJuh
nACcpJ0AoaGiAKenqACpqaoArq6uAKu7qQCvvq4AsL+uAK+vsACwsLAAsbaxALW1tgC+t7QAvrm3ALe3
uAC4uLkAvLy9AIPJggCC24IAid+JAJfBlQCH4IcAjeONAJDjkACjyaIArM6rALDArgCl2KQAqdmoALHC
sACyxLEAysC7AM3DvwC/v8AAwcHCAMPDxADFxMUAycLAAMrFwgDPx8MAycbGAM3HxQDIycYAx8fIAMnJ
yADOy8oAy8zIAM3MygDPz88A1cfBANHKxgDVycQA18zHANjLxgDVzswA2c7JAMnXxwDN1ssAy9rKANrQ
ywDa0c0Az8/QANbS0ADV1NIA1tbVANrV0QDc1dEA2tbUANnZ1wDe2NUA3NrZANvc2gDe3NsA3t7dAOXS
ygDl08wA5dXOAOfY0gDi2tYA6NnTAO3Z0QDp3NYA7t3WAOHb2ADi3NoA5N3ZAOXf3ADq39oA4OHfAOfg
3QDr4NsA6OHeAPDg2QDw4twA4uLhAOnj4ADq5OEA7OXiAO/p5QDv6ugA8ebhAPHq5gDy7eoA9u7qAPPv
7AD17+wA9vHuAPjy7gD08vEA+PTyAPn29AD6+PYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJOkE9PT09PT09PT09PT09
PUI7QgAAAGQ4GQUFBQUFBQUFBQUFBQUFBQUcREkAAEIZAQEBAQEBAQcHBwcHBwcHBwcBHD0AAEcFBwcB
AQEBH2dnZ2dnYWddYTcBB0kAAEILCQEDAwMDIKSdlpWLi4mJiz8LB0kAAEkHCwMDCwMDIKadk4uGhYWF
iz8DB0kAAEkLDRwaHBoZNKaTenVwbmpqi1MNC1oAAEkND2eYmJiYYaaZfo6GdXBullMNDV0AAF0PEGeT
hoaFWKaemZ56np11nVYND10AAF0NFWeTZm5YRaaOb4Z6pKB6nlYSDWcAAF0VEmeZmH6GXaaemZt6np56
oFYSFWQAAF0VF2eZYWF1RaaZjpiOjn5+pFYXF10AAF0dJXmejo6OZ6ampKCmoKB6eT4kHV0AAF0eKHmb
jn+OZ6ampKampqBdYTUnHl0AAEkkK36cenqOZ6impqampqBkNisrJF0AAEkkL3+cnJygf5F/f39yc3JN
LCwsJF0AAEkpMZGkoJymoKB6ZWFKLzAvMS8wKkkAAEIrS5GcppygnKR5f1FLMzMzMzMzK0gAAEkrTJil
pqWmpaV5UkxOTk5OTk5OK0gAAEghTFVVVVVVVVVUUFBQUFBQUFBMIzwAAHY4IiwuLi4uLiwsLC4sLi4u
LiwiOFsAAAByR0E9PDw8PDxBPTw9PTw9PT1DZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AMAA
AwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA
AQCAAAEAgAABAIAAAQCAAAEAgAABAMAAAwD///8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
AAAAAQAAAAEAAAAAAAAwkjAAMJYwADeSNgAwmzAAR5VGAEeZRgBInUcASZVIAFWUUwBWllUAWJtZAEii
RwBJp0gAVqBVAFSvUwBcp1sAW6FcAF2mXQBcq1sAXqtfAGiWaQBynnIAZ6NnAGmqagBqrmsAZLFlAGe0
ZgBgv2AAbLJsAGy2bABuuW4AeaZ6AHupewByu3MAdb11AHqzegB5tHoAeL14AGTNZAB0wXUAe8F6AHnG
eQB8xnwActVyAH7RfQCcvpsAp6moAKusqwCrr6wAt7q3AIbBhwCByoEAhsmFAIXOhgCF0IQAgN2AAIXZ
hACK0IoAncGcAJHQkQCS35IAnNecAJvemwChw58AjeKNAL3AuwC52rkAx8e/AMnGxgDIycIAyszFAM7O
ygDZycMA28zGANbOygDE08MA1NHPAN3QygDY0s8A39TPANbS0ADZ09AA2tTRANrW1QDe2NYA3dvaAN/d
2wDj1c4A4NbRAOPZ1QDl2dQA4NvYAOLc2QDk3dkA4d7cAOjf2wDC4sEA5eDeAOjh3gDt4dwA8ePdAPHk
3wDt5eEA6+bkAO3o5QDy5+IA8ermAPTq5QDx7OkA9e7qAPPw7gD08O0A+PLvAPXy8AD29PEA+PPwAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAADAWFxcXFxcXFxcXFyAvAAAVAQEBAQgKCgoKCgoB
IQAACgECAQIubmxqZmZqCBgAAAsCBAIEO2pZTkpKZAYYAAARDkdHREhsXGBOTmQHHQAAERNnW1hZZ1xi
bFtnDR0AABMTZ1lITW5cXG5cbw0fAAAaG21NWU1uZGdqXG0PKAAAHSttVFZWb3Nzb01CHCsAAB81bVxi
VnNzc3NIKyc1AAAiPHNubmpNR0A3LSwsNQAAIj5zbW9vX0w5OTg4ODoAACU+YWFhYUM9QUFBQUEzAAAy
JSYmJiYmJiYrIiYlMAAAAAAAAAAAAAAAAAAAAAAA//8AAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
AACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA//8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9fX4GeHh5Onp6
emmAgIF8gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GB
gn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf39/
gHx4eHlpdnZ3Onp6ewYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhISFBnl5
enSOjo7klpaX/pKSk/6Ojo7/i4uM/ouLi/+Li4v+i4uM/ouLjP6Li4v/i4uL/ouLi/6Li4v/i4uL/ouL
i/6Li4v/i4uL/ouLi/6Li4z/i4uL/ouLi/6Li4z/i4uM/ouLi/6Li4v/i4uL/ouLjP+Li4z+i4uM/ouL
i/+Li4z+i4uL/oyMjP+Ojo/+jY2O/oWFhuR1dXZ0enp7BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AACHh4gVjIyNxqSkpf+ZmZr/wMDB/87Ozv/Pz8//0NDQ/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR
0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR
0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0v/Y2Nn/1tbW/62trf+Pj4//fn5/xnh4eRYAAAAAAAAAAAAA
AAAAAAAAAAAAAJOTkwaUlJXGpqan/qSkpf6nrqj/X4tf/j+GP/42iDb/NYk1/jWJNf81iTX+NYk1/jWJ
Nf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJ
Nf41iTX/NYk1/jWJNf81iTX+NYk1/jWJNf81iTX+NYk1/jaINv8/hj/+YY1h/rW8tf/U1NT+jIyM/oCA
gMZ9fX4GAAAAAAAAAAAAAAAAAAAAAImJinTFxcX/n5+g/oOXg/41izX/L5Av/i+QL/4wkDD/L5Av/jCQ
MP8vkC/+L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+Q
L/4wkDD/L5Av/i+QL/4wkDD/L5Av/jCQMP8vkC/+L5Av/jCQMP8vkC/+L5Av/jCQMP8vkC/+L5Av/jWM
Nf+Po4/+1NTV/pKSk/96ent0AAAAAAAAAAAAAAAAmpqbB7CwsOSnp6j/maCa/zWNNf8wkTD/MJEw/zCR
MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
MP8wkTD/MJEw/zCRMP81jTX/tby1/7Ozs/+Li4zkg4OEBwAAAAAAAAAAl5eYO9PT1P6fn5//XItc/i+S
L/4wkjD/L5Iv/i+SL/4wkjD/L5Iv/jCSMP8vki/+L5Iv/i+SL/4wkjD/L5Iv/i+SL/4wkjD/N5Q3/jmU
Of45lTn/OZQ5/jmUOf45lDn/OZQ5/jmUOf45lDn/OZQ5/jmUOf45lDn/OZQ5/jmUOf85lDn+OZQ5/jmU
Of85lDn+OZQ5/jmUOf80kzT+L5Iv/jCSMP8vki/+YZBi/tra2v+VlZb+gICBOwAAAAAAAAAAnJydatPT
0/6cnJ3/QItA/i+TL/4wkzD/L5Mv/i+TL/4wkzD/L5Mv/jCTMP8vky/+L5Mv/i+TL/4wkzD/L5Mv/i+T
L/42ljb/i5eI/p6hm/6eoZv/naCa/p2fmf6cn5n/nJ6Y/puemP6bnZf/mp2X/pmclv6ZnJb/mZuV/pib
lf+Ym5X+l5qU/pealP+XmZP+lpmT/pSWkP9rkGn+L5Mv/jCTMP8vky/+QItB/tvb2/+ZmZn+g4OEagAA
AAAAAAAAq6urfc3Nzv+ZmZr/N484/zCVMP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCV
MP8wlTD/MJUw/zCVMP85mDj/o6ef//n6+f/6+vj/+fn4//n5+P/5+fj/+fn3//n59//5+fj/+fn3//n4
9//5+Pf/+fj3//n49//5+Pf/+fn3//n49//5+Pf/+fn3/+nq6f90knL/MJUw/zCVMP8wlTD/OI84/9XV
1v+YmJn/jIyNfQAAAAAAAAAAr6+wf87Ozv6bm5z/N5E3/i+WL/4wljD/L5Yv/i+WL/4wljD/L5Yv/jCW
MP8vli/+L5Yv/i+WL/4wljD/L5Yv/i+WL/45mjj/o6ig/vn5+P706+b/8+ji/vLm4P7y5d//8ePd/vDi
2/7w4Nr/79/Y/u/e1/7u3dX/7tzU/u3c0//t29P+7tvT/u3b0//t29P+8eXf/urq6f90knL+L5Yv/jCW
MP8vli/+N5E3/tXV1v+ampv+j4+QfwAAAAAAAAAAsbGyf8/Pz/+dnZ7/N5M4/zCYMP8wmDD/MJgw/zCY
MP8wmDD/MJgw/zCYMP8wmDD/MJgw/zCYMP8wmDD/MJgw/zCYMP85mzj/pKmh//n5+P/06+b/8+fi//Lm
4P/y5N7/8eLb//Dg2f/w39f/7t3V/+7b1P/t2tL/7dnR/+zYz//s187/7NfO/+zXzv/s187/8OLc/+rq
6f91k3L/MJgw/zCYMP8wmDD/N5M4/9bW1/+dnZ7/kZGSfwAAAAAAAAAAs7Ozf9DQ0f6fn6D/OJQ4/i+Z
L/4wmTD/L5kv/i+ZL/4wmTD/L5kv/jCZMP8vmS/+L5kv/i+ZL/4wmTD/L5kv/i+ZL/45nDj/pamh/vn5
+P717en/9Orl/vPp4/7z5+H/8uXf/vHj3f7x4tv/8ODZ/u/e1/7u3NX/7tvT/u3Z0f/s2ND+7NfP/uzX
zv/r1s3+8OLc/urq6f91lHP+L5kv/jCZMP8vmS/+OJQ4/tfX1/+fn6D+lJSVfwAAAAAAAAAAtLS1f9HR
0v6hoaL/OJY4/i+bL/4wmzD/L5sv/i+bL/4wmzD/L5sv/jCbMP8vmy/+L5sv/i+bL/4wmzD/L5sv/i+b
L/45njj/paqi/vn6+f727+v/9ezn/ufe2v7l29f/5NrV/uLX0/7i1tH/4dTP/uDTzf7f0cz/39DK/t7O
yP/dzcf+3czG/t/Nxv/s187+8OPd/urq6v91lHP+L5sv/jCbMP8vmy/+OJY4/tjY2P+hoaP+lpaXfwAA
AAAAAAAAtra2f9LS0/6jo6T/OJg4/i+dL/4wnTD/L50v/jGdMf4xnjH/MZ4x/jGeMf8xnjH+MZ4x/jGe
Mf4xnjH/MZ4x/jGeMf46oDr/pqqi/vn6+P738O3/8erm/s3Gw/7MxMH/y8PA/sjAvf7Hv7v/xr26/sa8
uf7Fu7f/xbq2/sO5tf/CuLP+wrey/sO3sv/r18/+8ePd/urq6v92lXP+L50v/jCdMP8vnS/+OJg4/tnZ
2f+kpKX+mJiZfwAAAAAAAAAAt7e4f9PT1P+lpaf/OZo5/zCfMP8wnzD/OKA3/4CTff+IlIX/iJSE/4eT
hP+Gk4P/hpOD/4WSgv+EkYH/hJGB/4SQgP+GkYL/qqem//n6+f/38e3/9u/r//Dp5f/u5+P/7ubh/+3k
3//s497/6+Hc/+vf2v/q3tj/6dzW/+ja1P/o2dP/59fR/+jX0P/t29P/8eXf/+rr6v92lnT/MJ8w/zCf
MP8wnzD/OZo5/9nZ2v+mpqf/mpqbfwAAAAAAAAAAuLi5f9TU1f6np6j/Opw6/jCgMP4xoDH/PKI8/qOk
oP7r7Ov/6+vq/uvr6v/r6+r+6+vq/uvr6v7r6+r/6uvq/urr6v7n5+b/sa6u/vn6+P738e3/9u/r/vLr
6P7x6ub/8enl/vDo5P716+f/8+nk/u7k3/7u4t3/7ODb/uzf2f/r3df+6tvV/uvb1P/u3dX+8ubg/urr
6v93l3T+MKAw/jGgMf8woDD+Opw6/tra2/+oqKn+nJydfwAAAAAAAAAAubm6f9XV1v6pqar/Op06/jCi
MP4xojH/PaM8/qSmov7v7+3/6uLd/urg2//p3tr+6N3Y/ujc1v7n29X/5trU/ubZ0v7j1c//sq2s/vn6
+P738e3/8uvn/s/Jx/7Nx8X/zcfE/sjCv/7o4d3/39jU/szFwv7Lw8D/x7+8/se+uv/Gvbn+xby4/sa8
uP/u3tf+8uji/urr6v93mHT+MKIw/jGiMf8wojD+Op06/tvb2/+qqqv+np6ffwAAAAAAAAAAurq7f9bW
1/+rq6z/Op86/zGkMf8xpDH/PaU8/6Wmov/v7+3/6uDb/+nd1//o29b/59nU/+fY0v/m19D/5dXO/+TT
zP/h0Mn/sq6t//n6+f/38e3/9e/r/+Xe2//j3Nn/49zZ/+Ha1//z7Oj/3dfT/9jSzv/u5uL/7eTg/+3j
3v/s4tz/6t7Z/8W8uP/u4Nr/8+nl/+rr6v93mXX/MaQx/zGkMf8xpDH/Op86/9vb3P+srK3/n5+hfwAA
AAAAAAAAu7u8f9fX2P6srK7/OqE7/jCmMP4xpjH/Pac8/qano/7v7+3/6+Ld/urf2v/p3tj+6dzX/uja
1f7n2dP/5tfR/uXWz/7i08v/sq6t/vn6+f738e3/9u/r/vbv6/738Oz/9u/r/vbv6/738Oz/3dfU/tvV
0f727ur/9e3p/vXs5//06uX+8ufi/sa+uv/v493+9Ovn/urr6v94mnX+MKYw/jGmMf8wpjD+OqE7/tzc
3P+tra/+oaGifwAAAAAAAAAAvLy9f9jY2P6tra//O6M7/jCoMP4xqDH/Pak8/qaopP7v7+7/7OTg/uvi
3f/i2dT+4NfS/t/V0P7e087/3tHN/t3Qy/7azcf/s6+u/vr6+f738e3/9O3p/tXPzf7Tzcr/0szJ/s/I
xv7t5uL/3tfV/tvV0v738Oz/9+/r/vbu6v/27ej+8+nl/si/vP/x5uH+9e3p/uvr6v94m3b+MKgw/jGo
Mf8wqDD+O6M7/tzc3f+vr7D+oqKjfwAAAAAAAAAAvb2+f9jY2f+urrD/O6U7/zGqMf8xqjH/Pas8/6eo
pP/v7+7/7ebi/+Xd2f/Cvbr/wry5/8C6t/++uLT/vbaz/721sf+8tLD/sa2s//n6+f/38e3/9O3p/9rT
0f/X0c7/1tDO/9PNyv/v6OT/3dfU/9vV0v/38Oz/9/Ds//fv6//27+v/9Ozn/8jBvv/y6OP/9u/r/+vr
6v95nHb/Maox/zGqMf8xqjH/O6U7/93d3f+wsLH/o6OlfwAAAAAAAAAAvb2+f9jY2f6vr7H/O6c7/jCs
MP4xrDH/Pa08/qiopP7v7+7/7ebi/uzk4P/f2dX+3tfT/t3W0v7c1ND/29PO/tvRzP7Yzsn/s7Cv/vn6
+f738e3/9u/r/vbv6/738Oz/9u/r/vbv6/738Oz/3dfU/tvV0v738Oz/9u/r/vfw7P/38Oz+9O3p/sjC
v//z6ub+9/Ht/uvr6v95nXb+MKww/jGsMf8wrDD+O6c7/t3d3f+wsLL+pKSlfwAAAAAAAAAAvr6+f9nZ
2f6wsLH/O6g7/jCuMP4xrjH/Pa49/qippf7v7+7/7ebi/u3m4v/s5eH+6+Tg/uvj3/7q4t7/6+Ld/urg
2/7m29b/tbGw/vn6+f738e3/9e7q/uDa1/7e2NX/3tfV/tzV0v7x6ub/3dfU/tfRz/7r5eH/6uTg/urk
4P/r5OD+6eLf/sjCv//z7Oj+9/Lv/uvr6v96nnf+MK4w/jGuMf8wrjD+O6g7/t3d3f+xsbP+pKSmfwAA
AAAAAAAAvr6+f9nZ2f+wsLH/O6o8/zGwMf8xsDH/PbA9/6mppf/v7+7/7ebi/+fg3P/Gwb//xcC+/8S/
vf/AvLn/49vX/9TNyv/Dvbr/s6+v//n6+f/38e3/8+zo/9HLyf/Pycf/zsjG/8rEwf/q5OD/4tzZ/8/J
x//OyMb/y8XC/8rEwv/LxML/ysTB/83Gw//17ur/+PPw/+vr6v96n3j/MbAx/zGwMf8xsDH/O6o8/93d
3f+xsbP/paWmfwAAAAAAAAAAvr6+f9nZ2f6vr7H/Pq0+/kG3Qf49tj3/RrVG/qusqP7v7+7/7ebi/urj
3//Uzsv+083K/tLNyv7Qy8j/6OHd/s/Kxv7MxsP/tbGx/vn6+f738e3/9u/r/vXu6v717ur/9O7q/vTt
6v738Oz/9u/r/vTu6v707er/9O3p/vTt6f/07en+8uvn/vHr5//z7Oj+9PDt/urq6f9+onz+P7c//kK4
Qv9GuUb+P60//t3d3f+xsbL+pKSmfwAAAAAAAAAAvb2+f9jY2f6vr7D/P68//k6+Tv5Ovk7/Wb5Z/ra2
sv7x8fD/7+nm/u/p5f/v6OX+7+jl/u7o5P7u6OT/7ujk/tPOy/7Uz8z/u7e3/vr6+f738u7/9/Dt/vfw
7f738O3/9/Dt/vfw7f738e3/9/Dt/vfx7f738e3/9/Ht/vfx7f/07uv+7Obj/ubg3f/l39z+5+Ph/uLi
4f9+n3z+Tr5O/k6+Tv9Ovk7+QK9B/t3d3f+wsLL+o6OlfwAAAAAAAAAAvb2+f9jY2f+urq//QLFA/1LB
Uv9SwVL/XcFd/7i4tf/y8vH/8Orn/+3n5P/Y09H/19LQ/9bRz//U0M3/6+Xi/9fT0f/Z1NL/wr+///v7
+v/48/D/+PLv//jy7//48u//+PLv//jy7//48u//+PLv//jy7//48u//+PLv//jy7//x7On/0s3L/8bB
v//FwL7/yMXE/8rJyP+Bon//UsFS/1LBUv9SwVL/QbFB/9zc3f+vr7D/o6OkfwAAAAAAAAAAvLy9f9fX
2P6tra7/QLJA/lfEV/5XxFf/YcRh/rq7t/7y8vH/8Ovn/uvm4//Szsz+0c3L/tHMy/7Oy8j/6eTh/tjU
0f7Z1dP/xMHA/vv7+v749PD/+PLv/vjy7/748+//+PLv/vjy7/748+//+PLv/vjy7/748+//+PLv/vjy
7//s5uP+s6+v/sjGx//FxMT+v729/qqmpv97sXn+V8RX/lfEV/9XxFf+QrNC/tzc3f+urq/+oaGjfwAA
AAAAAAAAu7u8f9bW1/6rq63/QLRB/lvHW/5bx1v/Zcdl/ry9uf7y8vH/8evo/vDr6P/w6uf+8Orn/vDq
5/7w6uf/8Orn/tnV0/7a1tT/xsPC/vv7+v759PH/+PLv/vjy7/758/D/+PLv/vjy7/758/D/+PLv/vjy
7/758/D/+PLv/vjy7//s5+T+vbq6/urq6v/g39/+vry8/oawhP9cx1z+W8db/lvHW/9bx1v+QrRC/tvb
3P+srK7+oKChfwAAAAAAAAAAurq7f9bW1v+qqqv/QbVB/1/KX/9fyl//acpp/76/u//y8/H/8ezp/+/q
5//j39z/497b/+Ld2//h3dr/7+nm/9rW1P/a1tT/x8XE//v7+v/59PH/+fPw//nz8P/58/D/+fPw//nz
8P/58/D/+fPw//nz8P/58/D/+fPw//jz7//t6OX/vru7/+Hh4f/BwL//i7OJ/2HKYf9fyl//X8pf/1/K
X/9fyl//Q7ZD/9vb2/+qqqz/np6gfwAAAAAAAAAAubm6f9XV1f6oqKn/QbdB/mTNZP5kzWT/bc1t/sDB
vv7z8/L/8ezp/uzn5P/Szs3+0s7N/tHOzP7Oy8j/6eTh/t3Z1/7Rzsz/x8XE/vv7+v769/X/+vf0/vr3
9P769/T/+vf0/vr39P769/T/+vf0/vr39P769/T/+vf0/vr39P/w7ev+vbu7/sXDw/+RtY/+Zsxm/mTN
ZP9kzWT+ZM1k/mTNZP9kzWT+Q7hE/tra2/+oqKr+nZ2efwAAAAAAAAAAt7e4f9TU1P+mpqf/QbhC/2nQ
af9p0Gn/ctBy/8LDwP/z8/L/8u3q//Hs6f/u6eb/7ejm/+3o5f/t6OX/8ezp//Dr6P/r5uT/ycbG//Hx
8P/y8vH/8fHx//Hx8f/x8fH/8fHx//Hx8P/x8vH/8fHw//Hx8P/x8fD/8fHw//Hx8P/q6un/t7Sz/5q6
mP9qz2r/adBp/2nQaf9p0Gn/adBp/2nQaf9p0Gn/RLlF/9ra2v+np6j/m5ucfwAAAAAAAAAAtra3f9LS
0/6kpKX/QrpC/m3Tbf5t023/dtJ2/sTGwv7z9PP/8u3q/vLt6v/x7er+8u3q/vLt6v7y7er/8e3q/vHt
6v7w7On/0s7N/s3Kyf7Oysn/zMnH/snGxf7HxMP/x8PC/sfExP7FwsL/rLWp/qbCo/6mw6T/psOk/qXB
o/+jwKH+mcSX/nHScf9t023+bdNt/m3Tbf9t023+bdNt/m3Tbf9t023+RbtF/tnZ2f+kpKb+mZmafwAA
AAAAAAAAtbW1f9HR0v6ioqP/Q7tD/nPVc/5z1XP/e9V7/sfIxf709PT/8+7r/vPu6//z7uv+8+7r/vPu
6/7z7uv/8+7r/vPu6/7z7uv/8+7r/vPu6/7z7ev/7ejm/tnV0/7RzMr/0MvK/tTR0P7R0ND/kLWP/nPV
c/5z1XP/c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+RrxG/tjY
2P+ioqP+l5eYfwAAAAAAAAAAs7O0f9DQ0f+goKH/Q7xD/3fYd/932Hf/gNd//8nKxv/09fT/8+7s//Pu
7P/z7uv/8+7s//Pu7P/z7uz/8+7r//Pu6//z7uz/8+7r//Pu6//z7uv/5eHf/7u5uf/GxMT/xMLC/8G/
v/+1srL/ksKR/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fY
d/932Hf/R71H/9fX2P+goKH/lJSWfwAAAAAAAAAAsrKyf8/P0P6dnZ7/Q75D/nzafP582nz/hNqE/svM
yf709fT/8+/s/vPv7P/z7uz+8+/s/vPv7P7z7+z/8+7s/vPu7P7z7+z/8+7s/vPu7P7z7uz/5eHf/sfG
xv7o6Oj/4eHh/sjHxv6ewJ3/fdl9/nzafP582nz/fNp8/nzafP982nz+fNp8/nzafP982nz+fNp8/nza
fP982nz+fNp8/nzafP982nz+SL9I/tbW1/+dnZ7+kpKTfwAAAAAAAAAAsLCxf87Oz/6bm5z/RL9E/oDd
gP6B3YH/iNyI/s3Oy/719fT/9PDt/vTv7f/z7+z+9O/t/vTv7f707+3/8+/s/vPv7P707+3/8+/s/vPv
7P7z7+3/5+Lg/snHx/7i4uL/y8rK/qTCov6C3IL/gN2A/oDdgP6B3YH/gN2A/oHdgf+A3YD+gN2A/oHd
gf+A3YD+gN2A/oHdgf+A3YD+gN2A/oHdgf+A3YD+ScFJ/tXV1f+bm5z+kJCRfwAAAAAAAAAArKytfdHR
0f+ZmZr/RL9E/4TfhP+F34X/jN6M/8/Qzf/19vX/9fLv//Xx7//18e//9fHv//Xx7//18e//9fHv//Xx
7//18e//9fHv//Xx7//08e//6ebl/8jGxv/Ozc3/qcOn/4fdh/+F34X/hd+F/4Xfhf+F34X/hd+F/4Xf
hf+F34X/hd+F/4Xfhf+F34X/hd+F/4Xfhf+F34X/hd+F/4Xfhf+F34X/SMBI/9PT1P+ampz/jY2OfQAA
AAAAAAAAnp6fatvb2/6YmJn/RbVG/oXghf6J4Yn/keCQ/tDRzv7z9PP/8/Pz/vP08//z8/P+8/Tz/vPz
8/7z8/P/8/Pz/vPz8/7z8/P/8/Pz/vPz8/7z8/P/6urq/sLAwP6vx63/i9+L/onhif6J4Yn/ieGJ/onh
if6J4Yn/ieGJ/onhif+J4Yn+ieGJ/onhif+J4Yn+ieGJ/onhif+J4Yn+ieGJ/onhif+F4IX+R7ZH/tLS
0v+cnJ3+hYWGagAAAAAAAAAAm5ubO9vb2/6cnJz/XKVc/nDbcP6O447/kuKS/r7PvP7Cz8D/ws/A/sLP
wP/Cz8D+ws/A/sLOv/7Bzr//wc6//sHNv/7Bzb//wM2+/sDNvv6/zL3/vcq7/rPOsf6R4pH/juOO/o7j
jv6O447/juOO/o7jjv6O447/juOO/o7jjv+O447+juOO/o7jjv+O447+juOO/o7jjv+O447+juOO/o7j
jv9s2mz+Yaph/sbGxv+enp/+hISFOwAAAAAAAAAAoKCgB7GxsuS3t7f/iJSJ/0XGRf+K44r/kuSS/5Lk
kv+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Lk
kv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lk
kv+S5JL/kuSS/4Xhhf9AxUD/qLSo/6Cgof+UlJXkioqKBwAAAAAAAAAAAAAAAI+PkHTg4OD/kpKS/naV
dv5Fx0b/dd51/pHkkf6V5pX/luaW/pbmlv+W5pb+luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbm
lv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv+W5pb+luaW/pbm
lv+W5pb+luaW/pXmlf+P5I/+cN1w/kDGQP+EpIX+pqan/qenqP9/f4B0AAAAAAAAAAAAAAAAAAAAAKCg
oAaenp/G1tbX/pCQkf6GkYf/WqNb/kS2Rf5Fw0X/RcRF/kXERf9FxEX+RcRF/kXERf5FxEX/RcRF/kXE
Rf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXE
Rf9FxEX+RcRF/kXERf9FxEX+RcRF/kXDRf9EtkT+XKRd/pijmf+enp/+p6eo/o+Pj8aKiosGAAAAAAAA
AAAAAAAAAAAAAAAAAACampoVnZ2dxd/f3/+zs7T/lJSV/4+PkP+Ojo//jo6P/46Oj/+Ojo//jo6P/46O
j/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46O
j/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/4+PkP+UlJX/mJiZ/6Ojo//Dw8T/k5OUxYmJ
ihUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAn5+fBoyMjHSurq7k19fY/tjY2P7MzMz/x8fH/sbG
x//Gxsf+xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbG
x/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx//Gxsf+xsbH/sbGx//Gxsf+xsbH/sjIyP/Pz9D+0NDQ/qys
rOOHh4d0lZWVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKAGl5eXOpaW
l2ihoaJ8pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6Sk
pH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6Gh
oXyVlZZolpaWOp6engYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAPwA
AAAAPwAA8AAAAAAPAADgAAAAAAcAAMAAAAAAAwAAwAAAAAADAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAA
AAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAA
AAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAADAAAAAAAMAAMAAAAAAAwAA4AAAAAAHAADwAAAAAA8AAPwA
AAAAPwAA////////AAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAB9fX02ioqKqoaGh+mHh4f9hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aG
h/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaG/YODg+mCgoOqd3d4NgAA
AAAAAAAAAAAAAAAAAAAAAAAAjIyNap2dnvytra7/prKm/561nv+ftp//n7ef/5+3n/+ft5//n7ef/5+3
n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft6D/r7uw/8HB
wf+VlZX8e3t8agAAAAAAAAAAAAAAAI+Pjzavr6/8maKa/0SLRP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCP
MP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCP
MP8wjzD/RYxG/7rDuv+Xl5j8fHx9NgAAAAAAAAAAr6+vq6enqP9EjET/MJEw/zCRMP8wkTD/MJEw/zCR
MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
MP8wkTD/MJEw/zCRMP8wkTD/Ro5G/8XFxf+JiYqrAAAAAAAAAAC5ubnph5SH/zCTMP8wkzD/MJMw/zCT
MP8wkzD/MJMw/zCTMP8wkzD/MJMw/0aWRf99m3v/f559/3+dfP9+nHz/fpx7/32be/98mnr/fJp6/3ya
ef97mXn/e5l5/3qYeP95l3f/TJJL/zCTMP8wkzD/sr+y/42NjukAAAAAAAAAALu7vP57lHz/MJUw/zCV
MP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCVMP8wlTD/VZlU/+Pi4f/49fP/9/Tx//fz8P/38u//9/Lv//bx
7v/28O3/9fDt//bw7f/28O3/9vDt/+7u7P9dk1z/MJUw/zCVMP+jvKT/k5OU/gAAAAAAAAAAvb2+/32X
fv8wlzD/MJcw/zCXMP8wlzD/MJcw/zCXMP8wlzD/MJcw/zCXMP9Wm1T/4+Ph//Tp5P/y5d//8ePc//Dg
2f/v3tb/7tvT/+3Z0f/s2M//7NfO/+zXzv/s187/7evp/16UXP8wlzD/MJcw/6S+pP+Xl5j/AAAAAAAA
AAC/v8D/gJqB/zCaMP8wmjD/MJow/zCaMP8wmjD/MJow/zCaMP8wmjD/MJow/1adVf/k4+L/9e3o//Tp
5P/y5+H/8eTe//Di2//v39j/7t3V/+3a0v/s2ND/7NfO/+zXzv/t6+n/XpZc/zCaMP8wmjD/pb+l/5qa
m/8AAAAAAAAAAMHBwv+CnYP/MJww/zCcMP8wnTD/MZ0x/zGdMf8xnTH/MZ0x/zGdMf8xnTH/V59W/+Tj
4//38Oz/29TQ/8/HxP/NxMH/y8K+/8rAvP/Jvrr/yLy4/8a7tv/HurX/7NjQ/+7r6v9emF3/MJww/zCc
MP+mwab/np6f/wAAAAAAAAAAw8PE/4Wghv8wnzD/MJ8w/3Obcf+osKX/p6+l/6avpP+mrqP/pa6j/6Wt
ov+jp5//5OTj//fw7f/07On/8enl//Dn4//v5eD/7uPd/+3g2//r3tj/6tvV/+rZ0v/u29T/7uzq/1+Z
Xf8wnzD/MJ8w/6fDqP+hoaL/AAAAAAAAAADFxcb/h6OI/zGiMf8xojH/hqWE/+7s6v/s5eL/6+Tg/+rj
3//q4t3/6eDc/9HKxv/k5OP/9/Dt/+Hb2P/X0c//1M7L/+7m4v/Xz8z/1MvH/9HIxP/RxsL/0MXA/+7e
1//u7Ov/YJte/zGiMf8xojH/qMSp/6Skpf8AAAAAAAAAAMfHx/+Jpor/MaQx/zGkMf+Gp4T/7ero/+ne
2f/o29b/59nT/+bX0P/l1M3/zsG8/+Xk4//38O3/7ujk/+nj3//o4t7/8uvn/9XPy//x6OT/8Obh/+/k
3//SyMT/7+Lb/+7t6/9gnV7/MaQx/zGkMf+pxqn/pqao/wAAAAAAAAAAyMjJ/4qoi/8xpzH/Macx/4eo
hf/u6+n/6+Ld/+Ta1f/j19P/4dXQ/+DSzf/Mwbz/5eXk//fw7f/n4N3/39jV/93W0//v6OX/19DO//fv
6//27un/9ezn/9XMyP/x5uD/7+7s/2CfX/8xpzH/Macx/6rHqv+oqKr/AAAAAAAAAADJycr/i6qM/zGq
Mf8xqjH/iKqG/+7s6v/o4d3/x8K//8bAvf/DvLn/wru3/7ixrv/l5eT/9/Dt/+ni3//i29j/4NnW//Dp
5f/X0M7/9/Ds//fv6//27+v/1s7L//Pq5f/v7u3/YaFf/zGqMf8xqjH/qsmr/6qqq/8AAAAAAAAAAMrK
yv+Mq43/Ma0x/zGtMf+Iq4b/7uzq/+3m4v/s5eH/6+Pf/+ri3f/q4Nv/0snG/+Xl5P/38O3/7OXi/+bg
3f/l3tv/8erm/9XPzP/v6OT/7ujk/+/o5P/Uzcr/9O3o/+/v7f9ho1//Ma0x/zGtMf+ryqv/q6ut/wAA
AAAAAAAAysrK/4ysjf8ysTL/MbAx/4msh//u7Or/6eLe/8XAvv/Ev73/yMPA/9vU0P+7trT/5uXk//fw
7f/j3dr/29XS/9jSz//w6eX/3NbT/9nT0P/Y0c7/2NHO/9jSz//27+v/8O/t/2KlYP8zsTP/NbI1/6vL
q/+rq63/AAAAAAAAAADJycr/jKyN/0a7Rv9MvUz/l7eV//Du7P/u6OT/6+Xh/+vk4f/r5eH/29XS/8jC
wP/n5uX/9/Ht//fw7P/38Oz/9/Ds//fw7f/38Oz/9/Dt//fw7f/z7en/6uTh/+nj4P/n5uX/b6pt/029
Tf9Hu0f/q8ur/6qqrP8AAAAAAAAAAMjIyf+LrIz/S79L/1PCU/+evJv/8e/u/+3n5P/Uz83/087N/9bS
z//g2tj/z8vJ/+rq6f/48/D/+PLv//jy7//48u//+PLv//jy7//48u//+PLv/+Pe2/++urn/vLi3/7+8
vP90r3L/U8JT/0y/TP+qy6v/qamq/wAAAAAAAAAAx8fI/4mriv9Qw1D/Wsda/6LAoP/x8O7/8Orn/+ji
4P/n4t//6eTh/+Hc2f/Rzcv/6+vq//nz8P/48/D/+PPw//jz8P/58/D/+PPw//jz8P/48u//2NPR/93d
3f/a2tr/oLKe/1/DX/9ax1r/UcNR/6nLqv+np6j/AAAAAAAAAADFxcb/iKqI/1XHVf9hy2H/psOk//Lw
7//v6eb/3dnW/9zY1v/f29j/4t3b/8/Lyv/s7Ov/+fTx//nz8P/58/D/+fPw//nz8P/58/D/+fPw//nz
8P/a1tT/1dTU/6m4p/9nx2b/Ycth/2HLYf9WyFb/qcup/6Skpv8AAAAAAAAAAMTExf+FqYb/Wsta/2jP
aP+qx6j/8/Hw//Dr6P/l4N7/5ODd/+bi3//t6OX/2NTS/+jn5v/19PP/9PTz//T08//09PP/9PTz//T0
8//09PL/9PTy/9vZ2f+suan/b8tu/2jPaP9oz2j/aM9o/1zMXP+oy6j/oqKj/wAAAAAAAAAAwsLC/4On
hP9gz2D/b9Nv/67Krf/z8vD/8u3q//Lt6v/y7ev/8u3q//Lt6v/s5+X/2tbU/9rV1P/Tz87/zcnI/87L
yv/DwcH/k8OS/5XJk/+UyJL/kseR/3jReP9v02//b9Nv/2/Tb/9v02//Ys9i/6fKp/+enp//AAAAAAAA
AADAwMD/gaWC/2XSZf9213b/ss2x//Tz8f/z7uv/8+7r//Pu6//z7uv/8+7r//Pu6//z7uv/8u3q/8zJ
yP/Gw8P/xMLC/7W3s/9403j/dtd2/3bXdv9213b/dtd2/3bXdv9213b/dtd2/3bXdv9o02j/psqm/5ub
nP8AAAAAAAAAAL6+vv9+o3//a9Zr/33bff+30bX/9PPy//Pv7P/z7+z/8+/s//Pv7P/z7+z/8+/s//Pv
7P/y7uv/zszL/+Xl5f/Iycb/js6N/33bff99233/fdt9/33bff99233/fdt9/33bff99233/fdt9/27X
bv+lyqX/l5eY/wAAAAAAAAAAvb29/nyhff9v2W//hN6E/7rUuf/19PP/9PHu//Tx7v/08e7/9PHu//Tx
7v/08e7/9PHu//Pw7v/Qzs3/zc3L/5XRlP+E3oT/hN6E/4TehP+E3oT/hN6E/4TehP+E3oT/hN6E/4Te
hP+E3oT/ctpy/6PIo/+UlJX+AAAAAAAAAAC+vr/phJiF/2nZaf+K4Yr/u9S6/+bl5f/m5eX/5uXl/+bl
5f/l5eX/5eXk/+Xl5P/l5OT/5eTk/8jIx/+d1J3/iuGK/4rhiv+K4Yr/iuGK/4rhiv+K4Yr/iuGK/4rh
iv+K4Yr/iuGK/4rhiv9o2Wj/qr6r/5GRkekAAAAAAAAAALOzs6unp6f/VrtX/43jjf+a4Zr/oN+f/6Df
n/+g35//n9+f/5/fn/+f35//n9+e/5/fnv+e3p7/m+Ca/5Hkkf+R5JH/keSR/5Hkkf+R5JH/keSR/5Hk
kf+R5JH/keSR/5Hkkf+R5JH/i+OL/1W9Vf+ysrL/kpKSqwAAAAAAAAAAlpaXNsbGx/yEkoT/V7tX/2/d
b/994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33g
ff994H3/feB9/33gff994H3/feB9/27dbv9UvFX/mqia/5+foPyFhYU2AAAAAAAAAAAAAAAAnJydacXF
xvyjo6P/fZB+/3SadP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP9zmnT/c5p0/3Oa
dP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP90mnT/gZSC/6Ojo/+tra78jY2OaQAAAAAAAAAAAAAAAAAA
AAAAAAAAlZWVNq+vr6q5ubnotbW1/bOztP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP+zs7T/s7O0/7Oz
tP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP2zs7PorKysqpCQkTYAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAP/////gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABwAAAA+AAAAf/////KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAGNjYxBsbGw5cHBxP3FxcT9xcXE/cXFxP3FxcT9xcXE/cXFxP3FxcT9xcXE/cXFxP3Fx
cT9xcXE/cXFxP3BwcT9ra2w5Y2NjEAAAAAAAAAAAAAAAAAAAAABubm8Fi4uMj5+foPivr7D/rq6u/q6u
rv+urq7/rq6u/q6urv+urq7/rq6u/66urv6urq7/rq6u/q6urv+urq7/rq6u/q6urv+xsbH/paWm+H9/
gI9ra2wFAAAAAAAAAACdnZ6Qm6Cc/luVW/41izX+Mowy/jKMMv4yjDL+Mowy/jKMMv4yjDL+Mowy/jKM
Mv4yjDL+Mowy/jKMMv4yjDL+Mowy/jKMMv41izX+X5lf/rG2sf6CgoOQAAAAAHh4eBCysrP4VpJW/jCR
MP8wkTD/L5Ev/jCRMP8wkTD/L5Ev/jGSMf80kzT/NJM0/zSTNP40kzT/NJI0/jSTNP80kjT/NJI0/jSS
NP8zkjP/L5Ev/l+bX/+rq6z4dnZ3EImJiTm1tbb/NpA2/jCUMP8wlDD/L5Qv/jCUMP8wlDD/L5Qv/meb
Zf/Mzcr/y8zJ/8vMyP7Ky8f/ycrH/snKxv/Iysb/yMnF/sjJxf+XqJX/L5Qv/jaRNv+4uLn/g4OEOZWV
lj+1tbb+M5Qz/i+XL/4vly/+L5cv/i+XL/4vly/+L5cv/m6hbP738u/+8+fh/vHj3f7w4Nn+793W/u3b
0/7t2dH+7dnQ/u/e1/6vvq7+L5cv/jOUM/65ubn+jY2OP5iYmT+4uLn/NJg0/jCaMP8wmjD/L5ov/jCa
MP8wmjD/L5ov/m+jbf/49PH/8efi/+vg2/7q3Nf/6NnT/ubWz//l08z/5dLK/u7d1f+wv67/L5ov/jSY
NP+8vL3/kZGTP5ubnD+8vLz/NJs0/jKeMv9bmVn/XJlb/lyYWv9bmFn/W5dZ/oShgf/49fP/6eLe/9zV
0f7a0c3/2c7K/tfMx//VycT/1cfB/u/e1/+wwK7/MJ4w/jSbNP+/v8D/lpaXP56enz++vr/+NZ81/jai
Nv7Iycb+6ubj/urk4v7p4+D+6OLe/svGxP749fP+6uTg/t/Y1f7l3dr+49vW/tvRzf7Zzsn+2MvG/vDi
3P6xwa/+MKEw/jWfNf7CwsP+mpqbP6CgoT/BwcL/NaM1/jemNv/Ky8j/6t/a/ujc1v/n2NL/5dXO/srA
u//49fP/8uvn/+3m4v7w6eb/29XS/vLq5f/x5+L/2tDL/vHm4f+xwrD/MKUw/jWjNv/ExMX/nZ2eP6Ki
oz/Dw8T/NqY2/jepNv/LzMn/6uLe/tHKxv/Px8P/zcO//r63tP/49fP/5t/c/9XOzP7f2db/3NbT/vfv
6//27ur/3dXR/vPr5v+yw7D/MKkw/jamNv/Gxsf/n5+hP6Ojoz/ExMX/Nqo2/jetNv/LzMn/7Obi/uXe
2v/k3Nj/49nV/snCwP/49fP/8erm/+rk4P7v6OT/29XS/vHq5v/x6ub/29XR/vXu6/+yxLD/MK0w/jaq
Nv/Hx8j/oaGiP6OjpD/ExMX+O687/jyzPP7Mzcr+6uTg/s3Hxf7KxcL+29XR/r65t/749fP+7OXi/uLb
2P7o4d7+5+Dd/uDa1/7f2dX+3tjV/vXv7P6zxbL+ObM5/jywPP7Hx8j+oaGiP6Kioz/Dw8T/SLhI/lbA
Vv/U1NL/7+nm/uPd2v/i3Nn/4dvY/svGxf/59vT/9/Hu//fx7v748e7/9/Hu/vfx7v/17+z/2tXT/tbS
0P+ru6n/UMBQ/km4Sf/Gxsf/oKChP6CgoT/BwcL+TbxN/l7GXv7W19X+7+rm/uHc2v7g29j+497b/s/M
yv769/X++PLv/vjy7/748+/++PLv/vjy7/7y7On+yMbH/snHx/6CtID+WcZZ/k29Tv7ExMX+nZ2fP56e
nz+/v8D/UcFR/mbMZv/Z2df/7+rn/trW1P/Z1dL/5N/d/s7Lyv/6+Pb/+fXy//n18v759fL/+fXy/vn1
8v/08O3/yMfG/pG9j/9izGL/Ysxi/lLBUv/CwsP/mpqcP5ycnT+8vL3/VsVW/nDRb//b3Nr/8u3q/u/r
6P/v6uj/8ezp/t7a2P/f3t3/3tzb/9za2v7c2tr/zdbL/svayv/J18f/l8GV/mzRbP9r0Wv/a9Fr/ljG
WP+/v8D/l5eYP5mZmj+5ubr+XMlc/nnWef7e393+8+7r/vPu6/7z7uv+8+7r/vPu6/7z7uv+2tbU/srH
x/7HxcT+g8mC/nXWdf511nX+ddZ1/nXWdf511nX+ddZ1/l7JXv68vL3+kpKTP5aWlj+1tbb/Yc1h/oLb
gv/g4d//8+/s/vPv7P/z7+z/8+/s/vPv7P/z7+z/19TT/97d3f6jyaL/f9t//n7cfv9+3H7/ftx+/n7c
fv9+3H7/ftx+/mPOY/+5ubr/jo6PP4uLizm3t7j/Zc1l/ovfi//i4uH/9PLx/vTy8f/08vH/9PLx/vTy
8f/08vH/19bV/6zOq/6I34j/h+CH/ofgh/+H4If/h+CH/ofgh/+H4If/h+CH/mbNZv+3t7j/hYWGOXx8
fBC4uLj4ZrZn/o/jj/6p2qj+qtqp/qraqf6q2an+qtmp/qrZqf6p2Kj+pdik/pDjkP6Q45D+kOOQ/pDj
kP6Q45D+kOOQ/pDjkP6Q45D+jOOM/m2/bf6mpqf4e3t8EAAAAACrq6yQm6Oc/me2Z/9s0Wz/bdVt/m3V
bf9t1W3/bdVt/m3Vbf9t1W3/bdVt/23Vbf5t1W3/bdVt/m3Vbf9t1W3/bdVt/m3Vbf9r0Wv/abpp/pyk
nf+QkJGQAAAAAAAAAACAgIAFqqqqj7OztPiwsLH/qqqr/qqqq/+qqqv/qqqr/qqqq/+qqqv/qqqr/6qq
q/6qqqv/qqqr/qqqq/+qqqv/qqqr/qqqq/+vr6//rq6u+J2dnY99fX4FAAAAAAAAAAAAAAAAAAAAAIKC
gxCRkZI5m5ucP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ub
nD+SkpI5hISEEAAAAAAAAAAAAAAAAOAABwCAAAEAgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAQCAAAEA4AAHACgA
AAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS0tMDXR0dGR5eXp/eXl6f3l5
en95eXp/eXl6f3l5en95eXp/eXl6f3l5en95eXl/cXFyZExMTA0AAAAAU1NUDZyendhynnL/Z6Nn/2ej
Z/9no2f/Z6Nn/2ejZ/9no2f/Z6Nn/2ejZ/9no2f/Z6Nn/3mmev+YmpnYU1NTDZWVlWVolmn/MJIw/zCS
MP8wkjD/MJIw/0mVSP9Xl1b/V5dW/1aWVf9WlVT/VZVU/1WUU/83kjb/e6l7/4KCg2Wmpqd/VpZW/zCW
MP8wljD/MJYw/zCWMP+cvpv/9e7q//Tq5f/y5+L/8eTf//Hj3f/v6OT/R5VG/2mqav+QkJF/rKysf1ib
Wf8wmzD/MJsw/zCbMP8wmzD/ncGc/+/m4v/g1tH/3dDL/9vMxv/ZycP/7eHc/0eZRv9qrmv/l5eZf6+v
sH9boVz/VqBV/8rMxf/IycL/x8e//8/Oy//x6ub/49zY/+jf2//f1M//3dDK/+7k4P9InUf/bLJs/56e
n3+zs7N/XaZd/1ynW//s5eL/5dnU/+PVzv/Z09D/8erm/+Pd2f/j3dn/8+vn/+PZ1f/v6OX/SKJH/222
bf+jo6R/tLS1f16rX/9cq1v/7Ojl/9nSz//Wzsr/1dHP//Hq5v/j3dn/493Z//Ps6P/k3dn/8e3q/0mn
SP9tum7/pqanf7W1tX9ksWX/Z7Rm/+3p5v/Y0s//2tTR/9TRz//y7Oj/6OLe/+7o5P/o4d7/493a/+3q
5/9Ur1P/dMF1/6amqH+zs7R/bLZs/3vBev/w7Or/3tjW/+Db2P/d29r/+PPw//jy7//48u//+PLv/9bS
0P+9wLv/YL9g/3zGfP+jo6V/sLCxf2+5b/+GyYX/8e7r/+Hc2v/l4N7/393b//f08v/29PH/9vTx//bz
8f/Nz8r/ecZ5/2TNZP+ByoH/np6gf6ysrX9yu3P/kdCR//Pw7v/y7ev/8u3r/+vm5P/a1tX/ycbG/6HD
n/+F0IT/ftF9/3LVcv9y1XL/hc6G/5iYmX+oqKh/db11/5zXnP/08vD/9PDt//Tw7f/08O3/4d7c/8TT
w/+F2YT/gN2A/4DdgP+A3YD/gN2A/4rQiv+RkZJ/mZmZZXq1e/+b3pv/w+LC/8Piwv/C4sL/wuLB/7na
uf+S35L/juOO/47jjv+O447/juOO/4zijP+GwYf/h4eIZVtbXA2rrqvYerN6/3i9eP94vXj/eL14/3i9
eP94vXj/eL14/3i9eP94vXj/eL14/3i9eP95tHr/naGe2FxcXA0AAAAAXl5eDZycnWSpqap/qqqqf6qq
qn+qqqp/qqqqf6qqqn+qqqp/qqqqf6qqqn+pqal/m5ubZGBgYA0AAAAAgAEAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAA==
</value>
</data>
</root>
@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
+5 -1
View File
@@ -1,3 +1,7 @@
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
+16 -2
View File
@@ -137,8 +137,22 @@
<Content Include="licenses\duplicati-url.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="licenses\SSH.NET\Homepage.txt" />
<Content Include="licenses\SSH.NET\License.txt" />
<Content Include="..\..\thirdparty\SSH.NET\Homepage.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>licenses\SSH.NET\Homepage.txt</Link>
</Content>
<Content Include="..\..\thirdparty\SSH.NET\License.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>licenses\SSH.NET\License.txt</Link>
</Content>
<Content Include="..\..\thirdparty\Json.NET\Homepage.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>licenses\Json.NET\Homepage.txt</Link>
</Content>
<Content Include="..\..\thirdparty\Json.NET\License.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>licenses\Json.NET\License.txt</Link>
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -61,6 +61,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LightDatamodel">
<HintPath>..\..\..\thirdparty\LightDataModel\LightDatamodel.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\thirdparty\Json.NET\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -70,14 +76,15 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ApplicationSettings.cs" />
<Compile Include="Backend.cs" />
<Compile Include="EncryptionModule.cs" />
<Compile Include="Enums.cs" />
<Compile Include="GenericModule.cs" />
<Compile Include="Schedule.cs" />
<Compile Include="Implementations\ProgressEventData.cs" />
<Compile Include="Implementations\SerializableStatus.cs" />
<Compile Include="InterfaceResolver.cs" />
<Compile Include="IProgressEventData.cs" />
<Compile Include="ISerializableStatus.cs" />
<Compile Include="JsonSerializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Task.cs" />
<Compile Include="Serializer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
@@ -5,11 +5,72 @@ using System.Text;
namespace Duplicati.Server.Serialization
{
public enum ServiceState
public enum RunnerState
{
Started,
Suspended,
Running,
Paused,
Suspended
Stopped,
}
public enum RunnerResult
{
OK,
Partial,
Warning,
Error
}
public enum CloseReason
{
None,
ApplicationExitCall,
TaskManagerClosing,
WindowsShutDown,
UserClosing
}
public enum LiveControlState
{
Running,
Paused
}
public enum DuplicatiOperation
{
Backup,
Restore,
List,
Remove
}
public enum DuplicatiOperationMode
{
Backup,
BackupFull,
BackupIncremental,
Restore,
RestoreControlfiles,
List,
GetBackupSets,
ListCurrentFiles,
ListSourceFolders,
ListActualSignatureFiles,
DeleteAllButNFull,
DeleteAllButN,
DeleteOlderThan,
CleanUp,
CreateFolder,
FindLastFileVersion,
Verify
}
public static class EnumConverter
{
public static T Convert<T>(Enum o)
{
return (T)Enum.Parse(typeof(T), o.ToString(), false);
}
}
}
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.Server.Serialization
{
public interface IProgressEventData
{
DuplicatiOperation Operation { get; }
DuplicatiOperationMode Mode { get; }
string Message { get; }
string SubMessage { get; }
int Progress { get; }
int SubProgress { get; }
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
namespace Duplicati.Server.Serialization
{
public interface ISerializableStatus
{
RunnerState ActiveBackupState { get; }
long ActiveScheduleId { get; }
LiveControlState ProgramState { get; }
IProgressEventData RunningBackupStatus { get; }
System.Collections.Generic.IList<long> SchedulerQueueIds { get; }
}
}
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.Server.Serialization.Implementations
{
internal class ProgressEventData : IProgressEventData
{
public DuplicatiOperation Operation { get; set; }
public DuplicatiOperationMode Mode { get; set; }
public string Message { get; set; }
public string SubMessage { get; set; }
public int Progress { get; set; }
public int SubProgress { get; set; }
}
}
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.Server.Serialization.Implementations
{
internal class SerializableStatus : ISerializableStatus
{
public RunnerState ActiveBackupState { get; set; }
public long ActiveScheduleId { get; set; }
public LiveControlState ProgramState { get; set; }
public IProgressEventData RunningBackupStatus { get; set; }
public IList<long> SchedulerQueueIds { get; set; }
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Converters;
namespace Duplicati.Server.Serialization
{
public class SerializableStatusCreator : CustomCreationConverter<ISerializableStatus>
{
public override ISerializableStatus Create(Type objectType)
{
return new Implementations.SerializableStatus();
}
}
public class ProgressEventDataCreator : CustomCreationConverter<IProgressEventData>
{
public override IProgressEventData Create(Type objectType)
{
return new Implementations.ProgressEventData();
}
}
}
@@ -0,0 +1,180 @@
// Copyright (C) 2011, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Linq;
using Newtonsoft.Json.Serialization;
using System.Reflection;
using Newtonsoft.Json;
using System.Globalization;
using System.Collections.Generic;
namespace Duplicati.Server.Serialization
{
internal class JsonSerializer : DefaultContractResolver
{
private Dictionary<string, string> m_ignoreList = GetIgnoreList();
private static Dictionary<string, string> GetIgnoreList()
{
Dictionary<string, string> lst = new Dictionary<string, string>();
lst.Add("Datamodel.ApplicationSettings!RawOptions", null);
return lst;
}
private static string MemberInfoAsKey(MemberInfo mi) { return mi.DeclaringType.FullName + "!" + mi.Name; }
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
return base.GetSerializableMembers(objectType).Where(x => !m_ignoreList.ContainsKey(MemberInfoAsKey(x))).ToList();
}
protected override JsonObjectContract CreateObjectContract (Type objectType)
{
if (typeof(System.Data.LightDatamodel.IDataFetcher).IsAssignableFrom(objectType))
{
//If this type was ever serialized, it would expose the entire internal object cache, and we do NOT want that :)
throw new Exception("Internal error, a non-serializable type was hit");
}
else if (typeof(System.Data.LightDatamodel.IDataClass).IsAssignableFrom(objectType))
{
JsonObjectContract joc = new JsonObjectContract(objectType);
foreach(var pi in objectType.GetProperties( BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance ))
{
var customs = pi.GetCustomAttributes(false);
bool isRef = customs.Select(x => x.GetType()).Contains(typeof(System.Data.LightDatamodel.DataClassAttributes.Affects));
bool isParent = typeof(System.Data.LightDatamodel.IDataFetcher).IsAssignableFrom(pi.PropertyType);
isRef |= typeof(System.Data.LightDatamodel.IDataClass).IsAssignableFrom(pi.PropertyType);
joc.Properties.Add(new JsonProperty() {
PropertyName = pi.Name,
PropertyType = pi.PropertyType,
Ignored = isRef || isParent || m_ignoreList.ContainsKey(MemberInfoAsKey(pi)),
UnderlyingName = pi.Name,
Readable = pi.CanRead,
Writable = pi.CanWrite,
ValueProvider = CreateMemberValueProvider(pi)
});
}
return joc;
}
else
return base.CreateObjectContract (objectType);
}
protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
{
if (member.MemberType == System.Reflection.MemberTypes.Property && ((PropertyInfo)member).PropertyType.IsEnum)
return new EnumValueProvider(member);
else if (member.MemberType == System.Reflection.MemberTypes.Field && ((FieldInfo)member).FieldType.IsEnum)
return new EnumValueProvider(member);
else
return base.CreateMemberValueProvider(member);
}
/// <summary>
/// Get and set values for a <see cref="MemberInfo"/> Enum using reflection.
/// </summary>
private class EnumValueProvider : IValueProvider
{
private Type m_enumType;
private MemberInfo m_member;
/// <summary>
/// Initializes a new instance of the <see cref="EnumValueProvider"/> class.
/// </summary>
/// <param name="pi">The property info.</param>
public EnumValueProvider(MemberInfo mi)
{
if (mi == null)
throw new ArgumentNullException("mi");
if (mi.MemberType == MemberTypes.Property)
m_enumType = ((PropertyInfo)mi).PropertyType;
else if (mi.MemberType == MemberTypes.Field)
m_enumType = ((FieldInfo)mi).FieldType;
else
throw new ArgumentException(string.Format("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo", CultureInfo.InvariantCulture, m_member.Name, "member"));
m_member = mi;
}
/// <summary>
/// Sets the value.
/// </summary>
/// <param name="target">The target to set the value on.</param>
/// <param name="value">The value to set on the target.</param>
public void SetValue(object target, object value)
{
try
{
if (target == null)
throw new ArgumentNullException("target");
object parsedValue = value is string ? Enum.Parse(m_enumType, value as String, true) : value;
switch (m_member.MemberType)
{
case MemberTypes.Field:
((FieldInfo)m_member).SetValue(target, parsedValue);
break;
case MemberTypes.Property:
((PropertyInfo)m_member).SetValue(target, parsedValue, null);
break;
default:
throw new ArgumentException(string.Format("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo", CultureInfo.InvariantCulture, m_member.Name, "member"));
}
}
catch (Exception ex)
{
throw new JsonSerializationException(string.Format("Error setting value to '{0}' on '{1}'.", CultureInfo.InvariantCulture, m_member.Name, (target == null ? "null" : target.GetType().FullName)), ex);
}
}
/// <summary>
/// Gets the value.
/// </summary>
/// <param name="target">The target to get the value from.</param>
/// <returns>The value.</returns>
public object GetValue(object target)
{
try
{
if (target == null)
throw new ArgumentNullException("target");
switch (m_member.MemberType)
{
case MemberTypes.Field:
return ((FieldInfo)m_member).GetValue(target).ToString();
case MemberTypes.Property:
return ((PropertyInfo)m_member).GetValue(target, null).ToString();
default:
throw new ArgumentException(string.Format("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo", CultureInfo.InvariantCulture, m_member.Name, "member"));
}
}
catch (Exception ex)
{
throw new JsonSerializationException(string.Format("Error getting value to '{0}' on '{1}'.", CultureInfo.InvariantCulture, m_member.Name, (target == null ? "null" : target.GetType().FullName)), ex);
}
}
}
}
}
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace Duplicati.Server.Serialization
{
public class Serializer
{
private JsonSerializerSettings m_jsonSettings;
private Formatting m_jsonFormatting = Formatting.Indented;
public Serializer()
{
m_jsonSettings = new JsonSerializerSettings();
m_jsonSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
m_jsonSettings.ContractResolver = new JsonSerializer();
m_jsonSettings.Converters = new JsonConverter[]{
new SerializableStatusCreator(),
new ProgressEventDataCreator()
}.ToList();
}
public void SerializeJson(System.IO.StreamWriter sw, object o)
{
Newtonsoft.Json.JsonSerializer jsonSerializer = Newtonsoft.Json.JsonSerializer.Create(m_jsonSettings);
using (var jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = m_jsonFormatting;
jsonSerializer.Serialize(jsonWriter, o);
jsonWriter.Flush();
}
}
public T Deserialize<T>(System.IO.StreamReader sr)
{
Newtonsoft.Json.JsonSerializer jsonSerializer = Newtonsoft.Json.JsonSerializer.Create(m_jsonSettings);
using (var jsonReader = new JsonTextReader(sr))
{
jsonReader.Culture = System.Globalization.CultureInfo.InvariantCulture;
return jsonSerializer.Deserialize<T>(jsonReader);
}
}
}
}
+13 -9
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -54,6 +54,12 @@
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="HttpServer">
<HintPath>..\..\thirdparty\HttpServer\HttpServer.dll</HintPath>
@@ -64,9 +70,6 @@
<Reference Include="LightDatamodel">
<HintPath>..\..\thirdparty\LightDataModel\LightDatamodel.dll</HintPath>
</Reference>
<Reference Include="LitJson">
<HintPath>..\..\thirdparty\LitJSON\LitJson.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -83,7 +86,6 @@
<Compile Include="DuplicatiOutputParser.cs" />
<Compile Include="DuplicatiRunner.cs" />
<Compile Include="DynamicSetupHelper.cs" />
<Compile Include="EventQueue.cs" />
<Compile Include="LiveControls.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -122,9 +124,11 @@
</Compile>
<Compile Include="TaskPackages.cs" />
<Compile Include="WebServer.cs" />
<Compile Include="SerializableStatus.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Duplicati.snk" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Database schema\1. Support timestamp flag.sql" />
@@ -174,10 +178,6 @@
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.SkyDrive</Name>
</ProjectReference>
<ProjectReference Include="Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj">
<Project>{33FD1D24-C28F-4C71-933F-98F1586EA76C}</Project>
<Name>Duplicati.Server.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
<Name>Duplicati.Library.Backend.CloudFiles</Name>
@@ -242,6 +242,10 @@
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
<Name>Duplicati.License</Name>
</ProjectReference>
<ProjectReference Include="Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj">
<Project>{33FD1D24-C28F-4C71-933F-98F1586EA76C}</Project>
<Name>Duplicati.Server.Serialization</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Strings\DatabaseUpgrader.resx">
Binary file not shown.
+53 -53
View File
@@ -21,7 +21,8 @@ using System;
using System.Collections.Generic;
using System.Text;
using Duplicati.Datamodel;
using Duplicati.Library.Main;
//using Duplicati.Library.Main;
using Duplicati.Server.Serialization;
namespace Duplicati.Server
{
@@ -30,31 +31,16 @@ namespace Duplicati.Server
/// </summary>
public class DuplicatiRunner : Duplicati.Library.Main.LiveControl.ILiveControl
{
public enum RunnerState
public class ProgressEventData : IProgressEventData
{
Started,
Suspended,
Running,
Stopped,
public DuplicatiOperation Operation { get; set; }
public DuplicatiOperationMode Mode { get; set; }
public string Message { get; set; }
public string SubMessage { get; set; }
public int Progress { get; set; }
public int SubProgress { get; set; }
}
public enum RunnerResult
{
OK,
Partial,
Warning,
Error
}
public enum CloseReason
{
None,
ApplicationExitCall,
TaskManagerClosing,
WindowsShutDown,
UserClosing
}
public delegate void ResultEventDelegate(RunnerResult result, string parsedMessage, string message);
public event ResultEventDelegate ResultEvent;
@@ -64,18 +50,25 @@ namespace Duplicati.Server
private const int PERCENT_PR_EXTRA_OPERATION = 2;
private int m_extraOperations = 0;
private DuplicatiOperation m_lastPGOperation;
private DuplicatiOperationMode m_lastPGMode;
private int m_lastPGProgress;
private int m_lastPGSubprogress;
private string m_lastPGmessage;
private string m_lastPGSubmessage;
private ProgressEventData m_lastEvent = new ProgressEventData();
private object m_lock = new object();
private CloseReason m_stopReason = CloseReason.None;
private Library.Main.LiveControl.ILiveControl m_currentBackupControlInterface;
private bool m_isAborted = false;
private RunnerState m_currentRunnerState = RunnerState.Suspended;
public DuplicatiRunner()
{
ProgressEvent += new ProgressEventDelegate(DuplicatiRunner_ProgressEvent);
}
void DuplicatiRunner_ProgressEvent(DuplicatiOperation operation, RunnerState state, string message, string submessage, int progress, int subprogress)
{
m_currentRunnerState = state;
}
public void ExecuteTask(IDuplicityTask task)
{
Dictionary<string, string> options = new Dictionary<string,string>();
@@ -92,7 +85,7 @@ namespace Duplicati.Server
try
{
//TODO: Its a bit dirty to set the options after creating the instance
using (Interface i = new Interface(destination, options))
using (Duplicati.Library.Main.Interface i = new Duplicati.Library.Main.Interface(destination, options))
{
lock (m_lock)
{
@@ -101,8 +94,8 @@ namespace Duplicati.Server
}
SetupControlInterface();
i.OperationProgress += new OperationProgressEvent(Duplicati_OperationProgress);
i.OperationProgress += new Duplicati.Library.Main.OperationProgressEvent(Duplicati_OperationProgress);
switch (task.TaskType)
{
@@ -184,10 +177,10 @@ namespace Duplicati.Server
case DuplicityTaskType.ListBackups:
List<string> res = new List<string>();
foreach (ManifestEntry be in i.GetBackupSets())
foreach (Duplicati.Library.Main.ManifestEntry be in i.GetBackupSets())
{
res.Add(be.Time.ToString());
foreach (ManifestEntry bei in be.Incrementals)
foreach (Duplicati.Library.Main.ManifestEntry bei in be.Incrementals)
res.Add(bei.Time.ToString());
}
@@ -309,10 +302,10 @@ namespace Duplicati.Server
{
if (task.Schedule.Task.KeepFull > 0)
{
m_lastPGProgress = 100;
m_lastPGmessage = Strings.DuplicatiRunner.CleaningUpMessage;
m_lastPGSubmessage = "";
m_lastPGSubprogress = -1;
m_lastEvent.Progress = 100;
m_lastEvent.Message = Strings.DuplicatiRunner.CleaningUpMessage;
m_lastEvent.SubMessage = "";
m_lastEvent.SubProgress = -1;
ReinvokeLastProgressEvent();
m_extraOperations--;
@@ -324,10 +317,10 @@ namespace Duplicati.Server
if (!string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
{
m_lastPGProgress = 100;
m_lastPGmessage = Strings.DuplicatiRunner.CleaningUpMessage;
m_lastPGSubmessage = "";
m_lastPGSubprogress = -1;
m_lastEvent.Progress = 100;
m_lastEvent.Message = Strings.DuplicatiRunner.CleaningUpMessage;
m_lastEvent.SubMessage = "";
m_lastEvent.SubProgress = -1;
ReinvokeLastProgressEvent();
m_extraOperations--;
@@ -377,18 +370,23 @@ namespace Duplicati.Server
task.Schedule.ScheduledRunCompleted(); //Register as completed if not aborted
}
void Duplicati_OperationProgress(Interface caller, DuplicatiOperation operation, DuplicatiOperationMode specificmode, int progress, int subprogress, string message, string submessage)
void Duplicati_OperationProgress(Duplicati.Library.Main.Interface caller, Duplicati.Library.Main.DuplicatiOperation operation, Duplicati.Library.Main.DuplicatiOperationMode specificmode, int progress, int subprogress, string message, string submessage)
{
m_lastPGOperation = operation;
m_lastPGMode = specificmode;
m_lastPGProgress = progress;
m_lastPGSubprogress = subprogress;
m_lastPGmessage = message;
m_lastPGSubmessage = submessage;
Duplicati_OperationProgress(caller, EnumConverter.Convert<DuplicatiOperation>(operation), EnumConverter.Convert<DuplicatiOperationMode>(specificmode), progress, subprogress, message, submessage);
}
void Duplicati_OperationProgress(Duplicati.Library.Main.Interface caller, DuplicatiOperation operation, DuplicatiOperationMode specificmode, int progress, int subprogress, string message, string submessage)
{
m_lastEvent.Operation = operation;
m_lastEvent.Mode = specificmode;
m_lastEvent.Progress = progress;
m_lastEvent.SubProgress = subprogress;
m_lastEvent.Message = message;
m_lastEvent.SubMessage = submessage;
//If there are extra operations, reserve some space for it by reducing the displayed progress
if (m_extraOperations > 0 && progress > 0)
progress = (int)((m_lastPGProgress / 100.0) * (100 - (m_extraOperations * PERCENT_PR_EXTRA_OPERATION)));
progress = (int)((m_lastEvent.Progress / 100.0) * (100 - (m_extraOperations * PERCENT_PR_EXTRA_OPERATION)));
if (ProgressEvent != null)
try { ProgressEvent(operation, RunnerState.Running, message, submessage, progress, subprogress); }
@@ -397,10 +395,9 @@ namespace Duplicati.Server
public void ReinvokeLastProgressEvent()
{
Duplicati_OperationProgress(null, m_lastPGOperation, m_lastPGMode, m_lastPGProgress, m_lastPGSubprogress, m_lastPGmessage, m_lastPGSubmessage );
Duplicati_OperationProgress(null, m_lastEvent.Operation, m_lastEvent.Mode, m_lastEvent.Progress, m_lastEvent.SubProgress, m_lastEvent.Message, m_lastEvent.SubMessage );
}
private void PerformBackup(Schedule schedule, bool forceFull, string fullAfter)
{
if (forceFull)
@@ -425,7 +422,7 @@ namespace Duplicati.Server
return task.Backups;
}
public List<ManifestEntry> ListBackupEntries(Schedule schedule)
public List<Duplicati.Library.Main.ManifestEntry> ListBackupEntries(Schedule schedule)
{
ListBackupEntriesTask task = new ListBackupEntriesTask(schedule);
ExecuteTask(task);
@@ -527,6 +524,9 @@ namespace Duplicati.Server
m_currentBackupControlInterface.Resume();
}
public RunnerState CurrentState { get { return m_currentRunnerState; } }
public ProgressEventData LastEvent { get { return m_lastEvent; } }
public void Stop()
{
Stop(CloseReason.None);
+16
View File
@@ -240,5 +240,21 @@ namespace Duplicati.Server
}
}
}
/// <summary>
/// Suspends the backups for a given period
/// </summary>
/// <param name="timeout">The duration to wait</param>
public void Pause(TimeSpan timeout)
{
lock (m_lock)
{
if (m_state == LiveControlState.Running)
{
Pause();
m_waitTimer.Change((long)timeout.TotalMilliseconds, System.Threading.Timeout.Infinite);
}
}
}
}
}
+4 -12
View File
@@ -83,17 +83,12 @@ namespace Duplicati.Server
/// </summary>
public static WebServer WebServer;
/// <summary>
/// The queue for handling events
/// </summary>
public static EventQueue Events;
/// <summary>
/// The main entry point for the application.
/// <param name="args">Commandline arguments</param>
/// </summary>
[STAThread]
static void Main(string[] args)
public static void Main(string[] args)
{
//If we are on Windows, append the bundled "win-tools" programs to the search path
//We add it last, to allow the user to override with other versions
@@ -262,28 +257,25 @@ namespace Duplicati.Server
ApplicationExitEvent = new System.Threading.ManualResetEvent(false);
Events = new EventQueue();
LiveControl = new LiveControls(new Duplicati.Datamodel.ApplicationSettings(DataConnection));
LiveControl.StateChanged += new EventHandler(LiveControl_StateChanged);
LiveControl.ThreadPriorityChanged += new EventHandler(LiveControl_ThreadPriorityChanged);
LiveControl.ThrottleSpeedChanged += new EventHandler(LiveControl_ThrottleSpeedChanged);
Runner = new DuplicatiRunner();
WorkThread = new Duplicati.Library.Utility.WorkerThread<IDuplicityTask>(new Duplicati.Library.Utility.WorkerThread<IDuplicityTask>.ProcessItemDelegate(Runner.ExecuteTask), LiveControl.State == LiveControls.LiveControlState.Paused);
Scheduler = new Scheduler(DataConnection, WorkThread, MainLock);
WorkThread.StartingWork += new EventHandler(Events.WorkThread_StartingWork);
/*WorkThread.StartingWork += new EventHandler(Events.WorkThread_StartingWork);
WorkThread.CompletedWork += new EventHandler(Events.WorkThread_CompletedWork);
WorkThread.WorkQueueChanged += new EventHandler(Events.WorkThread_WorkQueueChanged);
Scheduler.NewSchedule += new EventHandler(Events.Scheduler_NewSchedule);
Runner.ProgressEvent += new DuplicatiRunner.ProgressEventDelegate(Events.Runner_DuplicatiProgress);
DataConnection.AfterDataConnection += new System.Data.LightDatamodel.DataConnectionEventHandler(Events.DataConnection_AfterDataConnection);
LiveControl.StateChanged += new EventHandler(Events.LiveControl_StateChanged);
LiveControl.ThreadPriorityChanged += new EventHandler(Events.LiveControl_ThreadPriorityChanged);
LiveControl.ThrottleSpeedChanged += new EventHandler(Events.LiveControl_ThrottleSpeedChanged);
LiveControl.ThrottleSpeedChanged += new EventHandler(Events.LiveControl_ThrottleSpeedChanged);*/
Program.WebServer = new Server.WebServer(8080);
+66
View File
@@ -0,0 +1,66 @@
#region "Disclaimer / License"
// Copyright (C) 2011, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#endregion
using System;
using System.Linq;
using System.Collections.Generic;
using Duplicati.Server.Serialization;
namespace Duplicati.Server
{
/// <summary>
/// This class collects all reportable status properties into a single class that can be exported as JSON
/// </summary>
public class SerializableStatus : ISerializableStatus
{
public LiveControlState ProgramState
{
get { return EnumConverter.Convert<LiveControlState>(Program.LiveControl.State); }
}
public RunnerState ActiveBackupState
{
get { return Program.Runner.CurrentState; }
}
public long ActiveScheduleId
{
get
{
IDuplicityTask t = Program.WorkThread.CurrentTask;
if (t == null || t.Schedule == null)
return -1;
else
return t.Schedule.ID;
}
}
public IList<long> SchedulerQueueIds
{
get { return Program.Scheduler.Schedule.Select(x => x.ID).ToList(); }
}
public IProgressEventData RunningBackupStatus
{
get { return Program.Runner.LastEvent; }
}
}
}
+207 -59
View File
@@ -4,13 +4,18 @@ using System.Linq;
using System.Text;
using HttpServer.MVC;
using HttpServer.HttpModules;
using System.IO;
using Duplicati.Server.Serialization;
namespace Duplicati.Server
{
public class WebServer
{
/// <summary>
/// The single webserver instance
/// </summary>
private HttpServer.HttpServer m_server;
public WebServer(int port)
{
m_server = new HttpServer.HttpServer();
@@ -27,115 +32,258 @@ namespace Duplicati.Server
private class BodyWriter : System.IO.StreamWriter, IDisposable
{
private HttpServer.IHttpResponse m_resp;
// We override the format provider so all JSON output uses US format
public override IFormatProvider FormatProvider
{
get { return System.Globalization.CultureInfo.InvariantCulture; }
}
public BodyWriter(HttpServer.IHttpResponse resp)
: base(resp.Body, resp.Encoding)
: base(resp.Body, resp.Encoding)
{
m_resp = resp;
}
protected override void Dispose(bool disposing)
protected override void Dispose (bool disposing)
{
base.Flush();
m_resp.ContentLength = base.BaseStream.Length;
m_resp.Send();
if (!m_resp.HeadersSent)
{
base.Flush();
m_resp.ContentLength = base.BaseStream.Length;
m_resp.Send();
}
base.Dispose(disposing);
}
}
private class DynamicHandler : HttpModule
{
private delegate void ProcessSub(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session);
private delegate void ProcessSub(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter writer);
private Server.Serialization.Serializer m_serializer;
private readonly Dictionary<string, ProcessSub> SUPPORTED_METHODS;
public DynamicHandler()
{
m_serializer = new Serializer();
SUPPORTED_METHODS = new Dictionary<string, ProcessSub>(System.StringComparer.InvariantCultureIgnoreCase);
//Make a list of all supported actions
SUPPORTED_METHODS.Add("supported-actions", ListSupportedActions);
SUPPORTED_METHODS.Add("list-schedules", ListSchedules);
SUPPORTED_METHODS.Add("get-current-state", GetCurrentState);
SUPPORTED_METHODS.Add("list-application-settings", ListApplicationSettings);
SUPPORTED_METHODS.Add("list-installed-backends", GetInstalledBackends);
SUPPORTED_METHODS.Add("list-installed-encryption-modules", ListInstalledEncryptionModules);
SUPPORTED_METHODS.Add("list-installed-compression-modules", ListInstalledCompressionModules);
SUPPORTED_METHODS.Add("list-installed-generic-modules", ListInstalledGenericModules);
SUPPORTED_METHODS.Add("list-options", ListCoreOptions);
SUPPORTED_METHODS.Add("list-recent-completed", ListRecentCompleted);
SUPPORTED_METHODS.Add("get-recent-log-details", GetLogBlob);
SUPPORTED_METHODS.Add("send-command", SendCommand);
}
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
public override bool Process (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
{
//We use the fake entry point /control.cgi to listen for requests
//This ensures that the rest of the webserver can just serve plain files
if (!request.Uri.AbsolutePath.Equals("/control.cgi", StringComparison.InvariantCultureIgnoreCase))
return false;
HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
string action = input["action"].Value ?? "";
//Lookup the actual handler method
ProcessSub method;
SUPPORTED_METHODS.TryGetValue(action, out method);
if (method == null)
{
if (method == null) {
response.Status = System.Net.HttpStatusCode.NotImplemented;
response.Reason = "Unsupported action: " + (action == null ? "<null>" : "");
response.Send();
}
else
{
} else {
//Default setup
response.Status = System.Net.HttpStatusCode.OK;
response.Reason = "OK";
//response.ContentType = "text/json";
#if DEBUG
response.ContentType = "text/plain";
method(request, response, session);
#else
response.ContentType = "text/json";
#endif
using (BodyWriter bw = new BodyWriter(response))
{
try
{
method(request, response, session, bw);
}
catch (Exception ex)
{
if (!response.HeadersSent)
{
response.Status = System.Net.HttpStatusCode.InternalServerError;
response.Reason = ex.Message;
response.ContentType = "text/plain";
bw.WriteLine("Internal error");
#if DEBUG
bw.Write("Stacktrace: " + ex.ToString());
#endif
bw.Flush();
}
}
}
}
return true;
}
private void ListSchedules(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
private void ReportError(HttpServer.IHttpResponse response, BodyWriter bw, string message)
{
using (var b = new BodyWriter(response))
response.Status = System.Net.HttpStatusCode.InternalServerError;
response.Reason = message;
OutputObject(bw, new { Error = message });
}
private void OutputObject (BodyWriter b, object o)
{
m_serializer.SerializeJson(b, o);
}
private void ListSupportedActions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, new { Version = 1, Methods = SUPPORTED_METHODS.Keys });
}
private void ListSchedules (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Program.DataConnection.GetObjects<Datamodel.Schedule>());
}
private void GetCurrentState (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, new SerializableStatus());
}
private void GetInstalledBackends(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Duplicati.Library.DynamicLoader.BackendLoader.Backends);
}
private void ListInstalledEncryptionModules(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Duplicati.Library.DynamicLoader.EncryptionLoader.Modules);
}
private void ListInstalledCompressionModules(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Duplicati.Library.DynamicLoader.CompressionLoader.Modules);
}
private void ListInstalledGenericModules(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Duplicati.Library.DynamicLoader.GenericLoader.Modules);
}
private void ListCoreOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, new Duplicati.Library.Main.Options(new Dictionary<string, string>()).SupportedCommands);
}
private void ListRecentCompleted(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
OutputObject(bw, Program.DataConnection.GetObjects<Datamodel.Log>("EndTime > ? AND SubAction LIKE ? ORDER BY EndTime DESC", Library.Utility.Timeparser.ParseTimeInterval(new Datamodel.ApplicationSettings(Program.DataConnection).RecentBackupDuration, DateTime.Now, true), "Primary"));
}
private void GetLogBlob(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
long id;
if (!long.TryParse(input["id"].Value, out id))
ReportError(response, bw, "Invalid or missing log id");
else
{
LitJson.JsonWriter w = new LitJson.JsonWriter(b);
w.WriteArrayStart();
foreach (Datamodel.Schedule s in Program.DataConnection.GetObjects<Datamodel.Schedule>())
{
w.WriteObjectStart();
w.WritePropertyName("name");
w.Write(s.Name);
w.WritePropertyName("id");
w.Write(s.ID);
w.WriteObjectEnd();
}
w.WriteArrayEnd();
Datamodel.LogBlob lb = Program.DataConnection.GetObject<Datamodel.LogBlob>("LogId = ?", id);
OutputObject(bw, lb);
}
}
private void GetCurrentState(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
private void ListApplicationSettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
using (var b = new BodyWriter(response))
{
LitJson.JsonWriter w = new LitJson.JsonWriter(b);
w.WriteObjectStart();
w.WritePropertyName("eventid");
w.Write(Program.Events.CurrentEventId);
w.WritePropertyName("paused");
w.Write(Program.LiveControl.State.ToString());
w.WritePropertyName("pause-timeout");
w.Write(0);
w.WriteObjectEnd();
}
OutputObject(bw, new Datamodel.ApplicationSettings(Program.DataConnection));
}
private void SendCommand(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
{
HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
string command = input["command"].Value ?? "";
long id;
switch (command.ToLowerInvariant())
{
case "pause":
if (input.Contains("duration"))
{
TimeSpan ts;
try { ts = Library.Utility.Timeparser.ParseTimeSpan(input["duration"].Value); }
catch (Exception ex)
{
ReportError(response, bw, ex.Message);
return;
}
Program.LiveControl.Pause(ts);
}
else
{
Program.LiveControl.Pause();
}
break;
case "resume":
Program.LiveControl.Resume();
break;
case "stop":
if (!Program.Runner.IsStopRequested)
Program.Runner.Stop(CloseReason.UserClosing);
break;
case "abort":
if (!Program.Runner.IsStopRequested)
{
Program.Runner.Stop(CloseReason.UserClosing);
Program.Runner.Stop(CloseReason.UserClosing);
}
break;
case "run":
case "run-backup":
{
Datamodel.Schedule schedule = null;
if (long.TryParse(input["id"].Value, out id))
schedule = Program.DataConnection.GetObjectById<Datamodel.Schedule>(id);
if (schedule == null)
{
ReportError(response, bw, string.Format("No backup found for id: {0}", input["id"].Value));
return;
}
if (Library.Utility.Utility.ParseBoolOption(input["full"].ToDictionary(x => x.Name, x => x.Value), "full"))
Program.WorkThread.AddTask(new FullBackupTask(schedule));
else
Program.WorkThread.AddTask(new IncrementalBackupTask(schedule));
}
break;
default:
ReportError(response, bw, string.Format("Unsupported command {0}", command));
break;
}
OutputObject(bw, new { Status = "OK" });
}
}
}
}
+5 -1
View File
@@ -1,3 +1,7 @@
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>